mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] Sequence by property
This commit is contained in:
@@ -28,8 +28,8 @@
|
||||
"security/pms_security.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"data/cron_jobs.xml",
|
||||
"data/pms_data.xml",
|
||||
"data/pms_sequence.xml",
|
||||
"data/pms_data.xml",
|
||||
"report/pms_folio.xml",
|
||||
"report/pms_folio_templates.xml",
|
||||
#"templates/pms_email_template.xml",
|
||||
@@ -61,6 +61,7 @@
|
||||
"views/product_pricelist_views.xml",
|
||||
"views/product_template_views.xml",
|
||||
"views/webclient_templates.xml",
|
||||
"views/ir_sequence_views.xml"
|
||||
],
|
||||
"demo": ["demo/pms_master_data.xml", "demo/pms_reservation.xml"],
|
||||
"qweb": ["static/src/xml/pms_base_templates.xml",],
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<field name="phone">+34 123 456 879</field>
|
||||
<field name="email">commitsun@hootel.com</field>
|
||||
<field name="website">https://www.commitsun.com</field>
|
||||
<field name="folio_sequence_id" ref="pms.seq_pms_folio" />
|
||||
</record>
|
||||
<record model="res.users" id="base.user_root">
|
||||
<field name="company_id" ref="base.main_company" />
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import ir_http
|
||||
from . import ir_sequence
|
||||
#from . import payment_return
|
||||
from . import pms_board_service_room_type
|
||||
from . import pms_property
|
||||
|
||||
9
pms/models/ir_sequence.py
Normal file
9
pms/models/ir_sequence.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class IrSequence(models.Model):
|
||||
_inherit = "ir.sequence"
|
||||
|
||||
pms_property_id = fields.Many2one("pms.property", string="Property")
|
||||
@@ -14,10 +14,11 @@ class MailComposeMessage(models.TransientModel):
|
||||
and self._context.get("mark_so_as_sent")
|
||||
):
|
||||
folio = self.env["pms.folio"].browse([self._context["default_res_id"]])
|
||||
if folio:
|
||||
cmds = [
|
||||
(1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids
|
||||
]
|
||||
if any(cmds):
|
||||
folio.reservation_ids = cmds
|
||||
#TODO: WorkFlow Mails
|
||||
# if folio:
|
||||
# cmds = [
|
||||
# (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids
|
||||
# ]
|
||||
# if any(cmds):
|
||||
# folio.reservation_ids = cmds
|
||||
return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)
|
||||
|
||||
@@ -147,8 +147,9 @@ class PmsFolio(models.Model):
|
||||
)
|
||||
channel_type = fields.Selection(
|
||||
[("direct", "Direct"), ("agency", "Agency"),],
|
||||
"Sales Channel",
|
||||
default="direct",
|
||||
string="Sales Channel",
|
||||
compute="_compute_channel_type",
|
||||
store=True,
|
||||
)
|
||||
date_order = fields.Datetime(
|
||||
string="Order Date",
|
||||
@@ -286,6 +287,14 @@ class PmsFolio(models.Model):
|
||||
addr = folio.partner_id.address_get(["invoice"])
|
||||
folio.partner_invoice_id = addr["invoice"]
|
||||
|
||||
@api.depends("agency_id")
|
||||
def _compute_channel_type(self):
|
||||
for folio in self:
|
||||
if folio.agency_id:
|
||||
folio.channel_type = 'agency'
|
||||
else:
|
||||
folio.channel_type = 'direct'
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_payment_term_id(self):
|
||||
self.payment_term_id = False
|
||||
@@ -527,15 +536,13 @@ class PmsFolio(models.Model):
|
||||
# ORM Overrides
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
#TODO: Make sequence from property, not company
|
||||
if vals.get("name", _("New")) == _("New") or "name" not in vals:
|
||||
if "company_id" in vals:
|
||||
vals["name"] = self.env["ir.sequence"].with_context(
|
||||
force_company=vals["company_id"]
|
||||
).next_by_code("pms.folio") or _("New")
|
||||
else:
|
||||
vals["name"] = self.env["ir.sequence"].next_by_code("pms.folio") or _(
|
||||
"New"
|
||||
)
|
||||
#TODO: change for property env variable
|
||||
pms_property_id = self.env.user.pms_property_id.id if "pms_property_id" not in vals else vals["pms_property_id"]
|
||||
vals["name"] = self.env["ir.sequence"].search([
|
||||
('pms_property_id', '=', pms_property_id)
|
||||
]).next_by_code("pms.folio") or _("New")
|
||||
result = super(PmsFolio, self).create(vals)
|
||||
return result
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ class PmsProperty(models.Model):
|
||||
_name = "pms.property"
|
||||
_description = "Property"
|
||||
_inherits = {"res.partner": "partner_id"}
|
||||
_check_company_auto = True
|
||||
|
||||
# Fields declaration
|
||||
partner_id = fields.Many2one(
|
||||
@@ -51,6 +52,9 @@ class PmsProperty(models.Model):
|
||||
)
|
||||
default_cancel_policy_days = fields.Integer("Cancellation Days")
|
||||
default_cancel_policy_percent = fields.Float("Percent to pay")
|
||||
folio_sequence_id = fields.Many2one(
|
||||
'ir.sequence', 'Folio Sequence',
|
||||
check_company=True, copy=False)
|
||||
|
||||
# Constraints and onchanges
|
||||
@api.constrains("default_arrival_hour", "default_departure_hour")
|
||||
|
||||
@@ -15,7 +15,7 @@ class PmsReservation(models.Model):
|
||||
_name = "pms.reservation"
|
||||
_description = "Reservation"
|
||||
_inherit = ["mail.thread", "mail.activity.mixin", "portal.mixin"]
|
||||
_order = "last_updated_res desc, name"
|
||||
_order = "priority desc, name"
|
||||
_check_company_auto = True
|
||||
|
||||
# Default Methods ang Gets
|
||||
@@ -43,6 +43,7 @@ class PmsReservation(models.Model):
|
||||
|
||||
def _get_default_arrival_hour(self):
|
||||
folio = False
|
||||
#TODO: Change by property env variable (like company)
|
||||
default_arrival_hour = self.env.user.pms_property_id.default_arrival_hour
|
||||
if "folio_id" in self._context:
|
||||
folio = self.env["pms.folio"].search(
|
||||
@@ -55,6 +56,7 @@ class PmsReservation(models.Model):
|
||||
|
||||
def _get_default_departure_hour(self):
|
||||
folio = False
|
||||
#TODO: Change by property env variable (like company)
|
||||
default_departure_hour = self.env.user.pms_property_id.default_departure_hour
|
||||
if "folio_id" in self._context:
|
||||
folio = self.env["pms.folio"].search(
|
||||
@@ -65,6 +67,11 @@ class PmsReservation(models.Model):
|
||||
else:
|
||||
return default_departure_hour
|
||||
|
||||
@api.model
|
||||
def _get_default_pms_property(self):
|
||||
#TODO: Change by property env variable (like company)
|
||||
return self.env.user.pms_property_id
|
||||
|
||||
def _get_default_segmentation(self):
|
||||
folio = False
|
||||
segmentation_ids = False
|
||||
@@ -92,7 +99,11 @@ class PmsReservation(models.Model):
|
||||
|
||||
# Fields declaration
|
||||
name = fields.Text(
|
||||
"Reservation Description", compute="_compute_name", store=True, readonly=False,
|
||||
"Reservation Description",
|
||||
compute="_compute_name",
|
||||
store=True,
|
||||
readonly=False,
|
||||
#required=True,
|
||||
)
|
||||
priority = fields.Integer(compute="_compute_priority", store="True", index=True)
|
||||
room_id = fields.Many2one(
|
||||
@@ -103,13 +114,14 @@ class PmsReservation(models.Model):
|
||||
compute="_compute_room_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
#required=True,
|
||||
domain="[('id', 'in', allowed_room_ids)]",
|
||||
)
|
||||
allowed_room_ids = fields.Many2many(
|
||||
"pms.room", string="Allowed Rooms", compute="_compute_allowed_room_ids",
|
||||
)
|
||||
folio_id = fields.Many2one(
|
||||
"pms.folio", string="Folio", track_visibility="onchange", ondelete="cascade",
|
||||
"pms.folio", string="Folio", track_visibility="onchange", ondelete="restrict",
|
||||
)
|
||||
board_service_room_id = fields.Many2one(
|
||||
"pms.board.service.room.type", string="Board Service",
|
||||
@@ -118,6 +130,7 @@ class PmsReservation(models.Model):
|
||||
"pms.room.type",
|
||||
string="Room Type",
|
||||
track_visibility="onchange",
|
||||
required=True,
|
||||
compute="_compute_room_type_id",
|
||||
store=True,
|
||||
readonly=False,
|
||||
@@ -144,7 +157,7 @@ class PmsReservation(models.Model):
|
||||
related="folio_id.company_id", string="Company", store=True, readonly=True
|
||||
)
|
||||
pms_property_id = fields.Many2one(
|
||||
"pms.property", store=True, readonly=True, related="folio_id.pms_property_id"
|
||||
"pms.property", default=_get_default_pms_property, #required=True
|
||||
)
|
||||
reservation_line_ids = fields.One2many(
|
||||
"pms.reservation.line",
|
||||
@@ -284,10 +297,6 @@ class PmsReservation(models.Model):
|
||||
detail_origin = fields.Char(
|
||||
"Detail Origin", compute="_compute_detail_origin", store=True
|
||||
)
|
||||
# TODO: Review functionality of last_update_res
|
||||
last_updated_res = fields.Datetime(
|
||||
"Last Updated", compute="_compute_last_updated_res", store=True, readonly=False,
|
||||
)
|
||||
folio_pending_amount = fields.Monetary(related="folio_id.pending_amount")
|
||||
shared_folio = fields.Boolean(compute="_computed_shared")
|
||||
# Used to notify is the reservation folio has other reservations/services
|
||||
@@ -371,6 +380,7 @@ class PmsReservation(models.Model):
|
||||
# Compute and Search methods
|
||||
@api.depends("checkin", "checkout", "room_type_id")
|
||||
def _compute_name(self):
|
||||
_logger.info("CALCULO NOMBRE-------------------")
|
||||
for reservation in self:
|
||||
if (
|
||||
reservation.room_type_id
|
||||
@@ -388,6 +398,8 @@ class PmsReservation(models.Model):
|
||||
)
|
||||
else:
|
||||
reservation.name = "/"
|
||||
_logger.info("RESERVA")
|
||||
_logger.info(reservation.name)
|
||||
|
||||
@api.depends("checkin")
|
||||
def _compute_priority(self):
|
||||
@@ -430,7 +442,7 @@ class PmsReservation(models.Model):
|
||||
def _compute_partner_id(self):
|
||||
for reservation in self:
|
||||
if reservation.reservation_type == "out":
|
||||
reservation.partner_id = self.env.user.pms_property_id.partner_id.id
|
||||
reservation.partner_id = reservation.pms_property_id.partner_id.id
|
||||
if reservation.folio_id:
|
||||
reservation.partner_id = reservation.folio_id.partner_id
|
||||
else:
|
||||
@@ -513,18 +525,6 @@ class PmsReservation(models.Model):
|
||||
elif reservation.adults == False:
|
||||
reservation.adults = 0
|
||||
|
||||
@api.depends("checkin", "checkout", "state")
|
||||
def _compute_to_send(self):
|
||||
for reservation in self:
|
||||
reservation.to_send = True
|
||||
|
||||
@api.depends(
|
||||
"checkin", "checkout", "discount", "state", "room_type_id", "to_assign"
|
||||
)
|
||||
def _compute_last_updated_res(self):
|
||||
for reservation in self:
|
||||
reservation.last_updated_res = fields.Datetime.now()
|
||||
|
||||
@api.depends("reservation_line_ids", "reservation_line_ids.room_id")
|
||||
def _compute_splitted(self):
|
||||
for reservation in self:
|
||||
@@ -687,6 +687,20 @@ class PmsReservation(models.Model):
|
||||
if len(record.checkin_partner_ids) > record.adults + record.children:
|
||||
raise models.ValidationError(_("The room already is completed"))
|
||||
|
||||
@api.constrains("reservation_type", "partner_id")
|
||||
def _check_partner_reservation(self):
|
||||
for reservation in self:
|
||||
if reservation.reservation_type == "out" and \
|
||||
reservation.partner_id != reservation.pms_property_id.partner_id.id:
|
||||
raise models.ValidationError(_("The partner on out reservations must be a property partner"))
|
||||
|
||||
@api.constrains("closure_reason_id", "reservation_type")
|
||||
def _check_partner_reservation(self):
|
||||
for reservation in self:
|
||||
if reservation.closure_reason_id and \
|
||||
reservation.reservation_type != 'out':
|
||||
raise models.ValidationError(_("Only the out reservations can has a clousure reason"))
|
||||
|
||||
# @api.onchange("checkin_partner_ids")
|
||||
# def onchange_checkin_partner_ids(self):
|
||||
# _logger.info("----------ONCHANGE2-----------")
|
||||
@@ -1010,15 +1024,6 @@ class PmsReservation(models.Model):
|
||||
# TODO
|
||||
return True
|
||||
|
||||
def send_reservation_mail(self):
|
||||
return self.folio_id.send_reservation_mail()
|
||||
|
||||
def send_exit_mail(self):
|
||||
return self.folio_id.send_exit_mail()
|
||||
|
||||
def send_cancel_mail(self):
|
||||
return self.folio_id.send_cancel_mail()
|
||||
|
||||
def _compute_tax_ids(self):
|
||||
for record in self:
|
||||
# If company_id is set, always filter taxes by the company
|
||||
|
||||
@@ -16,6 +16,16 @@ class PmsRoom(models.Model):
|
||||
_description = "Property Room"
|
||||
_order = "sequence, room_type_id, name"
|
||||
|
||||
# Defaults and Gets
|
||||
def name_get(self):
|
||||
result = []
|
||||
for room in self:
|
||||
name = room.name
|
||||
if room.room_type_id:
|
||||
name += ' [%s]' % room.room_type_id.code_type
|
||||
result.append((room.id, name))
|
||||
return result
|
||||
|
||||
# Fields declaration
|
||||
name = fields.Char("Room Name", required=True)
|
||||
pms_property_id = fields.Many2one(
|
||||
@@ -54,7 +64,7 @@ class PmsRoom(models.Model):
|
||||
raise ValidationError(
|
||||
_(
|
||||
"The capacity of the \
|
||||
room must be greater than 0."
|
||||
room must be greater than 0."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
29
pms/views/ir_sequence_views.xml
Normal file
29
pms/views/ir_sequence_views.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="ir_sequence_view_form" model="ir.ui.view">
|
||||
<field name="model">ir.sequence</field>
|
||||
<field name="inherit_id" ref="base.sequence_view" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='company_id']" position="after">
|
||||
<field
|
||||
string="Property"
|
||||
name="pms_property_id"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="ir_sequence_view_tree" model="ir.ui.view">
|
||||
<field name="model">ir.sequence</field>
|
||||
<field name="inherit_id" ref="base.sequence_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='company_id']" position="after">
|
||||
<field
|
||||
string="Property"
|
||||
name="pms_property_id"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -150,14 +150,14 @@
|
||||
colspan="4"
|
||||
string="Room Line"
|
||||
nolabel="1"
|
||||
context="{'from_folio':True,'reservation_ids':reservation_ids,'folio_id': id,'tree_view_ref':'pms.pms_reservation_view_bottom_tree', 'form_view_ref':'pms.pms_reservation_view_form'}"
|
||||
context="{'reservation_ids':reservation_ids,'folio_id': id,'tree_view_ref':'pms.pms_reservation_view_bottom_tree', 'form_view_ref':'pms.pms_reservation_view_form'}"
|
||||
/>
|
||||
</page>
|
||||
<page string="Services">
|
||||
<separator string="Service Lines" colspan="4" />
|
||||
<field
|
||||
name="service_ids"
|
||||
context="{'from_room':False,'folio_id': id,'tree_view_ref':'pms.pms_service_view_tree', 'form_view_ref':'pms.pms_service_view_form'}"
|
||||
context="{'folio_id': id,'tree_view_ref':'pms.pms_service_view_tree', 'form_view_ref':'pms.pms_service_view_form'}"
|
||||
nolabel="1"
|
||||
/>
|
||||
</page>
|
||||
@@ -249,7 +249,11 @@
|
||||
<field name="name" />
|
||||
<field name="partner_id" select="1" />
|
||||
<field name="date_order" select="1" />
|
||||
<field name="create_uid" optional="show" widget="many2one_avatar_user"/>
|
||||
<field
|
||||
name="create_uid"
|
||||
optional="show"
|
||||
widget="many2one_avatar_user"
|
||||
/>
|
||||
<field name="reservation_ids" widget="many2many_tags" />
|
||||
<field name="amount_total" sum="Total amount" />
|
||||
<field name="pending_amount" sum="Total debt" />
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
<group string="Timezone">
|
||||
<field name="tz" widget="timezone_mismatch" />
|
||||
</group>
|
||||
<group string="Sequences">
|
||||
<field name="folio_sequence_id" />
|
||||
</group>
|
||||
<group colspan="4" col="4" string="Check-in hours">
|
||||
<field name="default_arrival_hour" />
|
||||
<field name="default_departure_hour" />
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<field name="name">Reservation</field>
|
||||
<field name="res_model">pms.reservation</field>
|
||||
<field name="view_mode">tree,form,graph,pivot</field>
|
||||
<field name="context">{'from_room': True}</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pms_reservation_view_form">
|
||||
<field name="name">pms.reservation.form</field>
|
||||
@@ -576,7 +575,7 @@
|
||||
options="{'no_create': True,'no_open': True}"
|
||||
style="margin-right: 30px;"
|
||||
/>
|
||||
<field
|
||||
<!-- <field
|
||||
name="partner_id"
|
||||
readonly="1"
|
||||
options="{'no_open': True}"
|
||||
@@ -590,7 +589,7 @@
|
||||
class="fa-black-tie"
|
||||
style="margin-left:20px; color: #C67;"
|
||||
attrs="{'invisible': [('reservation_type','not in',('staff'))]}"
|
||||
/>
|
||||
/> -->
|
||||
<h3>
|
||||
From <span class="fa-sign-in" style="margin: 5px;" />
|
||||
<field
|
||||
@@ -634,37 +633,34 @@
|
||||
>
|
||||
<field name="splitted" invisible="1" />
|
||||
<field name="pricelist_id" invisible="1" />
|
||||
<field name="room_id" options="{'no_create': True,'no_open': True}" />
|
||||
<field name="checkin" widget="daterange" class="oe_inline" options="{'related_end_date': 'checkout'}"/>
|
||||
<field name="checkout" widget="date" />
|
||||
<field name="nights" />
|
||||
<button
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-file"
|
||||
name="open_folio"
|
||||
/>
|
||||
<field name="checkin" widget="remaining_days" optional="show" attrs="{'invisible': [['state', '=', 'done']]}" />
|
||||
<field name="folio_id" />
|
||||
<field name="folio_id" decoration-bf="1"/>
|
||||
<field name="allowed_room_ids" invisible="1" />
|
||||
<field name="room_id" options="{'no_create': True,'no_open': True}" />
|
||||
<field name="partner_id" />
|
||||
<field name="room_type_id" string="Reserved Unit Type" />
|
||||
<field name="nights" />
|
||||
<field name="room_type_id" invisible="1" />
|
||||
<field name="adults" string="Persons" />
|
||||
<field name="checkout" widget="date" />
|
||||
<field name="create_date" />
|
||||
<field name="overbooking" invisible="1" />
|
||||
<field name="last_updated_res" string="Updated on" />
|
||||
<field name="activity_ids" widget="list_activity" optional="show"/>
|
||||
<field name="create_uid" optional="show" widget="many2one_avatar_user"/>
|
||||
<field name="origin" />
|
||||
<field name="checkin_partner_ids" invisible="1" />
|
||||
<field name="to_assign" invisible="1" />
|
||||
<field name="checkin_partner_pending_count" invisible="1" />
|
||||
<field name="discount" />
|
||||
<field name="tax_ids" invisible="1" />
|
||||
<field name="price_subtotal" invisible="1" />
|
||||
<field name="price_total" />
|
||||
<field name="folio_pending_amount" string="Folio Pending Amount" />
|
||||
<field name="company_id" />
|
||||
<field name="state" decoration-success="state == 'done'" decoration-info="state == 'confirm'" warning-info="state == 'onboard'" widget="badge" optional="show"/>
|
||||
<field name="state" decoration-success="state == 'done'" decoration-info="state == 'confirm'" widget="badge" optional="show"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -713,12 +709,6 @@
|
||||
<xpath expr="//field[@name='create_uid']" position="attributes">
|
||||
<attribute name="invisible">True</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='create_date']" position="attributes">
|
||||
<attribute name="invisible">True</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='last_updated_res']" position="attributes">
|
||||
<attribute name="invisible">True</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pms_reservation_view_search">
|
||||
|
||||
Reference in New Issue
Block a user