Merge PR #11 into 14.0

Signed-off-by DarioLodeiros
This commit is contained in:
OCA-git-bot
2021-06-19 06:44:22 +00:00
28 changed files with 1762 additions and 746 deletions

View File

@@ -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",

View File

@@ -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>

View 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>

View File

@@ -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

View File

@@ -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()
):

View File

@@ -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:

View File

@@ -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]

View File

@@ -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",
)

View File

@@ -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

View 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"))

View 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>

View File

@@ -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",
)

View File

@@ -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",
)

View File

@@ -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(

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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"

View 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>

View 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="{&quot;widget&quot;: &quot;date&quot;}"
/>
</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="{&quot;widget&quot;: &quot;date&quot;}"
/>
</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>

View File

@@ -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",
],

View 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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1 +0,0 @@
from . import test_partner

View File

@@ -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")

View File

@@ -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>

View File

@@ -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>