[WIP]pms: change checkin name field arriva-departure

This commit is contained in:
Darío Lodeiros
2020-11-04 08:57:09 +01:00
parent a76b444452
commit ccf4245aeb
6 changed files with 175 additions and 191 deletions

View File

@@ -34,7 +34,7 @@
/>
</record>
<!-- reservation of 3 single rooms for 3 people with 1 cancelled -->
<!-- TODO: The third reservation is marked from State: Cancelled to Pending Entry at Folio creation -->
<!-- TODO: The third reservation is marked from State: Cancelled to Pending arrival at Folio creation -->
<record id="pms_folio_2" model="pms.folio">
<field name="partner_id" ref="base.res_partner_address_10" />
<field
@@ -344,7 +344,7 @@
/>
</record>
<!--Reservation of the conference room whit cancelled-->
<!-- TODO: The reservation is marked from State: Cancelled to Pending Entry at Folio creation -->
<!-- TODO: The reservation is marked from State: Cancelled to Pending arrival at Folio creation -->
<record id="pms_folio_15" model="pms.folio">
<field name="partner_id" ref="base.res_partner_18" />
<field name="reservation_type">normal</field>
@@ -381,7 +381,7 @@
/>
</record>
<!--Reservation of triple room whit draft state-->
<!-- TODO: The reservation is marked from State: Pre-reservation to Pending Entry at Folio creation -->
<!-- TODO: The reservation is marked from State: Pre-reservation to Pending arrival at Folio creation -->
<record id="pms_folio_17" model="pms.folio">
<field name="partner_id" ref="base.res_partner_address_32" />
<field name="reservation_type">normal</field>

View File

@@ -5700,12 +5700,12 @@ msgid "End Date"
msgstr "Fecha de finalización"
#. module: hotel
#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_enter_date
#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_arrival
msgid "Enter Date"
msgstr "Fecha de entrada"
#. module: hotel
#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_exit_date
#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_departure
msgid "Exit Date"
msgstr "Fecha salida"
@@ -6671,7 +6671,7 @@ msgstr "Mail"
#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_valuation
msgid ""
"Manual: The accounting entries to value the inventory are not posted automatically.\n"
" Automated: An accounting entry is automatically created to value the inventory when a product enters or leaves the company."
" Automated: An accounting arrival is automatically created to value the inventory when a product enters or leaves the company."
msgstr ""
"Manual: Los registros contables de valoración del inventario no se publican automáticamente.\n"
" Automatizado: Se crea automáticamente un registro contable para evaluar el inventario cuando un producto entra o sale de la empresa."
@@ -7215,7 +7215,7 @@ msgstr "Pagos"
#. module: hotel
#: selection:hotel.checkin.partner,state:0 selection:hotel.reservation,state:0
msgid "Pending Entry"
msgid "Pending arrival"
msgstr "Por entrar"
#. module: hotel

View File

