mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
@@ -16,10 +16,16 @@
|
||||
"base",
|
||||
"mail",
|
||||
# "account_payment_return",
|
||||
# "partner_firstname",
|
||||
# "email_template_qweb",
|
||||
"sale",
|
||||
"multi_pms_properties",
|
||||
"partner_identification",
|
||||
"partner_firstname",
|
||||
"partner_second_lastname",
|
||||
"partner_contact_gender",
|
||||
"partner_contact_birthdate",
|
||||
"partner_contact_nationality",
|
||||
# "partner_identification_unique_by_category",
|
||||
],
|
||||
"data": [
|
||||
"security/pms_security.xml",
|
||||
@@ -27,8 +33,10 @@
|
||||
"data/cron_jobs.xml",
|
||||
"data/pms_sequence.xml",
|
||||
"data/pms_data.xml",
|
||||
"data/traveller_report_paperformat.xml",
|
||||
"report/pms_folio.xml",
|
||||
"report/pms_folio_templates.xml",
|
||||
"report/traveller_report_action.xml",
|
||||
# "templates/pms_email_template.xml",
|
||||
"data/menus.xml",
|
||||
"wizards/wizard_payment_folio.xml",
|
||||
@@ -67,6 +75,8 @@
|
||||
"views/account_journal_views.xml",
|
||||
"views/folio_portal_templates.xml",
|
||||
"views/reservation_portal_templates.xml",
|
||||
"views/res_company_views.xml",
|
||||
"views/traveller_report_template.xml",
|
||||
"wizards/wizard_split_join_swap_reservation.xml",
|
||||
"wizards/wizard_massive_changes.xml",
|
||||
"wizards/wizard_advanced_filters.xml",
|
||||
|
||||
@@ -52,5 +52,90 @@
|
||||
<field name="name">Agency</field>
|
||||
<field name="channel_type">indirect</field>
|
||||
</record>
|
||||
<!--res.partner_category_id-->
|
||||
<record id="document_type_passport" model="res.partner.id_category">
|
||||
<field name="name">Passport</field>
|
||||
<field name="code">P</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
<record id="document_type_driving_license" model="res.partner.id_category">
|
||||
<field name="name">Driving License</field>
|
||||
<field name="code">C</field>
|
||||
<field name="validation_code">
|
||||
letters = {
|
||||
0: "T",
|
||||
1: "R",
|
||||
2: "W",
|
||||
3: "A",
|
||||
4: "G",
|
||||
5: "M",
|
||||
6: "Y",
|
||||
7: "F",
|
||||
8: "P",
|
||||
9: "D",
|
||||
10: "X",
|
||||
11: "B",
|
||||
12: "N",
|
||||
13: "J",
|
||||
14: "Z",
|
||||
15: "S",
|
||||
16: "Q",
|
||||
17: "V",
|
||||
18: "H",
|
||||
19: "L",
|
||||
20: "C",
|
||||
21: "K",
|
||||
22: "E",
|
||||
}
|
||||
dni_number = id_number.name[0:8]
|
||||
dni_letter = id_number.name[
|
||||
len(id_number.name) - 1 : len(id_number.name)
|
||||
]
|
||||
if dni_number.isdigit() and not dni_letter.isdigit():
|
||||
if letters.get(int(dni_number) % 23) != dni_letter.upper():
|
||||
failed = True
|
||||
else:
|
||||
failed = True
|
||||
</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
<record
|
||||
id="document_type_identification_document"
|
||||
model="res.partner.id_category"
|
||||
>
|
||||
<field name="name">Identification Document</field>
|
||||
<field name="code">I</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
<record id="document_type_spanish_residence" model="res.partner.id_category">
|
||||
<field name="name">Spanish Residence permit</field>
|
||||
<field name="code">N</field>
|
||||
<field name="validation_code">
|
||||
permit_first_letter=id_number.name[0:1]
|
||||
permit_last_letter = id_number.name[
|
||||
len(id_number.name) - 1 : len(id_number.name)
|
||||
]
|
||||
if (permit_first_letter.upper() in ['X','Y']) and id_number.name[1:8].isdigit() and not permit_last_letter.isdigit():
|
||||
failed = False
|
||||
else:
|
||||
failed = True
|
||||
</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
<record id="document_type_european_residence" model="res.partner.id_category">
|
||||
<field name="name">European Residence permit</field>
|
||||
<field name="code">X</field>
|
||||
<field name="validation_code">
|
||||
permit_first_letter=id_number.name[0:1]
|
||||
permit_last_letter = id_number.name[
|
||||
len(id_number.name) - 1 : len(id_number.name)
|
||||
]
|
||||
if (permit_first_letter.upper() in ['X','Y']) and id_number.name[1:8].isdigit() and not permit_last_letter.isdigit():
|
||||
failed = False
|
||||
else:
|
||||
failed = True
|
||||
</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
20
pms/data/traveller_report_paperformat.xml
Normal file
20
pms/data/traveller_report_paperformat.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="report_viajero_paperformat" model="report.paperformat">
|
||||
<field name="name">Traveller Report PaperFormat</field>
|
||||
<field name="default" eval="True" />
|
||||
<field name="format">custom</field>
|
||||
<field name="page_height">200</field>
|
||||
<field name="page_width">75</field>
|
||||
<field name="orientation">Portrait</field>
|
||||
<field name="margin_top">1</field>
|
||||
<field name="margin_bottom">3</field>
|
||||
<field name="margin_left">0</field>
|
||||
<field name="margin_right">0</field>
|
||||
<field name="header_line" eval="False" />
|
||||
<field name="header_spacing">1</field>
|
||||
<field name="dpi">201</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -46,3 +46,4 @@ from . import account_bank_statement_line
|
||||
from . import account_bank_statement
|
||||
from . import account_journal
|
||||
from . import pms_availability
|
||||
from . import res_partner_id_number
|
||||
|
||||
@@ -25,8 +25,11 @@ class PmsCheckinPartner(models.Model):
|
||||
partner_id = fields.Many2one(
|
||||
string="Partner",
|
||||
help="Partner associated with checkin partner",
|
||||
readonly=False,
|
||||
store=True,
|
||||
comodel_name="res.partner",
|
||||
domain="[('is_company', '=', False)]",
|
||||
compute="_compute_partner_id",
|
||||
)
|
||||
reservation_id = fields.Many2one(
|
||||
string="Reservation",
|
||||
@@ -52,11 +55,7 @@ class PmsCheckinPartner(models.Model):
|
||||
check_pms_properties=True,
|
||||
)
|
||||
name = fields.Char(
|
||||
string="Name",
|
||||
help="Checkin partner name",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_name",
|
||||
string="Name", help="Checkin partner name", related="partner_id.name"
|
||||
)
|
||||
email = fields.Char(
|
||||
string="E-mail",
|
||||
@@ -68,9 +67,9 @@ class PmsCheckinPartner(models.Model):
|
||||
mobile = fields.Char(
|
||||
string="Mobile",
|
||||
help="Checkin Partner Mobile",
|
||||
compute="_compute_mobile",
|
||||
store=True,
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_mobile",
|
||||
)
|
||||
image_128 = fields.Image(
|
||||
string="Image",
|
||||
@@ -80,8 +79,8 @@ class PmsCheckinPartner(models.Model):
|
||||
segmentation_ids = fields.Many2many(
|
||||
string="Segmentation",
|
||||
help="Segmentation tags to classify checkin partners",
|
||||
related="reservation_id.segmentation_ids",
|
||||
readonly=True,
|
||||
related="reservation_id.segmentation_ids",
|
||||
)
|
||||
checkin = fields.Date(
|
||||
string="Checkin",
|
||||
@@ -116,7 +115,167 @@ class PmsCheckinPartner(models.Model):
|
||||
compute="_compute_state",
|
||||
)
|
||||
|
||||
# Compute
|
||||
gender = fields.Selection(
|
||||
string="Gender",
|
||||
help="host gender",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_gender",
|
||||
selection=[("male", "Male"), ("female", "Female"), ("other", "Other")],
|
||||
)
|
||||
nationality_id = fields.Many2one(
|
||||
string="Nationality ID",
|
||||
help="host nationality",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_nationality",
|
||||
comodel_name="res.country",
|
||||
)
|
||||
firstname = fields.Char(
|
||||
string="First Name",
|
||||
help="host firstname",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_firstname",
|
||||
)
|
||||
lastname = fields.Char(
|
||||
string="Last Name",
|
||||
help="host lastname",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_lastname",
|
||||
)
|
||||
lastname2 = fields.Char(
|
||||
string="Second Last Name",
|
||||
help="host second lastname",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_lastname2",
|
||||
)
|
||||
birthdate_date = fields.Date(
|
||||
string="Birthdate",
|
||||
help="host birthdate",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_birth_date",
|
||||
)
|
||||
document_number = fields.Char(
|
||||
string="Document Number",
|
||||
help="Host document number",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_document_number",
|
||||
)
|
||||
document_type = fields.Many2one(
|
||||
string="Document Type",
|
||||
help="Select a valid document type",
|
||||
readonly=False,
|
||||
store=True,
|
||||
comodel_name="res.partner.id_category",
|
||||
compute="_compute_document_type",
|
||||
)
|
||||
document_expedition_date = fields.Date(
|
||||
string="Expedition Date",
|
||||
help="Date on which document_type was issued",
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_document_expedition_date",
|
||||
)
|
||||
|
||||
document_id = fields.Many2one(
|
||||
string="Document",
|
||||
help="Technical field",
|
||||
readonly=False,
|
||||
store=True,
|
||||
comodel_name="res.partner.id_number",
|
||||
compute="_compute_document_id",
|
||||
ondelete="restrict",
|
||||
)
|
||||
|
||||
incongruences = fields.Char(
|
||||
string="Incongruences",
|
||||
help="Technical field",
|
||||
compute="_compute_incongruences",
|
||||
)
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_document_number(self):
|
||||
for record in self:
|
||||
if not record.document_number:
|
||||
if record.partner_id.id_numbers:
|
||||
record.document_number = record.partner_id.id_numbers[0].name
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_document_type(self):
|
||||
for record in self:
|
||||
if record.partner_id and record.partner_id.id_numbers:
|
||||
if not record.document_type:
|
||||
if record.partner_id.id_numbers:
|
||||
record.document_type = record.partner_id.id_numbers[
|
||||
0
|
||||
].category_id
|
||||
|
||||
@api.depends(
|
||||
"partner_id",
|
||||
)
|
||||
def _compute_document_expedition_date(self):
|
||||
for record in self:
|
||||
if record.partner_id and record.partner_id.id_numbers:
|
||||
if not record.document_expedition_date:
|
||||
record.document_expedition_date = record.partner_id.id_numbers[
|
||||
0
|
||||
].valid_from
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_firstname(self):
|
||||
for record in self:
|
||||
if not record.firstname and record.partner_id.firstname:
|
||||
record.firstname = record.partner_id.firstname
|
||||
elif not record.firstname:
|
||||
record.firstname = False
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_lastname(self):
|
||||
for record in self:
|
||||
if not record.lastname and record.partner_id.lastname:
|
||||
record.lastname = record.partner_id.lastname
|
||||
elif not record.lastname:
|
||||
record.lastname = False
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_lastname2(self):
|
||||
for record in self:
|
||||
if not record.lastname2 and record.partner_id.lastname2:
|
||||
record.lastname2 = record.partner_id.lastname2
|
||||
elif not record.lastname2:
|
||||
record.lastname2 = False
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_birth_date(self):
|
||||
for record in self:
|
||||
if not record.birthdate_date and record.partner_id.birthdate_date:
|
||||
record.birthdate_date = record.partner_id.birthdate_date
|
||||
elif not record.birthdate_date:
|
||||
record.birthdate_date = False
|
||||
|
||||
@api.depends(
|
||||
"partner_id",
|
||||
)
|
||||
def _compute_gender(self):
|
||||
for record in self:
|
||||
if not record.gender and record.partner_id.gender:
|
||||
record.gender = record.partner_id.gender
|
||||
elif not record.gender:
|
||||
record.gender = False
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_nationality(self):
|
||||
for record in self:
|
||||
if not record.nationality_id and record.partner_id.nationality_id:
|
||||
record.nationality_id = record.partner_id.nationality_id
|
||||
elif not record.nationality_id:
|
||||
record.nationality_id = False
|
||||
|
||||
@api.depends("reservation_id", "folio_id", "reservation_id.preferred_room_id")
|
||||
def _compute_identifier(self):
|
||||
for record in self:
|
||||
@@ -163,21 +322,109 @@ class PmsCheckinPartner(models.Model):
|
||||
)
|
||||
def _compute_name(self):
|
||||
for record in self:
|
||||
if not record.name:
|
||||
if not record.name or record.partner_id.name:
|
||||
record.name = record.partner_id.name
|
||||
|
||||
@api.depends("partner_id", "partner_id.email")
|
||||
@api.depends("partner_id")
|
||||
def _compute_email(self):
|
||||
for record in self:
|
||||
if not record.email:
|
||||
if not record.email or record.partner_id.email:
|
||||
record.email = record.partner_id.email
|
||||
|
||||
@api.depends("partner_id", "partner_id.mobile")
|
||||
@api.depends("partner_id")
|
||||
def _compute_mobile(self):
|
||||
for record in self:
|
||||
if not record.mobile:
|
||||
if not record.mobile or record.partner_id.mobile:
|
||||
record.mobile = record.partner_id.mobile
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_document_id(self):
|
||||
for record in self:
|
||||
if record.partner_id:
|
||||
if (
|
||||
not record.document_id
|
||||
and record.document_number
|
||||
and record.document_type
|
||||
):
|
||||
id_number_id = self.env["res.partner.id_number"].search(
|
||||
[
|
||||
("partner_id", "=", record.partner_id.id),
|
||||
("name", "=", record.document_number),
|
||||
("category_id", "=", record.document_type.id),
|
||||
]
|
||||
)
|
||||
if not id_number_id:
|
||||
id_number_id = self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"partner_id": record.partner_id.id,
|
||||
"name": record.document_number,
|
||||
"category_id": record.document_type.id,
|
||||
"valid_from": record.document_expedition_date,
|
||||
}
|
||||
)
|
||||
|
||||
record.document_id = id_number_id
|
||||
else:
|
||||
record.document_id = False
|
||||
|
||||
@api.depends(
|
||||
"document_number", "document_type", "firstname", "lastname", "lastname2"
|
||||
)
|
||||
def _compute_partner_id(self):
|
||||
for record in self:
|
||||
if not record.partner_id:
|
||||
if record.document_number and record.document_type:
|
||||
number = self.env["res.partner.id_number"].search(
|
||||
[
|
||||
("name", "=", record.document_number),
|
||||
("category_id", "=", record.document_type.id),
|
||||
]
|
||||
)
|
||||
partner = self.env["res.partner"].search(
|
||||
[("id", "=", number.partner_id.id)]
|
||||
)
|
||||
if not partner:
|
||||
if record.firstname or record.lastname or record.lastname2:
|
||||
partner_values = {
|
||||
"firstname": record.firstname,
|
||||
"lastname": record.lastname,
|
||||
"lastname2": record.lastname2,
|
||||
"gender": record.gender,
|
||||
"birthdate_date": record.birthdate_date,
|
||||
"nationality_id": record.nationality_id.id,
|
||||
}
|
||||
partner = self.env["res.partner"].create(partner_values)
|
||||
record.partner_id = partner
|
||||
|
||||
@api.depends(
|
||||
"firstname",
|
||||
"lastname",
|
||||
"lastname2",
|
||||
"gender",
|
||||
"birthdate_date",
|
||||
"nationality_id",
|
||||
"email",
|
||||
"mobile",
|
||||
)
|
||||
def _compute_incongruences(self):
|
||||
for record in self:
|
||||
incongruous_fields = ""
|
||||
if record.partner_id:
|
||||
for field in record._checkin_partner_fields():
|
||||
if (
|
||||
record.partner_id[field]
|
||||
and record.partner_id[field] != record[field]
|
||||
):
|
||||
incongruous_fields += record._fields[field].string + ", "
|
||||
if incongruous_fields:
|
||||
record.incongruences = (
|
||||
incongruous_fields + "field/s don't correspond to saved host"
|
||||
)
|
||||
else:
|
||||
record.incongruences = False
|
||||
else:
|
||||
record.incongruences = False
|
||||
|
||||
@api.constrains("departure", "arrival")
|
||||
def _check_departure(self):
|
||||
for record in self:
|
||||
@@ -224,6 +471,15 @@ class PmsCheckinPartner(models.Model):
|
||||
):
|
||||
raise ValidationError(_("'%s' is not a valid phone", record.mobile))
|
||||
|
||||
@api.constrains("document_number")
|
||||
def check_document_number(self):
|
||||
for record in self:
|
||||
if record.partner_id:
|
||||
for number in record.partner_id.id_numbers:
|
||||
if record.document_type == number.category_id:
|
||||
if record.document_number != number.name:
|
||||
raise ValidationError(_("Document_type has already exists"))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
# The checkin records are created automatically from adult depends
|
||||
@@ -255,43 +511,6 @@ class PmsCheckinPartner(models.Model):
|
||||
_("Is not possible to create the proposed check-in in this reservation")
|
||||
)
|
||||
|
||||
def write(self, vals):
|
||||
res = super(PmsCheckinPartner, self).write(vals)
|
||||
ResPartner = self.env["res.partner"]
|
||||
if any(field in vals for field in ResPartner._get_key_fields()):
|
||||
# Create Partner if get key field in the checkin
|
||||
for record in self:
|
||||
key = False
|
||||
partner = False
|
||||
if not record.partner_id:
|
||||
partner_vals = {}
|
||||
for field in self._checkin_partner_fields():
|
||||
if getattr(record, field):
|
||||
partner_vals[field] = getattr(record, field)
|
||||
if field in ResPartner._get_key_fields() and partner_vals.get(
|
||||
field
|
||||
):
|
||||
key = True
|
||||
# REVIEW: if partner exist, we can merge?
|
||||
partner = ResPartner.search(
|
||||
[(field, "=", getattr(record, field))]
|
||||
)
|
||||
if key:
|
||||
if not partner:
|
||||
partner = ResPartner.create(partner_vals)
|
||||
record.partner_id = partner
|
||||
|
||||
if any(field in vals for field in self._checkin_partner_fields()):
|
||||
# Update partner when the checkin partner field is not set on the partner
|
||||
for record in self:
|
||||
if record.partner_id:
|
||||
partner_vals = {}
|
||||
for field in self._checkin_partner_fields():
|
||||
if not getattr(record.partner_id, field):
|
||||
partner_vals[field] = getattr(record, field)
|
||||
record.partner_id.write(partner_vals)
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
reservations = self.mapped("reservation_id")
|
||||
res = super().unlink()
|
||||
@@ -303,13 +522,30 @@ class PmsCheckinPartner(models.Model):
|
||||
# api.depends need "reservation_id.state" in the lambda function
|
||||
if depends:
|
||||
return ["reservation_id.state", "name"]
|
||||
return ["name"]
|
||||
mandatory_fields = [
|
||||
"name",
|
||||
"birthdate_date",
|
||||
"gender",
|
||||
"document_number",
|
||||
"document_type",
|
||||
"document_expedition_date",
|
||||
]
|
||||
|
||||
return mandatory_fields
|
||||
|
||||
@api.model
|
||||
def _checkin_partner_fields(self):
|
||||
# api.depends need "reservation_id.state" in the lambda function
|
||||
checkin_fields = self._checkin_mandatory_fields()
|
||||
checkin_fields.extend(["mobile", "email"])
|
||||
checkin_fields = [
|
||||
"firstname",
|
||||
"lastname",
|
||||
"lastname2",
|
||||
"mobile",
|
||||
"email",
|
||||
"gender",
|
||||
"nationality_id",
|
||||
"birthdate_date",
|
||||
]
|
||||
return checkin_fields
|
||||
|
||||
@api.model
|
||||
@@ -339,6 +575,7 @@ class PmsCheckinPartner(models.Model):
|
||||
raise ValidationError(_("It is not yet checkin day!"))
|
||||
if record.reservation_id.checkout <= fields.Date.today():
|
||||
raise ValidationError(_("Its too late to checkin"))
|
||||
|
||||
if any(
|
||||
not getattr(record, field) for field in self._checkin_mandatory_fields()
|
||||
):
|
||||
|
||||
@@ -89,6 +89,15 @@ class PmsProperty(models.Model):
|
||||
selection=_tz_get,
|
||||
)
|
||||
|
||||
cardex_warning = fields.Text(
|
||||
string="Warning in Cardex",
|
||||
default="Time to access rooms: 14: 00h. "
|
||||
"Departure time: 12: 00h. If the accommodation "
|
||||
"is not left at that time, the establishment will "
|
||||
"charge a day's stay according to current rate that day",
|
||||
help="Notice under the signature on the traveler's ticket.",
|
||||
)
|
||||
|
||||
@api.constrains("default_arrival_hour")
|
||||
def _check_arrival_hour(self):
|
||||
for record in self:
|
||||
|
||||
@@ -1340,6 +1340,16 @@ class PmsReservation(models.Model):
|
||||
raise ValidationError(_("booking agency with wrong configuration: "))
|
||||
|
||||
# Action methods
|
||||
def print_all_checkins(self):
|
||||
checkins = self.env["pms.checkin.partner"]
|
||||
for record in self:
|
||||
checkins += record.checkin_partner_ids.filtered(
|
||||
lambda s: s.state in ("onboard", "done")
|
||||
)
|
||||
if checkins:
|
||||
return self.env.ref("pms.action_report_viajero").report_action(checkins)
|
||||
else:
|
||||
raise ValidationError(_("Some checkin partners "))
|
||||
|
||||
def open_folio(self):
|
||||
action = self.env.ref("pms.open_pms_folio1_form_tree_all").sudo().read()[0]
|
||||
|
||||
@@ -13,3 +13,8 @@ class ResCompany(models.Model):
|
||||
comodel_name="pms.property",
|
||||
inverse_name="company_id",
|
||||
)
|
||||
|
||||
privacy_policy = fields.Text(
|
||||
string="Privacy Policy",
|
||||
help="Authorization by the user for the" "manage of their personal data",
|
||||
)
|
||||
|
||||
@@ -56,6 +56,180 @@ class ResPartner(models.Model):
|
||||
check_pms_properties=True,
|
||||
)
|
||||
|
||||
pms_checkin_partner_ids = fields.One2many(
|
||||
string="Checkin Partners",
|
||||
help="Associated checkin partners",
|
||||
comodel_name="pms.checkin.partner",
|
||||
inverse_name="partner_id",
|
||||
)
|
||||
|
||||
gender = fields.Selection(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_gender",
|
||||
)
|
||||
|
||||
birthdate_date = fields.Date(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_birthdate_date",
|
||||
)
|
||||
|
||||
nationality_id = fields.Many2one(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_nationality_id",
|
||||
)
|
||||
|
||||
email = fields.Char(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_email",
|
||||
)
|
||||
mobile = fields.Char(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_mobile",
|
||||
)
|
||||
|
||||
firstname = fields.Char(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_firstname",
|
||||
)
|
||||
|
||||
lastname = fields.Char(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_lastname",
|
||||
)
|
||||
|
||||
lastname2 = fields.Char(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_lastname2",
|
||||
)
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.gender")
|
||||
def _compute_gender(self):
|
||||
if hasattr(super(), "_compute_gender"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.gender and record.pms_checkin_partner_ids:
|
||||
gender = list(set(record.pms_checkin_partner_ids.mapped("gender")))
|
||||
if len(gender) == 1:
|
||||
record.gender = gender[0]
|
||||
else:
|
||||
record.gender = False
|
||||
elif not record.gender:
|
||||
record.gender = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.birthdate_date")
|
||||
def _compute_birthdate_date(self):
|
||||
if hasattr(super(), "_compute_birthdate_date"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.birthdate_date and record.pms_checkin_partner_ids:
|
||||
birthdate = list(
|
||||
set(record.pms_checkin_partner_ids.mapped("birthdate_date"))
|
||||
)
|
||||
if len(birthdate) == 1:
|
||||
record.birthdate_date = birthdate[0]
|
||||
else:
|
||||
record.birthdate_date = False
|
||||
elif not record.birthdate_date:
|
||||
record.birthdate_date = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.nationality_id")
|
||||
def _compute_nationality_id(self):
|
||||
if hasattr(super(), "_compute_nationality_id"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.nationality_id and record.pms_checkin_partner_ids:
|
||||
nationality_id = list(
|
||||
set(record.pms_checkin_partner_ids.mapped("nationality_id"))
|
||||
)
|
||||
if len(nationality_id) == 1:
|
||||
record.nationality_id = nationality_id[0]
|
||||
else:
|
||||
record.nationality_id = False
|
||||
elif not record.nationality_id:
|
||||
record.nationality_id = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.email")
|
||||
def _compute_email(self):
|
||||
if hasattr(super(), "_compute_email"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.email and record.pms_checkin_partner_ids:
|
||||
email = list(set(record.pms_checkin_partner_ids.mapped("email")))
|
||||
if len(email) == 1:
|
||||
record.email = email[0]
|
||||
else:
|
||||
record.email = False
|
||||
elif not record.email:
|
||||
record.email = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.mobile")
|
||||
def _compute_mobile(self):
|
||||
if hasattr(super(), "_compute_mobile"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.mobile and record.pms_checkin_partner_ids:
|
||||
mobile = list(set(record.pms_checkin_partner_ids.mapped("mobile")))
|
||||
if len(mobile) == 1:
|
||||
record.mobile = mobile[0]
|
||||
else:
|
||||
record.mobile = False
|
||||
elif not record.mobile:
|
||||
record.mobile = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.firstname")
|
||||
def _compute_firstname(self):
|
||||
if hasattr(super(), "_compute_firstname"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.firstname and record.pms_checkin_partner_ids:
|
||||
firstname = list(
|
||||
set(record.pms_checkin_partner_ids.mapped("firstname"))
|
||||
)
|
||||
if len(firstname) == 1:
|
||||
record.firstname = firstname[0]
|
||||
else:
|
||||
record.firstname = False
|
||||
elif not record.firstname:
|
||||
record.firstname = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.lastname")
|
||||
def _compute_lastname(self):
|
||||
if hasattr(super(), "_compute_lastname"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.lastname and record.pms_checkin_partner_ids:
|
||||
lastname = list(set(record.pms_checkin_partner_ids.mapped("lastname")))
|
||||
if len(lastname) == 1:
|
||||
record.lastname = lastname[0]
|
||||
else:
|
||||
record.lastname = False
|
||||
elif not record.lastname:
|
||||
record.lastname = False
|
||||
|
||||
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.lastname2")
|
||||
def _compute_lastname2(self):
|
||||
if hasattr(super(), "_compute_lastname2"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.lastname2 and record.pms_checkin_partner_ids:
|
||||
lastname2 = list(
|
||||
set(record.pms_checkin_partner_ids.mapped("lastname2"))
|
||||
)
|
||||
if len(lastname2) == 1:
|
||||
record.lastname2 = lastname2[0]
|
||||
else:
|
||||
record.lastname2 = False
|
||||
elif not record.lastname2:
|
||||
record.lastname2 = False
|
||||
|
||||
def _compute_reservations_count(self):
|
||||
# TODO: recuperar las reservas de los folios del partner
|
||||
pms_reservation_obj = self.env["pms.reservation"]
|
||||
@@ -149,4 +323,6 @@ class ResPartner(models.Model):
|
||||
|
||||
@api.model
|
||||
def _get_key_fields(self):
|
||||
return []
|
||||
key_fields = super(ResPartner, self)._get_key_fields()
|
||||
key_fields.extend(["document_number"])
|
||||
return key_fields
|
||||
|
||||
55
pms/models/res_partner_id_number.py
Normal file
55
pms/models/res_partner_id_number.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# Copyright 2004-2010 Tiny SPRL http://tiny.be
|
||||
# Copyright 2010-2012 ChriCar Beteiligungs- und Beratungs- GmbH
|
||||
# http://www.camptocamp.at
|
||||
# Copyright 2015 Antiun Ingenieria, SL (Madrid, Spain)
|
||||
# http://www.antiun.com
|
||||
# Antonio Espinosa <antonioea@antiun.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class ResPartnerIdNumber(models.Model):
|
||||
_inherit = "res.partner.id_number"
|
||||
|
||||
valid_from = fields.Date(
|
||||
readonly=False,
|
||||
store=True,
|
||||
compute="_compute_valid_from",
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
"partner_id", "partner_id.pms_checkin_partner_ids.document_expedition_date"
|
||||
)
|
||||
def _compute_valid_from(self):
|
||||
if hasattr(super(), "_compute_valid_from"):
|
||||
super()._compute_field()
|
||||
for record in self:
|
||||
if not record.valid_from and record.partner_id.pms_checkin_partner_ids:
|
||||
document_expedition_date = list(
|
||||
set(
|
||||
record.partner_id.pms_checkin_partner_ids.mapped(
|
||||
"document_expedition_date"
|
||||
)
|
||||
)
|
||||
)
|
||||
if len(document_expedition_date) == 1:
|
||||
record.valid_from = document_expedition_date[0]
|
||||
else:
|
||||
record.valid_from = False
|
||||
elif not record.valid_from:
|
||||
record.valid_from = False
|
||||
|
||||
@api.constrains("partner_id", "category_id")
|
||||
def _check_category_id_unique(self):
|
||||
for record in self:
|
||||
id_number = self.env["res.partner.id_number"].search(
|
||||
[
|
||||
("partner_id", "=", record.partner_id.id),
|
||||
("category_id", "=", record.category_id.id),
|
||||
]
|
||||
)
|
||||
if len(id_number) > 1:
|
||||
raise ValidationError(_("Partner already has this document type"))
|
||||
14
pms/report/traveller_report_action.xml
Normal file
14
pms/report/traveller_report_action.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<report
|
||||
id="action_report_viajero"
|
||||
string="Parte de Viajero"
|
||||
model="pms.checkin.partner"
|
||||
report_type="qweb-pdf"
|
||||
name="pms.report_viajero"
|
||||
file="pms.report_viajero"
|
||||
paperformat="report_viajero_paperformat"
|
||||
/>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,49 +1,98 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo import fields
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import common
|
||||
|
||||
from .common import TestPms
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
class TestPmsCheckinPartner(common.SavepointCase):
|
||||
@classmethod
|
||||
def arrange_single_checkin(cls):
|
||||
# Arrange for one checkin on one reservation
|
||||
cls.host1 = cls.env["res.partner"].create(
|
||||
class TestPmsCheckinPartner(TestPms):
|
||||
@freeze_time("2012-01-14")
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.room_type1 = self.env["pms.room.type"].create(
|
||||
{
|
||||
"pms_property_ids": [self.pms_property1.id],
|
||||
"name": "Triple",
|
||||
"default_code": "TRP",
|
||||
"class_id": self.room_type_class1.id,
|
||||
}
|
||||
)
|
||||
self.room1 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Triple 101",
|
||||
"room_type_id": self.room_type1.id,
|
||||
"capacity": 3,
|
||||
}
|
||||
)
|
||||
self.room1_2 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Triple 111",
|
||||
"room_type_id": self.room_type1.id,
|
||||
"capacity": 3,
|
||||
}
|
||||
)
|
||||
self.room1_3 = self.env["pms.room"].create(
|
||||
{
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"name": "Triple 222",
|
||||
"room_type_id": self.room_type1.id,
|
||||
"capacity": 3,
|
||||
}
|
||||
)
|
||||
|
||||
self.host1 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Miguel",
|
||||
"phone": "654667733",
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.id_category = self.env["res.partner.id_category"].create(
|
||||
{"name": "DNI", "code": "D"}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host1.id,
|
||||
}
|
||||
)
|
||||
reservation_vals = {
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": cls.env.ref("pms.pms_room_type_3").id,
|
||||
"partner_id": cls.host1.id,
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=3),
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.host1.id,
|
||||
"adults": 3,
|
||||
"pms_property_id": cls.env.ref("pms.main_pms_property").id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
demo_user = cls.env.ref("base.user_demo")
|
||||
cls.reservation_1 = (
|
||||
cls.env["pms.reservation"].with_user(demo_user).create(reservation_vals)
|
||||
)
|
||||
cls.checkin1 = cls.env["pms.checkin.partner"].create(
|
||||
self.reservation_1 = self.env["pms.reservation"].create(reservation_vals)
|
||||
self.checkin1 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": cls.host1.id,
|
||||
"reservation_id": cls.reservation_1.id,
|
||||
"partner_id": self.host1.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_auto_create_checkins(self):
|
||||
"""
|
||||
Check that as many checkin_partners are created as there
|
||||
adults on the reservation
|
||||
|
||||
Reservation has three adults
|
||||
"""
|
||||
|
||||
# ACTION
|
||||
self.arrange_single_checkin()
|
||||
checkins_count = len(self.reservation_1.checkin_partner_ids)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
@@ -52,17 +101,24 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"the automatic partner checkin was not created successful",
|
||||
)
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
def test_auto_unlink_checkins(self):
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
|
||||
# ACTION
|
||||
host2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Carlos",
|
||||
"phone": "654667733",
|
||||
"email": "carlos@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host2.id,
|
||||
}
|
||||
)
|
||||
self.reservation_1.checkin_partner_ids = [
|
||||
@@ -85,19 +141,23 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
)
|
||||
|
||||
def test_onboard_checkin(self):
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
"""
|
||||
Check that the reservation cannot be onboard because
|
||||
checkin_partner data are incomplete and not have onboard status
|
||||
"""
|
||||
|
||||
# ACT & ASSERT
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
with self.assertRaises(
|
||||
ValidationError, msg="Reservation state cannot be 'onboard'"
|
||||
):
|
||||
self.reservation_1.state = "onboard"
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
def test_onboard_reservation(self):
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
|
||||
"""
|
||||
Check that reservation state is onboard as the checkin day is
|
||||
today and checkin_partners data are complete
|
||||
"""
|
||||
# ACT
|
||||
self.checkin1.action_on_board()
|
||||
|
||||
@@ -108,24 +168,38 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"the reservation checkin was not successful",
|
||||
)
|
||||
|
||||
def test_premature_checkin(self):
|
||||
@freeze_time("2012-01-14")
|
||||
def test_late_checkin(self):
|
||||
"""
|
||||
Check that cannot change checkin_partner state to onboard if
|
||||
it's not yet checkin day
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
self.reservation_1.write(
|
||||
{
|
||||
"checkin": "2012-01-15",
|
||||
"checkin": datetime.date.today() + datetime.timedelta(days=1),
|
||||
}
|
||||
)
|
||||
# ACT & ASSERT
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
with self.assertRaises(ValidationError, msg="Cannot do checkin onboard"):
|
||||
self.checkin1.action_on_board()
|
||||
|
||||
def test_late_checkin(self):
|
||||
@freeze_time("2012-01-13")
|
||||
def test_premature_checkin(self):
|
||||
"""
|
||||
When host arrives late anad has already passed the checkin day,
|
||||
the arrival date is updated up to that time.
|
||||
|
||||
In this case checkin day was 2012-01-14 and the host arrived a day later
|
||||
so the arrival date is updated to that time
|
||||
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
self.reservation_1.write(
|
||||
{
|
||||
"checkin": "2012-01-13",
|
||||
"checkin": datetime.date.today(),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -139,14 +213,29 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"the late checkin has problems",
|
||||
)
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
def test_too_many_people_checkin(self):
|
||||
"""
|
||||
Reservation cannot have more checkin_partners than adults who have
|
||||
Reservation has three adults and cannot have four checkin_partner
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
host2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Carlos",
|
||||
"phone": "654667733",
|
||||
"email": "carlos@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host2.id,
|
||||
}
|
||||
)
|
||||
host3 = self.env["res.partner"].create(
|
||||
@@ -154,6 +243,16 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"name": "Enmanuel",
|
||||
"phone": "654667733",
|
||||
"email": "enmanuel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host3.id,
|
||||
}
|
||||
)
|
||||
host4 = self.env["res.partner"].create(
|
||||
@@ -161,6 +260,16 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"name": "Enrique",
|
||||
"phone": "654667733",
|
||||
"email": "enrique@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host4.id,
|
||||
}
|
||||
)
|
||||
self.env["pms.checkin.partner"].create(
|
||||
@@ -176,7 +285,10 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
# ACT & ASSERT
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
with self.assertRaises(
|
||||
ValidationError,
|
||||
msg="Reservation cannot have more checkin_partner than adults who have",
|
||||
):
|
||||
self.reservation_1.write(
|
||||
{
|
||||
"checkin_partner_ids": [
|
||||
@@ -191,89 +303,49 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def arrange_folio_reservations(cls):
|
||||
# Arrange on one folio with 3 reservations
|
||||
demo_user = cls.env.ref("base.user_demo")
|
||||
cls.host1 = cls.env["res.partner"].create(
|
||||
{
|
||||
"name": "Miguel",
|
||||
"phone": "654667733",
|
||||
"email": "miguel@example.com",
|
||||
}
|
||||
)
|
||||
cls.host2 = cls.env["res.partner"].create(
|
||||
@freeze_time("2012-01-14")
|
||||
def test_count_pending_arrival_persons(self):
|
||||
"""
|
||||
After making onboard of two of the three checkin_partners,
|
||||
one must remain pending arrival, that is a ratio of two thirds
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.host2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Carlos",
|
||||
"phone": "654667733",
|
||||
"email": "carlos@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
cls.host3 = cls.env["res.partner"].create(
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host2.id,
|
||||
}
|
||||
)
|
||||
self.host3 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Enmanuel",
|
||||
"phone": "654667733",
|
||||
"email": "enmanuel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
cls.host4 = cls.env["res.partner"].create(
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"name": "Enrique",
|
||||
"phone": "654667733",
|
||||
"email": "enrique@example.com",
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host3.id,
|
||||
}
|
||||
)
|
||||
folio_vals = {
|
||||
"partner_id": cls.host1.id,
|
||||
}
|
||||
cls.folio_1 = cls.env["pms.folio"].with_user(demo_user).create(folio_vals)
|
||||
reservation1_vals = {
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": cls.env.ref("pms.pms_room_type_3").id,
|
||||
"partner_id": cls.host1.id,
|
||||
"adults": 3,
|
||||
"pms_property_id": cls.env.ref("pms.main_pms_property").id,
|
||||
"folio_id": cls.folio_1.id,
|
||||
}
|
||||
reservation2_vals = {
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": cls.env.ref("pms.pms_room_type_2").id,
|
||||
"partner_id": cls.host1.id,
|
||||
"adults": 2,
|
||||
"pms_property_id": cls.env.ref("pms.main_pms_property").id,
|
||||
"folio_id": cls.folio_1.id,
|
||||
}
|
||||
reservation3_vals = {
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": cls.env.ref("pms.pms_room_type_2").id,
|
||||
"partner_id": cls.host1.id,
|
||||
"adults": 2,
|
||||
"pms_property_id": cls.env.ref("pms.main_pms_property").id,
|
||||
"folio_id": cls.folio_1.id,
|
||||
}
|
||||
cls.reservation_1 = (
|
||||
cls.env["pms.reservation"].with_user(demo_user).create(reservation1_vals)
|
||||
)
|
||||
cls.reservation_2 = (
|
||||
cls.env["pms.reservation"].with_user(demo_user).create(reservation2_vals)
|
||||
)
|
||||
cls.reservation_3 = (
|
||||
cls.env["pms.reservation"].with_user(demo_user).create(reservation3_vals)
|
||||
)
|
||||
|
||||
def test_count_pending_arrival_persons(self):
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_folio_reservations()
|
||||
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,
|
||||
@@ -304,17 +376,35 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
)
|
||||
|
||||
def test_complete_checkin_data(self):
|
||||
"""
|
||||
Reservation for three adults in a first place has three checkin_partners
|
||||
pending data. Check that there decrease once their data are entered.
|
||||
|
||||
Reservation has three adults, after entering data of two of them,
|
||||
check that only one remains to be checked and the ratio of data entered
|
||||
from checkin_partners is two thirds
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_folio_reservations()
|
||||
|
||||
# ACT
|
||||
self.checkin1 = self.env["pms.checkin.partner"].create(
|
||||
self.host2 = self.env["res.partner"].create(
|
||||
{
|
||||
"partner_id": self.host1.id,
|
||||
"reservation_id": self.reservation_1.id,
|
||||
"name": "Carlos",
|
||||
"phone": "654667733",
|
||||
"email": "carlos@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host2.id,
|
||||
}
|
||||
)
|
||||
# ACT
|
||||
|
||||
self.checkin2 = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": self.host2.id,
|
||||
@@ -335,18 +425,107 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"Fail the checkins data ratio on reservation",
|
||||
)
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
def test_auto_arrival_delayed(self):
|
||||
"""
|
||||
The state of reservation 'arrival_delayed' happen when the checkin day
|
||||
has already passed and the resrvation had not yet changed its state to onboard.
|
||||
|
||||
The date that was previously set was 2012-01-14,
|
||||
it was advanced one day (to 2012-01-15).
|
||||
There are three reservations with checkin day on 2012-01-14,
|
||||
after invoking the method auto_arrival_delayed
|
||||
those reservation change their state to 'auto_arrival_delayed'
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_folio_reservations()
|
||||
self.host2 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Carlos",
|
||||
"phone": "654667733",
|
||||
"email": "carlos@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host2.id,
|
||||
}
|
||||
)
|
||||
self.host3 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Enmanuel",
|
||||
"phone": "654667733",
|
||||
"email": "enmanuel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host3.id,
|
||||
}
|
||||
)
|
||||
self.host4 = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Enrique",
|
||||
"phone": "654667733",
|
||||
"email": "enrique@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host4.id,
|
||||
}
|
||||
)
|
||||
self.reservation_1.write(
|
||||
{
|
||||
"checkin": datetime.date.today() + datetime.timedelta(days=4),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=6),
|
||||
"adults": 1,
|
||||
}
|
||||
)
|
||||
reservation2_vals = {
|
||||
"checkin": datetime.date.today() + datetime.timedelta(days=4),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=6),
|
||||
"adults": 1,
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.host1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"folio_id": self.reservation_1.folio_id.id,
|
||||
}
|
||||
reservation3_vals = {
|
||||
"checkin": datetime.date.today() + datetime.timedelta(days=4),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=6),
|
||||
"adults": 1,
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.host1.id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
"folio_id": self.reservation_1.folio_id.id,
|
||||
}
|
||||
self.reservation_2 = self.env["pms.reservation"].create(reservation2_vals)
|
||||
self.reservation_3 = self.env["pms.reservation"].create(reservation3_vals)
|
||||
folio_1 = self.reservation_1.folio_id
|
||||
PmsReservation = self.env["pms.reservation"]
|
||||
|
||||
# ACTION
|
||||
freezer = freeze_time("2012-01-15 10:00:00")
|
||||
freezer = freeze_time("2012-01-19 10:00:00")
|
||||
freezer.start()
|
||||
PmsReservation.auto_arrival_delayed()
|
||||
|
||||
arrival_delayed_reservations = self.folio_1.reservation_ids.filtered(
|
||||
arrival_delayed_reservations = folio_1.reservation_ids.filtered(
|
||||
lambda r: r.state == "arrival_delayed"
|
||||
)
|
||||
|
||||
@@ -358,10 +537,28 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
)
|
||||
freezer.stop()
|
||||
|
||||
@freeze_time("2012-01-14")
|
||||
def test_auto_departure_delayed(self):
|
||||
"""
|
||||
When it's checkout dat and the reservation
|
||||
was in 'onboard' state, that state change to
|
||||
'departure_delayed' if the manual checkout wasn't performed.
|
||||
|
||||
The date that was previously set was 2012-01-14,
|
||||
it was advanced two days (to 2012-01-17).
|
||||
Reservation1 has checkout day on 2012-01-17,
|
||||
after invoking the method auto_departure_delayed
|
||||
this reservation change their state to 'auto_departure_delayed'
|
||||
"""
|
||||
|
||||
# ARRANGE
|
||||
self.arrange_single_checkin()
|
||||
self.reservation_1.write(
|
||||
{
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=3),
|
||||
"adults": 1,
|
||||
}
|
||||
)
|
||||
PmsReservation = self.env["pms.reservation"]
|
||||
self.checkin1.action_on_board()
|
||||
|
||||
@@ -378,19 +575,20 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
"Reservations not set like Departure delayed",
|
||||
)
|
||||
|
||||
@freeze_time("2010-12-10")
|
||||
def test_not_valid_emails(self):
|
||||
# TEST CASES
|
||||
# emails that should be detected as incorrect
|
||||
# Check that the email format is incorrect
|
||||
|
||||
# ARRANGE
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": self.env.ref("pms.pms_room_type_3").id,
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=3),
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.env.ref("base.res_partner_12").id,
|
||||
"adults": 3,
|
||||
"pms_property_id": self.env.ref("pms.main_pms_property").id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
test_cases = [
|
||||
@@ -404,7 +602,9 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
]
|
||||
for mail in test_cases:
|
||||
with self.subTest(i=mail):
|
||||
with self.assertRaises(ValidationError):
|
||||
with self.assertRaises(
|
||||
ValidationError, msg="Email format is correct and shouldn't"
|
||||
):
|
||||
reservation.write(
|
||||
{
|
||||
"checkin_partner_ids": [
|
||||
@@ -420,19 +620,20 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
|
||||
@freeze_time("2014-12-10")
|
||||
def test_valid_emails(self):
|
||||
# TEST CASES
|
||||
# emails that should be detected as correct
|
||||
# Check that the email format is correct
|
||||
|
||||
# ARRANGE
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": self.env.ref("pms.pms_room_type_3").id,
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=4),
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.env.ref("base.res_partner_12").id,
|
||||
"adults": 3,
|
||||
"pms_property_id": self.env.ref("pms.main_pms_property").id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
test_cases = [
|
||||
@@ -457,19 +658,20 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
)
|
||||
guest.unlink()
|
||||
|
||||
@freeze_time("2016-12-10")
|
||||
def test_not_valid_phone(self):
|
||||
# TEST CASES
|
||||
# phones that should be detected as incorrect
|
||||
# Check that the phone format is incorrect
|
||||
|
||||
# ARRANGE
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": self.env.ref("pms.pms_room_type_3").id,
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=1),
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.env.ref("base.res_partner_12").id,
|
||||
"adults": 3,
|
||||
"pms_property_id": self.env.ref("pms.main_pms_property").id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
test_cases = [
|
||||
@@ -481,7 +683,9 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
]
|
||||
for phone in test_cases:
|
||||
with self.subTest(i=phone):
|
||||
with self.assertRaises(ValidationError):
|
||||
with self.assertRaises(
|
||||
ValidationError, msg="Phone format is correct and shouldn't"
|
||||
):
|
||||
self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"name": "Carlos",
|
||||
@@ -490,19 +694,20 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
|
||||
@freeze_time("2018-12-10")
|
||||
def test_valid_phones(self):
|
||||
# TEST CASES
|
||||
# emails that should be detected as incorrect
|
||||
# Check that the phone format is correct
|
||||
|
||||
# ARRANGE
|
||||
reservation = self.env["pms.reservation"].create(
|
||||
{
|
||||
"checkin": "2012-01-14",
|
||||
"checkout": "2012-01-17",
|
||||
"room_type_id": self.env.ref("pms.pms_room_type_3").id,
|
||||
"checkin": datetime.date.today(),
|
||||
"checkout": datetime.date.today() + datetime.timedelta(days=5),
|
||||
"room_type_id": self.room_type1.id,
|
||||
"partner_id": self.env.ref("base.res_partner_12").id,
|
||||
"adults": 3,
|
||||
"pms_property_id": self.env.ref("pms.main_pms_property").id,
|
||||
"pms_property_id": self.pms_property1.id,
|
||||
}
|
||||
)
|
||||
test_cases = [
|
||||
@@ -523,3 +728,194 @@ class TestPmsCheckinPartner(common.SavepointCase):
|
||||
mobile,
|
||||
guest.mobile,
|
||||
)
|
||||
|
||||
def test_complete_checkin_data_with_partner_data(self):
|
||||
"""
|
||||
When a partner is asociated with a checkin, checkin data
|
||||
will be equal to the partner data
|
||||
|
||||
Host1:
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
|
||||
Checkin1:
|
||||
"partner_id": host1.id
|
||||
|
||||
So after this:
|
||||
Checkin1:
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
"""
|
||||
# ARRANGE
|
||||
partner_data = [self.host1.birthdate_date, self.host1.email, self.host1.gender]
|
||||
checkin_data = [
|
||||
self.checkin1.birthdate_date,
|
||||
self.checkin1.email,
|
||||
self.checkin1.gender,
|
||||
]
|
||||
|
||||
# ASSERT
|
||||
for i in [0, 1, 2]:
|
||||
self.assertEqual(
|
||||
partner_data[i],
|
||||
checkin_data[i],
|
||||
"Checkin data must be the same as partner data ",
|
||||
)
|
||||
|
||||
def test_create_partner_when_checkin_has_enought_data(self):
|
||||
"""
|
||||
Check that partner is created when the necessary minimum data is entered
|
||||
into checkin_partner data
|
||||
"""
|
||||
# ACT & ASSERT
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"firstname": "Pepe",
|
||||
"lastname": "Paz",
|
||||
"document_type": self.id_category.id,
|
||||
"document_number": "77156490T",
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertTrue(
|
||||
checkin.partner_id,
|
||||
"Partner should have been created and associated with the checkin",
|
||||
)
|
||||
|
||||
def test_not_create_partner_checkin_hasnt_enought_data(self):
|
||||
"""
|
||||
Check that partner is not created when the necessary minimum data isn't entered
|
||||
into checkin_partner data, in this case document_id and document_number
|
||||
"""
|
||||
# ACT & ASSERT
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"firstname": "Pepe",
|
||||
"lastname": "Paz",
|
||||
"email": "pepepaz@gmail.com",
|
||||
"mobile": "666777777",
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertFalse(
|
||||
checkin.partner_id,
|
||||
"Partner mustn't have been created and associated with the checkin",
|
||||
)
|
||||
|
||||
def test_add_partner_data_from_checkin(self):
|
||||
"""
|
||||
If the checkin_partner has some data that the partner doesn't have,
|
||||
these are saved in the partner
|
||||
|
||||
In this case, host1 hasn't mobile but the checkin_partner associated with it does,
|
||||
so the mobile of checkin_partner is added to the partner data
|
||||
|
||||
Note that if the mobile is entered before partnee was associated, this or other fields
|
||||
are overwritten by the partner's fields. In this case it is entered once the partner has
|
||||
already been associated
|
||||
"""
|
||||
# ARRANGE
|
||||
self.checkin1.mobile = "666777888"
|
||||
# ASSERT
|
||||
self.assertTrue(self.host1.mobile, "Partner mobile must be added")
|
||||
|
||||
def _test_partner_id_numbers_created_from_checkin(self):
|
||||
"""
|
||||
Some of the required data of the checkin_partner to create the partner are document_type
|
||||
and document_number, with them an id_number is created associated with the partner that
|
||||
has just been created.
|
||||
In this test it is verified that this document has been created correctly
|
||||
"""
|
||||
# ACT & ARRANGE
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"firstname": "Pepe",
|
||||
"lastname": "Paz",
|
||||
"document_type": self.id_category.id,
|
||||
"document_number": "77156490T",
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertTrue(
|
||||
checkin.partner_id.id_numbers,
|
||||
"Partner id_number should have been created and hasn't been",
|
||||
)
|
||||
|
||||
def test_partner_not_modified_when_checkin_modified(self):
|
||||
"""
|
||||
If a partner is associated with a checkin
|
||||
and some of their data is modified in the checkin,
|
||||
they will not be modified in the partner
|
||||
"""
|
||||
# ARRANGE
|
||||
self.checkin1.email = "prueba@gmail.com"
|
||||
|
||||
# ASSERT
|
||||
self.assertNotEqual(
|
||||
self.host1.email,
|
||||
self.checkin1.email,
|
||||
"Checkin partner email and partner email shouldn't match",
|
||||
)
|
||||
|
||||
def _test_partner_modified_previous_checkin_not_modified(self):
|
||||
"""
|
||||
If a partner modifies any of its fields, these change mustn't be reflected
|
||||
in the previous checkins associated with it
|
||||
"""
|
||||
# ARRANGE
|
||||
self.host1.gender = "female"
|
||||
# ASSERT
|
||||
self.assertNotEqual(
|
||||
self.host1.gender,
|
||||
self.checkin1.gender,
|
||||
"Checkin partner gender and partner gender shouldn't match",
|
||||
)
|
||||
|
||||
def test_add_partner_if_exists_from_checkin(self):
|
||||
"""
|
||||
Check when a document_type and document_number are entered in a checkin if this
|
||||
document already existes and is associated with a partner, this partner will be
|
||||
associated with the checkin
|
||||
"""
|
||||
# ACT
|
||||
host = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "Ricardo",
|
||||
"phone": "666555666",
|
||||
"email": "ricardo@example.com",
|
||||
"birthdate_date": "1995-11-14",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "55562998N",
|
||||
"partner_id": host.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ARRANGE
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"document_type": self.id_category.id,
|
||||
"document_number": "55562998N",
|
||||
"reservation_id": self.reservation_1.id,
|
||||
}
|
||||
)
|
||||
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
checkin.partner_id.id,
|
||||
host.id,
|
||||
"Checkin partner_id must be the same as the one who has that document",
|
||||
)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import common
|
||||
|
||||
from .common import TestPms
|
||||
|
||||
|
||||
class TestPmsResUser(common.SavepointCase):
|
||||
def create_common_scenario(self):
|
||||
# create a room type availability
|
||||
self.room_type_availability = self.env["pms.availability.plan"].create(
|
||||
{"name": "Availability plan 1"}
|
||||
)
|
||||
|
||||
class TestPmsResUser(TestPms):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# create a company and properties
|
||||
self.company_A = self.env["res.company"].create(
|
||||
{
|
||||
@@ -20,104 +17,50 @@ class TestPmsResUser(common.SavepointCase):
|
||||
"name": "Pms_Company2",
|
||||
}
|
||||
)
|
||||
self.folio_sequenceA = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Folio",
|
||||
"code": "pms.folio",
|
||||
"padding": 4,
|
||||
"company_id": self.company_A.id,
|
||||
}
|
||||
)
|
||||
self.reservation_sequenceA = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Reservation",
|
||||
"code": "pms.reservation",
|
||||
"padding": 4,
|
||||
"company_id": self.company_A.id,
|
||||
}
|
||||
)
|
||||
self.checkin_sequenceA = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Checkin",
|
||||
"code": "pms.checkin.partner",
|
||||
"padding": 4,
|
||||
"company_id": self.company_A.id,
|
||||
}
|
||||
)
|
||||
self.folio_sequenceB = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Folio",
|
||||
"code": "pms.folio",
|
||||
"padding": 4,
|
||||
"company_id": self.company_B.id,
|
||||
}
|
||||
)
|
||||
self.reservation_sequenceB = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Reservation",
|
||||
"code": "pms.reservation",
|
||||
"padding": 4,
|
||||
"company_id": self.company_B.id,
|
||||
}
|
||||
)
|
||||
self.checkin_sequenceB = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Checkin",
|
||||
"code": "pms.checkin.partner",
|
||||
"padding": 4,
|
||||
"company_id": self.company_B.id,
|
||||
}
|
||||
)
|
||||
self.property_A1 = self.env["pms.property"].create(
|
||||
{
|
||||
"name": "Pms_property",
|
||||
"company_id": self.company_A.id,
|
||||
"default_pricelist_id": self.env.ref("product.list0").id,
|
||||
"folio_sequence_id": self.folio_sequenceA.id,
|
||||
"reservation_sequence_id": self.reservation_sequenceA.id,
|
||||
"checkin_sequence_id": self.checkin_sequenceA.id,
|
||||
"default_pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
self.property_A2 = self.env["pms.property"].create(
|
||||
{
|
||||
"name": "Pms_property2",
|
||||
"company_id": self.company_A.id,
|
||||
"default_pricelist_id": self.env.ref("product.list0").id,
|
||||
"folio_sequence_id": self.folio_sequenceA.id,
|
||||
"reservation_sequence_id": self.reservation_sequenceA.id,
|
||||
"checkin_sequence_id": self.checkin_sequenceA.id,
|
||||
"default_pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
self.property_B1 = self.env["pms.property"].create(
|
||||
{
|
||||
"name": "Pms_propertyB1",
|
||||
"company_id": self.company_B.id,
|
||||
"default_pricelist_id": self.env.ref("product.list0").id,
|
||||
"folio_sequence_id": self.folio_sequenceB.id,
|
||||
"reservation_sequence_id": self.reservation_sequenceB.id,
|
||||
"checkin_sequence_id": self.checkin_sequenceB.id,
|
||||
"default_pricelist_id": self.pricelist1.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_property_not_allowed(self):
|
||||
def test_property_not_in_allowed_properties(self):
|
||||
"""
|
||||
Property not allowed, it belongs to another company
|
||||
Property not allowed for the user
|
||||
Check a user cannot have an active property
|
||||
that is not in the allowed properties
|
||||
|
||||
Company_A ---> Property_A1, Property_A2
|
||||
Company_B ---> Property_B1
|
||||
|
||||
|
||||
"""
|
||||
# ARRANGE
|
||||
name = "test user"
|
||||
login = "test_user"
|
||||
self.create_common_scenario()
|
||||
Users = self.env["res.users"]
|
||||
# ACT & ASSERT
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
with self.assertRaises(
|
||||
ValidationError,
|
||||
msg="Some property is not included in the allowed properties",
|
||||
):
|
||||
Users.create(
|
||||
{
|
||||
"name": name,
|
||||
"login": login,
|
||||
"name": "Test User",
|
||||
"login": "test_user",
|
||||
"company_ids": [(4, self.company_A.id)],
|
||||
"company_id": self.company_A.id,
|
||||
"pms_property_ids": [(4, self.property_A1.id)],
|
||||
@@ -125,18 +68,26 @@ class TestPmsResUser(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
|
||||
def test_check_allowed_property_ids(self):
|
||||
def test_property_not_in_allowed_companies(self):
|
||||
"""
|
||||
Property not allowed for the user
|
||||
Check a user cannot have a property in allowed properties
|
||||
that does not belong to their companies
|
||||
|
||||
Company_A ---> Property_A1, Property_A2
|
||||
Company_B ---> Property_B1
|
||||
|
||||
"""
|
||||
# ARRANGE
|
||||
name = "test user2"
|
||||
login = "test_user2"
|
||||
self.create_common_scenario()
|
||||
Users = self.env["res.users"]
|
||||
# ACT & ASSERT
|
||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||
with self.assertRaises(
|
||||
ValidationError, msg="Some property doesn't belong to the allowed companies"
|
||||
):
|
||||
Users.create(
|
||||
{
|
||||
"name": name,
|
||||
"login": login,
|
||||
"name": "Test User",
|
||||
"login": "test_user",
|
||||
"company_ids": [(4, self.company_A.id)],
|
||||
"company_id": self.company_A.id,
|
||||
"pms_property_ids": [
|
||||
@@ -146,3 +97,68 @@ class TestPmsResUser(common.SavepointCase):
|
||||
"pms_property_id": self.property_A1.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_property_in_allowed_properties(self):
|
||||
"""
|
||||
Successful user creation
|
||||
Check user creation with active property in allowed properties
|
||||
|
||||
Company_A ---> Property_A1, Property_A2
|
||||
Company_B ---> Property_B1
|
||||
|
||||
"""
|
||||
# ARRANGE
|
||||
Users = self.env["res.users"]
|
||||
# ACT
|
||||
user1 = Users.create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "test_user",
|
||||
"company_ids": [(4, self.company_A.id)],
|
||||
"company_id": self.company_A.id,
|
||||
"pms_property_ids": [
|
||||
(4, self.property_A1.id),
|
||||
(4, self.property_A2.id),
|
||||
],
|
||||
"pms_property_id": self.property_A1.id,
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertIn(
|
||||
user1.pms_property_id,
|
||||
user1.pms_property_ids,
|
||||
"Active property not in allowed properties",
|
||||
)
|
||||
|
||||
def test_properties_belong_to_companies(self):
|
||||
"""
|
||||
Successful user creation
|
||||
Check user creation with active property and allowed properties
|
||||
belonging to the allowed companies
|
||||
|
||||
Company_A ---> Property_A1, Property_A2
|
||||
Company_B ---> Property_B1
|
||||
|
||||
"""
|
||||
# ARRANGE
|
||||
Users = self.env["res.users"]
|
||||
# ACT
|
||||
user1 = Users.create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "test_user",
|
||||
"company_ids": [(4, self.company_A.id)],
|
||||
"company_id": self.company_A.id,
|
||||
"pms_property_ids": [
|
||||
(4, self.property_A1.id),
|
||||
(4, self.property_A2.id),
|
||||
],
|
||||
"pms_property_id": self.property_A1.id,
|
||||
}
|
||||
)
|
||||
# ASSERT
|
||||
self.assertEqual(
|
||||
user1.pms_property_id.company_id,
|
||||
user1.company_id,
|
||||
"Active property doesn't belong to active company",
|
||||
)
|
||||
|
||||
@@ -104,6 +104,9 @@ class TestPmsReservations(common.SavepointCase):
|
||||
}
|
||||
)
|
||||
self.demo_user = self.env.ref("base.user_admin")
|
||||
self.id_category = self.env["res.partner.id_category"].create(
|
||||
{"name": "DNI", "code": "D"}
|
||||
)
|
||||
|
||||
def create_multiproperty_scenario(self):
|
||||
self.create_common_scenario()
|
||||
@@ -831,6 +834,16 @@ class TestPmsReservations(common.SavepointCase):
|
||||
"name": "Miguel",
|
||||
"phone": "654667733",
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host.id,
|
||||
}
|
||||
)
|
||||
r1 = self.env["pms.reservation"].create(
|
||||
@@ -1004,6 +1017,16 @@ class TestPmsReservations(common.SavepointCase):
|
||||
"name": "Miguel",
|
||||
"phone": "654667733",
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": host.id,
|
||||
}
|
||||
)
|
||||
r1 = self.env["pms.reservation"].create(
|
||||
@@ -1271,6 +1294,16 @@ class TestPmsReservations(common.SavepointCase):
|
||||
"name": "Miguel",
|
||||
"phone": "654667733",
|
||||
"email": "miguel@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065000H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host1.id,
|
||||
}
|
||||
)
|
||||
self.host2 = self.env["res.partner"].create(
|
||||
@@ -1278,6 +1311,16 @@ class TestPmsReservations(common.SavepointCase):
|
||||
"name": "Brais",
|
||||
"phone": "654437733",
|
||||
"email": "brais@example.com",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
}
|
||||
)
|
||||
self.env["res.partner.id_number"].create(
|
||||
{
|
||||
"category_id": self.id_category.id,
|
||||
"name": "30065089H",
|
||||
"valid_from": datetime.date.today(),
|
||||
"partner_id": self.host2.id,
|
||||
}
|
||||
)
|
||||
self.reservation = self.env["pms.reservation"].create(
|
||||
|
||||
@@ -25,14 +25,32 @@
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div
|
||||
class="alert alert-danger"
|
||||
role="danger"
|
||||
style="margin-bottom:0px;"
|
||||
attrs="{'invisible': [('incongruences','=',False)]}"
|
||||
>
|
||||
<field name="incongruences" />
|
||||
</div>
|
||||
<group name="group_top">
|
||||
<group name="group_left">
|
||||
<field
|
||||
name="partner_id"
|
||||
required="True"
|
||||
domain="[('is_company','=', False)]"
|
||||
/>
|
||||
<field name="name" />
|
||||
<field name="firstname" />
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
<field name="email" />
|
||||
<field name="mobile" />
|
||||
<field name="document_id" invisible="1" />
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
<field name="arrival" />
|
||||
<field name="departure" />
|
||||
@@ -44,6 +62,14 @@
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
</group>
|
||||
</group>
|
||||
<button
|
||||
type="action"
|
||||
class="btn-primary float-right"
|
||||
icon="fa-file-pdf-o"
|
||||
name="%(action_report_viajero)d"
|
||||
string="Print in PDF"
|
||||
attrs="{'invisible': [('state','not in', ('onboard','done'))]}"
|
||||
/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
@@ -70,7 +96,15 @@
|
||||
/>
|
||||
<field name="identifier" />
|
||||
<field name="partner_id" />
|
||||
<field name="name" />
|
||||
<field name="firstname" />
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
<field name="mobile" />
|
||||
<field name="email" />
|
||||
<field name="arrival" />
|
||||
@@ -107,7 +141,15 @@
|
||||
<field name="reservation_id" />
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
<field name="partner_id" domain="[('is_company','=', False)]" />
|
||||
<field name="name" />
|
||||
<field name="firstname" />
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
<field name="mobile" />
|
||||
<field name="email" />
|
||||
<field name="arrival" invisible="1" />
|
||||
@@ -139,13 +181,21 @@
|
||||
/>
|
||||
<field name="identifier" />
|
||||
<field name="partner_id" domain="[('is_company','=', False)]" />
|
||||
<field name="name" />
|
||||
<field name="reservation_id" />
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
<field name="firstname" />
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
<field name="mobile" />
|
||||
<field name="email" />
|
||||
<field name="arrival" />
|
||||
<field name="departure" />
|
||||
<field name="reservation_id" />
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
<field name="folio_id" force_save="1" invisible="1" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
@@ -167,11 +217,19 @@
|
||||
>
|
||||
<field name="id" />
|
||||
<field name="identifier" />
|
||||
<field name="partner_id" />
|
||||
<field name="reservation_id" />
|
||||
<field name="folio_id" />
|
||||
<field name="pms_property_id" />
|
||||
<field name="name" />
|
||||
<field name="pms_property_id" invisible="1" />
|
||||
<field name="partner_id" domain="[('is_company','=', False)]" />
|
||||
<field name="firstname" />
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
<field name="email" />
|
||||
<field name="mobile" />
|
||||
<field name="arrival" />
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
<field name="default_arrival_hour" />
|
||||
<field name="default_departure_hour" />
|
||||
</group>
|
||||
<group string="Print in cardex">
|
||||
<field name="cardex_warning" />
|
||||
</group>
|
||||
</page>
|
||||
<page string="Rooms" name="property_rooms">
|
||||
<group>
|
||||
|
||||
@@ -108,6 +108,15 @@
|
||||
name="button_box"
|
||||
attrs="{'invisible': [('folio_id','=',False)]}"
|
||||
>
|
||||
<button
|
||||
name="print_all_checkins"
|
||||
string="Print All Checkins"
|
||||
type="object"
|
||||
icon="fa-print"
|
||||
attrs="{'invisible':[
|
||||
('checkin_partner_ids','=', [])
|
||||
]}"
|
||||
/>
|
||||
<button
|
||||
name="preview_reservation"
|
||||
type="object"
|
||||
|
||||
16
pms/views/res_company_views.xml
Normal file
16
pms/views/res_company_views.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="company_view_form" model="ir.ui.view">
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='general_info']" position="after">
|
||||
<page string="Cardex Settings" name="cardex_settings">
|
||||
<group name="privacy_policy" string="Privacy Policy">
|
||||
<field name="privacy_policy" />
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
259
pms/views/traveller_report_template.xml
Normal file
259
pms/views/traveller_report_template.xml
Normal file
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<template id="report_viajero">
|
||||
<t t-call="web.basic_layout">
|
||||
<t t-foreach="docs" t-as="docs">
|
||||
<img
|
||||
t-attf-src="data:image/*;base64,{{docs.pms_property_id.company_id.logo}}"
|
||||
t-att-alt="docs.pms_property_id.company_id.name"
|
||||
/>
|
||||
<p>PART OF TRAVELERS ENTRY</p>
|
||||
<p>Document number:
|
||||
<strong><span t-field="docs.id" /></strong>/
|
||||
<span t-field="docs.reservation_id" />
|
||||
</p>
|
||||
<p>
|
||||
Total amount (Reservation Card):
|
||||
<strong><span
|
||||
t-field="docs.reservation_id.folio_id.amount_total"
|
||||
/></strong>
|
||||
</p>
|
||||
<div class="property">
|
||||
<strong><span t-field="docs.pms_property_id.name" /></strong><br />
|
||||
<strong>CIF:
|
||||
<span t-field="docs.pms_property_id.company_id.vat" /></strong><br
|
||||
/>
|
||||
<span t-field="docs.pms_property_id.company_id.name" /><br />
|
||||
<strong><span t-field="docs.pms_property_id.company_id.street" />
|
||||
<span
|
||||
t-field="docs.pms_property_id.company_id.street2"
|
||||
/></strong><br />
|
||||
<strong><span t-field="docs.pms_property_id.company_id.zip" />
|
||||
<span t-field="docs.pms_property_id.company_id.city" /></strong><b
|
||||
/>
|
||||
</div>
|
||||
<p>TRAVELER'S DOCUMENT</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Document number</td>
|
||||
<td><strong><span t-field="docs.document_number" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td><strong><span t-field="docs.document_type" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Expedition date</td>
|
||||
<td><strong><span
|
||||
t-field="docs.document_expedition_date"
|
||||
/></strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td><strong> <span t-field="docs.firstname" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lastnames</td>
|
||||
<td><strong><span t-field="docs.lastname" /><span
|
||||
t-field="docs.lastname2"
|
||||
/></strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
Gender</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.gender" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Birthdate</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.birthdate_date" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
Entry date</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.arrival" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Exit date</td>
|
||||
<td>
|
||||
<strong><span t-field="docs.departure" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div>
|
||||
<p class="date">
|
||||
<span t-field="docs.pms_property_id.partner_id.city" />, at
|
||||
<span
|
||||
t-esc="time.strftime('%Y-%m-%d')"
|
||||
t-options="{"widget": "date"}"
|
||||
/>
|
||||
</p>
|
||||
<div class="firma" /><br />
|
||||
<p>Traveler's signature</p>
|
||||
<p><span t-field="docs.pms_property_id.cardex_warning" /></p>
|
||||
<p><span t-field="docs.pms_property_id.company_id.privacy_policy" /></p>
|
||||
</div>
|
||||
<p style="page-break-after:always;" />
|
||||
<img
|
||||
t-attf-src="data:image/*;base64,{{docs.pms_property_id.company_id.logo}}"
|
||||
t-att-alt="docs.pms_property_id.company_id.name"
|
||||
/>
|
||||
<p>PART OF TRAVELERS ENTRY</p>
|
||||
<p>Document number:
|
||||
<strong><span t-field="docs.id" /></strong>/
|
||||
<span t-field="docs.reservation_id" />
|
||||
</p>
|
||||
<p>
|
||||
Total amount (Reservation Card):
|
||||
<strong><span
|
||||
t-field="docs.reservation_id.folio_id.amount_total"
|
||||
/></strong>
|
||||
</p>
|
||||
<div class="property">
|
||||
<strong><span t-field="docs.pms_property_id.name" /></strong><br />
|
||||
<strong>CIF:
|
||||
<span t-field="docs.pms_property_id.company_id.vat" /></strong><br
|
||||
/>
|
||||
<span t-field="docs.pms_property_id.company_id.name" /><br />
|
||||
<strong><span t-field="docs.pms_property_id.company_id.street" />
|
||||
<span
|
||||
t-field="docs.pms_property_id.company_id.street2"
|
||||
/></strong><br />
|
||||
<strong><span t-field="docs.pms_property_id.company_id.zip" />
|
||||
<span t-field="docs.pms_property_id.company_id.city" /></strong><b
|
||||
/>
|
||||
</div>
|
||||
<p>TRAVELER'S DOCUMENT</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Document number</td>
|
||||
<td><strong><span t-field="docs.document_number" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td><strong><span t-field="docs.document_type" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Expedition date</td>
|
||||
<td><strong><span
|
||||
t-field="docs.document_expedition_date"
|
||||
/></strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td><strong> <span t-field="docs.firstname" /></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lastnames</td>
|
||||
<td><strong><span t-field="docs.lastname" /><span
|
||||
t-field="docs.lastname2"
|
||||
/></strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
Gender</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.gender" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Birthdate</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.birthdate_date" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
Entry date</td>
|
||||
<td>
|
||||
<strong>
|
||||
<span t-field="docs.arrival" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Exit date</td>
|
||||
<td>
|
||||
<strong><span t-field="docs.departure" /></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div>
|
||||
<p class="date">
|
||||
<span t-field="docs.pms_property_id.partner_id.city" />, at
|
||||
<span
|
||||
t-esc="time.strftime('%Y-%m-%d')"
|
||||
t-options="{"widget": "date"}"
|
||||
/>
|
||||
</p>
|
||||
<p><strong>Copy for the host</strong></p>
|
||||
<p><span t-field="docs.pms_property_id.cardex_warning" /></p>
|
||||
<p><span t-field="docs.pms_property_id.company_id.privacy_policy" /></p>
|
||||
</div>
|
||||
<div class="final" />
|
||||
<p style="page-break-after:always;" />
|
||||
<style>
|
||||
table{
|
||||
width: 100%;
|
||||
border: 1;
|
||||
border-style: double;
|
||||
margin-top:8px;
|
||||
}
|
||||
td:first-child{
|
||||
width:40%;
|
||||
padding-left:3px;
|
||||
border:double;
|
||||
border-width:1px;
|
||||
}
|
||||
td:last-child{
|
||||
width:100%;
|
||||
padding-left:3px;
|
||||
border:double;
|
||||
border-width:1px;
|
||||
}
|
||||
.firma{
|
||||
width: 85%;
|
||||
border:dotted 1px;
|
||||
height: 80px;
|
||||
margin:0 auto;
|
||||
}
|
||||
p,.property{
|
||||
text-align: center;
|
||||
font-family: kiro, Verdana, Geneva, sans-serif;
|
||||
}
|
||||
.date{
|
||||
margin-top:8px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -25,12 +25,11 @@
|
||||
},
|
||||
"data": [
|
||||
"data/cron_jobs.xml",
|
||||
"data/pms_data.xml",
|
||||
"data/queue_data.xml",
|
||||
"data/queue_job_function_data.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"views/pms_checkin_partner_views.xml",
|
||||
"views/pms_property_views.xml",
|
||||
"views/res_partner_views.xml",
|
||||
"views/pms_log_institution_traveller_report_views.xml",
|
||||
"wizards/traveller_report.xml",
|
||||
],
|
||||
|
||||
46
pms_l10n_es/data/pms_data.xml
Normal file
46
pms_l10n_es/data/pms_data.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="document_type_dni" model="res.partner.id_category">
|
||||
<field name="name">DNI</field>
|
||||
<field name="code">D</field>
|
||||
<field name="validation_code">
|
||||
letters = {
|
||||
0: "T",
|
||||
1: "R",
|
||||
2: "W",
|
||||
3: "A",
|
||||
4: "G",
|
||||
5: "M",
|
||||
6: "Y",
|
||||
7: "F",
|
||||
8: "P",
|
||||
9: "D",
|
||||
10: "X",
|
||||
11: "B",
|
||||
12: "N",
|
||||
13: "J",
|
||||
14: "Z",
|
||||
15: "S",
|
||||
16: "Q",
|
||||
17: "V",
|
||||
18: "H",
|
||||
19: "L",
|
||||
20: "C",
|
||||
21: "K",
|
||||
22: "E",
|
||||
}
|
||||
dni_number = id_number.name[0:8]
|
||||
dni_letter = id_number.name[
|
||||
len(id_number.name) - 1 : len(id_number.name)
|
||||
]
|
||||
if dni_number.isdigit() and not dni_letter.isdigit():
|
||||
if letters.get(int(dni_number) % 23) != dni_letter.upper():
|
||||
failed = True
|
||||
else:
|
||||
failed = True
|
||||
</field>
|
||||
<!-- <field name="has_unique_numbers">True</field>-->
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,4 +1,4 @@
|
||||
from . import res_partner
|
||||
from . import pms_checkin_partner
|
||||
# from . import res_partner
|
||||
# from . import pms_checkin_partner
|
||||
from . import pms_property
|
||||
from . import pms_log_institution_traveller_report
|
||||
|
||||
@@ -1,143 +1,5 @@
|
||||
from odoo import api, fields, models
|
||||
from odoo import models
|
||||
|
||||
|
||||
class PmsCheckinPartner(models.Model):
|
||||
_inherit = "pms.checkin.partner"
|
||||
|
||||
firstname = fields.Char(
|
||||
"First Name",
|
||||
compute="_compute_firstname",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
lastname = fields.Char(
|
||||
"Last Name",
|
||||
compute="_compute_lastname",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
lastname2 = fields.Char(
|
||||
"Second Last Name",
|
||||
compute="_compute_lastname2",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
birthdate_date = fields.Date(
|
||||
"Birthdate",
|
||||
compute="_compute_birth_date",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
document_number = fields.Char(
|
||||
"Document Number",
|
||||
compute="_compute_document_number",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
document_type = fields.Selection(
|
||||
[
|
||||
("D", "DNI"),
|
||||
("P", "Passport"),
|
||||
("C", "Driving License"),
|
||||
("I", "Identification Document"),
|
||||
("N", "Spanish residence permit"),
|
||||
("X", "European residence permit"),
|
||||
],
|
||||
string="Document Type",
|
||||
help="Select a valid document type",
|
||||
compute="_compute_document_type",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
document_expedition_date = fields.Date(
|
||||
"Expedition Date",
|
||||
compute="_compute_document_expedition_date",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
gender = fields.Selection(
|
||||
[("male", "Male"), ("female", "Female"), ("other", "Other")],
|
||||
string="Gender",
|
||||
compute="_compute_gender",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
nationality_id = fields.Many2one(
|
||||
string="Nationality ID",
|
||||
compute="_compute_nationality",
|
||||
comodel_name="res.country",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@api.depends("partner_id", "partner_id.firstname")
|
||||
def _compute_firstname(self):
|
||||
for record in self:
|
||||
if not record.firstname:
|
||||
record.firstname = record.partner_id.firstname
|
||||
|
||||
@api.depends("partner_id", "partner_id.lastname")
|
||||
def _compute_lastname(self):
|
||||
for record in self:
|
||||
if not record.lastname:
|
||||
record.lastname = record.partner_id.lastname
|
||||
|
||||
@api.depends("partner_id", "partner_id.lastname2")
|
||||
def _compute_lastname2(self):
|
||||
for record in self:
|
||||
if not record.lastname2:
|
||||
record.lastname2 = record.partner_id.lastname2
|
||||
|
||||
@api.depends("partner_id", "partner_id.birthdate_date")
|
||||
def _compute_birth_date(self):
|
||||
for record in self:
|
||||
if not record.birthdate_date:
|
||||
record.birthdate_date = record.partner_id.birthdate_date
|
||||
|
||||
@api.depends("partner_id", "partner_id.document_number")
|
||||
def _compute_document_number(self):
|
||||
for record in self:
|
||||
if not record.document_number:
|
||||
record.document_number = record.partner_id.document_number
|
||||
|
||||
@api.depends("partner_id", "partner_id.document_type")
|
||||
def _compute_document_type(self):
|
||||
for record in self:
|
||||
if not record.document_type:
|
||||
record.document_type = record.partner_id.document_type
|
||||
|
||||
@api.depends("partner_id", "partner_id.document_expedition_date")
|
||||
def _compute_document_expedition_date(self):
|
||||
for record in self:
|
||||
if not record.document_expedition_date:
|
||||
record.document_expedition_date = (
|
||||
record.partner_id.document_expedition_date
|
||||
)
|
||||
|
||||
@api.depends("partner_id", "partner_id.gender")
|
||||
def _compute_gender(self):
|
||||
for record in self:
|
||||
if not record.gender:
|
||||
record.gender = record.partner_id.gender
|
||||
|
||||
@api.depends("partner_id", "partner_id.lastname")
|
||||
def _compute_nationality(self):
|
||||
for record in self:
|
||||
if not record.nationality_id:
|
||||
record.nationality_id = record.partner_id.nationality_id
|
||||
|
||||
@api.model
|
||||
def _checkin_mandatory_fields(self, depends=False):
|
||||
mandatory_fields = super(PmsCheckinPartner, self)._checkin_mandatory_fields(
|
||||
depends
|
||||
)
|
||||
mandatory_fields.extend(
|
||||
[
|
||||
"birthdate_date",
|
||||
"document_number",
|
||||
"document_type",
|
||||
"document_expedition_date",
|
||||
"gender",
|
||||
]
|
||||
)
|
||||
return mandatory_fields
|
||||
|
||||
@@ -1,49 +1,5 @@
|
||||
from odoo import _, api, fields, models
|
||||
from odoo import models
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = "res.partner"
|
||||
|
||||
document_type = fields.Selection(
|
||||
[
|
||||
("D", "DNI"),
|
||||
("P", "Passport"),
|
||||
("C", "Driving License"),
|
||||
("I", "Identification Document"),
|
||||
("N", "Spanish residence permit"),
|
||||
("X", "European residence permit"),
|
||||
],
|
||||
help="Select a valid document type",
|
||||
string="Doc. type",
|
||||
)
|
||||
document_number = fields.Char(
|
||||
string="Document number",
|
||||
)
|
||||
document_expedition_date = fields.Date(string="Document expedition date")
|
||||
|
||||
@api.constrains("document_number", "document_type")
|
||||
def _check_document(self):
|
||||
for record in self.filtered("document_number"):
|
||||
if not record.document_type:
|
||||
raise models.ValidationError(_("Document Type field are mandatory"))
|
||||
partner = self.search(
|
||||
[
|
||||
("document_number", "=", record.document_number),
|
||||
("document_type", "=", record.document_type),
|
||||
("id", "!=", record.id),
|
||||
]
|
||||
)
|
||||
if partner:
|
||||
raise models.ValidationError(
|
||||
_(
|
||||
"Document Number Partner %s already exist (%s)",
|
||||
record.document_number,
|
||||
partner.name,
|
||||
)
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_key_fields(self):
|
||||
key_fields = super(ResPartner, self)._get_key_fields()
|
||||
key_fields.extend(["document_number"])
|
||||
return key_fields
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
from . import test_partner
|
||||
@@ -1,149 +0,0 @@
|
||||
import datetime
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo import fields
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
@freeze_time("2011-03-16")
|
||||
class TestResPartner(common.SavepointCase):
|
||||
def create_common_scenario(self):
|
||||
self.folio_sequence = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Folio",
|
||||
"code": "pms.folio",
|
||||
"padding": 4,
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
}
|
||||
)
|
||||
self.reservation_sequence = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Reservation",
|
||||
"code": "pms.reservation",
|
||||
"padding": 4,
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
}
|
||||
)
|
||||
self.checkin_sequence = self.env["ir.sequence"].create(
|
||||
{
|
||||
"name": "PMS Checkin",
|
||||
"code": "pms.checkin.partner",
|
||||
"padding": 4,
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
}
|
||||
)
|
||||
self.property_test = self.property = self.env["pms.property"].create(
|
||||
{
|
||||
"name": "My property test",
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
"default_pricelist_id": self.env.ref("product.list0").id,
|
||||
"folio_sequence_id": self.folio_sequence.id,
|
||||
"reservation_sequence_id": self.reservation_sequence.id,
|
||||
"checkin_sequence_id": self.checkin_sequence.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_check_precheckin_state(self):
|
||||
# arrange
|
||||
self.create_common_scenario()
|
||||
today = fields.date.today()
|
||||
partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "name1",
|
||||
# "lastname": "lastname1",
|
||||
"lastname2": "secondlastname",
|
||||
"document_expedition_date": "2011-02-20",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
"document_type": "D",
|
||||
"document_number": "30065089H",
|
||||
}
|
||||
)
|
||||
reservation_vals = {
|
||||
"checkin": today,
|
||||
"checkout": today + datetime.timedelta(days=3),
|
||||
"partner_id": partner.id,
|
||||
"adults": 1,
|
||||
"pms_property_id": self.property_test.id,
|
||||
}
|
||||
# action
|
||||
reservation = self.env["pms.reservation"].create(reservation_vals)
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"reservation_id": reservation.id,
|
||||
}
|
||||
)
|
||||
|
||||
# assert
|
||||
|
||||
self.assertEqual(
|
||||
checkin.state, "precheckin", "partner's fields weren't checked"
|
||||
)
|
||||
|
||||
def test_error_action_on_board(self):
|
||||
# arrange
|
||||
self.create_common_scenario()
|
||||
today = fields.date.today()
|
||||
partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "partner1",
|
||||
}
|
||||
)
|
||||
reservation_vals = {
|
||||
"checkin": today,
|
||||
"checkout": today + datetime.timedelta(days=3),
|
||||
"partner_id": partner.id,
|
||||
"adults": 1,
|
||||
"pms_property_id": self.property_test.id,
|
||||
}
|
||||
# action
|
||||
reservation = self.env["pms.reservation"].create(reservation_vals)
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"reservation_id": reservation.id,
|
||||
}
|
||||
)
|
||||
|
||||
# arrange
|
||||
with self.assertRaises(ValidationError):
|
||||
checkin.action_on_board()
|
||||
|
||||
def test_right_action_on_board(self):
|
||||
# arrange
|
||||
self.create_common_scenario()
|
||||
today = fields.date.today()
|
||||
partner = self.env["res.partner"].create(
|
||||
{
|
||||
"name": "name1",
|
||||
# "lastname": "lastname1",
|
||||
"lastname2": "secondlastname",
|
||||
"document_expedition_date": "2011-02-20",
|
||||
"birthdate_date": "1995-12-10",
|
||||
"gender": "male",
|
||||
"document_type": "D",
|
||||
"document_number": "30065089H",
|
||||
}
|
||||
)
|
||||
reservation_vals = {
|
||||
"checkin": today,
|
||||
"checkout": today + datetime.timedelta(days=3),
|
||||
"partner_id": partner.id,
|
||||
"adults": 1,
|
||||
"pms_property_id": self.property_test.id,
|
||||
}
|
||||
# action
|
||||
reservation = self.env["pms.reservation"].create(reservation_vals)
|
||||
checkin = self.env["pms.checkin.partner"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"reservation_id": reservation.id,
|
||||
}
|
||||
)
|
||||
checkin.action_on_board()
|
||||
# arrange
|
||||
self.assertEqual(reservation.state, "onboard", "reservation's state is wrong")
|
||||
self.assertEqual(checkin.state, "onboard", "checkin's state is wrong")
|
||||
@@ -1,100 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="pms_checkin_partner_view_form" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view form Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
<field name="inherit_id" ref="pms.pms_checkin_partner_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pms_checkin_partner_reservation_view_tree" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view reservation tree Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
<field name="inherit_id" ref="pms.pms_checkin_partner_reservation_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pms_checkin_partner_folio_view_tree" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view reservation tree Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
<field name="inherit_id" ref="pms.pms_checkin_partner_folio_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pms_checkin_partner_view_tree" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view tree Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
<field name="inherit_id" ref="pms.pms_checkin_partner_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
<record id="pms_checkin_partner_view_search" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view tree Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
<field name="inherit_id" ref="pms.pms_checkin_partner_view_search" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="view_partner_pms_l10n_es" model="ir.ui.view">
|
||||
<field name="name">Legal Spanish information</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="partner_contact_personal_information_page.personal_information"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='personal_information_group']" position="inside">
|
||||
<field name='document_type' />
|
||||
<field name='document_number' />
|
||||
<field name='document_expedition_date' />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user