Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions booking_engine/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
],
'data': [
'data/res_config_settings.xml',
'data/ir_model.xml',
'data/ir_model_access.xml',
'data/ir_model_fields.xml',
'data/account_tax.xml',
'data/product_template.xml',
Expand Down
11 changes: 1 addition & 10 deletions booking_engine/data/base_automation.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="industry_on_so_line" model="base.automation">
<field name="model_id" ref="sale.model_sale_order"/>
<field name="action_server_ids" eval="[(6, 0, [ref('industry_add_update')])]"/>
<field name="trigger">on_create_or_write</field>
<field name="name">On SO line edit, add/edit city tax</field>
<field name="trigger_field_ids" eval="[(6, 0, [ref('sale_model_sale_order_x_picked_up')])]"/>
<field name="filter_pre_domain">[('x_picked_up', '=', False)]</field>
<field name="filter_domain">[('x_picked_up', '=', True)]</field>
</record>
<record id="industry_on_slot_fix_times" model="base.automation">
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="action_server_ids" eval="[(6, 0, [ref('industry_fix_slot_times'), ref('industry_trigger_so_update_from_slot')])]"/>
<field name="action_server_ids" eval="[(6, 0, [ref('industry_fix_slot_times')])]"/>
<field name="trigger">on_create_or_write</field>
<field name="name">Fix Slot Times</field>
<field name="trigger_field_ids" eval="[(6, 0, [ref('planning.field_planning_slot__end_datetime'), ref('planning.field_planning_slot__start_datetime'), ref('sale_planning.field_planning_slot__sale_line_id')])]"/>
Expand Down
111 changes: 57 additions & 54 deletions booking_engine/data/ir_actions_server.xml
Original file line number Diff line number Diff line change
@@ -1,59 +1,52 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="industry_add_update" model="ir.actions.server">
<record id="update_city_tax_action" model="ir.actions.server">
<field name="name">Add/Update City Tax</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="usage">base_automation</field>
<field name="model_id" ref="x_model_city_tax"/>
<field name="state">code</field>
<field name="code"><![CDATA[for record in records:
stay_taxes = 0
stay_tax_line = False
for so_line in record.order_line:
if so_line.product_id.x_is_a_room_offer:
if so_line.x_nights > 0: stay_taxes += so_line.x_nights
if so_line.product_id.x_is_stay_tax: stay_tax_line = so_line
if stay_taxes > 0:
if stay_tax_line: stay_tax_line['product_uom_qty'] = stay_taxes
else: # Add stay tax product
product = env['product.product'].search([('x_is_stay_tax', '=', True)], limit=1)
env['sale.order.line'].create({'order_id': record.id, 'product_id': product.id, 'product_uom_qty': stay_taxes})
<field name="code"><![CDATA[
stay_tax_line = False
sequence = 0
for so_line in record.x_sale_order_id.order_line:
if so_line.product_id.x_is_stay_tax: stay_tax_line = so_line
sequence = max(sequence, so_line.sequence)
if stay_tax_line: stay_tax_line.write({'product_uom_qty': record.x_total, 'qty_delivered': record.x_total, 'sequence': 1 + sequence})
elif record.x_total > 0:
product = env['product.product'].search([('x_is_stay_tax', '=', True)], limit=1)
env['sale.order.line'].create({'order_id': record.x_sale_order_id.id, 'product_id': product.id, 'product_uom_qty': record.x_total, 'qty_delivered': record.x_total})
]]></field>
</record>
<record id="industry_trigger_so_update_from_slot" model="ir.actions.server">
<field name="name">Trigger SO Update from Slot</field>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="usage">base_automation</field>
<record id="open_x_city_tax_action" model="ir.actions.server">
<field name="name">Open City Tax</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="state">code</field>
<field name="code"><![CDATA[
sale_order = record.sale_order_id
if sale_order:
stay_taxes = 0
stay_tax_line = False
for so_line in sale_order.order_line:
if so_line.product_id.x_is_a_room_offer:
if so_line.x_nights > 0:
stay_taxes += so_line.x_nights
if so_line.product_id.x_is_stay_tax:
stay_tax_line = so_line
if stay_taxes > 0:
if stay_tax_line:
stay_tax_line['product_uom_qty'] = stay_taxes
record.order_line.planning_slot_ids['x_guests'] = len(record.x_guests) // (len(record.order_line.planning_slot_ids) or 1) or 1
action = {
'type': 'ir.actions.act_window',
'name': 'City tax',
'res_model': 'x_city_tax',
'view_mode': 'form',
'target': 'new',
'context': {'search_default_x_sale_order_id': record.id, 'default_x_sale_order_id': record.id},
'domain': [('x_sale_order_id', '=', record.id)],
}
]]></field>
</record>
<record id="industry_fix_slot_times" model="ir.actions.server">
<field name="binding_model_id" ref="planning.model_planning_slot"/>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="usage">base_automation</field>
<field name="state">code</field>
<field name="name">Fix Slot Times</field>
<field name="code"><![CDATA[def ceil(x):
return int(x) if x == int(x) else int(x) + 1
<record id="industry_fix_slot_times" model="ir.actions.server">
<field name="binding_model_id" ref="planning.model_planning_slot"/>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="usage">base_automation</field>
<field name="state">code</field>
<field name="name">Fix Slot Times</field>
<field name="code"><![CDATA[
pickup_time = env.ref('sale_renting.recurrence_nightly').pickup_time
return_time = env.ref('sale_renting.recurrence_nightly').return_time
start_datetime = record.start_datetime.astimezone(tz=dateutil.tz.UTC)
end_datetime = record.end_datetime.astimezone(tz=dateutil.tz.UTC)
tz = env.ref('website.default_website').tz
if record.role_id.x_is_a_room_offer:
for record in records:
if not record.role_id.x_is_a_room_offer: continue
start_datetime = record.start_datetime.astimezone(tz=dateutil.tz.UTC)
end_datetime = record.end_datetime.astimezone(tz=dateutil.tz.UTC)
if record.start_datetime and str(record.start_datetime.time()) != f"{int(pickup_time):02d}:{int(pickup_time % 1 * 60):02d}:00":
start = timezone(tz).localize(datetime.datetime(year=start_datetime.year, month=start_datetime.month, day=start_datetime.day, hour=int(pickup_time), minute=int(pickup_time % 1 * 60), second=0))
start_datetime = start.astimezone(tz=dateutil.tz.UTC)
Expand All @@ -66,12 +59,10 @@ if record.role_id.x_is_a_room_offer:
end_datetime = end_datetime + datetime.timedelta(days=1)
record['start_datetime'] = start_datetime.replace(tzinfo=None)
record['end_datetime'] = end_datetime.replace(tzinfo=None)
if record.sale_line_id:
for record in records:
nights = 0
if record.sale_line_id.planning_slot_ids:
for slot in record.sale_line_id.planning_slot_ids:
if slot.start_datetime and slot.end_datetime:
nights += ceil((slot.end_datetime - slot.start_datetime).total_seconds() / (24 * 3600))
if record.sale_line_id and record.sale_line_id.planning_slot_ids:
nights = sum(record.sale_line_id.planning_slot_ids.mapped('x_nights'))
record.sale_line_id.update({
'start_date': record.start_datetime,
'return_date': record.end_datetime,
Expand All @@ -91,14 +82,26 @@ return_time = env.ref('sale_renting.recurrence_nightly').return_time
for record in records:
tz = env.ref('website.default_website').tz
rental_start_date = record.rental_start_date.astimezone(tz=dateutil.tz.gettz(tz))
start = rental_start_date.replace(hour=int(pickup_time), minute=int(pickup_time % 1 * 60), second=0)
record['rental_start_date'] = start.astimezone(tz=dateutil.tz.UTC).replace(tzinfo=None)

rental_return_date = record.rental_return_date.astimezone(tz=dateutil.tz.gettz(tz))
start = rental_start_date.replace(hour=int(pickup_time), minute=int(pickup_time % 1 * 60), second=0, microsecond=0)
start_datetime = start.astimezone(tz=dateutil.tz.UTC)
record['rental_start_date'] = start_datetime.replace(tzinfo=None)
end = rental_return_date.replace(hour=int(return_time), minute=int(return_time % 1 * 60), second=0, microsecond=0)
end_datetime = end.astimezone(tz=dateutil.tz.UTC)
record['rental_return_date'] = end_datetime.replace(tzinfo=None)
end = rental_return_date.replace(hour=int(return_time), minute=int(return_time % 1 * 60), second=0)
record['rental_return_date'] = end.astimezone(tz=dateutil.tz.UTC).replace(tzinfo=None)
record.action_update_rental_prices()
]]></field>
</record>
<record id="apply_rental_check_out" model="ir.actions.server">
<field name="name">Apply Rental Checkout</field>
<field name="model_id" ref="sale_renting.model_rental_order_wizard"/>
<field name="state">code</field>
<field name="code"><![CDATA[
id = record.order_id.id
record.apply()
if record.order_id.rental_status == "returned":
action = record.env['ir.actions.server'].browse(record.env.ref('booking_engine.open_x_city_tax_action').id)
# raise UserError("sale order: " + str(record.order_id.id) + "\naction = " + str(action))
action.with_context(active_id=id, active_model="sale.order").run()
]]></field>
</record>
</odoo>
8 changes: 8 additions & 0 deletions booking_engine/data/ir_model.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="x_model_city_tax" model="ir.model">
<field name="name">City tax</field>
<field name="model">x_city_tax</field>
<field name="transient" eval="True" />
</record>
</odoo>
12 changes: 12 additions & 0 deletions booking_engine/data/ir_model_access.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="city_tax_access" model="ir.model.access">
<field name="group_id" ref="base.group_user"/>
<field name="model_id" ref="x_model_city_tax"/>
<field name="name">x_city_tax_user_access</field>
<field name="perm_create" eval="True"/>
<field name="perm_read" eval="True"/>
<field name="perm_unlink" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
</odoo>
85 changes: 76 additions & 9 deletions booking_engine/data/ir_model_fields.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@
<field name="relation_table">x_res_partner_sale_order_rel</field>
</record>
<record id="base_model_res_partner_x_identity_check_field" model="ir.model.fields">
<field name="compute"><![CDATA[for record in self:
<field name="compute"><![CDATA[
for record in self:
if not record.x_nationality and not record.x_document_type and not record.x_document_number:
record['x_identity_check'] = 'na'
elif record.x_nationality and record.x_document_type and record.x_document_number:
record['x_identity_check'] = 'ok'
else:
record['x_identity_check'] = 'invalid'
else: record['x_identity_check'] = 'invalid'
]]></field>
<field name="ttype">selection</field>
<field name="depends">x_nationality, x_document_type, x_document_number</field>
Expand Down Expand Up @@ -113,7 +113,8 @@
<field name="field_description">Order Involves Room</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="name">x_order_involves_room</field>
<field name="compute"><![CDATA[for record in self:
<field name="compute"><![CDATA[
for record in self:
record['x_order_involves_room'] = any(line.product_id.x_is_a_room_offer for line in record.order_line)
]]></field>
<field name="depends">order_line</field>
Expand All @@ -124,7 +125,8 @@
<field name="readonly" eval="True"/>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="name">x_picked_up</field>
<field name="compute"><![CDATA[for record in self:
<field name="compute"><![CDATA[
for record in self:
record['x_picked_up'] = False
if record.state == 'sale' and record.is_rental_order:
rental_order_lines = record.order_line.filtered(lambda line: line.is_rental and line.product_type != 'combo')
Expand All @@ -133,7 +135,8 @@
<field name="depends">order_line.qty_delivered</field>
</record>
<record id="res_partner_x_guests_count" model="ir.model.fields">
<field name="compute"><![CDATA[for record in self:
<field name="compute"><![CDATA[
for record in self:
record['x_guests_count'] = self.env['sale.order'].search_count([('x_guests', '=', record.id)])
]]></field>
<field name="ttype">integer</field>
Expand All @@ -160,9 +163,9 @@
<field name="relation">res.partner</field>
<field name="readonly" eval="True"/>
<field name="depends">x_ongoing_booking.partner_id</field>
<field name="compute"><![CDATA[for record in self:
booking = record.x_ongoing_booking
record['x_occupant'] = booking[:1].partner_id.id
<field name="compute"><![CDATA[
for record in self:
record['x_occupant'] = record.x_ongoing_booking[:1].partner_id.id
]]></field>
</record>
<record id="res_partner_x_ongoing_bookings" model="ir.model.fields">
Expand All @@ -174,4 +177,68 @@
<field name="readonly" eval="True"/>
<field name="name">x_ongoing_bookings</field>
</record>
<record id="model_planning_slot_x_nights" model="ir.model.fields">
<field name="ttype">integer</field>
<field name="field_description">Nights</field>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="depends">start_datetime, end_datetime</field>
<field name="name">x_nights</field>
<field name="compute"><![CDATA[
for record in self:
record['x_nights'] = ((record.end_datetime - record.start_datetime).total_seconds() + 86399) // 86400
]]></field>
</record>
<record id="model_planning_slot_x_guests" model="ir.model.fields">
<field name="ttype">integer</field>
<field name="field_description">Guests</field>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="name">x_guests</field>
</record>
<record id="model_planning_slot_x_city_tax" model="ir.model.fields">
<field name="ttype">integer</field>
<field name="field_description">City tax count</field>
<field name="model_id" ref="planning.model_planning_slot"/>
<field name="depends">x_nights, x_guests</field>
<field name="name">x_city_tax</field>
<field name="compute"><![CDATA[
for record in self:
record['x_city_tax'] = record.x_nights * record.x_guests
]]></field>
</record>
<record id="x_model_city_tax_x_sale_order_id" model="ir.model.fields">
<field name="ttype">many2one</field>
<field name="field_description">Sale order</field>
<field name="model_id" ref="x_model_city_tax"/>
<field name="relation">sale.order</field>
<field name="name">x_sale_order_id</field>
<field name="readonly" eval="True"/>
</record>
<record id="x_model_city_tax_x_slot_ids" model="ir.model.fields">
<field name="ttype">many2many</field>
<field name="field_description">Slots</field>
<field name="model_id" ref="x_model_city_tax"/>
<field name="relation">planning.slot</field>
<field name="relation_table">x_planning_slot_city_tax_rel</field>
<field name="depends">x_sale_order_id.order_line.planning_slot_ids</field>
<field name="name">x_slot_ids</field>
<field name="compute"><![CDATA[
for record in self:
record['x_slot_ids'] = record.x_sale_order_id.order_line.planning_slot_ids
]]></field>
<field name="store" eval="False"/>
</record>
<record id="x_model_city_tax_x_total" model="ir.model.fields">
<field name="ttype">integer</field>
<field name="field_description">Total</field>
<field name="model_id" ref="x_model_city_tax"/>
<field name="relation_field">planning_total</field>
<field name="name">x_total</field>
<field name="depends">x_slot_ids.x_city_tax</field>
<field name="compute"><![CDATA[
for record in self:
record['x_total'] = sum(record.x_slot_ids.mapped('x_city_tax'))
]]></field>
<field name="readonly" eval="True"/>
<field name="selectable" eval="False"/>
</record>
</odoo>
44 changes: 43 additions & 1 deletion booking_engine/data/ir_ui_view.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<record id="x_city_tax_form_view" model="ir.ui.view">
<field name="arch" type="xml">
<form>
<field name="x_slot_ids">
<list string="City tax" editable="bottom" multi_edit="1" class="d-flex">
<field name="role_id" string="Room" readonly="True" width="92px"/>
<field name="start_datetime" string="Slot" readonly="True" widget="daterange" options="{'end_date_field': 'end_datetime'}"/>
<field name="x_nights"/>
<field name="x_guests"/>
<field name="x_city_tax"/>
</list>
</field>
<group class="d-flex justify-content-end">
<field name="x_total" class="text-center"/>
</group>
<footer>
<button string="Save" class="btn btn-primary" type="action" name="%(update_city_tax_action)d"/>
<button special="cancel" string="Cancel" class="btn btn-secondary"/>
</footer>
</form>
</field>
<field name="mode">primary</field>
<field name="model">x_city_tax</field>
<field name="name">x_city_tax.form.booking_engine</field>
<field name="priority">200</field>
<field name="type">form</field>
<field name="active" eval="True"/>
</record>
<record id="rental_order_view_inherit" model="ir.ui.view">
<field name="arch" type="xml">
<xpath expr="//button[@name='apply']" position="replace">
<button string="Validate" class="btn btn-primary" type="action" name="%(apply_rental_check_out)d" data-hotkey="q"/>
</xpath>
</field>
<field name="inherit_id" ref="sale_renting.rental_order_wizard_view_form"/>
<field name="mode">extension</field>
<field name="model">rental.order.wizard</field>
<field name="name">rental.order.wizard.form.booking_engine</field>
<field name="priority">200</field>
<field name="type">form</field>
<field name="active" eval="True"/>
</record>
<record id="rental_order_view" model="ir.ui.view">
<field name="arch" type="xml">
<xpath expr="//button[@name='action_open_pickup']" position="attributes">
Expand All @@ -9,7 +51,7 @@
<attribute name="string">Check Out</attribute>
</xpath>
<xpath expr="//field[@name='is_rental_order']" position="after">
<button string="City Tax" name="%(industry_add_update)d" type="action"/>
<button string="City Tax" type="action" name="%(open_x_city_tax_action)d"/>
</xpath>
<xpath expr="//form[1]/sheet[1]/notebook[1]" position="inside">
<page string="Guests">
Expand Down
Loading