mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] Checkin status indicators
This commit is contained in:
@@ -31,10 +31,12 @@ class PmsCheckinPartner(models.Model):
|
||||
pms_property_id = fields.Many2one(
|
||||
"pms.property", default=_get_default_pms_property, required=True
|
||||
)
|
||||
name = fields.Char("E-mail", related="partner_id.name")
|
||||
email = fields.Char("E-mail", related="partner_id.email")
|
||||
mobile = fields.Char("Mobile", related="partner_id.mobile")
|
||||
arrival = fields.Datetime("Enter")
|
||||
departure = fields.Datetime("Exit")
|
||||
completed_data = fields.Boolean(compute="_compute_completed_data", store=True)
|
||||
state = fields.Selection(
|
||||
selection=[
|
||||
("draft", "Pending arrival"),
|
||||
@@ -54,6 +56,20 @@ class PmsCheckinPartner(models.Model):
|
||||
for record in self:
|
||||
record.folio_id = record.reservation_id.folio_id
|
||||
|
||||
@api.depends(lambda self: self._checkin_mandatory_fields(), "state")
|
||||
def _compute_completed_data(self):
|
||||
self.completed_data = False
|
||||
for record in self:
|
||||
if any(
|
||||
not getattr(self, field) for field in record._checkin_mandatory_fields()
|
||||
):
|
||||
record.completed_data = False
|
||||
break
|
||||
record.completed_data = True
|
||||
|
||||
def _checkin_mandatory_fields(self):
|
||||
return ["name"]
|
||||
|
||||
# Constraints and onchanges
|
||||
|
||||
@api.constrains("departure", "arrival")
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, float_compare, float_is_zero
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -188,7 +188,7 @@ class PmsReservation(models.Model):
|
||||
# TODO: Warning Mens to update pricelist
|
||||
checkin_partner_ids = fields.One2many("pms.checkin.partner", "reservation_id")
|
||||
count_pending_arrival = fields.Integer(
|
||||
"Reservation Description",
|
||||
"Pending Arrival",
|
||||
compute="_compute_count_pending_arrival",
|
||||
store=True,
|
||||
)
|
||||
@@ -196,6 +196,21 @@ class PmsReservation(models.Model):
|
||||
string="Pending Arrival Ratio",
|
||||
compute="_compute_checkins_ratio",
|
||||
)
|
||||
pending_checkin_data = fields.Integer(
|
||||
"Pending Checkin Data",
|
||||
compute="_compute_pending_checkin_data",
|
||||
store=True,
|
||||
)
|
||||
arrival_today = fields.Boolean(
|
||||
compute="_compute_arrival_today", search="_search_arrival_today"
|
||||
)
|
||||
departure_today = fields.Boolean(
|
||||
compute="_compute_departure_today", search="_search_departure_today"
|
||||
)
|
||||
ratio_checkin_data = fields.Integer(
|
||||
string="Pending Checkin Data Ratio",
|
||||
compute="_compute_ratio_checkin_data",
|
||||
)
|
||||
segmentation_ids = fields.Many2many(
|
||||
"res.partner.category",
|
||||
string="Segmentation",
|
||||
@@ -562,6 +577,66 @@ class PmsReservation(models.Model):
|
||||
/ reservation.adults
|
||||
)
|
||||
|
||||
@api.depends("checkin_partner_ids", "checkin_partner_ids.completed_data")
|
||||
def _compute_pending_checkin_data(self):
|
||||
for reservation in self:
|
||||
reservation.pending_checkin_data = reservation.adults - len(
|
||||
reservation.checkin_partner_ids.filtered(
|
||||
lambda c: c.state != "cancelled" and c.completed_data
|
||||
)
|
||||
)
|
||||
|
||||
@api.depends("pending_checkin_data")
|
||||
def _compute_ratio_checkin_data(self):
|
||||
self.ratio_checkin_data = 0
|
||||
for reservation in self.filtered(lambda r: r.adults > 0):
|
||||
reservation.ratio_checkin_data = (
|
||||
(reservation.adults - reservation.pending_checkin_data)
|
||||
* 100
|
||||
/ reservation.adults
|
||||
)
|
||||
|
||||
def _compute_arrival_today(self):
|
||||
for record in self:
|
||||
record.arrival_today = (
|
||||
True if record.checkin == fields.Date.today() else False
|
||||
)
|
||||
# REVIEW: Late checkin?? (next day)
|
||||
|
||||
def _search_arrival_today(self, operator, value):
|
||||
if operator not in ("=", "!="):
|
||||
raise UserError(_("Invalid domain operator %s", operator))
|
||||
|
||||
if value not in (False, True):
|
||||
raise UserError(_("Invalid domain right operand %s", value))
|
||||
|
||||
searching_for_true = (operator == "=" and value) or (
|
||||
operator == "!=" and not value
|
||||
)
|
||||
today = fields.Date.context_today(self)
|
||||
|
||||
return [("checkin", searching_for_true, today)]
|
||||
|
||||
def _compute_departure_today(self):
|
||||
for record in self:
|
||||
record.departure_today = (
|
||||
True if record.checkout == fields.Date.today() else False
|
||||
)
|
||||
|
||||
def _search_departure_today(self, operator, value):
|
||||
if operator not in ("=", "!="):
|
||||
raise UserError(_("Invalid domain operator %s", operator))
|
||||
|
||||
if value not in (False, True):
|
||||
raise UserError(_("Invalid domain right operand %s", value))
|
||||
|
||||
searching_for_true = (operator == "=" and value) or (
|
||||
operator == "!=" and not value
|
||||
)
|
||||
today = fields.Date.context_today(self)
|
||||
|
||||
return [("checkout", searching_for_true, today)]
|
||||
|
||||
# REVIEW: Dont run with set room_type_id -> room_id(compute)-> No set adults¿?
|
||||
@api.depends("preferred_room_id")
|
||||
def _compute_adults(self):
|
||||
|
||||
@@ -267,3 +267,36 @@ class TestPmsCheckinPartner(TestHotel):
|
||||
int(2 * 100 / 3),
|
||||
"Fail the checkins ratio on reservation",
|
||||
)
|
||||
|
||||
def test_complete_checkin_data(self):
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_folio_reservations()
|
||||
|
||||
# ACT
|
||||
self.checkin1 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.host1.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
self.checkin2 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.host2.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
pending_checkin_data = self.reservation_1.pending_checkin_data
|
||||
ratio_checkin_data = self.reservation_1.ratio_checkin_data
|
||||
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
pending_checkin_data,
|
||||
1,
|
||||
"Fail the count pending checkin data on reservation",
|
||||
)
|
||||
self.assertEqual(
|
||||
ratio_checkin_data,
|
||||
int(2 * 100 / 3),
|
||||
"Fail the checkins data ratio on reservation",
|
||||
)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<header>
|
||||
<field name="splitted" invisible="True" />
|
||||
<field name="tax_ids" invisible="1" />
|
||||
<field name="arrival_today" invisible="1" />
|
||||
<field name="checkin_partner_count" invisible="1" />
|
||||
<button
|
||||
name="confirm"
|
||||
@@ -96,18 +97,6 @@
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
type="action"
|
||||
class="oe_stat_button"
|
||||
icon="fa-list-ul"
|
||||
attrs="{'invisible': ['|', ('partner_id','=',False), ('reservation_type','in',('out'))]}"
|
||||
name="%(open_pms_reservation_form_tree_all)d"
|
||||
context="{'search_default_partner_id': partner_id}"
|
||||
>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_text">Books</span>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
@@ -132,11 +121,33 @@
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_checks"
|
||||
attrs="{'invisible': [('state', 'in', ('cancelled','done'))]}"
|
||||
attrs="{'invisible': [
|
||||
('state', '!=', ('onboard')),
|
||||
('arrival_today', '=', False),
|
||||
'|',
|
||||
('state', 'in', ('cancelled','done')),
|
||||
]}"
|
||||
>
|
||||
<field
|
||||
name="checkins_ratio"
|
||||
string="Checkins"
|
||||
string="On Board"
|
||||
widget="percentpie"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
name="action_checks"
|
||||
attrs="{'invisible': [
|
||||
('state', 'not in', ('onboard','confirm')),
|
||||
('arrival_today', '=', False),
|
||||
'|',
|
||||
('state', 'in', ('cancelled','done')),
|
||||
]}"
|
||||
>
|
||||
<field
|
||||
name="ratio_checkin_data"
|
||||
string="Checkin Data"
|
||||
widget="percentpie"
|
||||
/>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user