Skip to content
Merged
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
31 changes: 25 additions & 6 deletions pms/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -3853,8 +3853,8 @@ msgstr ""

#. module: pms
#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_intime
msgid "Days Late"
msgstr "Nº de días pre-checkin"
msgid "Free Cancellation Days"
msgstr "Días de cancelación gratuita"

#. module: pms
#: model:ir.model.fields,field_description:pms.field_pms_folio__days_to_checkin
Expand Down Expand Up @@ -6734,8 +6734,8 @@ msgstr "La Estancia Máxima no puede ser menor que cero"

#. module: pms
#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form
msgid "Max. days InTime before Checkin"
msgstr "Máximo de días a tiempo antes del Checkin"
msgid "Free cancellation up to (days before check-in)"
msgstr "Cancelación gratuita hasta (días antes del check-in)"

#. module: pms
#: model:ir.model.fields,field_description:pms.field_pms_room_type__tourist_tax_max_age
Expand All @@ -6751,9 +6751,14 @@ msgstr "Importe máximo para crear la factura simplificada"

#. module: pms
#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_intime
msgid "Maximum number of days for free cancellation before Checkin"
msgid ""
"Minimum number of days before check-in to cancel free of charge. Later "
"cancellations apply the late penalty. With 0, cancellation is free until the "
"day of arrival."
msgstr ""
"Número máximo de días para que la cancelación sea gratis antes del checkin"
"Antelación mínima, en días antes del check-in, para cancelar sin coste. Las "
"cancelaciones posteriores aplican la penalización por cancelación tardía. Con "
"0, la cancelación es gratuita hasta el día de llegada."

#. module: pms
#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_avail
Expand Down Expand Up @@ -15190,3 +15195,17 @@ msgstr ""

#~ msgid "host state"
#~ msgstr "Provincia"

#. module: pms
#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__is_non_refundable
msgid "Non-refundable"
msgstr "No reembolsable"

#. module: pms
#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__is_non_refundable
msgid ""
"There is no free cancellation period: the late penalty applies whenever the "
"reservation is cancelled before check-in."
msgstr ""
"No hay periodo de cancelación gratuita: la penalización por cancelación tardía "
"se aplica siempre que se cancele la reserva antes del check-in."
11 changes: 9 additions & 2 deletions pms/models/pms_cancelation_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ class PmsCancelationRule(models.Model):
active = fields.Boolean(
help="Determines if cancelation rule is active", default=True
)
is_non_refundable = fields.Boolean(
string="Non-refundable",
help="There is no free cancellation period: the late penalty applies "
"whenever the reservation is cancelled before check-in.",
)
days_intime = fields.Integer(
string="Days Late",
help="Maximum number of days for free cancellation before Checkin",
string="Free Cancellation Days",
help="Minimum number of days before check-in to cancel free of charge. "
"Later cancellations apply the late penalty. With 0, cancellation "
"is free until the day of arrival.",
)
penalty_late = fields.Integer(
string="% Penalty Late",
Expand Down
2 changes: 1 addition & 1 deletion pms/models/pms_reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2454,7 +2454,7 @@ def _check_cancel_penalty(self):
days = 1
elif rule.apply_on_noshow == "days":
days = rule.days_late - 1
elif days_diff < pricelist.cancelation_rule_id.days_intime:
elif rule.is_non_refundable or days_diff < rule.days_intime:
record.cancelled_reason = "late"
penalty_percent = rule.penalty_late
if rule.apply_on_late == "first":
Expand Down
67 changes: 67 additions & 0 deletions pms/tests/test_pms_reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,73 @@ def test_cancelation_reason_late(self):
reservation.flush_recordset()
self.assertEqual(reservation.cancelled_reason, "late", "-----------")

def _create_reservation_with_rule(self, rule_vals, days_to_checkin):
rule = self.env["pms.cancelation.rule"].create(
dict(
{
"name": "Cancelation Rule Test",
"pms_property_ids": [self.pms_property1.id],
},
**rule_vals,
)
)
pricelist = self.env["product.pricelist"].create(
{
"name": "Pricelist Test",
"pms_property_ids": [self.pms_property1.id],
"cancelation_rule_id": rule.id,
"availability_plan_id": self.availability_plan1.id,
"is_pms_available": True,
}
)
partner = self.env["res.partner"].create({"firstname": "Host1"})
checkin = fields.date.today() + datetime.timedelta(days=days_to_checkin)
return self.env["pms.reservation"].create(
{
"checkin": checkin,
"checkout": checkin + datetime.timedelta(days=3),
"room_type_id": self.room_type_double.id,
"partner_id": partner.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": pricelist.id,
"sale_channel_origin_id": self.sale_channel_direct.id,
}
)

@freeze_time("2012-01-14")
def test_cancelation_reason_non_refundable(self):
"""
A non-refundable rule applies the late penalty whenever the
reservation is cancelled before check-in, however far ahead.
"""
reservation = self._create_reservation_with_rule(
{"is_non_refundable": True, "days_intime": 0}, days_to_checkin=30
)
reservation.action_cancel()
reservation.flush_recordset()
self.assertEqual(
reservation.cancelled_reason,
"late",
"A non-refundable rule must always apply the late penalty",
)

@freeze_time("2012-01-14")
def test_cancelation_reason_zero_days_is_free_until_arrival(self):
"""
Without the non-refundable flag, 0 free cancellation days means
that cancellation is free until the day of arrival.
"""
reservation = self._create_reservation_with_rule(
{"days_intime": 0}, days_to_checkin=30
)
reservation.action_cancel()
reservation.flush_recordset()
self.assertEqual(
reservation.cancelled_reason,
"intime",
"With 0 free cancellation days, cancelling before arrival is free",
)

@freeze_time("2012-01-14")
def test_compute_checkin_partner_count(self):
"""
Expand Down
13 changes: 11 additions & 2 deletions pms/views/pms_cancelation_rule_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@
options="{'no_create': True,'no_open': True}"
/>
<separator />
<label for="name" string="Max. days InTime before Checkin" />
<field name="days_intime" />
<label
for="days_intime"
string="Free cancellation up to (days before check-in)"
attrs="{'invisible': [('is_non_refundable', '=', True)]}"
/>
<field
name="days_intime"
attrs="{'invisible': [('is_non_refundable', '=', True)]}"
/>
</h3>
<group>
<group string="Late">
<field name="is_non_refundable" />
<field name="penalty_late" />
<field name="apply_on_late" />
<field
Expand Down Expand Up @@ -48,6 +56,7 @@
<field name="arch" type="xml">
<tree name="Cancelation Rules">
<field name="name" />
<field name="is_non_refundable" />
<field name="days_intime" />
<field name="penalty_late" />
<field name="apply_on_late" />
Expand Down
Loading