From c19b56a912a187c5509ef1aff4e812b54c75b030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Lodeiros?= Date: Thu, 26 Nov 2020 12:19:35 +0100 Subject: [PATCH] [ADD] Cron no_show and no_checkout --- pms/data/cron_jobs.xml | 32 +++++++ pms/models/pms_checkin_partner.py | 24 +++++- pms/models/pms_folio.py | 4 +- pms/models/pms_reservation.py | 70 +++++++++++++--- pms/tests/test_pms_checkin_partner.py | 45 ++++++++++ pms/views/pms_checkin_partner_views.xml | 12 ++- pms/views/pms_reservation_views.xml | 106 +----------------------- 7 files changed, 170 insertions(+), 123 deletions(-) diff --git a/pms/data/cron_jobs.xml b/pms/data/cron_jobs.xml index 7adf1a6a5..06d4bce45 100644 --- a/pms/data/cron_jobs.xml +++ b/pms/data/cron_jobs.xml @@ -1,6 +1,38 @@ + + + Automatic No Show Reservation + 1 + + days + -1 + + code + + + model.auto_no_show() + + + + Automatic No Checkout Reservations + 1 + + days + -1 + + code + + + model.auto_no_checkout() + Automatic Checkout on past reservations diff --git a/pms/models/pms_checkin_partner.py b/pms/models/pms_checkin_partner.py index f67124df4..e4c1d5649 100644 --- a/pms/models/pms_checkin_partner.py +++ b/pms/models/pms_checkin_partner.py @@ -82,7 +82,7 @@ class PmsCheckinPartner(models.Model): for record in self.filtered("reservation_id"): record.folio_id = record.reservation_id.folio_id - @api.depends(lambda self: self._checkin_mandatory_fields(), "reservation_id.state") + @api.depends(lambda self: self._checkin_mandatory_fields(depends=True)) def _compute_state(self): for record in self: if not record.state: @@ -98,7 +98,11 @@ class PmsCheckinPartner(models.Model): else: record.state = "precheckin" - def _checkin_mandatory_fields(self): + @api.model + def _checkin_mandatory_fields(self, depends=False): + # api.depends need "reservation_id.state" in de lambda function + if depends: + return ["reservation_id.state", "name"] return ["name"] # Constraints and onchanges @@ -156,6 +160,22 @@ class PmsCheckinPartner(models.Model): record.update(vals) if record.reservation_id.state == "confirm": record.reservation_id.state = "onboard" + if self._context.get("popup"): + self.ensure_one() + kanban_id = self.env.ref("pms.pms_checkin_partner_kanban_view").id + return { + "name": _("Register Checkins"), + "views": [[kanban_id, "tree"]], + "res_model": "pms.checkin.partner", + "type": "ir.actions.act_window", + "context": { + "create": False, + "edit": True, + "popup": True, + }, + "domain": [("reservation_id", "=", self.reservation_id.id)], + "target": "new", + } def action_done(self): for record in self: diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index d63b01c46..d48de2ba4 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -245,7 +245,9 @@ class PmsFolio(models.Model): ) # Checkin Fields----------------------------------------------------- reservation_pending_arrival_ids = fields.One2many( - string="Pending Arrival Rooms", compute="_compute_reservations_pending_arrival" + comodel_name="pms.checkin.partner", + string="Pending Arrival Rooms", + compute="_compute_reservations_pending_arrival", ) reservations_pending_count = fields.Integer( compute="_compute_reservations_pending_arrival" diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index c07fae506..830993f5b 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -2,7 +2,7 @@ # Copyright 2017 Dario Lodeiros # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging -from datetime import timedelta +from datetime import datetime, time, timedelta from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError @@ -274,6 +274,8 @@ class PmsReservation(models.Model): ("onboard", "On Board"), ("done", "Out"), ("cancelled", "Cancelled"), + ("no_show", "No Show"), + ("no_checkout", "No Checkout"), ], string="Status", default=lambda *a: "draft", @@ -653,12 +655,9 @@ class PmsReservation(models.Model): 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)] + return [("checkin", operator, today)] def _compute_departure_today(self): for record in self: @@ -1224,13 +1223,60 @@ class PmsReservation(models.Model): def action_checks(self): self.ensure_one() - action = self.env.ref("pms.open_pms_reservation_form_tree_all").read()[0] - action["views"] = [ - (self.env.ref("pms.pms_reservation_checkin_view_form").id, "form") - ] - action["res_id"] = self.id - action["target"] = "new" - return action + tree_id = self.env.ref("pms.pms_checkin_partner_reservation_view_tree").id + return { + "name": _("Register Partners"), + "views": [[tree_id, "tree"]], + "res_model": "pms.checkin.partner", + "type": "ir.actions.act_window", + "context": { + "create": False, + "edit": True, + "popup": True, + }, + "domain": [("reservation_id", "=", self.id), ("state", "=", "draft")], + "target": "new", + } + + def action_onboard(self): + self.ensure_one() + kanban_id = self.env.ref("pms.pms_checkin_partner_kanban_view").id + return { + "name": _("Register Checkins"), + "views": [[kanban_id, "kanban"]], + "res_model": "pms.checkin.partner", + "type": "ir.actions.act_window", + "context": { + "create": False, + "edit": True, + "popup": True, + }, + "domain": [("reservation_id", "=", self.id), ("state", "=", "precheckin")], + "target": "new", + } + + @api.model + def auto_no_show(self): + no_show_reservations = self.env["pms.reservation"].search( + [ + ("state", "in", ("draft", "confirm")), + ("checkin", "<", fields.Date.today()), + ] + ) + no_show_reservations.state = "no_show" + + @api.model + def auto_no_checkout(self): + reservations = self.env["pms.reservation"].search( + [("state", "in", ("onboard",))] + ) + for reservation in reservations: + checkout_hour = int(reservation.departure_hour[0:2]) + checkout_minut = int(reservation.departure_hour[3:5]) + checkout_time = time(checkout_hour, checkout_minut, 00) + checkout_datetime = datetime.combine(reservation.checkout, checkout_time) + if checkout_datetime <= fields.Datetime.now(): + reservation.state = "no_checkout" def unify(self): # TODO diff --git a/pms/tests/test_pms_checkin_partner.py b/pms/tests/test_pms_checkin_partner.py index 9485e6dd1..2cf23f05d 100644 --- a/pms/tests/test_pms_checkin_partner.py +++ b/pms/tests/test_pms_checkin_partner.py @@ -338,3 +338,48 @@ class TestPmsCheckinPartner(TestHotel): int(2 * 100 / 3), "Fail the checkins data ratio on reservation", ) + + def test_auto_no_show(self): + + # ARRANGE + self.arrange_folio_reservations() + PmsReservation = self.env["pms.reservation"] + + # ACTION + freezer = freeze_time("2012-01-15 10:00:00") + freezer.start() + PmsReservation.auto_no_show() + + no_show_reservations = PmsReservation.search([("state", "=", "no_show")]) + + # ASSERT + self.assertEqual( + len(no_show_reservations), + 3, + "Reservations not set like No Show", + ) + freezer.stop() + + def test_auto_no_checkout(self): + + # ARRANGE + self.arrange_single_checkin() + PmsReservation = self.env["pms.reservation"] + self.checkin1.action_on_board() + + # ACTION + freezer = freeze_time("2012-01-17 12:00:00") + freezer.start() + PmsReservation.auto_no_checkout() + + no_checkout_reservations = PmsReservation.search( + [("state", "=", "no_checkout")] + ) + freezer.stop() + + # ASSERT + self.assertEqual( + len(no_checkout_reservations), + 1, + "Reservations not set like No checkout", + ) diff --git a/pms/views/pms_checkin_partner_views.xml b/pms/views/pms_checkin_partner_views.xml index 8fb5af300..b9fbf1eb8 100644 --- a/pms/views/pms_checkin_partner_views.xml +++ b/pms/views/pms_checkin_partner_views.xml @@ -49,7 +49,6 @@ @@ -71,7 +70,7 @@ - + @@ -114,7 +113,12 @@ pms.checkin.partner.kanban pms.checkin.partner - + diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml index 8c3399719..3ce4b6eeb 100644 --- a/pms/views/pms_reservation_views.xml +++ b/pms/views/pms_reservation_views.xml @@ -120,7 +120,7 @@