@@ -1,103 +1,44 @@
# Copyright 2017 Dario Lodeiros
# Copyright 2018 Alexandre Diaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
class PmsCheckinPartner(models.Model):
_name = "pms.checkin.partner"
_description = "Partner Checkins"
# Default Methods ang Gets
def _default_reservation_id(self):
if "reservation_id" in self.env.context:
reservation = self.env["pms.reservation"].browse(
[self.env.context["reservation_id"]]
)
return reservation
return False
def _default_partner_id(self):
if "reservation_id" in self.env.context:
reservation = self.env["pms.reservation"].browse(
[self.env.context["reservation_id"]]
)
partner_ids = []
if reservation.folio_id:
for room in reservation.folio_id.reservation_ids:
partner_ids.append(room.mapped("checkin_partner_ids.partner_id.id"))
if "checkin_partner_ids" in self.env.context:
for checkin in self.env.context["checkin_partner_ids"]:
if checkin[0] == 0:
partner_ids.append(checkin[2].get("partner_id"))
if (
self._context.get("include_customer")
and reservation.partner_id.id not in partner_ids
and not reservation.partner_id.is_company
):
return reservation.partner_id
return False
def _default_folio_id(self):
if "folio_id" in self.env.context:
folio = self.env["pms.folio"].browse([self.env.context["folio_id"]])
return folio
if "reservation_id" in self.env.context:
folio = (
self.env["pms.reservation"]
.browse([self.env.context["reservation_id"]])
.folio_id
)
return folio
return False
def _default_enter_date(self):
if "reservation_id" in self.env.context:
reservation = self.env["pms.reservation"].browse(
[self.env.context["reservation_id"]]
)
return reservation.checkin
return False
def _default_exit_date(self):
if "reservation_id" in self.env.context:
reservation = self.env["pms.reservation"].browse(
[self.env.context["reservation_id"]]
)
return reservation.checkout
return False
@api.model
def _get_default_pms_property(self):
# TODO: Change by property env variable (like company)
return self.env.user.pms_property_id
# Fields declaration
partner_id = fields.Many2one(
"res.partner", default=_default_partner_id, required=True
"res.partner",
required=True,
domain="[('is_company', '=', False)]",
)
reservation_id = fields.Many2one("pms.reservation", default=_default_reservation_id)
reservation_id = fields.Many2one("pms.reservation")
folio_id = fields.Many2one(
"pms.folio", default=_default_folio_id, readonly=True, required=True
"pms.folio",
compute="_compute_folio_id",
store=True,
readonly=False,
)
pms_property_id = fields.Many2one(
"pms.property", default=_get_default_pms_property, required=True
)
email = fields.Char("E-mail", related="partner_id.email")
mobile = fields.Char("Mobile", related="partner_id.mobile")
enter_date = fields.Date(default=_default_enter_date, required=True)
exit_date = fields.Date(default=_default_exit_date, required=True)
arrival_hour = fields.Char("Arrival Hour", help="Default Arrival Hour (HH:MM)")
departure_hour = fields.Char(
"Departure Hour", help="Default Departure Hour (HH:MM)"
)
arrival = fields.Datetime("Enter")
departure = fields.Datetime("Exit")
auto_booking = fields.Boolean("Get in Now", default=False)
state = fields.Selection(
selection=[
("draft", "Pending Entry"),
("draft", "Pending arrival"),
("onboard", "On Board"),
("done", "Out"),
("cancelled", "Cancelled"),
@@ -105,50 +46,36 @@ class PmsCheckinPartner(models.Model):
string="State",
readonly=True,
default=lambda *a: "draft",
tracking=True,
)
# Compute
@api.depends("reservation_id", "reservation_id.folio_id")
def _compute_folio_id(self):
for record in self:
record.folio_id = record.reservation_id.folio_id
# Constraints and onchanges
@api.constrains("exit_date", "enter_date")
def _check_exit_date(self):
@api.constrains("departure", "arrival")
def _check_departure(self):
for record in self:
date_in = fields.Date.from_string(record.enter_date)
date_out = fields.Date.from_string(record.exit_date)
if date_out < date_in:
raise models.ValidationError(
if record.departure and record.arrival < record.departure:
raise ValidationError(
_("Departure date (%s) is prior to arrival on %s")
% (date_out, date_in)
% (record.departure, record.arrival)
)
@api.onchange("enter_date", "exit_date")
def _onchange_enter_date(self):
date_in = fields.Date.from_string(self.enter_date)
date_out = fields.Date.from_string(self.exit_date)
if date_out <= date_in:
date_out = date_in + datetime.timedelta(days=1)
self.update({"exit_date": date_out})
raise ValidationError(
_("Departure date, is prior to arrival. Check it now. %s") % date_out
)
@api.onchange("partner_id")
@api.constrains("partner_id")
def _check_partner_id(self):
for record in self:
if record.partner_id:
if record.partner_id.is_company:
raise models.ValidationError(
_(
"A Checkin Guest is configured like a company, \
modify it in contact form if its a mistake"
)
)
indoor_partner_ids = record.reservation_id.checkin_partner_ids.filtered(
lambda r: r.id != record.id
).mapped("partner_id.id")
if indoor_partner_ids.count(record.partner_id.id) > 1:
record.partner_id = None
raise models.ValidationError(
raise ValidationError(
_("This guest is already registered in the room")
)
@@ -157,18 +84,16 @@ class PmsCheckinPartner(models.Model):
def action_on_board(self):
for record in self:
if record.reservation_id.checkin > fields.Date.today():
raise models.ValidationError(_("It is not yet checkin day!"))
hour = record._get_arrival_hour()
raise ValidationError(_("It is not yet checkin day!"))
if record.reservation_id.checkout <= fields.Date.today():
raise ValidationError(_("Its too late to checkin"))
vals = {
"state": "onboard",
"arrival_hour": hour,
"arrival": fields.Datetime.now(),
}
record.update(vals)
if record.reservation_id.state == "confirm":
record.reservation_id.state = "onboard"
return {
"type": "ir.actions.do_nothing",
}
def action_done(self):
for record in self:
@@ -188,42 +113,3 @@ class PmsCheckinPartner(models.Model):
if vals.get("auto_booking", False):
record.action_on_board()
return record
# Business methods
def _get_arrival_hour(self):
self.ensure_one()
tz_property = self.env.user.pms_property_id.tz
today = fields.Datetime.context_timestamp(
self.with_context(tz=tz_property),
datetime.datetime.strptime(fields.Date.today(), DEFAULT_SERVER_DATE_FORMAT),
)
default_arrival_hour = self.env.user.pms_property_id.default_arrival_hour
if self.reservation_id.checkin < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
return default_arrival_hour
now = fields.Datetime.context_timestamp(
self.with_context(tz=tz_property),
datetime.datetime.strptime(
fields.Datetime.now(), DEFAULT_SERVER_DATETIME_FORMAT
),
)
arrival_hour = now.strftime("%H:%M")
return arrival_hour
def _get_departure_hour(self):
self.ensure_one()
tz_property = self.env.user.pms_property_id.tz
today = fields.Datetime.context_timestamp(
self.with_context(tz=tz_property),
datetime.datetime.strptime(fields.Date.today(), DEFAULT_SERVER_DATE_FORMAT),
)
default_departure_hour = self.env.user.pms_property_id.default_departure_hour
if self.reservation_id.checkout < today.strftime(DEFAULT_SERVER_DATE_FORMAT):
return default_departure_hour
now = fields.Datetime.context_timestamp(
self.with_context(tz=tz_property),
datetime.datetime.strptime(
fields.Datetime.now(), DEFAULT_SERVER_DATETIME_FORMAT
),
)
departure_hour = now.strftime("%H:%M")
return departure_hour

View File

@@ -239,7 +239,7 @@ class PmsReservation(models.Model):
state = fields.Selection(
[
("draft", "Pre-reservation"),
("confirm", "Pending Entry"),
("confirm", "Pending arrival"),
("onboard", "On Board"),
("done", "Out"),
("cancelled", "Cancelled"),

View File

@@ -1,18 +1,21 @@
import logging
from freezegun import freeze_time
from odoo import fields
from odoo.exceptions import ValidationError
from .common import TestHotel
_logger = logging.getLogger(__name__)
@freeze_time("2012-01-14")
class TestPmsCheckinPartner(TestHotel):
@classmethod
def setUpClass(cls):
super(TestHotel, cls).setUpClass()
def test_create_checkin_partner(self):
# ARRANGE
host1 = self.env["res.partner"].create(
def arrange_single_checkin(cls):
# Arrange for one checkin on one reservation
cls.host1 = cls.env["res.partner"].create(
{
"name": "Miguel",
"phone": "654667733",
@@ -22,27 +25,124 @@ class TestPmsCheckinPartner(TestHotel):
reservation_vals = {
"checkin": "2012-01-14",
"checkout": "2012-01-17",
"room_type_id": self.env.ref("pms.pms_room_type_3").id,
"partner_id": host1.id,
"pms_property_id": self.env.ref("pms.main_pms_property").id,
"room_type_id": cls.env.ref("pms.pms_room_type_3").id,
"partner_id": cls.host1.id,
"pms_property_id": cls.env.ref("pms.main_pms_property").id,
}
demo_user = self.env.ref("base.user_demo")
# ACT
reservation_1 = (
self.env["pms.reservation"].with_user(demo_user).create(reservation_vals)
demo_user = cls.env.ref("base.user_demo")
cls.reservation_1 = (
cls.env["pms.reservation"].with_user(demo_user).create(reservation_vals)
)
checkin1 = self.env["pms.checkin.partner"].create(
cls.checkin1 = cls.env["pms.checkin.partner"].create(
{
"partner_id": host1.id,
"reservation_id": reservation_1.id,
"partner_id": cls.host1.id,
"reservation_id": cls.reservation_1.id,
}
)
checkin1.onboard()
def test_onboard_checkin(self):
# ARRANGE
self.arrange_single_checkin()
# ACT
self.checkin1.action_on_board()
# ASSERT
self.assertEqual(
checkin1.state,
self.checkin1.state,
"onboard",
"the checkin was not successful",
"the partner checkin was not successful",
)
def test_onboard_reservation(self):
# ARRANGE
self.arrange_single_checkin()
# ACT
self.checkin1.action_on_board()
# ASSERT
self.assertEqual(
self.reservation_1.state,
"onboard",
"the reservation checkin was not successful",
)
def test_premature_checkin(self):
# ARRANGE
self.arrange_single_checkin()
self.reservation_1.write(
{
"checkin": "2012-01-15",
}
)
# ACT & ASSERT
with self.assertRaises(ValidationError), self.cr.savepoint():
self.checkin1.action_on_board()
def test_late_checkin(self):
# ARRANGE
self.arrange_single_checkin()
self.reservation_1.write(
{
"checkin": "2012-01-13",
}
)
# ACT
self.checkin1.action_on_board()
# ASSERT
self.assertEqual(
self.checkin1.arrival,
fields.datetime.now(),
"the late checkin has problems",
)
def test_too_many_people_checkin(self):
# ARRANGE
self.arrange_single_checkin()
host2 = self.env["res.partner"].create(
{
"name": "Carlos",
"phone": "654667733",
"email": "carlos@example.com",
}
)
host3 = self.env["res.partner"].create(
{
"name": "Enmanuel",
"phone": "654667733",
"email": "enmanuel@example.com",
}
)
host4 = self.env["res.partner"].create(
{
"name": "Enrique",
"phone": "654667733",
"email": "enrique@example.com",
}
)
self.env["pms.checkin.partner"].create(
{
"partner_id": host2.id,
"reservation_id": self.reservation_1.id,
}
)
self.env["pms.checkin.partner"].create(
{
"partner_id": host3.id,
"reservation_id": self.reservation_1.id,
}
)
# ACT & ASSERT
with self.assertRaises(ValidationError), self.cr.savepoint():
self.env["pms.checkin.partner"].create(
{
"partner_id": host4.id,
"reservation_id": self.reservation_1.id,
}
)

View File

@@ -27,10 +27,8 @@
domain="[('is_company','=', False)]"
/>
<field name="pms_property_id" invisible="1" />
<field name="enter_date" />
<field name="exit_date" />
<field name="arrival_hour" />
<field name="departure_hour" />
<field name="arrival" />
<field name="departure" />
</group>
<group name="group_left">
<field name="reservation_id" />
@@ -56,7 +54,7 @@
<button
type="object"
class="oe_read_only oe_stat_button"
icon="fa fa-2x fa-check-circle"
icon="fa-2x fa-check-circle"
name="action_on_board"
help="Get in"
attrs="{'invisible': [('state','!=','draft')]}"
@@ -65,8 +63,8 @@
<field name="partner_id" required="True" />
<field name="mobile" />
<field name="email" />
<field name="enter_date" />
<field name="exit_date" />
<field name="arrival" />
<field name="departure" />
<field name="reservation_id" invisible="1" />
<field name="folio_id" force_save="1" invisible="1" />
<field name="state" invisible="1" />
@@ -99,8 +97,8 @@
/>
<field name="mobile" />
<field name="email" />
<field name="enter_date" />
<field name="exit_date" />
<field name="arrival" />
<field name="departure" />
<field name="reservation_id" />
<field name="folio_id" force_save="1" invisible="1" />
<field name="state" />
@@ -129,21 +127,21 @@
<filter
string="Checkins Tomorrow"
name="enter_tomorrow"
domain="[('enter_date', '=', (context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')),
domain="[('arrival', '=', (context_today()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')),
('state', '=', 'confirm')]"
help="Show all checkins for enter tomorrow"
/>
<filter
string="Checkins to 7 days"
name="next_res_week"
domain="[('enter_date', '&lt;', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d')),
domain="[('arrival', '&lt;', (context_today()+datetime.timedelta(days=7)).strftime('%Y-%m-%d')),
('state', '=', 'confirm')]"
help="Show all reservations for which date enter is before than 7 days"
/>
<filter
string="On Board Tomorrow"
name="next_res_2week"
domain="[('enter_date', '&lt;', (context_today()+datetime.timedelta(days=14)).strftime('%Y-%m-%d')),
domain="[('arrival', '&lt;', (context_today()+datetime.timedelta(days=14)).strftime('%Y-%m-%d')),
('state', 'in', ['confirm','onboard'])]"
help="Show all checkins for Tomorrow"
/>
@@ -167,33 +165,33 @@
<filter
string="Checkin by Month"
name="checkin_by_month"
context="{'group_by':'enter_date', 'default_order': 'enter_date asc'}"
context="{'group_by':'arrival', 'default_order': 'arrival asc'}"
/>
<filter
string="Checkin by Week"
name="checkin_by_week"
context="{'group_by':'enter_date:week', 'default_order': 'enter_date'}"
context="{'group_by':'arrival:week', 'default_order': 'arrival'}"
/>
<filter
string="Checkin by Day"
name="checkin_by_week"
context="{'group_by':'enter_date:day', 'default_order': 'enter_date'}"
context="{'group_by':'arrival:day', 'default_order': 'arrival'}"
/>
<separator />
<filter
string="Checkout by Month"
name="checkout_by_month"
context="{'group_by':'exit_date', 'default_order': 'exit_date asc'}"
context="{'group_by':'departure', 'default_order': 'departure asc'}"
/>
<filter
string="Checkout by Week"
name="checkout_by_week"
context="{'group_by':'exit_date:week', 'default_order': 'exit_date'}"
context="{'group_by':'departure:week', 'default_order': 'departure'}"
/>
<filter
string="Checkout by Day"
name="checkout_by_week"
context="{'group_by':'exit_date:day', 'default_order': 'exit_date'}"
context="{'group_by':'departure:day', 'default_order': 'departure'}"
/>
<separator />
</group>