diff --git a/multi_pms_properties/README.rst b/multi_pms_properties/README.rst deleted file mode 100644 index 732d4a153..000000000 --- a/multi_pms_properties/README.rst +++ /dev/null @@ -1,97 +0,0 @@ -==================== -multi_pms_properties -==================== - -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png - :target: https://odoo-community.org/page/development-status - :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github - :target: https://github.com/OCA/pms/tree/14.0/multi_pms_properties - :alt: OCA/pms -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pms-14-0/pms-14-0-multi_pms_properties - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/293/14.0 - :alt: Try me on Runbot - -|badge1| |badge2| |badge3| |badge4| |badge5| - -Technical addon to support multiproperty in property management system (PMS). - -**Table of contents** - -.. contents:: - :local: - -Installation -============ - -To install this module, you only need to add it to your addons, and load it as -a server-wide module. - -This can be done with the ``server_wide_modules`` parameter in ``/etc/odoo.conf`` -or with the ``--load`` command-line parameter - -``server_wide_modules = "multi_pms_properties"`` - -Usage -===== - -* Use the standard multicompany guidelines applied to pms.property: - - ``_check_pms_properties_auto like model attribute to autocheck on create/write`` - ``check_pms_properties like field attribute to check relational record properties consistence`` - ``This module not implement propety dependent fields`` - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Commit [Sun] - -Contributors -~~~~~~~~~~~~ - -* `Commit [Sun] `: - - * Dario Lodeiros - * Eric Antones - * Sara Lago - -Maintainers -~~~~~~~~~~~ - -This module is maintained by the OCA. - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -This module is part of the `OCA/pms `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/multi_pms_properties/__init__.py b/multi_pms_properties/__init__.py deleted file mode 100644 index 16fb7d2d4..000000000 --- a/multi_pms_properties/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2021 Dario Lodeiros -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import logging - -from odoo import fields -from odoo.tools import config - -from . import models - - -def _description_domain(self, env): - if self.check_company and not self.domain: - if self.company_dependent: - if self.comodel_name == "res.users": - # user needs access to current company (self.env.company) - return "[('company_ids', 'in', allowed_company_ids[0])]" - else: - return "[('company_id', 'in', [allowed_company_ids[0], False])]" - else: - # when using check_company=True on a field on 'res.company', the - # company_id comes from the id of the current record - cid = "id" if self.model_name == "res.company" else "company_id" - if self.comodel_name == "res.users": - # User allowed company ids = user.company_ids - return f"['|', (not {cid}, '=', True), ('company_ids', 'in', [{cid}])]" - else: - return f"[('company_id', 'in', [{cid}, False])]" - - if self.check_pms_properties and not self.domain: - record = env[self.model_name] - # Skip company_id domain to avoid domain multiproperty error in inherited views - if ( - self.check_pms_properties - and not self.domain - and self.name not in ["company_id"] - ): - if self.model_name == "pms.property": - prop1 = "id" - prop2 = f"[{prop1}]" - elif "pms_property_id" in record._fields: - prop1 = "pms_property_id" - prop2 = f"[{prop1}]" - else: - prop1 = prop2 = "pms_property_ids" - coprop = ( - "pms_property_id" - if "pms_property_id" in env[self.comodel_name]._fields - else "pms_property_ids" - ) - return f"['|', '|', \ - (not {prop1}, '=', True), \ - ('{coprop}', 'in', {prop2}), \ - ('{coprop}', '=', False)]" - - return self.domain(env[self.model_name]) if callable(self.domain) else self.domain - - -if "multi_pms_properties" in config.get("server_wide_modules"): - _logger = logging.getLogger(__name__) - _logger.info("monkey patching fields._Relational") - - fields._Relational.check_pms_properties = False - fields._Relational._description_domain = _description_domain diff --git a/multi_pms_properties/__manifest__.py b/multi_pms_properties/__manifest__.py deleted file mode 100644 index 4c5f81107..000000000 --- a/multi_pms_properties/__manifest__.py +++ /dev/null @@ -1,17 +0,0 @@ -# © 2013 Therp BV -# © 2014 ACSONE SA/NV -# Copyright 2018 Quartile Limited -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -{ - "name": "multi_pms_properties", - "summary": "Multi Properties Manager", - "version": "14.0.1.0.0", - "website": "https://github.com/OCA/pms", - "author": "Commit [Sun], Odoo Community Association (OCA)", - "license": "AGPL-3", - "category": "Pms", - "depends": ["base"], - "auto_install": False, - "installable": True, -} diff --git a/multi_pms_properties/i18n/multi_pms_properties.pot b/multi_pms_properties/i18n/multi_pms_properties.pot deleted file mode 100644 index a11d509b2..000000000 --- a/multi_pms_properties/i18n/multi_pms_properties.pot +++ /dev/null @@ -1,49 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * multi_pms_properties -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: multi_pms_properties -#: code:addons/multi_pms_properties/models.py:0 -#, python-format -msgid "" -"- %(record)r belongs to properties %(pms_properties)r and\n" -" %(field)r (%(fname)s: %(values)s) belongs to another properties." -msgstr "" - -#. module: multi_pms_properties -#: code:addons/multi_pms_properties/models.py:0 -#, python-format -msgid "" -"- Record is properties %(pms_properties)r and %(field)r\n" -" (%(fname)s: %(values)s) belongs to another properties." -msgstr "" - -#. module: multi_pms_properties -#: model:ir.model,name:multi_pms_properties.model_base -msgid "Base" -msgstr "" - -#. module: multi_pms_properties -#: code:addons/multi_pms_properties/models.py:0 -#, python-format -msgid "Incompatible properties on records:" -msgstr "" - -#. module: multi_pms_properties -#: code:addons/multi_pms_properties/models.py:0 -#, python-format -msgid "" -"You cannot establish a company other than the one with the established " -"properties" -msgstr "" diff --git a/multi_pms_properties/models.py b/multi_pms_properties/models.py deleted file mode 100644 index a2c0e7050..000000000 --- a/multi_pms_properties/models.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2021 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import _, api, models -from odoo.exceptions import UserError - - -class BaseModel(models.AbstractModel): - _inherit = "base" - _check_pms_properties_auto = False - """On write and create, call ``_check_pms_properties_auto`` to ensure properties - consistency on the relational fields having ``check_pms_properties=True`` - as attribute. - """ - - @api.model_create_multi - def create(self, vals_list): - records = super(BaseModel, self).create(vals_list) - if self._check_pms_properties_auto: - records._check_pms_properties() - return records - - def write(self, vals): - res = super(BaseModel, self).write(vals) - check_pms_properties = False - for fname in vals: - field = self._fields.get(fname) - if ( - fname == "pms_property_id" - or fname == "pms_property_ids" - or fname == "company_id" - or (field.relational and field.check_pms_properties) - ): - check_pms_properties = True - if res and check_pms_properties and self._check_pms_properties_auto: - self._check_pms_properties() - return res - - def _check_pms_properties(self, fnames=None): - """Check the properties of the values of the given field names. - - :param list fnames: names of relational fields to check - :raises UserError: if the `pms_properties` of the value of any field is not - in `[False, self.pms_property_id]` (or `self` if - :class:`~odoo.addons.base.models.pms_property`). - - For :class:`~odoo.addons.base.models.res_users` relational fields, - verifies record company is in `company_ids` fields. - - User with main pms property A, having access to pms property A and B, could be - assigned or linked to records in property B. - """ - if fnames is None: - fnames = self._fields - - regular_fields = self._get_regular_fields(fnames) - - if not regular_fields: - return - - inconsistencies = self._check_inconsistencies(regular_fields) - - if inconsistencies: - lines = [_("Incompatible properties on records:")] - property_msg = _( - """- Record is properties %(pms_properties)r and %(field)r - (%(fname)s: %(values)s) belongs to another properties.""" - ) - record_msg = _( - """- %(record)r belongs to properties %(pms_properties)r and - %(field)r (%(fname)s: %(values)s) belongs to another properties.""" - ) - for record, name, corecords in inconsistencies[:5]: - if record._name == "pms.property": - msg, pms_properties = property_msg, record - else: - msg, pms_properties = ( - record_msg, - record.pms_property_id.name - if "pms_property_id" in record - else ", ".join(repr(p.name) for p in record.pms_property_ids), - ) - field = self.env["ir.model.fields"]._get(self._name, name) - lines.append( - msg - % { - "record": record.display_name, - "pms_properties": pms_properties, - "field": field.field_description, - "fname": field.name, - "values": ", ".join( - repr(rec.display_name) for rec in corecords - ), - } - ) - raise UserError("\n".join(lines)) - - def _get_regular_fields(self, fnames): - regular_fields = [] - for name in fnames: - field = self._fields[name] - if ( - field.relational - and field.check_pms_properties - and ( - "pms_property_id" in self.env[field.comodel_name] - or "pms_property_ids" in self.env[field.comodel_name] - ) - ): - regular_fields.append(name) - return regular_fields - - def _check_inconsistencies(self, regular_fields): - inconsistencies = [] - for record in self: - pms_properties = False - if record._name == "pms.property": - pms_properties = record - if "pms_property_id" in record: - pms_properties = record.pms_property_id - if "pms_property_ids" in record: - pms_properties = record.pms_property_ids - # Check the property & company consistence - if "company_id" in self._fields: - if record.company_id and pms_properties: - property_companies = pms_properties.mapped("company_id.id") - if ( - len(property_companies) > 1 - or record.company_id.id != property_companies[0] - ): - raise UserError( - _( - "You cannot establish a company other than " - "the one with the established properties" - ) - ) - # Check verifies that all - # records linked via relation fields are compatible - # with the properties of the origin document, - for name in regular_fields: - field = self._fields[name] - co_pms_properties = False - - corecord = record.sudo()[name] - # TODO:res.users management properties - if "pms_property_id" in corecord: - co_pms_properties = corecord.pms_property_id - if "pms_property_ids" in corecord: - co_pms_properties = corecord.pms_property_ids - if ( - # There is an inconsistency if: - # - # - Record has properties and corecord too and - # there's no match between them: - # X Pms_room_class with Property1 cannot contain - # Pms_room with property2 X - # - # - Record has a relation one2many with corecord and - # corecord properties aren't included in record properties - # or what is the same, subtraction between corecord properties - # and record properties must be False: - # X Pricelist with Prop1 and Prop2 cannot contain - # Pricelist_item with Prop1 and Prop3 X - # X Pricelist with Prop1 and Prop2 cannot contain - # Pricelist_item with Prop1, Prop2 and Prop3 X - # -In case that record has a relation many2one - # with corecord the condition is the same as avobe - ( - pms_properties - and co_pms_properties - and (not pms_properties & co_pms_properties) - ) - or ( - corecord - and field.type == "one2many" - and pms_properties - and (co_pms_properties - pms_properties) - ) - or ( - field.type == "many2one" - and co_pms_properties - and ((pms_properties - co_pms_properties) or not pms_properties) - ) - ): - inconsistencies.append((record, name, corecord)) - return inconsistencies diff --git a/multi_pms_properties/readme/CONTRIBUTORS.rst b/multi_pms_properties/readme/CONTRIBUTORS.rst deleted file mode 100644 index eb93871f1..000000000 --- a/multi_pms_properties/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,5 +0,0 @@ -* `Commit [Sun] `: - - * Dario Lodeiros - * Eric Antones - * Sara Lago diff --git a/multi_pms_properties/readme/DESCRIPTION.rst b/multi_pms_properties/readme/DESCRIPTION.rst deleted file mode 100644 index d0d40fd9d..000000000 --- a/multi_pms_properties/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -Technical addon to support multiproperty in property management system (PMS). diff --git a/multi_pms_properties/readme/INSTALL.rst b/multi_pms_properties/readme/INSTALL.rst deleted file mode 100644 index b6b2f665f..000000000 --- a/multi_pms_properties/readme/INSTALL.rst +++ /dev/null @@ -1,7 +0,0 @@ -To install this module, you only need to add it to your addons, and load it as -a server-wide module. - -This can be done with the ``server_wide_modules`` parameter in ``/etc/odoo.conf`` -or with the ``--load`` command-line parameter - -``server_wide_modules = "multi_pms_properties"`` diff --git a/multi_pms_properties/readme/USAGE.rst b/multi_pms_properties/readme/USAGE.rst deleted file mode 100644 index daa058b5f..000000000 --- a/multi_pms_properties/readme/USAGE.rst +++ /dev/null @@ -1,5 +0,0 @@ -* Use the standard multicompany guidelines applied to pms.property: - - ``_check_pms_properties_auto like model attribute to autocheck on create/write`` - ``check_pms_properties like field attribute to check relational record properties consistence`` - ``This module not implement propety dependent fields`` diff --git a/multi_pms_properties/static/description/icon.png b/multi_pms_properties/static/description/icon.png deleted file mode 100644 index 3a0328b51..000000000 Binary files a/multi_pms_properties/static/description/icon.png and /dev/null differ diff --git a/multi_pms_properties/static/description/index.html b/multi_pms_properties/static/description/index.html deleted file mode 100644 index 073cb4c4f..000000000 --- a/multi_pms_properties/static/description/index.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - -multi_pms_properties - - - -
-

multi_pms_properties

- - -

Beta License: AGPL-3 OCA/pms Translate me on Weblate Try me on Runbot

-

Technical addon to support multiproperty in property management system (PMS).

-

Table of contents

- -
-

Installation

-

To install this module, you only need to add it to your addons, and load it as -a server-wide module.

-

This can be done with the server_wide_modules parameter in /etc/odoo.conf -or with the --load command-line parameter

-

server_wide_modules = "multi_pms_properties"

-
-
-

Usage

-
    -
  • Use the standard multicompany guidelines applied to pms.property:

    -

    _check_pms_properties_auto like model attribute to autocheck  on create/write -check_pms_properties like field attribute to check relational record properties consistence -This module not implement propety dependent fields

    -
  • -
-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Commit [Sun]
  • -
-
-
-

Contributors

-
    -
  • Commit [Sun] <https://www.commitsun.com>:
      -
    • Dario Lodeiros
    • -
    • Eric Antones
    • -
    • Sara Lago
    • -
    -
  • -
-
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

This module is part of the OCA/pms project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- - diff --git a/multi_pms_properties/tests/__init__.py b/multi_pms_properties/tests/__init__.py deleted file mode 100644 index c80a139bc..000000000 --- a/multi_pms_properties/tests/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import common -from . import test_multi_pms_properties diff --git a/multi_pms_properties/tests/common.py b/multi_pms_properties/tests/common.py deleted file mode 100644 index d4e9e2183..000000000 --- a/multi_pms_properties/tests/common.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - - -def setup_test_model(env, model_clses): - for model_cls in model_clses: - model_cls._build_model(env.registry, env.cr) - - env.registry.setup_models(env.cr) - env.registry.init_models( - env.cr, - [model_cls._name for model_cls in model_clses], - dict(env.context, update_custom_fields=True), - ) - - -def teardown_test_model(env, model_clses): - for model_cls in model_clses: - del env.registry.models[model_cls._name] - env.registry.setup_models(env.cr) diff --git a/multi_pms_properties/tests/multi_pms_properties_tester.py b/multi_pms_properties/tests/multi_pms_properties_tester.py deleted file mode 100644 index eabf61aa1..000000000 --- a/multi_pms_properties/tests/multi_pms_properties_tester.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import fields, models - - -class ParentTester(models.Model): - _name = "pms.parent.tester" - - name = fields.Char(required=True) - - -class ChildTester(models.Model): - _name = "pms.child.tester" - - name = fields.Char(required=True) - parent_id = fields.Many2one("pms.parent.tester", check_pms_properties=True) diff --git a/multi_pms_properties/tests/test_multi_pms_properties.py b/multi_pms_properties/tests/test_multi_pms_properties.py deleted file mode 100644 index 10f81e022..000000000 --- a/multi_pms_properties/tests/test_multi_pms_properties.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import logging - -from odoo.tests import common - -from .common import setup_test_model # , teardown_test_model -from .multi_pms_properties_tester import ChildTester, ParentTester - -_logger = logging.getLogger(__name__) - - -@common.tagged("-at_install", "post_install") -class TestMultiPMSProperties(common.SavepointCase): - @classmethod - def setUpClass(cls): - super(TestMultiPMSProperties, cls).setUpClass() - model_classes = [ParentTester, ChildTester] - setup_test_model(cls.env, model_classes) - for mdl_cls in model_classes: - tester_model = cls.env["ir.model"].search([("model", "=", mdl_cls._name)]) - # Access record - cls.env["ir.model.access"].create( - { - "name": "access.%s" % mdl_cls._name, - "model_id": tester_model.id, - "perm_read": 1, - "perm_write": 1, - "perm_create": 1, - "perm_unlink": 1, - } - ) - - # @classmethod - # def tearDownClass(cls): - # teardown_test_model(cls.env, [ParentTester]) - # super(TestMultiPMSProperties, cls).tearDownClass() - - # def test_exist_attribute(self): - # parent = self.env["pms.parent.tester"].create({"name": "parent test"}) diff --git a/payment_acquirer_multi_pms_properties/README.rst b/payment_acquirer_multi_pms_properties/README.rst deleted file mode 100644 index 7c8d78033..000000000 --- a/payment_acquirer_multi_pms_properties/README.rst +++ /dev/null @@ -1,81 +0,0 @@ -============================== -Payment Acquirer Multiproperty -============================== - -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png - :target: https://odoo-community.org/page/development-status - :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github - :target: https://github.com/OCA/pms/tree/14.0/payment_acquirer_multi_pms_properties - :alt: OCA/pms -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pms-14-0/pms-14-0-payment_acquirer_multi_pms_properties - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/293/14.0 - :alt: Try me on Runbot - -|badge1| |badge2| |badge3| |badge4| |badge5| - -Set the pms property in the payment acquirer to filter on website payments - -**Table of contents** - -.. contents:: - :local: - -Usage -===== - -Sets one or more properties in the payment acquirer so that payment method is only available for documents of those properties. -If you leave it blank, it will be available to everyone. - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Commit [Sun] - -Contributors -~~~~~~~~~~~~ - -* `Commit [Sun] `: - - * Dario Lodeiros - -Maintainers -~~~~~~~~~~~ - -This module is maintained by the OCA. - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -This module is part of the `OCA/pms `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/payment_acquirer_multi_pms_properties/__init__.py b/payment_acquirer_multi_pms_properties/__init__.py deleted file mode 100644 index f7209b171..000000000 --- a/payment_acquirer_multi_pms_properties/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import models -from . import controllers diff --git a/payment_acquirer_multi_pms_properties/__manifest__.py b/payment_acquirer_multi_pms_properties/__manifest__.py deleted file mode 100644 index c6b236348..000000000 --- a/payment_acquirer_multi_pms_properties/__manifest__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2009-2020 Noviat. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -{ - "name": "Payment Acquirer Multiproperty", - "author": "Commit [Sun], Odoo Community Association (OCA)", - "website": "https://github.com/OCA/pms", - "category": "Generic Modules/Property Management System", - "version": "14.0.1.0.1", - "license": "AGPL-3", - "depends": [ - "pms", - ], - "data": [ - "views/payment_acquirer.xml", - ], - "installable": True, -} diff --git a/payment_acquirer_multi_pms_properties/controllers/__init__.py b/payment_acquirer_multi_pms_properties/controllers/__init__.py deleted file mode 100644 index 10ef4ca2e..000000000 --- a/payment_acquirer_multi_pms_properties/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import portal diff --git a/payment_acquirer_multi_pms_properties/controllers/portal.py b/payment_acquirer_multi_pms_properties/controllers/portal.py deleted file mode 100644 index 66872f8c7..000000000 --- a/payment_acquirer_multi_pms_properties/controllers/portal.py +++ /dev/null @@ -1,23 +0,0 @@ -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo.addons.account.controllers.portal import PortalAccount - - -class PortalAccount(PortalAccount): - def _invoice_get_page_view_values(self, invoice, access_token, **kwargs): - """ - Override to add the pms property filter - """ - values = super(PortalAccount, self)._invoice_get_page_view_values( - invoice, access_token, **kwargs - ) - for acquirer in values["acquirers"]: - if ( - acquirer.pms_property_ids - and invoice.pms_property_id.id not in acquirer.pms_property_ids.ids - ): - values["acquirers"] -= acquirer - for pms in values["pms"]: - if pms.acquirer_id not in values["acquirers"].ids: - values["pms"] -= pms - return values diff --git a/payment_acquirer_multi_pms_properties/i18n/payment_acquirer_multi_pms_properties.pot b/payment_acquirer_multi_pms_properties/i18n/payment_acquirer_multi_pms_properties.pot deleted file mode 100644 index 6733aee98..000000000 --- a/payment_acquirer_multi_pms_properties/i18n/payment_acquirer_multi_pms_properties.pot +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * payment_acquirer_multi_pms_properties -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model.fields,field_description:payment_acquirer_multi_pms_properties.field_payment_acquirer__display_name -msgid "Display Name" -msgstr "" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model.fields,field_description:payment_acquirer_multi_pms_properties.field_payment_acquirer__id -msgid "ID" -msgstr "" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model.fields,field_description:payment_acquirer_multi_pms_properties.field_payment_acquirer____last_update -msgid "Last Modified on" -msgstr "" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model,name:payment_acquirer_multi_pms_properties.model_payment_acquirer -msgid "Payment Acquirer" -msgstr "" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model.fields,field_description:payment_acquirer_multi_pms_properties.field_payment_acquirer__pms_property_ids -msgid "Properties" -msgstr "" - -#. module: payment_acquirer_multi_pms_properties -#: model:ir.model.fields,help:payment_acquirer_multi_pms_properties.field_payment_acquirer__pms_property_ids -msgid "" -"Properties with access to the element; if not set, all properties can access" -msgstr "" diff --git a/payment_acquirer_multi_pms_properties/models/__init__.py b/payment_acquirer_multi_pms_properties/models/__init__.py deleted file mode 100644 index 14289a55a..000000000 --- a/payment_acquirer_multi_pms_properties/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import payment_acquirer diff --git a/payment_acquirer_multi_pms_properties/models/payment_acquirer.py b/payment_acquirer_multi_pms_properties/models/payment_acquirer.py deleted file mode 100644 index 0cdece11e..000000000 --- a/payment_acquirer_multi_pms_properties/models/payment_acquirer.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2009-2020 Noviat -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import fields, models - - -class PaymentAcquirer(models.Model): - _inherit = "payment.acquirer" - _check_pms_properties_auto = True - - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - comodel_name="pms.property", - relation="pms_acquirer_property_rel", - column1="acquirer_id", - column2="property_id", - check_pms_properties=True, - ) diff --git a/payment_acquirer_multi_pms_properties/readme/CONTRIBUTORS.rst b/payment_acquirer_multi_pms_properties/readme/CONTRIBUTORS.rst deleted file mode 100644 index f94c25c48..000000000 --- a/payment_acquirer_multi_pms_properties/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* `Commit [Sun] `: - - * Dario Lodeiros diff --git a/payment_acquirer_multi_pms_properties/readme/DESCRIPTION.rst b/payment_acquirer_multi_pms_properties/readme/DESCRIPTION.rst deleted file mode 100644 index 867281477..000000000 --- a/payment_acquirer_multi_pms_properties/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -Set the pms property in the payment acquirer to filter on website payments diff --git a/payment_acquirer_multi_pms_properties/readme/USAGE.rst b/payment_acquirer_multi_pms_properties/readme/USAGE.rst deleted file mode 100644 index ab14d2bed..000000000 --- a/payment_acquirer_multi_pms_properties/readme/USAGE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Sets one or more properties in the payment acquirer so that payment method is only available for documents of those properties. -If you leave it blank, it will be available to everyone. diff --git a/payment_acquirer_multi_pms_properties/static/description/icon.png b/payment_acquirer_multi_pms_properties/static/description/icon.png deleted file mode 100644 index 3a0328b51..000000000 Binary files a/payment_acquirer_multi_pms_properties/static/description/icon.png and /dev/null differ diff --git a/payment_acquirer_multi_pms_properties/static/description/index.html b/payment_acquirer_multi_pms_properties/static/description/index.html deleted file mode 100644 index fa8c42020..000000000 --- a/payment_acquirer_multi_pms_properties/static/description/index.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - -Payment Acquirer Multiproperty - - - -
-

Payment Acquirer Multiproperty

- - -

Beta License: AGPL-3 OCA/pms Translate me on Weblate Try me on Runbot

-

Set the pms property in the payment acquirer to filter on website payments

-

Table of contents

- -
-

Usage

-

Sets one or more properties in the payment acquirer so that payment method is only available for documents of those properties. -If you leave it blank, it will be available to everyone.

-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Commit [Sun]
  • -
-
-
-

Contributors

-
    -
  • Commit [Sun] <https://www.commitsun.com>:
      -
    • Dario Lodeiros
    • -
    -
  • -
-
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

This module is part of the OCA/pms project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- - diff --git a/payment_acquirer_multi_pms_properties/views/payment_acquirer.xml b/payment_acquirer_multi_pms_properties/views/payment_acquirer.xml deleted file mode 100644 index 068bed062..000000000 --- a/payment_acquirer_multi_pms_properties/views/payment_acquirer.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - muliproperty.payment.acquirer.form - payment.acquirer - - - - - - - - - diff --git a/pms/README.rst b/pms/README.rst deleted file mode 100644 index c7dc5bd70..000000000 --- a/pms/README.rst +++ /dev/null @@ -1,109 +0,0 @@ -================================ -PMS (Property Management System) -================================ - -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github - :target: https://github.com/OCA/pms/tree/14.0/pms - :alt: OCA/pms -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pms-14-0/pms-14-0-pms - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/293/14.0 - :alt: Try me on Runbot - -|badge1| |badge2| |badge3| |badge4| |badge5| - -This module is an all-in-one property management system (PMS) focused on medium-sized properties -for managing every aspect of your property's daily operations. - -You can manage properties with multi-property and multi-company support, including your rooms inventory, -reservations, check-in, daily reports, board services, rate and availability plans among other property functionalities. - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -Installation -============ - -This module depends on modules ``base``, ``mail``, ``sale`` and ``multi_pms_properties``. -Ensure yourself to have all them in your addons list. - -Configuration -============= - -You will find the hotel settings in PMS Management > Configuration > Properties > Your Property. - -This module required additional configuration for company, accounting, invoicing and user privileges. - -Usage -===== - -To use this module, please, read the complete user guide at ``_. - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Commit [Sun] - -Contributors -~~~~~~~~~~~~ - -* Alexandre Díaz -* Pablo Quesada -* Jose Luis Algara -* `Commit [Sun] `: - - * Dario Lodeiros - * Eric Antones - * Sara Lago - * Brais Abeijon - * Miguel Padin - -Maintainers -~~~~~~~~~~~ - -This module is maintained by the OCA. - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -This module is part of the `OCA/pms `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pms/__init__.py b/pms/__init__.py deleted file mode 100644 index a4616f410..000000000 --- a/pms/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from . import models -from . import wizards -from . import controllers -from .init_hook import pre_init_hook diff --git a/pms/__manifest__.py b/pms/__manifest__.py deleted file mode 100644 index 6c8087cc1..000000000 --- a/pms/__manifest__.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2019 Darío Lodeiros, Alexandre Díaz, Jose Luis Algara, Pablo Quesada -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -{ - "name": "PMS (Property Management System)", - "summary": "A property management system", - "version": "14.0.2.22.0", - "development_status": "Alpha", - "category": "Generic Modules/Property Management System", - "website": "https://github.com/OCA/pms", - "author": "Commit [Sun], Odoo Community Association (OCA)", - "license": "AGPL-3", - "application": True, - "installable": True, - "depends": [ - "base", - "base_automation", - "mail", - # "account_payment_return", - # "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", - "security/ir.model.access.csv", - "data/cron_jobs.xml", - "data/pms_sequence.xml", - "data/pms_confirmed_reservation_email_template.xml", - "data/pms_modified_reservation_email_template.xml", - "data/pms_cancelled_reservation_email_template.xml", - "data/pms_precheckin_invitation_email_template.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", - "wizards/folio_make_invoice_advance_views.xml", - "wizards/pms_booking_engine_views.xml", - "wizards/wizard_folio_changes.xml", - "wizards/wizard_several_partners.xml", - "views/pms_amenity_views.xml", - "views/pms_amenity_type_views.xml", - "views/pms_board_service_views.xml", - "views/pms_board_service_room_type_views.xml", - "views/pms_cancelation_rule_views.xml", - "views/pms_checkin_partner_views.xml", - "views/pms_ubication_views.xml", - "views/pms_property_views.xml", - "views/pms_reservation_views.xml", - "views/pms_service_views.xml", - "views/pms_service_line_views.xml", - "views/pms_folio_views.xml", - "views/pms_room_type_views.xml", - "views/pms_room_views.xml", - "views/pms_room_closure_reason_views.xml", - "views/account_payment_views.xml", - "views/account_move_views.xml", - "views/account_bank_statement_views.xml", - "views/res_users_views.xml", - "views/pms_room_type_class_views.xml", - "views/pms_availability_plan_views.xml", - "views/pms_availability_plan_rule_views.xml", - "views/res_partner_views.xml", - "views/product_pricelist_views.xml", - "views/product_pricelist_item_views.xml", - "views/pms_sale_channel.xml", - "views/product_template_views.xml", - "views/webclient_templates.xml", - "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", - "views/assets.xml", - "wizards/wizard_split_join_swap_reservation.xml", - "views/pms_automated_mails_views.xml", - "views/precheckin_portal_templates.xml", - "wizards/wizard_massive_changes.xml", - "wizards/wizard_advanced_filters.xml", - "views/payment_transaction_views.xml", - ], - "demo": [ - "demo/pms_master_data.xml", - "demo/pms_folio.xml", - "demo/pms_reservation.xml", - ], - "qweb": [ - "static/src/xml/pms_base_templates.xml", - "static/src/xml/reservation_group_button_views.xml", - ], - "pre_init_hook": "pre_init_hook", -} diff --git a/pms/controllers/__init__.py b/pms/controllers/__init__.py deleted file mode 100644 index 52d463f19..000000000 --- a/pms/controllers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import pms_portal diff --git a/pms/controllers/pms_portal.py b/pms/controllers/pms_portal.py deleted file mode 100644 index dcbb93192..000000000 --- a/pms/controllers/pms_portal.py +++ /dev/null @@ -1,719 +0,0 @@ -import re - -from odoo import _, fields, http, tools -from odoo.exceptions import AccessError, MissingError -from odoo.http import request - -from odoo.addons.payment.controllers.portal import PaymentProcessing -from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager - - -class PortalFolio(CustomerPortal): - def _prepare_home_portal_values(self, counters): - partner = request.env.user.partner_id - values = super()._prepare_home_portal_values(counters) - Folio = request.env["pms.folio"] - if "folio_count" in counters: - values["folio_count"] = ( - Folio.search_count( - [ - ("partner_id", "=", partner.id), - ] - ) - if Folio.check_access_rights("read", raise_exception=False) - else 0 - ) - return values - - def _folio_get_page_view_values(self, folio, access_token, **kwargs): - values = {"folio": folio, "token": access_token} - payment_inputs = request.env["payment.acquirer"]._get_available_payment_input( - partner=folio.partner_id, company=folio.company_id - ) - is_public_user = request.env.user._is_public() - if is_public_user: - payment_inputs.pop("pms", None) - token_count = ( - request.env["payment.token"] - .sudo() - .search_count( - [ - ("acquirer_id.company_id", "=", folio.company_id.id), - ("partner_id", "=", folio.partner_id.id), - ] - ) - ) - values["existing_token"] = token_count > 0 - values.update(payment_inputs) - values["partner_id"] = ( - folio.partner_id if is_public_user else request.env.user.partner_id, - ) - return self._get_page_view_values( - folio, access_token, values, "my_folios_history", False, **kwargs - ) - - @http.route( - "/folio/pay//form_tx", type="json", auth="public", website=True - ) - def folio_pay_form( - self, acquirer_id, folio_id, save_token=False, access_token=None, **kwargs - ): - folio_sudo = request.env["pms.folio"].sudo().browse(folio_id) - if not folio_sudo: - return False - - try: - acquirer_id = int(acquirer_id) - except Exception: - return False - - if request.env.user._is_public(): - save_token = False # we avoid to create a token for the public user - - success_url = kwargs.get( - "success_url", - "%s?%s" % (folio_sudo.access_url, access_token if access_token else ""), - ) - vals = { - "acquirer_id": acquirer_id, - "return_url": success_url, - } - - if save_token: - vals["type"] = "form_save" - transaction = folio_sudo._create_payment_transaction(vals) - PaymentProcessing.add_payment_transaction(transaction) - if not transaction: - return False - tx_ids_list = set(request.session.get("__payment_tx_ids__", [])) | set( - transaction.ids - ) - request.session["__payment_tx_ids__"] = list(tx_ids_list) - return transaction.render_folio_button( - folio_sudo, - submit_txt=_("Pay & Confirm"), - render_values={ - "type": "form_save" if save_token else "form", - "alias_usage": _( - "If we store your payment information on our server, " - "subscription payments will be made automatically." - ), - }, - ) - - @http.route( - ["/my/folios", "/my/folios/page/"], - type="http", - auth="public", - website=True, - ) - def portal_my_folios( - self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw - ): - partner = request.env.user.partner_id - values = self._prepare_portal_layout_values() - PmsFolio = request.env["pms.folio"] - values["folios"] = PmsFolio.search( - [ - ("partner_id", "child_of", partner.id), - ] - ) - domain = [ - ("partner_id", "child_of", partner.id), - ] - searchbar_sortings = { - "date": {"label": _("Order Date"), "folio": "date_order desc"}, - "name": {"label": _("Reference"), "folio": "name"}, - "stage": {"label": _("Stage"), "folio": "state"}, - } - if not sortby: - sortby = "date" - sort_order = searchbar_sortings[sortby]["folio"] - - if date_begin and date_end: - domain += [ - ("create_date", ">", date_begin), - ("create_date", "<=", date_end), - ] - folio_count = PmsFolio.search_count(domain) - pager = portal_pager( - url="/my/folios", - url_args={"date_begin": date_begin, "date_end": date_end, "sortby": sortby}, - total=folio_count, - page=page, - step=self._items_per_page, - ) - folios = PmsFolio.search( - domain, order=sort_order, limit=self._items_per_page, offset=pager["offset"] - ) - request.session["my_folios_history"] = folios.ids[:100] - values.update( - { - "date": date_begin, - "folios": folios.sudo(), - "page_name": "folios", - "pager": pager, - "default_url": "/my/folios", - "searchbar_sortings": searchbar_sortings, - "sortby": sortby, - } - ) - return request.render("pms.portal_my_folio", values) - - @http.route(["/my/folios/"], type="http", auth="public", website=True) - def portal_my_folio_detail( - self, folio_id, access_token=None, report_type=None, download=False, **kw - ): - try: - folio_sudo = self._document_check_access( - "pms.folio", - folio_id, - access_token=access_token, - ) - except (AccessError, MissingError): - return request.redirect("/my") - if report_type in ("html", "pdf", "text"): - return self._show_report( - model=folio_sudo, - report_type=report_type, - report_ref="pms.action_report_folio", - download=download, - ) - values = self._folio_get_page_view_values(folio_sudo, access_token, **kw) - return request.render("pms.folio_portal_template", values) - - @http.route( - ["/my/folios//precheckin"], - type="http", - auth="public", - website=True, - ) - def portal_my_folio_precheckin( - self, folio_id, access_token=None, report_type=None, download=False, **kw - ): - values = self._prepare_portal_layout_values() - try: - folio_sudo = self._document_check_access( - "pms.folio", - folio_id, - access_token=access_token, - ) - except (AccessError, MissingError): - return request.redirect("/my") - values.update(self._folio_get_page_view_values(folio_sudo, access_token, **kw)) - values.update({"no_breadcrumbs": True, "error": {}}) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) - values.update( - { - "country_ids": country_ids, - "state_ids": state_ids, - "doc_type_ids": doc_type_ids, - } - ) - return request.render("pms.portal_my_folio_precheckin", values) - - -class PortalReservation(CustomerPortal): - def _prepare_home_portal_values(self, counters): - partner = request.env.user.partner_id - values = super()._prepare_home_portal_values(counters) - Reservation = request.env["pms.reservation"] - if "reservation_count" in counters: - values["reservation_count"] = ( - Reservation.search_count( - [ - ("partner_id", "=", partner.id), - ] - ) - if Reservation.check_access_rights("read", raise_exception=False) - else 0 - ) - return values - - def _reservation_get_page_view_values(self, reservation, access_token, **kwargs): - values = {"reservation": reservation, "token": access_token} - return self._get_page_view_values( - reservation, - access_token, - values, - "my_reservations_history", - False, - **kwargs - ) - - @http.route( - ["/my/reservations", "/my/reservations/page/"], - type="http", - auth="public", - website=True, - ) - def portal_my_reservations(self, page=1, date_begin=None, date_end=None): - partner = request.env.user.partner_id - values = self._prepare_portal_layout_values() - Reservation = request.env["pms.reservation"] - values["reservations"] = Reservation.search( - [ - ("partner_id", "child_of", partner.id), - ] - ) - domain = [ - ("partner_id", "child_of", partner.id), - ] - if date_begin and date_end: - domain += [ - ("create_date", ">", date_begin), - ("create_date", "<=", date_end), - ] - reservation_count = Reservation.search_count(domain) - pager = portal_pager( - url="/my/reservations", - url_args={"date_begin": date_begin, "date_end": date_end}, - total=reservation_count, - page=page, - step=self._items_per_page, - ) - reservations = Reservation.search( - domain, limit=self._items_per_page, offset=pager["offset"] - ) - folios_dict = {} - for reservation in reservations: - folio = reservation.folio_id - folios_dict[folio] = "" - - request.session["my_reservations_history"] = reservations.ids[:100] - values.update( - { - "date": date_begin, - "reservations": reservations.sudo(), - "page_name": "reservations", - "pager": pager, - "default_url": "/my/reservations", - "folios_dict": folios_dict, - "partner": partner, - } - ) - return request.render("pms.portal_my_reservation", values) - - @http.route( - ["/my/reservations/"], - type="http", - auth="public", - website=True, - ) - def portal_my_reservation_detail(self, reservation_id, access_token=None, **kw): - try: - reservation_sudo = self._document_check_access( - "pms.reservation", - reservation_id, - access_token=access_token, - ) - except (AccessError, MissingError): - return request.redirect("/my") - values = self._reservation_get_page_view_values( - reservation_sudo, access_token, **kw - ) - return request.render("pms.portal_my_reservation_detail", values) - - @http.route( - ["/my/reservations//precheckin"], - type="http", - auth="public", - website=True, - ) - def portal_my_reservation_precheckin(self, reservation_id, access_token=None, **kw): - try: - reservation_sudo = self._document_check_access( - "pms.reservation", - reservation_id, - access_token=access_token, - ) - except (AccessError, MissingError): - return request.redirect("/my") - values = self._reservation_get_page_view_values( - reservation_sudo, access_token, **kw - ) - values.update({"no_breadcrumbs": True, "error": {}}) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) - values.update( - { - "country_ids": country_ids, - "state_ids": state_ids, - "doc_type_ids": doc_type_ids, - } - ) - return request.render("pms.portal_my_reservation_precheckin", values) - - -class PortalPrecheckin(CustomerPortal): - def _precheckin_get_page_view_values(self, checkin_partner, access_token, **kwargs): - values = {"checkin_partner": checkin_partner, "token": access_token} - return self._get_page_view_values( - checkin_partner, - access_token, - values, - "my_precheckins_history", - False, - **kwargs - ) - - @http.route( - ["/my/precheckin/"], - type="http", - auth="public", - website=True, - ) - def portal_my_precheckin_detail(self, checkin_partner_id, access_token=None, **kw): - try: - checkin_sudo = self._document_check_access( - "pms.checkin.partner", - checkin_partner_id, - access_token=access_token, - ) - except (AccessError, MissingError): - return request.redirect("/my") - values = self._precheckin_get_page_view_values(checkin_sudo, access_token, **kw) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) - values.update( - { - "doc_type_ids": doc_type_ids, - "country_ids": country_ids, - "state_ids": state_ids, - "no_breadcrumbs": True, - "error": {}, - } - ) - return request.render("pms.portal_my_precheckin_detail", values) - - @http.route( - ["/my/precheckin"], type="http", auth="public", website=True, csrf=False - ) - def portal_precheckin_submit(self, **kw): - values = dict() - checkin_partner = request.env["pms.checkin.partner"].browse(int(kw.get("id"))) - values.update( - { - "checkin_partner": checkin_partner, - "error": {}, - "error_message": {}, - } - ) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) - if kw: - error, error_message = self.form_validate(kw, None) - values.update( - { - "no_breadcrumbs": True, - "error": error, - "error_message": error_message, - "country_ids": country_ids, - "state_ids": state_ids, - "doc_type_ids": doc_type_ids, - } - ) - if error: - return request.render("pms.portal_my_precheckin_detail", values) - else: - try: - values = kw - if values.get("document_type"): - doc_type = ( - request.env["res.partner.id_category"] - .sudo() - .search([("name", "=", values.get("document_type"))]) - ) - values.update( - { - "document_type": doc_type.id, - } - ) - request.env["pms.checkin.partner"].sudo()._save_data_from_portal( - values - ) - doc_type_ids = ( - request.env["res.partner.id_category"].sudo().search([]) - ) - values.update( - { - "doc_type_ids": doc_type_ids, - } - ) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - values.update( - { - "country_ids": country_ids, - "state_ids": state_ids, - } - ) - values.update( - { - "success": True, - "checkin_partner": checkin_partner, - "no_breadcrumbs": True, - "error": {}, - } - ) - return request.render("pms.portal_my_precheckin_detail", values) - except (AccessError, MissingError): - return request.redirect("/my") - - @http.route( - ["/my/precheckin/folio_reservation"], - type="http", - auth="public", - website=True, - csrf=False, - ) - def portal_precheckin_folio_submit(self, **kw): - errors = {} - e_messages = {} - counter = 1 - has_error = False - checkin_partners = False - if kw.get("folio_id"): - folio = request.env["pms.folio"].sudo().browse(int(kw.get("folio_id"))) - checkin_partners = folio.checkin_partner_ids - elif kw.get("reservation_id"): - reservation = ( - request.env["pms.reservation"] - .sudo() - .browse(int(kw.get("reservation_id"))) - ) - checkin_partners = reservation.checkin_partner_ids - for checkin in checkin_partners: - values = { - "id": kw.get("id-" + str(counter)), - "firstname": kw.get("firstname-" + str(counter)), - "lastname": kw.get("lastname-" + str(counter)), - "lastname2": kw.get("lastname2-" + str(counter)), - "gender": kw.get("gender-" + str(counter)), - "birthdate_date": kw.get("birthdate_date-" + str(counter)) - if kw.get("birthdate_date-" + str(counter)) - else False, - "document_type": kw.get("document_type-" + str(counter)), - "document_number": kw.get("document_number-" + str(counter)), - "document_expedition_date": kw.get( - "document_expedition_date-" + str(counter) - ) - if kw.get("document_expedition_date-" + str(counter)) - else False, - "mobile": kw.get("mobile-" + str(counter)), - "email": kw.get("email-" + str(counter)), - "nationality_id": kw.get("nationality_id-" + str(counter)), - "state": kw.get("state-" + str(counter)), - } - - if values.get("document_type"): - doc_type_code = values.get("document_type") - doc_type = ( - request.env["res.partner.id_category"] - .sudo() - .search([("name", "=", doc_type_code)]) - ) - values.update( - { - "document_type": doc_type.id, - } - ) - error, error_message = self.form_validate(kw, counter) - errors.update(error) - e_messages.update(error_message) - if error_message: - has_error = True - else: - checkin.sudo()._save_data_from_portal(values) - counter = counter + 1 - values = {"no_breadcrumbs": True} - doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) - country_ids = request.env["res.country"].search([]) - state_ids = request.env["res.country.state"].search([]) - values.update( - { - "doc_type_ids": doc_type_ids, - "country_ids": country_ids, - "state_ids": state_ids, - } - ) - if has_error: - filtered_dict_error = {k: v for k, v in errors.items() if v} - filtered_dict_error_messages = {k: v for k, v in e_messages.items() if v} - values.update( - { - "error": filtered_dict_error, - "error_message": filtered_dict_error_messages, - } - ) - else: - values.update({"success": True, "error": {}}) - if kw.get("folio_id"): - folio = request.env["pms.folio"].sudo().browse(int(kw.get("folio_id"))) - values.update( - { - "folio": folio, - } - ) - return request.render("pms.portal_my_folio_precheckin", values) - elif kw.get("reservation_id"): - reservation = request.env["pms.reservation"].browse( - int(kw.get("reservation_id")) - ) - values.update( - { - "reservation": reservation, - } - ) - return request.render("pms.portal_my_reservation_precheckin", values) - - def form_validate(self, data, counter): - error, error_message = self.form_document_validate(data, counter) - keys = data.keys() - mobile = "mobile" if "mobile" in keys else "mobile-" + str(counter) - if data[mobile]: - if not re.match( - r"^(\d{3}[\-\s]?\d{2}[\-\s]?\d{2}[\-\s]?\d{2}[\-\s]?|" - r"\d{3}[\-\s]?\d{3}[\-\s]?\d{3})$", - data[mobile], - ): - error[mobile] = "error" - error_message[mobile] = "Invalid phone" - birthdate_date = ( - "birthdate_date" - if "birthdate_date" in keys - else "birthdate_date-" + str(counter) - ) - if data[birthdate_date] and data[birthdate_date] > str(fields.Datetime.today()): - error[birthdate_date] = "error" - error_message[birthdate_date] = "Birthdate must be less than today" - email = "email" if "email" in keys else "email-" + str(counter) - if data[email] and not tools.single_email_re.match(data[email]): - error[email] = "error" - error_message[email] = "Email format is wrong" - firstname = "firstname" if "firstname" in keys else "firstname-" + str(counter) - lastname = "lastname" if "lastname" in keys else "lastname-" + str(counter) - lastname2 = "lastname2" if "lastname2" in keys else "lastname2-" + str(counter) - if not data[firstname] and not data[lastname] and not data[lastname2]: - error[firstname] = "error" - error_message[firstname] = "Firstname or any lastname are not included" - return error, error_message - - def form_document_validate(self, data, counter): - error = dict() - error_message = {} - keys = data.keys() - document_number = ( - "document_number" - if "document_number" in keys - else "document_number-" + str(counter) - ) - document_type = ( - "document_type" - if "document_type" in keys - else "document_type-" + str(counter) - ) - document_expedition_date = ( - "document_expedition_date" - if "document_expedition_date" in keys - else "document_expedition_date-" + str(counter) - ) - if data[document_expedition_date] and not data[document_number]: - error[document_expedition_date] = "error" - error_message[ - document_expedition_date - ] = "Document Number not entered and Document Type is not selected" - if data[document_number]: - if not data[document_type]: - error[document_type] = "error" - error_message[document_type] = "Document Type is not selected" - if data[document_type] == "D": - if len(data[document_number]) == 9 or len(data[document_number]) == 10: - if not re.match(r"^\d{8}[ -]?[a-zA-Z]$", data[document_number]): - error[document_number] = "error" - error_message[document_number] = "The DNI format is wrong" - 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 = data[document_number][0:8] - dni_letter = data[document_number][ - len(data[document_number]) - 1 : len(data[document_number]) - ] - if letters.get(int(dni_number) % 23) != dni_letter.upper(): - error[document_number] = "error" - error_message[document_number] = "DNI format is invalid" - else: - error[document_number] = "error" - error_message[document_number] = "DNI is invalid" - if data[document_type] == "C" and not re.match( - r"^\d{8}[ -]?[a-zA-Z]$", data[document_number] - ): - error[document_number] = "error" - error_message[document_number] = "The Driving License format is wrong" - if data[document_type] == "N" and not re.match( - r"^[X|Y]{1}[ -]?\d{7,8}[ -]?[a-zA-Z]$", data[document_number] - ): - error[document_number] = "error" - error_message[ - document_number - ] = "The Spanish Residence Permit format is wrong" - if data[document_type] == "X" and not re.match( - r"^[X|Y]{1}[ -]?\d{7,8}[ -]?[a-zA-Z]$", data[document_number] - ): - error[document_number] = "error" - error_message[ - document_number - ] = "The European Residence Permit format is wrong" - elif data[document_type]: - error[document_number] = "error" - error_message[document_number] = "Document Number not entered" - return error, error_message - - @http.route( - ["/my/precheckin/send_invitation"], - auth="public", - type="json", - website=True, - csrf=False, - ) - def portal_precheckin_folio_send_invitation(self, **kw): - if kw.get("folio_id"): - folio = request.env["pms.folio"].browse(int(kw.get("folio_id"))) - kw.update({"folio": folio}) - checkin_partner = ( - request.env["pms.checkin.partner"] - .sudo() - .browse(int(kw["checkin_partner_id"])) - ) - firstname = kw["firstname"] - email = kw["email"] - if firstname and email: - checkin_partner.write({"firstname": firstname, "email": email}) - checkin_partner.send_portal_invitation_email(firstname, email) diff --git a/pms/data/cron_jobs.xml b/pms/data/cron_jobs.xml deleted file mode 100644 index ec067d944..000000000 --- a/pms/data/cron_jobs.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - Automatic No Show Reservation - 1 - - days - -1 - - code - - - model.auto_arrival_delayed() - - - - Automatic No Checkout Reservations - 5 - - minutes - -1 - - code - - - model.auto_departure_delayed() - - - - Automatic Checkout on past reservations - 1 - - days - -1 - - code - - - model.autocheckout() - - - Recompute priority on reservations - 1 - - days - -1 - - code - - - model.update_daily_priority_reservation() - - - - Send Confirmation Email - 5 - - minutes - - -1 - - code - - - model.send_confirmation_mail() - - - Send Modification Email - 5 - - minutes - - -1 - - code - - - model.send_modification_mail() - - - Send Cancellation Email - 5 - - - minutes - -1 - - code - - - model.send_cancelation_mail() - - - diff --git a/pms/data/menus.xml b/pms/data/menus.xml deleted file mode 100644 index 46b5751a4..000000000 --- a/pms/data/menus.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - diff --git a/pms/data/pms_cancelled_reservation_email_template.xml b/pms/data/pms_cancelled_reservation_email_template.xml deleted file mode 100644 index 31ab04cc0..000000000 --- a/pms/data/pms_cancelled_reservation_email_template.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - - - Cancelled Reservation - - Your reservation in ${object.pms_property_id.name} has been cancelled - ${object.pms_property_id.partner_id.email | safe} - ${(object.email and '"%s" <%s>' % (object.name, object.email) or object.partner_id.email_formatted or '') | safe} - - - - - -
- - - - - - - - - - - - -
- - - -
-
- % if object.pms_property_id.partner_id.street -

${object.pms_property_id.partner_id.street}

- % endif - % if object.pms_property_id.partner_id.street2 -

${object.pms_property_id.partner_id.street2}

- % endif -

${object.pms_property_id.partner_id.zip}

-

${object.pms_property_id.partner_id.city}

-

${object.pms_property_id.partner_id.country_id.name}

-
-
-
-
- Hello ${object.partner_id.name or ''},
- Your reservation at ${object.pms_property_id.name} has been successfully canceled. -
-
-
- - -
-
- -
-
If you have questions please contact with us:
-
    -
  • ${object.pms_property_id.name}
  • - % if object.pms_property_id.partner_id.email -
  • Mail: ${object.pms_property_id.partner_id.email}
  • - % endif - % if object.pms_property_id.partner_id.phone -
  • Phone: ${object.pms_property_id.partner_id.phone}
  • - % endif - % if object.pms_property_id.partner_id.mobile -
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • - % endif -
-
-
-
-
- % if object.pms_property_id.privacy_policy - - -
- ${object.pms_property_id.privacy_policy} -
- % endif -
- % if object.company_id - - -
- Sent by ${object.company_id.name} -
-
- % endif -
-
- ${object.partner_id.lang} -
-
-
diff --git a/pms/data/pms_confirmed_reservation_email_template.xml b/pms/data/pms_confirmed_reservation_email_template.xml deleted file mode 100644 index b4de65eac..000000000 --- a/pms/data/pms_confirmed_reservation_email_template.xml +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Confirmed Reservation - - ${object.company_id.name} has confirmed your reservation in ${object.pms_property_id.name} - ${object.pms_property_id.partner_id.email | safe} - ${(object.email and '"%s" <%s>' % (object.name, object.email) or object.partner_id.email_formatted or '') | safe} - - - - - -
- - - - - - - - - - - - - - -
- - - -
-
- % if object.pms_property_id.partner_id.street -

${object.pms_property_id.partner_id.street}

- % endif - % if object.pms_property_id.partner_id.street2 -

${object.pms_property_id.partner_id.street2}

- % endif -

${object.pms_property_id.partner_id.zip}

-

${object.pms_property_id.partner_id.city}

-

${object.pms_property_id.partner_id.country_id.name}

-
-
-
-
- Hello ${object.partner_id.name or ''},
- We are happy to confirm your reservation in ${object.pms_property_id.name} -
-
- See you soon,
- -
- ${object.company_id.name} -
-
-
-
-
-
Reservation Details
- - - - - - - - -
- - - - - - - - - - - - - -
-
-
-
From ${object.checkin} At ${object.arrival_hour}
-
To ${object.checkout} At ${object.departure_hour}
-
TZ ${object.pms_property_id.tz}
-
-
-
-
-
-
Room: ${object.room_type_id.name}
-
-
-
-
-
-
Price: ${object.price_room_services_set} ${object.pms_property_id.country_id.currency_id.symbol}
-
-
-
- % if object.pms_property_id.mail_information -
-
Additional Information
- ${object.pms_property_id.mail_information|safe} - % endif -
-
-
-
- Do your check-in now and save time. -
- Access our quick registration system. In a few steps you will be able to register your data in an agile, simple and secure way, avoiding queues at reception. - If you register your data in our system, your passage through reception will be much faster, being able to enjoy the comfort of your room right away. - - - - -
- -
Check-in -
-
Hacer check-in
-
-
-
-
- -
- Questions about the reservation? -
Please contact with us:
-
    -
  • ${object.pms_property_id.name}
  • - % if object.pms_property_id.partner_id.email -
  • Mail: ${object.pms_property_id.partner_id.email}
  • - % endif - % if object.pms_property_id.partner_id.phone -
  • Phone: ${object.pms_property_id.partner_id.phone}
  • - % endif - % if object.pms_property_id.partner_id.mobile -
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • - % endif -
-
-
-
-
- % if object.pms_property_id.privacy_policy - - -
- ${object.pms_property_id.privacy_policy|safe} -
- % endif -
- % if object.company_id - - -
- Sent by ${object.company_id.name} -
-
- % endif -
-
- ${object.partner_id.lang} -
-
-
diff --git a/pms/data/pms_data.xml b/pms/data/pms_data.xml deleted file mode 100644 index 57bd9e782..000000000 --- a/pms/data/pms_data.xml +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - Availability Plan - - - My Property - - - Rua Street Demo, s/n - Commitsun city - - 15703 - +34 123 456 879 - commitsun@hootel.com - https://www.commitsun.com - - - - - - - - - - - - - - - - - - - - - - Door - direct - - - Phone - direct - - - Mail - direct - - - Agency - indirect - - - - Passport - P - - - - Driving License - C - -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 - - - - - Identification Document - I - - - - Spanish Residence permit - N - -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 - - - - - European Residence permit - X - -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 - - - - - Confirmed Reservation - False - - creation - - in_act - - - Modified Reservation - False - - write - - in_act - - - Cancelled Reservation - False - - cancel - - in_act - - - diff --git a/pms/data/pms_modified_reservation_email_template.xml b/pms/data/pms_modified_reservation_email_template.xml deleted file mode 100644 index 9ca3a0942..000000000 --- a/pms/data/pms_modified_reservation_email_template.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - Modified Reservation - - Your reservation in ${object.pms_property_id.name} has been modified - ${object.pms_property_id.partner_id.email | safe} - ${(object.email and '"%s" <%s>' % (object.name, object.email) or object.partner_id.email_formatted or '') | safe} - - - - - -
- - - - - - - - - - - - - - - -
- - - -
-
- % if object.pms_property_id.partner_id.street -

${object.pms_property_id.partner_id.street}

- % endif - % if object.pms_property_id.partner_id.street2 -

${object.pms_property_id.partner_id.street2}

- % endif -

${object.pms_property_id.partner_id.zip}

-

${object.pms_property_id.partner_id.city}

-

${object.pms_property_id.partner_id.country_id.name}

-
-
-
-
- Hello ${object.partner_id.name or ''},
- Your reservation in ${object.pms_property_id.name} has been modified -
-
- See you soon,
- -
- ${object.company_id.name} -
-
-
-
-
-
Reservation Details
- - - - -
- - - - - - - - - - - - - -
-
-
-
From ${object.checkin} At ${object.arrival_hour}
-
To ${object.checkout} At ${object.departure_hour}
-
TZ ${object.pms_property_id.tz}
-
-
-
-
-
-
Room: ${object.room_type_id.name}
-
-
-
-
-
-
Price: ${object.price_total} ${object.pms_property_id.country_id.currency_id.symbol}
-
-
-
- % if object.pms_property_id.mail_information -
-
Additional Information
-

${object.pms_property_id.mail_information|safe}

- % endif -
-
-
- -
- Questions about the reservation? -
Please contact with us:
-
    -
  • ${object.pms_property_id.name}
  • - % if object.pms_property_id.partner_id.email -
  • Mail: ${object.pms_property_id.partner_id.email}
  • - % endif - % if object.pms_property_id.partner_id.phone -
  • Phone: ${object.pms_property_id.partner_id.phone}
  • - % endif - % if object.pms_property_id.partner_id.mobile -
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • - % endif -
-
-
-
-
- % if object.pms_property_id.privacy_policy - - -
- ${object.pms_property_id.privacy_policy|safe} -
- % endif -
- % if object.company_id - - -
- Sent by ${object.company_id.name} -
-
- % endif -
-
- ${object.partner_id.lang} -
-
-
diff --git a/pms/data/pms_precheckin_invitation_email_template.xml b/pms/data/pms_precheckin_invitation_email_template.xml deleted file mode 100644 index a9f1fc444..000000000 --- a/pms/data/pms_precheckin_invitation_email_template.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - Precheckin Invitation - - Hi ${object.firstname}, do your check-in now in ${object.pms_property_id.name} - ${object.pms_property_id.partner_id.email | safe} - ${(object.email and '"%s" <%s>' % (object.name, object.email) or object.partner_id.email_formatted or '') | safe} - -
- Do your check-in now and save time. -
- Access our quick registration system. In a few steps you will be able to register your data in an agile, simple and secure way, avoiding queues at reception. - If you register your data in our system, your passage through reception will be much faster, being able to enjoy the comfort of your room right away. - - - - -
- - - - -
- -
Check-in -
-
Hacer check-in
-
-
-
-
-
-
-
diff --git a/pms/data/pms_sequence.xml b/pms/data/pms_sequence.xml deleted file mode 100644 index 3af5fe1d4..000000000 --- a/pms/data/pms_sequence.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - PMS Folio - pms.folio - F%(y)s - 5 - - - - PMS Reservation - pms.reservation - R%(y)s - 6 - - - - PMS Checkin - pms.checkin.partner - %(y)s - 6 - - - diff --git a/pms/data/traveller_report_paperformat.xml b/pms/data/traveller_report_paperformat.xml deleted file mode 100644 index c853b7b91..000000000 --- a/pms/data/traveller_report_paperformat.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Traveller Report PaperFormat - - custom - 200 - 75 - Portrait - 1 - 3 - 0 - 0 - - 1 - 201 - - - diff --git a/pms/demo/pms_folio.xml b/pms/demo/pms_folio.xml deleted file mode 100644 index d5edeabd7..000000000 --- a/pms/demo/pms_folio.xml +++ /dev/null @@ -1,841 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - normal - - - cancel - - - - - - - - - - - - - - - - normal - - - - - - - - - normal - - - - - - - - - - normal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pms/demo/pms_master_data.xml b/pms/demo/pms_master_data.xml deleted file mode 100644 index 685355325..000000000 --- a/pms/demo/pms_master_data.xml +++ /dev/null @@ -1,511 +0,0 @@ - - - - - - Alda Company - - - - - - Availability Plan Demo - - - - PMS Folio 2 - pms.folio - F/%(y)s - %(sec)s - 4 - - - - - PMS Reservation 2 - pms.reservation - R/%(y)s - %(sec)s - 4 - - - - - PMS Checkin 2 - pms.checkin.partner - C/%(y)s - %(sec)s - 4 - - - - - - San Carlos - - - - - - - - Algalia - - - - - - - - Pilgrim Leon - - - - - - - - - - - - - - - - - - - - - - - - - Ground Floor - - - First Floor - - - Second Floor - - - - Toiletries - - - Connectivity - - - Kitchen facilities - - - - Shampoo and Soap - - - - High-quality Shampoo and Soap Essential Herbs - - - - Hair Dryer - - - - High speed Wired Internet access - - - - Wi-Fi - - - - Microwave oven - - - - Half-sized Refrigerator - - - - - Room - RO - - - Conference - CO - - - - Economic - ECO - 21.00 - - - - - Single - SNG - 20.00 - - - - - Double - DBL - 25.00 - - - - - Triple - TRP - 35.00 - - - - - Conference Room - CFR - 80.00 - - - - - - Economic-101 - - - 2 - - - - Single-101 - - - 1 - - - - Single-102 - - - 1 - - - - Single-103 - - - 1 - - - - Double-201 - - - 2 - 1 - - - - Double-202 - - - 2 - - - - Triple-203 - - - 3 - - - - Open Talk Away Room - - - 10 - - - - - Breakfast Buffet - 5.0 - service - False - True - True - after - - - Extra Bed - 15.0 - service - False - True - False - 1 - True - - - Late Check-out - 10.0 - service - False - False - False - - - Lunch - 15.0 - service - False - True - True - - - Dinner - 20.0 - service - False - True - True - - - Free Bar - 40.0 - service - False - True - True - - - - BreakFast - BB - - - - Half Board - HB - - - - FullBoard - FB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Maintenance - - Used for closing of rooms which require a maintenance. You can specify - the reason in the own reservation. - - - - VIP Privacy - - Used for closing of rooms for extra privacy. - - - - - - Prop. Demo Suite - SUI - 21.00 - - - - - - Prop. Demo Views - VIE - 20.00 - - - - - - True - - Agency 000 - 1st St - Fremont - (870)-333-0515 - - agency000@example.com - http://www.agency000travel.com - - - - True - - Agency 111 - 2st St - Stockton - (872)-941-0441 - - agency111@example.com - http://www.agency1travel.com - - - - - 645773288 - - - 666777888 - - - 611567888 - - - 610067000 - - - 689017000 - - - 633773338 - - - 678112438 - - - diff --git a/pms/demo/pms_reservation.xml b/pms/demo/pms_reservation.xml deleted file mode 100644 index 17976e55d..000000000 --- a/pms/demo/pms_reservation.xml +++ /dev/null @@ -1,491 +0,0 @@ - - - - - - - - - - 1 - - - - - - - - - out - - - - - - - - - - - - 2 - onboard - - - - - - - - - - - - 1 - - - - - - - - - - 2 - - - - - - - - - - 1 - - - - - - - - - - - 1 - - - - - - - - - - - - 1 - - - - - - - - - - - - 1 - - - - - - - - - - - 1 - - - - - - - - - - 1 - 1 - - - - - - - - - - 1 - - - - - - - - - - - 1 - - - - - - - - - - - 2 - - - - - - - - - - - 2 - - - - - - - - - - - 1 - 1 - - - - - - - - - - - 2 - - - - - - - - - - 2 - - - - - - - - - - - 2 - - - - - - - - - - - 2 - - - - - - - - - - - 1 - 1 - - - - - - - - - - 2 - - - - - - - - - - - 2 - - - - - - - - - - - 3 - - - - - - - - - - - 3 - - - - - - - - - - - 1 - - 2 - - - - - - - - - - - 3 - - - - - - - - - - - 2 - 1 - onboard - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - 0 - paid - - done - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pms/i18n/es.po b/pms/i18n/es.po deleted file mode 100644 index bd12c85eb..000000000 --- a/pms/i18n/es.po +++ /dev/null @@ -1,8492 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pms -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-12 14:11+0000\n" -"PO-Revision-Date: 2021-09-12 18:14+0200\n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"Language: pms\n" -"X-Generator: Poedit 2.3\n" - -#. module: pms -#: model:room.closure.reason,description:pms.pms_room_closure_reason_1 -msgid "" -"\n" -" Used for closing of rooms for extra privacy.\n" -" " -msgstr "" -"\n" -"\t\tUtilizado para el cierre de habitaciones para una mayor privacidad\n" -"\t" - -#. module: pms -#: model:room.closure.reason,description:pms.pms_room_closure_reason_0 -msgid "" -"\n" -" Used for closing of rooms which require a maintenance. You can specify\n" -" the reason in the own reservation.\n" -" " -msgstr "" -"\n" -"\t\tUtilizado para el cierre de habitaciones que requieren mantenimiento. Puede especificar la razón en la propia reserva.\n" -"\t\t" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_count -msgid "# Product Variants" -msgstr "Variantes del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__penalty_late -msgid "% Penalty Late" -msgstr "% Penalización por cancelación fuera de tiempo" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__penalty_noshow -msgid "% Penalty No Show" -msgstr "% Penalización No Show" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "%s is not a valid %s identifier" -msgstr "%s no es un %s identificador válido" - -#. module: pms -#: code:addons/pms/models/pms_service_line.py:0 -#, python-format -msgid "%s limit exceeded for %s" -msgstr "%s límite excedido por %s" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "%s not found in checkins (%s)" -msgstr "%s no encontrado en los checkins (%s)" - -#. module: pms -#: code:addons/pms/models/pms_reservation_line.py:0 -#, python-format -msgid "%s: No room available in %s <-> %s." -msgstr "%s: No hay habitaciones disponibles en %s <-> %s." - -#. module: pms -#: code:addons/pms/models/pms_reservation_line.py:0 -#, python-format -msgid "%s: No room type available" -msgstr "%s: Tipo de habitación no disponible" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "&nbsp;on&nbsp;" -msgstr "&nbsp;en&nbsp;" - -#. module: pms -#: model:ir.actions.report,print_report_name:pms.action_report_folio model:ir.actions.report,print_report_name:pms.action_traveller_report -msgid "(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)" -msgstr "(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid ", at" -msgstr ", a" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Days:" -msgstr "Días:" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Rules to apply:" -msgstr "Reglas a aplicar:" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid " Reservations by folio: " -msgstr " Reservas por ficha: " - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Send message" -msgstr " Enviar mensaje" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid " Cancelled Reservation!" -msgstr " Reserva Cancelada!" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Download" -msgstr " Descargar" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Print" -msgstr " Imprimir" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid " OverBooking" -msgstr " OverBooking" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Status:" -msgstr "Estado:" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "" -"\"" -msgstr "Formato de las direcciones de correo electrónico \"Nombre \"" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__email_formatted -msgid "Formatted Email" -msgstr "Email Formateado" - -#. module: pms -#: model:product.product,name:pms.pms_service_6 model:product.template,name:pms.pms_service_6_product_template -msgid "Free Bar" -msgstr "Barra Libre" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Friday" -msgstr "Viernes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__start_date -msgid "From" -msgstr "Desde" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__start_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkin -msgid "From:" -msgstr "Desde:" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__invoiced -msgid "Fully Invoiced" -msgstr "Totalmente Facturada" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Future" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__gender model:ir.model.fields,field_description:pms.field_pms_property__gender -#: model:ir.model.fields,field_description:pms.field_res_partner__gender model:ir.model.fields,field_description:pms.field_res_users__gender -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Gender" -msgstr "Género" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "General Info" -msgstr "Info General" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "General Information" -msgstr "Información General" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__quota model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__quota -msgid "Generic Quota assigned." -msgstr "Cupo Genérico Asignada." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_latitude -msgid "Geo Latitude" -msgstr "Latitud Geográfica" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_longitude -msgid "Geo Longitude" -msgstr "Longitud Geofráfica" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_folio_view_tree model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_reservation_view_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_tree -msgid "Get in" -msgstr "Llega" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__board_price model:ir.model.fields,help:pms.field_product_product__board_price -msgid "Get price on board service" -msgstr "Regímenes incluidos en el Servicio de Habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__packaging_ids -msgid "Gives the different ways to package the same product." -msgstr "Ofrece diferentes formas de empaquetar el mismo producto." - -#. module: pms -#: model:pms.ubication,name:pms.pms_ubication_0 -msgid "Ground Floor" -msgstr "Planta Baja" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Group By" -msgstr "Agrupar Por" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_search model_terms:ir.ui.view,arch_db:pms.pms_service_view_search -msgid "Group By..." -msgstr "Agrupar Por..." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Guest" -msgstr "Invitado/a" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_requests -msgid "Guest requests" -msgstr "Peticiones del Cliente" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_ids -msgid "Guests who will occupy the room" -msgstr "Huéspedes de la habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__default_arrival_hour model:ir.model.fields,help:pms.field_pms_property__default_departure_hour -msgid "HH:mm Format" -msgstr "Formato HH:mm" - -#. module: pms -#: model:ir.model,name:pms.model_ir_http -msgid "HTTP Routing" -msgstr "Ruta HTTP " - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_2 -msgid "Hair Dryer" -msgstr "Secador de Pelo" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_6 -msgid "Half-sized Refrigerator" -msgstr "Nevera Mediana" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__has_folios_outstanding -#: model:ir.model.fields,field_description:pms.field_account_move__has_folios_outstanding -#: model:ir.model.fields,field_description:pms.field_account_payment__has_folios_outstanding -msgid "Has Folios Outstanding" -msgstr "Tiene Pagos Pendientes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__show_update_pricelist -msgid "Has Pricelist Changed" -msgstr "Regla de Tarifa" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__has_unreconciled_entries -msgid "Has Unreconciled Entries" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__has_down_payments -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__has_down_payments -msgid "Has down payments" -msgstr "Tiene Pagos Iniciales" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Hide Strangers" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_3 -msgid "High speed Wired Internet access" -msgstr "Acceso a internet por cable de alta velocidad" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_1 -msgid "High-quality Shampoo and Soap Essential Herbs" -msgstr "Champú y Jabón de Esencias de Hiebas de Alta Calidad" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "History" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_number -msgid "Host document number" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Hosted's Name" -msgstr "Nombre del huésped" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_graph model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_pivot -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_calendar -msgid "Hosts" -msgstr "Huéspedes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement__id -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__id model:ir.model.fields,field_description:pms.field_account_journal__id -#: model:ir.model.fields,field_description:pms.field_account_move__id model:ir.model.fields,field_description:pms.field_account_move_line__id -#: model:ir.model.fields,field_description:pms.field_account_payment__id model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__id -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__id model:ir.model.fields,field_description:pms.field_ir_config_parameter__id -#: model:ir.model.fields,field_description:pms.field_ir_http__id model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_amenity__id model:ir.model.fields,field_description:pms.field_pms_amenity_type__id -#: model:ir.model.fields,field_description:pms.field_pms_availability__id model:ir.model.fields,field_description:pms.field_pms_availability_plan__id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__id model:ir.model.fields,field_description:pms.field_pms_board_service__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__id -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__id model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__id model:ir.model.fields,field_description:pms.field_pms_folio__id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__id model:ir.model.fields,field_description:pms.field_pms_property__id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__id model:ir.model.fields,field_description:pms.field_pms_reservation_line__id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__id model:ir.model.fields,field_description:pms.field_pms_room__id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__id model:ir.model.fields,field_description:pms.field_pms_room_type_class__id -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__id model:ir.model.fields,field_description:pms.field_pms_service__id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__id model:ir.model.fields,field_description:pms.field_pms_ubication__id -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__id -#: model:ir.model.fields,field_description:pms.field_product_pricelist__id model:ir.model.fields,field_description:pms.field_product_pricelist_item__id -#: model:ir.model.fields,field_description:pms.field_product_product__id model:ir.model.fields,field_description:pms.field_product_template__id -#: model:ir.model.fields,field_description:pms.field_res_company__id model:ir.model.fields,field_description:pms.field_res_partner__id -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number__id model:ir.model.fields,field_description:pms.field_res_users__id -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__id model:ir.model.fields,field_description:pms.field_wizard_folio_changes__id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__id -msgid "ID" -msgstr "Identificación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__im_status -msgid "IM Status" -msgstr "Estado del IM" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_exception_icon -msgid "Icon" -msgstr "Icono" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_exception_icon model:ir.model.fields,help:pms.field_pms_property__activity_exception_icon -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_exception_icon model:ir.model.fields,help:pms.field_pms_room_type__activity_exception_icon -msgid "Icon to indicate an exception activity." -msgstr "Icono para indicar una actividad excepcional." - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_identification_document -msgid "Identification Document" -msgstr "Documento de identificación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__id_numbers -msgid "Identification Numbers" -msgstr "Números de documentos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_code -msgid "Identification code for a room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__identifier -msgid "Identifier" -msgstr "Identificador" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "If a Folio is done, you cannot modify it manually anymore. However, you will still be able to invoice. This is used to freeze the Folio." -msgstr "Si un Folio está terminado, ya no puede modificarlo manualmente. Sin embargo, aún podrá facturar. Esto se utiliza para congelar el Folio." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_needaction model:ir.model.fields,help:pms.field_pms_folio__message_unread -#: model:ir.model.fields,help:pms.field_pms_property__message_needaction model:ir.model.fields,help:pms.field_pms_property__message_unread -#: model:ir.model.fields,help:pms.field_pms_reservation__message_needaction model:ir.model.fields,help:pms.field_pms_reservation__message_unread -#: model:ir.model.fields,help:pms.field_pms_room_type__message_needaction model:ir.model.fields,help:pms.field_pms_room_type__message_unread -msgid "If checked, new messages require your attention." -msgstr "Si está marcado, los mensajes nuevos requieren su atención." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_has_error model:ir.model.fields,help:pms.field_pms_property__message_has_error -#: model:ir.model.fields,help:pms.field_pms_reservation__message_has_error model:ir.model.fields,help:pms.field_pms_room_type__message_has_error -msgid "If checked, some messages have a delivery error." -msgstr "Si está marcado, algunos mensajes tienen un error de entrega." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__team_id -msgid "If set, this Sales Team will be used for sales and assignments related to this partner" -msgstr "Si está configurado, este Equipo de Ventas se utilizará para ventas y asignaciones relacionadas con este cliente" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__is_blacklisted -msgid "If the email address is on the blacklist, the contact won't receive mass mailing anymore, from any list" -msgstr "Si la dirección de email está en la lista negra, el contacto no recibirá correos masivos de ninguna lista" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__active -msgid "If unchecked, it will allow you to hide the Availability plan without removing it." -msgstr "Si no está seleccionado, se permitirá ocultar el plan de disponibilidad sin eliminarlo." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__active -msgid "If unchecked, it will allow you to hide the product without removing it." -msgstr "Si no está seleccionado, se permitirá ocultar el plan de disponibilidad sin eliminarlo." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__active -msgid "If unchecked, it will allow you to hide the room type" -msgstr "Si no está seleccionado, se permitirá ocultar el plan de disponibilidad sin eliminarlo." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__image_128 model:ir.model.fields,field_description:pms.field_pms_property__image_1920 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_1920 -msgid "Image" -msgstr "Imagen" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_1024 model:ir.model.fields,field_description:pms.field_pms_room_type__image_1024 -msgid "Image 1024" -msgstr "Imagen 1024" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_128 model:ir.model.fields,field_description:pms.field_pms_room_type__image_128 -msgid "Image 128" -msgstr "Imagen 128" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_256 model:ir.model.fields,field_description:pms.field_pms_room_type__image_256 -msgid "Image 256" -msgstr "Imagen 256" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_512 model:ir.model.fields,field_description:pms.field_pms_room_type__image_512 -msgid "Image 512" -msgstr "Imagen 512" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_image -msgid "Image of the service" -msgstr "Causa de estar Fuera de Servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__impacts_quota -msgid "Impacts quota" -msgstr "Impacts quota" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__standard_price -msgid "" -"In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n" -" In FIFO: value of the last unit that left the stock (automatically computed).\n" -" Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n" -" Used to compute margins on sale orders." -msgstr "" -"El Precio Estándar y AVCO: valor del producto (calculado automáticamente en AVCO)\n" -"\tEn FIFO: valor de la última unidad que salió de stock (calculado automáticamente).\n" -"\tSe utiliza para valorar el producto cuando el precio de compra se desconoce (por ej. ajuste de inventario).\n" -"\tUsado para calcular márgenes en pedidos de ventas." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_name -msgid "In the name of whom the reservation is made" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__intime -msgid "In time" -msgstr "A tiempo" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__partner_name -msgid "In whose name is the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__service_ids -msgid "Included services in the reservation" -msgstr "Servicios incluidos en la reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__deposit_account_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__property_account_income_id -msgid "Income Account" -msgstr "Cuenta de Ingresos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__overbooking -msgid "Indicate if exists overbooking" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__closed -msgid "Indicate if property is closed or not" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__cancelled_reason -msgid "Indicates cause of cancelled" -msgstr "Causa de la Cancelación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__daily_limit model:ir.model.fields,help:pms.field_product_product__daily_limit -#: model:ir.model.fields,help:pms.field_product_template__daily_limit -msgid "Indicates how much products can consumed in one day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__invoice_to_agency model:ir.model.fields,help:pms.field_res_partner__invoice_to_agency -#: model:ir.model.fields,help:pms.field_res_users__invoice_to_agency -msgid "Indicates if agency invoices partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__apply_pricelist model:ir.model.fields,help:pms.field_res_partner__apply_pricelist -#: model:ir.model.fields,help:pms.field_res_users__apply_pricelist -msgid "Indicates if agency pricelist is applied to his reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__per_day -msgid "Indicates if service is sold by days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__is_extra_bed model:ir.model.fields,help:pms.field_product_product__is_extra_bed -#: model:ir.model.fields,help:pms.field_product_template__is_extra_bed -msgid "Indicates if that product is a extra bed, add +1 capacity in the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__is_agency model:ir.model.fields,help:pms.field_res_partner__is_agency -#: model:ir.model.fields,help:pms.field_res_users__is_agency -msgid "Indicates if the partner is an agency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__is_on_line -msgid "Indicates if the sale channel is on-line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__is_board_service -msgid "Indicates if the service included in folio sale line is part of a board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__is_board_service -msgid "Indicates if the service is part of a board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__is_board_service -msgid "Indicates if the service line is part of a board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__by_default -msgid "Indicates if this board service is applied by default in the room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__per_day model:ir.model.fields,help:pms.field_product_product__per_day -#: model:ir.model.fields,help:pms.field_product_template__per_day -msgid "Indicates that the product is sold by days" -msgstr "Precio cuando el producto es vendido a los clientes." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__per_person model:ir.model.fields,help:pms.field_product_product__per_person -#: model:ir.model.fields,help:pms.field_product_template__per_person -msgid "Indicates that the product is sold per person" -msgstr "Precio cuando el producto es vendido a los clientes." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__parent_id -msgid "Indicates that this room is a child of another room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__out_service_description -msgid "Indicates the cause of out of service" -msgstr "Causa de estar Fuera de Servicio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__ready_for_checkin -msgid "Indicates the reservations with checkin_partner data enought to checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__consumed_on model:ir.model.fields,help:pms.field_product_product__consumed_on -#: model:ir.model.fields,help:pms.field_product_template__consumed_on -msgid "Indicates when the product is consumed" -msgstr "Precio cuando el producto es vendido a los clientes." - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_sale_channel__channel_type__indirect -msgid "Indirect" -msgstr "Indirecto" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_1 model:product.product,name:pms.pms_room_type_1_product_product -msgid "Individual" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__industry_id -msgid "Industry" -msgstr "Industria" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Information" -msgstr "Información" - -#. module: pms -#: code:addons/pms/models/pms_board_service.py:0 -#, python-format -msgid "Integrity error: There's multiple board services with the same code %s and properties" -msgstr "***Error de Integridad: Hay múltiples tipos de habitación con el código %s con el mismo código y propiedades" - -#. module: pms -#: code:addons/pms/models/pms_room_type.py:0 code:addons/pms/models/pms_room_type_class.py:0 -#, python-format -msgid "Integrity error: There's multiple room types with the same code %s and properties" -msgstr "***Error de Integridad: Hay múltiples tipos de habitación con el código %s con el mismo código y propiedades" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_folio__internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_internal_comment -msgid "Internal Folio Notes" -msgstr "Notas Internas del Folio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__internal_comment model:ir.model.fields,help:pms.field_pms_folio__internal_comment -msgid "Internal Folio notes for Staff" -msgstr "Notas Internas del Folio para staff" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_internal_comment -msgid "Internal Partner Notes" -msgstr "Notas Internas del Cliente" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__default_code -msgid "Internal Reference" -msgstr "Referencias Internas" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Internal comment Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_internal_comment -msgid "Internal comment for folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__check_adults -msgid "Internal field to force room capacity validations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_internal_comment model:ir.model.fields,help:pms.field_pms_reservation__partner_internal_comment -msgid "Internal notes of the partner" -msgstr "Referencias Internas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__default_code -msgid "Internal unique identifier of the amenity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__barcode -msgid "International Article Number used for product identification." -msgstr "Número de artículo internacional usado para la identificación del producto." - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Invalid date for reservation line " -msgstr "Fecha de linea de reserva duplicada" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of cancel" -msgstr "Operador del dominio no válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of checkin" -msgstr "Operador del dominio no válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of checkout" -msgstr "Operador del dominio no válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of cancel" -msgstr "El operador de la derecha del dominio no es válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of checkin" -msgstr "El operador de la derecha del dominio no es válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of checkout" -msgstr "El operador de la derecha del dominio no es válido %s para left of checkin" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Invalid reservation" -msgstr "Cancelar Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_warn -msgid "Invoice" -msgstr "Factura" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__type -msgid "Invoice & Delivery addresses are used in sales orders. Private addresses are only visible by authorized users." -msgstr "Las direcciones de facturación y entrega se usan en los pedidos de venta. Las direcciones privadas solo son visibles para los usuarios autorizados." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_to_agency -#: model:ir.model.fields,field_description:pms.field_res_partner__invoice_to_agency -#: model:ir.model.fields,field_description:pms.field_res_users__invoice_to_agency -msgid "Invoice Agency" -msgstr "Facturar a la agencia" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Invoice Contact" -msgstr "Contacto de Facturación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoice_count -msgid "Invoice Count" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "Invoice Folio Order" -msgstr "Facturación del Pedido del Folio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__invoice_lines -msgid "Invoice Lines" -msgstr "Líneas de Facturación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_reservation__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_service__invoice_status -msgid "Invoice Status" -msgstr "Estado de Facturación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__invoice_status model:ir.model.fields,help:pms.field_pms_folio__invoice_status -msgid "Invoice Status; it can be: upselling, invoiced, to invoice, no" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_invoice_ids -msgid "Invoice address for current group." -msgstr "Dirección de facturación para el grupo actual." - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__partner_invoice_id -msgid "Invoice address for current partner" -msgstr "Dirección de facturación para el grupo actual." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Invoiced" -msgstr "Facturado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_invoiced -msgid "Invoiced Quantity" -msgstr "Cantidad Facturada" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "Invoiced Quantity: %s" -msgstr "Cantidad Facturada: %s" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__move_ids model:ir.model.fields,field_description:pms.field_pms_property__invoice_ids -#: model:ir.ui.menu,name:pms.pms_invoice_menu model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Invoices" -msgstr "Facturas" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "" -"Invoices will be created in draft so that you can review\n" -" them before validation." -msgstr "" -"Las facturas será creadas en borrador por lo que puede revisarlas\n" -"\t\tantes de validar." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Invoicing" -msgstr "Facturación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__invoice_policy -msgid "Invoicing Policy" -msgstr "Política de Facturación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_agency model:ir.model.fields,field_description:pms.field_res_partner__is_agency -#: model:ir.model.fields,field_description:pms.field_res_users__is_agency -msgid "Is Agency" -msgstr "Es Agencia" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__is_board_service -#: model:ir.model.fields,field_description:pms.field_pms_service_line__is_board_service -msgid "Is Board Service" -msgstr "Es Regimen" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_property__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_is_follower -msgid "Is Follower" -msgstr "Es Seguidor" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__overbooking -msgid "Is Overbooking" -msgstr "Es Overbooking" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_product_variant -msgid "Is Product Variant" -msgstr "Es Variante de Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_company -msgid "Is a Company" -msgstr "Es una compañía" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__is_shared_room -msgid "Is a Shared Room" -msgstr "Es una habitación compartida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__has_configurable_attributes -msgid "Is a configurable product" -msgstr "Es un producto configurable" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__is_downpayment -msgid "Is a down payment" -msgstr "Es un pago adelantado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_extra_bed -#: model:ir.model.fields,field_description:pms.field_product_product__is_extra_bed -#: model:ir.model.fields,field_description:pms.field_product_template__is_extra_bed -msgid "Is extra bed" -msgstr "Es una cama supletoria" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Is mandatory indicate the reservation on the checkin" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Is not possible to create the proposed check-in in this reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_late -msgid "Is number of days late in the cancelation rule if the value of the apply_on_late field is specify days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_noshow -msgid "Is number of days no show in the cancelation rule if the value of the apply_on_show field is specify days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_wizard_reservation_lines_split__allowed_room_ids -msgid "It contains all available rooms for this line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_room_ids -msgid "It contains all available rooms for this reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__to_assign -msgid "It is True if the room of the reservation has been assigned automatically, False if it was confirmed by a person in charge" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "It is not yet checkin day!" -msgstr "¡Aún no es el día del checkin!" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__qty_invoiced -msgid "It is the amount invoiced when an invoice is issued" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin -msgid "It is the checkin date of the reservation, " -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkout -msgid "It is the checkout date of the reservation, " -msgstr "Checkout automático para reservas ya pasadas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__reservation_id -msgid "It is the reservation in a reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__preferred_room_id -msgid "It's the preferred room assigned to reservation, empty if reservation is splitted" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__item_ids -msgid "Items" -msgstr "Items" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__item_ids -msgid "Items for which the pricelist is made up" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Its too late to checkin" -msgstr "Es demasiado tarde para hacer el checkin/registrar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__function -msgid "Job Position" -msgstr "Puesto de trabajo" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__join -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Join reservation" -msgstr "Desde la reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Join the reservation" -msgstr "Unificar la reserva" - -#. module: pms -#: model:ir.model,name:pms.model_account_journal -msgid "Journal" -msgstr "Diario" - -#. module: pms -#: model:ir.model,name:pms.model_account_move -msgid "Journal Entry" -msgstr "Asiento contable" - -#. module: pms -#: model:ir.model,name:pms.model_account_move_line -msgid "Journal Item" -msgstr "Apunte contable" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__journal_item_count -msgid "Journal Items" -msgstr "Artículos Diarios" - -#. module: pms -#: code:addons/pms/models/account_payment.py:0 -#, python-format -msgid "Journal from %s to %s" -msgstr "Diario desde %s hasta %s" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__property_account_income_id -msgid "Keep this field empty to use the default value from the product category." -msgstr "Mantener este campo vacío para usar el valor por defecto de la categoría del producto." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__property_account_expense_id -msgid "" -"Keep this field empty to use the default value from the product category. If anglo-saxon accounting with automated valuation method is configured, the " -"expense account on the product category will be used." -msgstr "" -"Matener este campo vació para usar el valor por defecto de la categoría del producto. Si la contabilidad anglosajona con un método de evaluación automático " -"está configurado, la cuenta de gastos de la categoría del producto será usada." - -#. module: pms -#: model:pms.amenity.type,name:pms.pms_amenity_type_2 -msgid "Kitchen facilities" -msgstr "Instalaciones de la cocina" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_move_line__name -msgid "Label" -msgstr "Descripción" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lang -msgid "Language" -msgstr "Lenguaje" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement____last_update -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line____last_update -#: model:ir.model.fields,field_description:pms.field_account_journal____last_update -#: model:ir.model.fields,field_description:pms.field_account_move____last_update -#: model:ir.model.fields,field_description:pms.field_account_move_line____last_update -#: model:ir.model.fields,field_description:pms.field_account_payment____last_update -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv____last_update -#: model:ir.model.fields,field_description:pms.field_folio_sale_line____last_update -#: model:ir.model.fields,field_description:pms.field_ir_config_parameter____last_update -#: model:ir.model.fields,field_description:pms.field_ir_http____last_update -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_amenity____last_update -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine____last_update -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule____last_update -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner____last_update -#: model:ir.model.fields,field_description:pms.field_pms_folio____last_update -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection____last_update -#: model:ir.model.fields,field_description:pms.field_pms_property____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_room____last_update model:ir.model.fields,field_description:pms.field_pms_room_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class____last_update -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel____last_update -#: model:ir.model.fields,field_description:pms.field_pms_service____last_update -#: model:ir.model.fields,field_description:pms.field_pms_service_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_ubication____last_update -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split____last_update -#: model:ir.model.fields,field_description:pms.field_product_pricelist____last_update -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item____last_update -#: model:ir.model.fields,field_description:pms.field_product_product____last_update -#: model:ir.model.fields,field_description:pms.field_product_template____last_update -#: model:ir.model.fields,field_description:pms.field_res_company____last_update model:ir.model.fields,field_description:pms.field_res_partner____last_update -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number____last_update -#: model:ir.model.fields,field_description:pms.field_res_users____last_update -#: model:ir.model.fields,field_description:pms.field_room_closure_reason____last_update -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes____last_update -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio____last_update -msgid "Last Modified on" -msgstr "Última modificación en" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__lastname -msgid "Last Name" -msgstr "Apellido" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__write_uid -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_amenity__write_uid model:ir.model.fields,field_description:pms.field_pms_amenity_type__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__write_uid model:ir.model.fields,field_description:pms.field_pms_folio__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_property__write_uid model:ir.model.fields,field_description:pms.field_pms_reservation__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_room__write_uid model:ir.model.fields,field_description:pms.field_pms_room_type__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__write_uid model:ir.model.fields,field_description:pms.field_pms_service__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_service_line__write_uid model:ir.model.fields,field_description:pms.field_pms_ubication__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__write_uid -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_uid -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__write_uid -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_uid -msgid "Last Updated by" -msgstr "Última Actualización por" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__write_date -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_amenity__write_date model:ir.model.fields,field_description:pms.field_pms_amenity_type__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__write_date -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__write_date -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__write_date model:ir.model.fields,field_description:pms.field_pms_folio__write_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__write_date -#: model:ir.model.fields,field_description:pms.field_pms_property__write_date model:ir.model.fields,field_description:pms.field_pms_reservation__write_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_room__write_date model:ir.model.fields,field_description:pms.field_pms_room_type__write_date -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__write_date -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__write_date model:ir.model.fields,field_description:pms.field_pms_service__write_date -#: model:ir.model.fields,field_description:pms.field_pms_service_line__write_date model:ir.model.fields,field_description:pms.field_pms_ubication__write_date -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__write_date -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_date -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__write_date -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_date -msgid "Last Updated on" -msgstr "Última Actualización en" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lastname model:ir.model.fields,field_description:pms.field_res_partner__lastname -#: model:ir.model.fields,field_description:pms.field_res_users__lastname -msgid "Last name" -msgstr "Apellido" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__last_time_entries_checked -msgid "" -"Last time the invoices & payments matching was performed for this partner. It is set either if there's not at least an unreconciled debit and an " -"unreconciled credit or if you click the \"Done\" button." -msgstr "" -"Última vez que se realizó la igualación de las facturas y pagos para este cliente. Se establece si no hay al menos un débito no conciliado y un crédito no " -"conciliado o si hace click en el botón \"Listo\"." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Lastnames" -msgstr "Apellidos" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__late model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "Late" -msgstr "Tarde" - -#. module: pms -#: model:product.product,name:pms.pms_service_3 model:product.template,name:pms.pms_service_3_product_template -msgid "Late Check-out" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Late Payment" -msgstr "Retraso en el pago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_late -msgid "Late apply on" -msgstr "Aplicar Late" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_late -msgid "Late first days" -msgstr "Primeros días Late" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Lates and NoShows" -msgstr "Lates y NoShows" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__last_time_entries_checked -msgid "Latest Invoices & Payments Matching Date" -msgstr "Últimas facturas y Pagos por fecha de conciliación" - -#. module: pms -#: model:ir.model,name:pms.model_pms_wizard_reservation_lines_split -msgid "Lines available to split" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__adults -msgid "List of adults there in guest list" -msgstr "Lista de adultos en el rooming" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__room_amenity_ids -msgid "List of amenities included in room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__room_amenity_ids -msgid "List of amenities included in room type" -msgstr "***Servicios de habi" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__done -msgid "Locked" -msgstr "Bloqueado" - -#. module: pms -#: model:product.product,name:pms.pms_service_4 model:product.template,name:pms.pms_service_4_product_template -msgid "Lunch" -msgstr "Comida" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__mail -msgid "Mail" -msgstr "Correo" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_property__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_main_attachment_id -msgid "Main Attachment" -msgstr "Adjunto Principal" - -#. module: pms -#: model:room.closure.reason,name:pms.pms_room_closure_reason_0 -msgid "Maintenance" -msgstr "Mantenimiento" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__gender__male -msgid "Male" -msgstr "Hombre" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__service_type -msgid "" -"Manually set quantities on order: Invoice based on the manually entered quantity, without creating an analytic account.\n" -"Timesheets on contract: Invoice based on the tracked hours on the related timesheet.\n" -"Create a task and track hours: Create a task on the sales order validation and track the work hours." -msgstr "" -"Las cantidades fijadas manualmente en el pedido: factura basada en la cantidad ingresada manualmente, sin crear una cuenta analítica.\n" -"La plantilla horaria del contrato: factura basada en las horas registradas en la plantilla horaria relacionada..\n" -"Cree una tarea y realice un seguimiento de las horas: cree una tarea en la validación de la orden de venta y realice un seguimiento de las horas de trabajo." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__prepaid_warning_days -msgid "Margin in days to create a notice if a payment advance has not been recorded" -msgstr "El margen en días para crear un aviso si el pago avanzado no fue registrado" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_pms_room_massive_changes_wizard -msgid "Massive Changes" -msgstr "Cambios Masivos" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form model_terms:ir.ui.view,arch_db:pms.product_pricelist_view_form -msgid "Massive changes" -msgstr "Cambios Masivos" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_wizard_massive_changes -msgid "Massive changes on Pricelist & Availability Plans" -msgstr "Cambios masivos en las tarifas y planes de disponibilidad" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__max_reservation_priority -#: model:ir.model.fields,help:pms.field_pms_folio__max_reservation_priority -msgid "Max reservation priority on the entire folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_avail -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_avail -msgid "Max. Availability" -msgstr "Disponibilidad Máx" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_stay -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay -msgid "Max. Stay" -msgstr "Estancia Máx" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_stay_arrival -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay_arrival -msgid "Max. Stay Arrival" -msgstr "Máx. Estancia Llegada" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay Arrival can't be less than Min. Stay Arrival" -msgstr "Máx. Estancia Llegada no puede ser menor que la Min. Estancia Llegada" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay Arrival can't be less than zero" -msgstr "Máx. Estancia Llegada no puede ser menor que cero" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay can't be less than Min. Stay" -msgstr "La Estancia Máxima no puede ser menor que la Estancia Mínima" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay can't be less than zero" -msgstr "La Estancia Máxima no puede ser menor que cero" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "Max. days InTime before Checkin" -msgstr "Máximo de días a tiempo antes del Checkin" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_intime -msgid "Maximum number of days for free cancellation before Checkin" -msgstr "Número máximo de días para que la cancelación sea gratis antes del checkin" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_avail -msgid "Maximum simultaneous availability on own Booking Engine" -msgstr "Disponibilidad Simultánea Máxima en el propio Motor de Reservas." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_max_avail -msgid "Maximum simultaneous availability on own Booking Engine given no availability rules. Use `-1` for using maximum simultaneous availability." -msgstr "" -"La disponibilidad simultánea máxima en el propio Motor de Reservas sin Reglas de Disponibilidad. Utilice '-1' para usar la disponibilidad máxima simultánea." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__max_avail -msgid "Maximum simultaneous availability on own Booking Engine." -msgstr "Disponibilidad Simultánea Máxima el el propio Motor de Reservas." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_stay -msgid "Maximum stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_stay_arrival -msgid "Maximum stay if checkin is today" -msgstr "" - -#. module: pms -#: model:pms.board.service,name:pms.pms_board_service_1 -msgid "Media Pensión" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_property__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_has_error -msgid "Message Delivery error" -msgstr "Error en la entrega del mensaje" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_warn_msg -msgid "Message for Invoice" -msgstr "Mensaje para facturar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_warn_msg -msgid "Message for Sales Order" -msgstr "Mensaje para pedido de ventas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_line_warn_msg -msgid "Message for Sales Order Line" -msgstr "Mensaje para línea de pedido de ventas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_ids model:ir.model.fields,field_description:pms.field_pms_property__message_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_ids model:ir.model.fields,field_description:pms.field_pms_room_type__message_ids -msgid "Messages" -msgstr "Mensajes" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_5 -msgid "Microwave oven" -msgstr "Horno microondas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_quantity -msgid "Min. Quantity" -msgstr "Cantidad Mín" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__min_stay -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_stay -msgid "Min. Stay" -msgstr "Estancia mínima" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__min_stay_arrival -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_stay_arrival -msgid "Min. Stay Arrival" -msgstr "Min. Estancia Llegada" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Min. Stay Arrival can't be less than zero" -msgstr "Min. Estancia Llegada no puede ser menor que cero" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Min. Stay can't be less than zero" -msgstr "La estancia mínima no puede ser menor que cero" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__min_stay -msgid "Minimum stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__min_stay_arrival -msgid "Minimum stay if checkin is today" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__mobile model:ir.model.fields,field_description:pms.field_pms_folio__mobile -#: model:ir.model.fields,field_description:pms.field_pms_property__mobile model:ir.model.fields,field_description:pms.field_pms_reservation__mobile -#: model:ir.model.fields,field_description:pms.field_res_partner__mobile model:ir.model.fields,field_description:pms.field_res_users__mobile -msgid "Mobile" -msgstr "Móvil" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Model" -msgstr "Modelo" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Monday" -msgstr "Lunes" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form -msgid "Multi Properties" -msgstr "Multi Hoteles" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "My Reservations" -msgstr "Mis reservas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__name model:ir.model.fields,field_description:pms.field_pms_property__name -#: model:ir.model.fields,field_description:pms.field_pms_room_type__name model:ir.model.fields,field_description:pms.field_room_closure_reason__name -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Name" -msgstr "Nombre" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Name in reports" -msgstr "Nombre en los Informes" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__name -msgid "Name of availability plan" -msgstr "Nombre del plan de disponibilidad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__name -msgid "Name of the room type class" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_id -msgid "Name of who made the reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__nationality_id -#: model:ir.model.fields,field_description:pms.field_pms_property__nationality_id -#: model:ir.model.fields,field_description:pms.field_res_partner__nationality_id model:ir.model.fields,field_description:pms.field_res_users__nationality_id -msgid "Nationality" -msgstr "Nacionalidad" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 code:addons/pms/models/pms_folio.py:0 code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "New" -msgstr "Nuevo" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_board_service_id -msgid "New Board Service" -msgstr "Nuevo régimen" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_discount -msgid "New Discount %" -msgstr "Nuevo Descuento %" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_price -msgid "New Price" -msgstr "Nuevo Precio" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Next 7 days" -msgstr "Próximos 7 días" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_date_deadline -msgid "Next Activity Deadline" -msgstr "Fecha Límite para la Próxima Actividad" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_summary -msgid "Next Activity Summary" -msgstr "Resumen de la Siguiente Actividad" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_type_id -msgid "Next Activity Type" -msgstr "Siguiente tipo de actividad" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__nights -msgid "Nights" -msgstr "Noches" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No Checkins!" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__noshow model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "No Show" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_noshow -msgid "No Show apply on" -msgstr "Aplicar No Show en" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No checkin was made for this reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No person from reserve %s has arrived" -msgstr "Ninguna persona de la reserva %s ha llegado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_noshow -msgid "NoShow first days" -msgstr "NoShow los primeros días" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__normal -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__normal -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__normal -msgid "Normal" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__email_normalized -msgid "Normalized Email" -msgstr "Email normalizado" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__not_paid -msgid "Not Paid" -msgstr "No pagado" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__display_type__line_note -msgid "Note" -msgstr "Nota" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__comment model:ir.model.fields,field_description:pms.field_res_partner__comment -#: model:ir.model.fields,field_description:pms.field_res_users__comment -msgid "Notes" -msgstr "Notas" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__no -msgid "Nothing to Invoice" -msgstr "Nada para Facturar" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "Nothing to invoice" -msgstr "Nada paraFacturar" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__cardex_warning -msgid "Notice under the signature on the traveler's ticket." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_needaction_counter -msgid "Number of Actions" -msgstr "Número de Acciones" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_cancelled_rooms -msgid "Number of Cancelled Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__folios_count model:ir.model.fields,field_description:pms.field_res_partner__folios_count -#: model:ir.model.fields,field_description:pms.field_res_users__folios_count -msgid "Number of Folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__reservations_count -#: model:ir.model.fields,field_description:pms.field_res_partner__reservations_count -#: model:ir.model.fields,field_description:pms.field_res_users__reservations_count -msgid "Number of Reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_rooms -msgid "Number of Rooms" -msgstr "Número de Habitaciones" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__value_num_rooms_selected -msgid "Number of Rooms Selected" -msgstr "Número de Habitaciones Seleccionadas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_services -msgid "Number of Services" -msgstr "Número de reglas de precio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_cancelled_rooms -msgid "Number of cancelled rooms in folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_count -msgid "Number of checkin partners in a reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_pending_count -msgid "Number of checkin partners pending to checkin in a reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__children_occupying -msgid "Number of children there in guest list whose presence counts" -msgstr "Numero de niños en el rooming que ocupan plaza" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_has_error_counter -msgid "Number of errors" -msgstr "Número de errores" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__extra_beds_allowed -msgid "Number of extra beds allowed in room" -msgstr "Camas Supletorias Permtidas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__folios_count model:ir.model.fields,help:pms.field_res_partner__folios_count -#: model:ir.model.fields,help:pms.field_res_users__folios_count -msgid "Number of folios of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__count_pending_arrival -msgid "Number of guest with pending checkin" -msgstr "Número de mensajes que requiere una acción" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_needaction_counter model:ir.model.fields,help:pms.field_pms_property__message_needaction_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_needaction_counter -#: model:ir.model.fields,help:pms.field_pms_room_type__message_needaction_counter -msgid "Number of messages which requires an action" -msgstr "Número de mensajes que requiere una acción" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_has_error_counter model:ir.model.fields,help:pms.field_pms_property__message_has_error_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_has_error_counter -#: model:ir.model.fields,help:pms.field_pms_room_type__message_has_error_counter -msgid "Number of messages with delivery error" -msgstr "Número de mensajes con error de entrega" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__nights -msgid "Number of nights of a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pricelist_item_count -msgid "Number of price rules" -msgstr "Número de reglas de precio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__reservations_count model:ir.model.fields,help:pms.field_res_partner__reservations_count -#: model:ir.model.fields,help:pms.field_res_users__reservations_count -msgid "Number of reservations of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__availability -msgid "Number of rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_rooms -msgid "Number of rooms in folio. Canceled rooms do not count." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__num_rooms_available -msgid "Number of rooms that are available" -msgstr "%s: Tipo de habitación no disponible" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_services -msgid "Number of services in the folio" -msgstr "Número de reglas de precio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_qty -msgid "Number of services that were sold" -msgstr "Número de reglas de precio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_unread_counter model:ir.model.fields,help:pms.field_pms_property__message_unread_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_unread_counter model:ir.model.fields,help:pms.field_pms_room_type__message_unread_counter -msgid "Number of unread messages" -msgstr "Número de mensajes no leídos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__children -msgid "Number total of children there in guest list,whose presence counts or not" -msgstr "Número total de niños en el roomins" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__occupies_availability -msgid "Occupies" -msgstr "Ocupa" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__massive_changes_on -msgid "On" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__onboard -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__onboard -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "On Board" -msgstr "Dentro" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "On Board Tomorrow" -msgstr "Dentro Mañana" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__is_on_line -msgid "On Line" -msgstr "En línea" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Only Room" -msgstr "Solo habitaciones" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Only Services" -msgstr "Solo servicios" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__agency_id -msgid "Only allowed if the field of partner is_agency is True" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__channel_type_id -msgid "Only allowed if the field of sale channel channel_type is 'direct'" -msgstr "" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_availability_room_type_registry_unique -msgid "Only can exists one availability in the same day for the same room type!" -msgstr "Solo puede existir una regla de disponibilidad el mismo día para el mismo tipo de habitación!" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_availability_plan_rule_room_type_registry_unique -msgid "Only can exists one availability rule in the same day for the same room type!" -msgstr "Solo puede existir una regla de disponibilidad el mismo día para el mismo tipo de habitación!" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Only can payment by property" -msgstr "Solo puede pagar por propiedad" - -#. module: pms -#: code:addons/pms/models/pms_board_service_room_type.py:0 -#, python-format -msgid "Only can set one default board service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_bottom_tree -msgid "Open Reservation Room Detail" -msgstr "Detalles de la Habitación de la Reserva Abierta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__operation -msgid "Operation" -msgstr "Operación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_split_join_swap_wizard__operation -msgid "Operation to be applied on the reservation" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_reservation_split_join_swap_wizard -msgid "Operations in reservations" -msgstr "Operaciones en reservas" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Order #" -msgstr "Pedido #" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__count -msgid "Order Count" -msgstr "Nº de Pedidos" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 model:ir.model.fields,field_description:pms.field_pms_folio__date_order -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -#, python-format -msgid "Order Date" -msgstr "Fecha del Pedido" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__date_order -msgid "Order date of reservation" -msgstr "Fecha de pedido de la reserva" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "Ordered Quantity: %(old_qty)s -> %(new_qty)s" -msgstr "Cantidad Pedida: %(old_qty)s -> %(new_qty)s" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__invoice_policy -msgid "" -"Ordered Quantity: Invoice quantities ordered by the customer.\n" -"Delivered Quantity: Invoice quantities delivered to the customer." -msgstr "" -"Cantidad Pedida: facturas ordenadas por el cliente.\n" -"Cantiadad entregada: facturas entregadas al cliente." - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__gender__other -msgid "Other" -msgstr "Otro" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Other data" -msgstr "Otro dato" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#, python-format -msgid "Others" -msgstr "Otros" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__done -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__done model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Out" -msgstr "Fuera" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__out -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__out -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__out model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Out of Service" -msgstr "Fuera de Servicio" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Out service description" -msgstr "Descripción de Fuera de Servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__outstanding_folios_debits_widget -#: model:ir.model.fields,field_description:pms.field_account_move__outstanding_folios_debits_widget -#: model:ir.model.fields,field_description:pms.field_account_payment__outstanding_folios_debits_widget -msgid "Outstanding Folios Debits Widget" -msgstr "Widget para los Débitos pendientes de al ficha" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 -#, python-format -msgid "Outstanding credits in Folio" -msgstr "Créditos pendientes en Folio" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 -#, python-format -msgid "Outstanding debits" -msgstr "Débitos pendientes" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Overbookings" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "PART OF TRAVELERS ENTRY" -msgstr "PARTE DE ENTRADA DE VIAJEROS" - -#. module: pms -#: model:ir.model,name:pms.model_pms_folio -msgid "PMS Folio" -msgstr "FICHA" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_management_menu -msgid "PMS Management" -msgstr "Gestión de Hotel" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__paid model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Paid" -msgstr "Pagado/a" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoices_paid -msgid "Paid Out" -msgstr "Pagado/a" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__parent_avail_id -msgid "Parent Avail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__parent_id -msgid "Parent Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__parent_avail_id -msgid "Parent availability for this availability" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__parent_name -msgid "Parent name" -msgstr "Nombre del Padre" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Partial" -msgstr "Parcial" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__partial -msgid "Partially Paid" -msgstr "Parcialmente Pagado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__partner_id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__partner_id model:ir.model.fields,field_description:pms.field_pms_folio__partner_id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__partner_id model_terms:ir.ui.view,arch_db:pms.booking_engine -#: model_terms:ir.ui.view,arch_db:pms.view_partner_data_form -msgid "Partner" -msgstr "Cliente" - -#. module: pms -#: model:ir.model,name:pms.model_pms_checkin_partner -msgid "Partner Checkins" -msgstr "Checkins del Cliente" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__contract_ids -msgid "Partner Contracts" -msgstr "Contratos del Cliente" - -#. module: pms -#: model:ir.model,name:pms.model_res_partner_id_number -msgid "Partner ID Number" -msgstr "Número empresa" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_requests -msgid "Partner Requests" -msgstr "Notas del Cliente" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__segmentation_ids -msgid "Partner Tags" -msgstr "Cliente" - -#. module: pms -#: code:addons/pms/models/res_partner_id_number.py:0 -#, python-format -msgid "Partner already has this document type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__partner_id -msgid "Partner associated with checkin partner" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Partner contact name is required" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__partner_name -msgid "Partner name" -msgstr "nombre" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__partner_id -msgid "Partner who made the reservation" -msgstr "Cliente que ha realizado la reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__same_vat_partner_id -msgid "Partner with same Tax ID" -msgstr "Cliente con el mismo NIF" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_passport -msgid "Passport" -msgstr "Pasaporte" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form -msgid "Pay" -msgstr "Pagar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__debit_limit -msgid "Payable Limit" -msgstr "Limite por pagar" - -#. module: pms -#: code:addons/pms/models/account_payment.py:0 model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form -#, python-format -msgid "Payment" -msgstr "Pago" - -#. module: pms -#: code:addons/pms/models/account_payment.py:0 -#, python-format -msgid "Payment %s modified: \n" -msgstr "Pago % sModificado:\n" - -#. module: pms -#: code:addons/pms/models/account_payment.py:0 -#, python-format -msgid "Payment Deleted" -msgstr "Pago Borrado" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_payment_folio -msgid "Payment Folio" -msgstr "Pagsr Ficha" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__payment_method_id -msgid "Payment Method" -msgstr "Método de Pago" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Payment Pending" -msgstr "Pendiente de Pago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__reference -msgid "Payment Ref." -msgstr "Ref. del Pago." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_payment_state model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Payment State" -msgstr "Estado del Pago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_state -msgid "Payment Status" -msgstr "Estado del Pago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_term_id -msgid "Payment Terms" -msgstr "Términos del Pago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__payment_token_ids -msgid "Payment Tokens" -msgstr "Token Pago" - -#. module: pms -#: code:addons/pms/models/account_payment.py:0 -#, python-format -msgid "Payment of %s %s registered from %s using %s payment method" -msgstr "Pago de %s %s registrado desde %s usando %s método de pago" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 model:ir.model,name:pms.model_account_payment model:ir.model,name:pms.model_wizard_payment_folio -#: model:ir.model.fields,field_description:pms.field_pms_folio__move_line_ids -#, python-format -msgid "Payments" -msgstr "Pagos" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__pending_amount -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_pending_amount -msgid "Pending Amount" -msgstr "Cantidad pendiente del Folio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__count_rooms_pending_arrival -#: model:ir.model.fields,field_description:pms.field_pms_reservation__count_pending_arrival -msgid "Pending Arrival" -msgstr "Llegada Pendiente" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkins_ratio -msgid "Pending Arrival Ratio" -msgstr "Ratio de Llegadas Pendientes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__ratio_checkin_data -msgid "Pending Checkin Data" -msgstr "Detos del Checkin Pendientes" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__precheckin -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__confirm -msgid "Pending arrival" -msgstr "Llegada Pendiente" - -#. module: pms -#: model:pms.board.service,name:pms.pms_board_service_2 -msgid "Pensión Completa" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__per_day -msgid "Per Day" -msgstr "Por día" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__commission_percent -msgid "Percentage corresponding to commission" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__penalty_late -msgid "Percentage of the total price that partner has to pay in case of late arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__penalty_noshow -msgid "Percentage of the total price that partner has to pay in case of no show" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Personal data is missing for check-in" -msgstr "Faltan datos personales en el checkin" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Persons" -msgstr "Personas" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "Persons can't be higher than room capacity (%s)" -msgstr "Las personas no pueden superar a la capacidad de la habitación (%s)" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__phone model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__phone -msgid "Phone" -msgstr "Teléfono" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__plan_avail -msgid "Plan Avail" -msgstr "Plan de Disponibilidad" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Please define an accounting sales journal for the company %s (%s)." -msgstr "Defina un diario de ventas contables para la compañía %s (%s)." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__pms_property_id -msgid "Pms Property" -msgstr "Hotel" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__access_url model:ir.model.fields,field_description:pms.field_pms_reservation__access_url -msgid "Portal Access URL" -msgstr "URL de acceso al portal" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__is_possible_existing_customer_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__is_possible_existing_customer_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__is_possible_existing_customer_id -msgid "Possible existing customer" -msgstr "El cliente posiblemente ya exista registrado" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__draft -msgid "Pre-reservation" -msgstr "Pre-reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__prepaid_warning_days -msgid "Prepaid Warning Days" -msgstr "Días de advertencia del prepago" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__price -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__price model:ir.model.fields,field_description:pms.field_pms_room_type__price -msgid "Price" -msgstr "Precio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce -msgid "Price Reduce" -msgstr "Precio Reducido" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce_taxexcl -msgid "Price Reduce Tax excl" -msgstr "Precio Reducido Impuestos Excluidos" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce_taxinc -msgid "Price Reduce Tax inc" -msgstr "Precio Reducido Impuestos Incluidos" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Price Total" -msgstr "Precio total" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Price and Availability Plans" -msgstr "Tarifa y Planes de Disponibilidad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__list_price -msgid "Price at which the product is sold to customers." -msgstr "Precio cuando el producto es vendido a los clientes." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_line__amount -msgid "Price for this Board Service Line/Product" -msgstr "Servicios incluidos en el Servicio de Habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__amount -msgid "Price for this Board Service Room Type Line/Product" -msgstr "Pms Board Service Room Type" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__amount model:ir.model.fields,help:pms.field_pms_board_service_room_type__amount -msgid "Price for this Board Service. It corresponds to the sum of his board service lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__price_per_room -msgid "Price per room" -msgstr "Precio poo habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__price_per_room -msgid "Price per room in folio" -msgstr "Precio por habitación en la Ficha" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__price_unit -msgid "Price per unit of service" -msgstr "Precio ud de servicio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce_taxinc -msgid "Price with discounts applied and taxes included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce_taxexcl -msgid "Price with discounts applied without taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_tax -msgid "Price with taxes on a folio" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_pricelist model:ir.model.fields,field_description:pms.field_pms_booking_engine__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__pricelist_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_property__property_product_pricelist -#: model:ir.model.fields,field_description:pms.field_pms_reservation__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pricelist_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__pricelist_id -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__massive_changes_on__pricelist -#: model_terms:ir.ui.view,arch_db:pms.booking_engine model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Pricelist" -msgstr "Tarifa" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_items_to_overwrite -msgid "Pricelist Items to Override" -msgstr "Items de la tarefa a sobrescribir" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_readonly -msgid "Pricelist Readonly" -msgstr "Tarifas de solo lectura" - -#. module: pms -#: model:ir.model,name:pms.model_product_pricelist_item -msgid "Pricelist Rule" -msgstr "Regla de Tarifa" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__pricelist_type -msgid "Pricelist Type" -msgstr "Tipo de Tarifa" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__pricelist_id -msgid "Pricelist applied in folio" -msgstr "Tarifa para el Folio Actual." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__payment_term_id model:ir.model.fields,help:pms.field_pms_folio__pricelist_id -msgid "Pricelist for current folio." -msgstr "Tarifa para el Folio Actual." - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__pricelist_id -msgid "Pricelist in which this item is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__num_pricelist_items_to_overwrite -msgid "Pricelist items to overwrite on massive changes" -msgstr "Reglas de la tarifa que se sobrescribirán en los cambios" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__pricelist_id -msgid "Pricelist that guides the prices of the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__pricelist_ids -msgid "Pricelist that use this rule" -msgstr "Tarifas que usan esta regla" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_ids -msgid "Pricelist to apply massive changes" -msgstr "Tarifas a aplicar en los cambios masivos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__pricelist_type -msgid "Pricelist types, it can be Daily Plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__pms_pricelist_ids -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__product_pricelist_ids model:ir.ui.menu,name:pms.pricelist_menu -msgid "Pricelists" -msgstr "Tarifas" - -#. module: pms -#: model:ir.actions.act_window,name:pms.product_pricelist_item_action2 -msgid "Pricelists Items" -msgstr "Reglas de tarifa" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__product_pricelist_ids -msgid "Pricelists for a sale channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__pms_pricelist_ids -msgid "Pricelists of the availability plan " -msgstr "Tarifa del plan de disponibilidad" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "" -"Prices have been recomputed according to pricelist %s\n" -" and room type %s" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_folio_changes.py:0 -#, python-format -msgid "Prices/Discounts have been changed from folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "Print" -msgstr "Imprimir" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Print All Checkins" -msgstr "Imprimir todos los Checkins" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form -msgid "Print in PDF" -msgstr "Imprimir PDF" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Print in cardex" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__priority -msgid "Priority" -msgstr "Prioridad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__priority -msgid "Priority of a reservation" -msgstr "Unificar la reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_res_company__privacy_policy model_terms:ir.ui.view,arch_db:pms.company_view_form -msgid "Privacy Policy" -msgstr "Política de privacidad" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Procurement" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_product model:ir.model.fields,field_description:pms.field_folio_sale_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__product_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__product_id model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Product" -msgstr "Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__attribute_line_ids -msgid "Product Attributes" -msgstr "Atributos del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__categ_id -msgid "Product Category" -msgstr "Categoría del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__product_image -msgid "Product Image" -msgstr "Imagen del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__packaging_ids -msgid "Product Packages" -msgstr "Paquetes del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__default_pricelist_id -msgid "Product Pricelist" -msgstr "Tarifa del Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_id -msgid "Product Room Type" -msgstr "Producto del Tipo de Habitación" - -#. module: pms -#: model:ir.model,name:pms.model_product_template model:ir.model.fields,field_description:pms.field_pms_room_type__product_tmpl_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__product_tmpl_id -msgid "Product Template" -msgstr "Plantilla de producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__type -msgid "Product Type" -msgstr "Tipo de Producto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_readonly -msgid "Product Uom Readonly" -msgstr "Producto UOM solo lectura" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__product_id -msgid "" -"Product associated with folio sale line, can be product associated with service or product associated withreservation's room type, in other case it's false" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__product_id -msgid "Product associated with the item" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_line__product_id -msgid "Product associated with this board service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__product_id -msgid "Product associated with this board service room type line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_id -msgid "Product associated with this service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__product_id -msgid "Product associated with this service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__product_id -msgid "Product identifier associated with room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__product_tmpl_id -msgid "Product template associated with the item" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_ids -msgid "Products" -msgstr "Prductos" - -#. module: pms -#: model:pms.room.type,name:pms.demo_pms_room_type_0 model:product.product,name:pms.demo_pms_room_type_0_product_product -msgid "Prop. Demo Suite" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.demo_pms_room_type_1 model:product.product,name:pms.demo_pms_room_type_1_product_product -msgid "Prop. Demo Views" -msgstr "Prop. Demo Vistas" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_property_action model:ir.model.fields,field_description:pms.field_account_journal__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_amenity__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_ubication__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_pricelist__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_product__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_template__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_company__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__pms_property_ids model:ir.ui.menu,name:pms.general_property_menu -#: model:ir.ui.menu,name:pms.pms_property_menu -msgid "Properties" -msgstr "Hoteles" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement__pms_property_id -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__pms_property_id model:ir.model.fields,help:pms.field_res_company__pms_property_ids -msgid "Properties with access to the element" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_journal__pms_property_ids model:ir.model.fields,help:pms.field_pms_amenity__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_amenity_type__pms_property_ids model:ir.model.fields,help:pms.field_pms_availability_plan__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service__pms_property_ids model:ir.model.fields,help:pms.field_pms_board_service_line__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__pms_property_ids model:ir.model.fields,help:pms.field_pms_property__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_room__pms_property_id model:ir.model.fields,help:pms.field_pms_room_type__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_room_type_class__pms_property_ids model:ir.model.fields,help:pms.field_pms_sale_channel__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_ubication__pms_property_ids model:ir.model.fields,help:pms.field_product_pricelist__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_pricelist_item__pms_property_ids model:ir.model.fields,help:pms.field_product_product__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_template__pms_property_ids model:ir.model.fields,help:pms.field_res_partner__pms_property_ids -#: model:ir.model.fields,help:pms.field_room_closure_reason__pms_property_ids -msgid "Properties with access to the element; if not set, all properties can access" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__pms_property_id -msgid "Propertiy with access to the element;" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_property model:ir.model.fields,field_description:pms.field_account_bank_statement__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_move__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_payment__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_availability__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_room__pms_property_id model:ir.model.fields,field_description:pms.field_pms_service__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__pms_property_id model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Property" -msgstr "Hotel" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Property Configuration" -msgstr "Configuración del Hotel" - -#. module: pms -#: model:res.groups,name:pms.group_pms_call -msgid "Property Management / CallCenter" -msgstr "Gestión Hotel/ Centro de Llamadas" - -#. module: pms -#: model:res.groups,name:pms.group_pms_user -msgid "Property Management / User" -msgstr "Gestión Hotel/ Usuarios" - -#. module: pms -#: model:res.groups,name:pms.group_pms_manager -msgid "Property Management/ Manager" -msgstr "Gestión Hotel/ Gerente" - -#. module: pms -#: model:ir.model,name:pms.model_pms_room model_terms:ir.ui.view,arch_db:pms.pms_room_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_view_tree -msgid "Property Room" -msgstr "Habitación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__room_type_id model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_tree -msgid "Property Room Type" -msgstr "Tipo de Habitación del Hotel" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__class_id -msgid "Property Type Class" -msgstr "Clase del Tipo del Hotel" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_form -msgid "Property Ubication" -msgstr "Ubicación del Hotel" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_tree -msgid "Property Ubications" -msgstr "Zonas del Hotel" - -#. module: pms -#: code:addons/pms/models/pms_ubication.py:0 -#, python-format -msgid "Property not allowed" -msgstr "Hotel no permitido" - -#. module: pms -#: code:addons/pms/models/pms_availability.py:0 -#, python-format -msgid "Property not allowed on availability day compute" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_tree -msgid "Property settings summary" -msgstr "Resumen de la configuración del Hotel" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__pms_property_id -msgid "Property to which the availability is directed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__pms_property_id -msgid "Property to which the folio associated belongs" -msgstr "Hotel al que pertenece la ficha" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__pms_property_id -msgid "Property to which the folio belongs" -msgstr "Propiedad a la que pertenece la ficha" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__pms_property_id -msgid "Property to which the reservation belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__pms_property_id model:ir.model.fields,help:pms.field_pms_service_line__pms_property_id -msgid "Property to which the service belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__pms_property_id model:ir.model.fields,help:pms.field_account_move__pms_property_id -#: model:ir.model.fields,help:pms.field_account_payment__pms_property_id -msgid "Property with access to the element" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__pms_property_id -msgid "Property with access to the element; if not set, all properties can access" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__ratio_checkin_data -msgid "Proportion of guest data complete at checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkins_ratio -msgid "Proportion of guest pending checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__lst_price -msgid "Public Price" -msgstr "Precio Público" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__description_purchase -msgid "Purchase Description" -msgstr "Descripción de Compra" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__uom_po_id -msgid "Purchase Unit of Measure" -msgstr "Unidad de medida de la compra" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__auto_qty -msgid "Qty automated setted" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_qty -#: model:ir.model.fields,field_description:pms.field_pms_service__product_qty model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Quantity" -msgstr "Cantidad" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__visible_qty_configurator -msgid "Quantity visible in configurator" -msgstr "Cantidad visible en configurador" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__quota -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__quota -msgid "Quota" -msgstr "Cupo" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_quota -msgid "Quota assigned to the own Booking Engine given no availability rules. Use `-1` for managing no quota." -msgstr "Cupo asignada al propio Motor de Reservas sin reglas de disponibilidad. Utilice '-1' para gestionar la ausencia de cuota." - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__draft -msgid "Quotation" -msgstr "Presupuesto" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Quotation #" -msgstr "Presupuesto #" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__sent -msgid "Quotation Sent" -msgstr "Presupuesto Envíado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__expense_policy -msgid "Re-Invoice Expenses" -msgstr "Gastos de re-facturación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__visible_expense_policy -msgid "Re-Invoice Policy visible" -msgstr "Pol" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__ready_for_checkin -msgid "Ready for checkin" -msgstr "Listo para checkin" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__real_avail -msgid "Real Avail" -msgstr "Disponibilidad Real" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__real_avail -msgid "Real availability" -msgstr "Dispo Real" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Reason" -msgstr "Motivo" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__cancelled_reason -msgid "Reason of cancellation" -msgstr "Causa de la Cancelación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__closure_reason_id -msgid "Reason why the reservation cannot be made" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_model_id -msgid "Recipients Model" -msgstr "Modelos destinatarios" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_model_name -msgid "Recipients Model Name" -msgstr "Nombre del Modelo de destinatarios" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Recompute all prices based on this pricelist" -msgstr "Recalcular precios basados en la tarifa" - -#. module: pms -#: model:ir.actions.server,name:pms.priority_reservations_ir_actions_server model:ir.cron,cron_name:pms.priority_reservations -#: model:ir.cron,name:pms.priority_reservations -msgid "Recompute priority on reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce -msgid "Reduced price amount, that is, total price with discounts applied" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 model:ir.model.fields,field_description:pms.field_pms_property__ref -#: model:ir.model.fields,field_description:pms.field_pms_room_type__code -#, python-format -msgid "Reference" -msgstr "Referencia" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Register Checkins" -msgstr "Registro de checkin" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Register Partners" -msgstr "Registro de clientes" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Register Payment" -msgstr "Registro de pago" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__delivered -msgid "Regular invoice" -msgstr "Factura normal" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__parent_id -msgid "Related Company" -msgstr "Compañía relacionada" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__folio_partner_id -msgid "Related customer with Folio Sale Line" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Remove some of the leftover assigned checkins first" -msgstr "Elimine primero algunos de los registros sobrantes" - -#. module: pms -#: model:ir.actions.report,name:pms.action_report_folio -msgid "Report Folio" -msgstr "Informe de Ficha" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_reservation_form_tree_all model:ir.model,name:pms.model_pms_reservation -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__reservation_id model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_tree model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Reservation" -msgstr "Reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Reservation #" -msgstr "Reserva #" - -#. module: pms -#: model:ir.actions.act_window,name:pms.availability_action -msgid "Reservation Availability Plans" -msgstr "Planes de Disponibilidad" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservation Detail" -msgstr "Detalle de la Reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Details" -msgstr "Detalles de la Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_order -#: model:ir.model.fields,field_description:pms.field_pms_reservation__name -msgid "Reservation Id" -msgstr "Id reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__reservation_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_line_ids -msgid "Reservation Lines" -msgstr "Líneas de la Reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__name -msgid "Reservation Name" -msgstr "Notas de la Reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Notes" -msgstr "Notas de la Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_id -msgid "Reservation Reference" -msgstr "Referencia de la Reserva" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_reservation_rooms model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Reservation Rooms" -msgstr "Reservas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__reservation_sequence_id -msgid "Reservation Sequence" -msgstr "Referencia de la Reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_form model_terms:ir.ui.view,arch_db:pms.pms_service_view_search -msgid "Reservation Service" -msgstr "Servicios de la Reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Total" -msgstr "Total de la Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_type -msgid "Reservation Type" -msgstr "Tipo de Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__reservation_wizard_id -msgid "Reservation Wizard" -msgstr "Asistnte Reserva" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability_plan -msgid "Reservation availability plan" -msgstr "Plan de Disponibilidad de la Reserva" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Reservation dates should be consecutives" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 code:addons/pms/wizards/pms_booking_engine.py:0 -#, python-format -msgid "Reservation from " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__reservation_id -msgid "Reservation in which the service is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__reservation_line_ids -msgid "Reservation lines associated with folio sale line, they corresponds with nights" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_view_reservation_operations -msgid "Reservation operations" -msgstr "Operaciones sobre la reserva" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability_plan_rule -msgid "Reservation rule by day" -msgstr "Reglas de reserva por día" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__reservation_id -msgid "Reservation to which checkin partners belong" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__reservation_id -msgid "Reservation to which folio sale line belongs" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_partner_reservations -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__reservation_ids -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__reservation_ids model:ir.ui.menu,name:pms.menu_reservations -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_graph model_terms:ir.ui.view,arch_db:pms.pms_reservation_pivot -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_reservation model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservations model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Reservations" -msgstr "Reservas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_lines_to_change -msgid "Reservations Lines To Change" -msgstr "Líneas a cambiar de la reserva" - -#. module: pms -#: model:ir.model,name:pms.model_pms_reservation_line -msgid "Reservations by day" -msgstr "Reservas por día" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__reservation_ids -msgid "Reservations in which the Account Bank Statement Lines are included" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Reservations related with this contact" -msgstr "Reservas relacionadas con este contacto" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 1 month" -msgstr "Reservas a 1 mes" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 14 days" -msgstr "Reservas a 14 días" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 7 days" -msgstr "Reservas a 7 días" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_reservation -msgid "Reservations/" -msgstr "Reservas/" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_user_id -msgid "Responsible User" -msgstr "Usuario Responsabele" - -#. module: pms -#: model:ir.ui.menu,name:pms.revenue_management_menu -msgid "Revenue Management" -msgstr "Revenue" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__preferred_room_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__room_id -#: model:ir.model.fields,field_description:pms.field_pms_service__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__room_id model:pms.room.type.class,name:pms.pms_room_type_class_0 -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Room" -msgstr "Habitación" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_view_form model:ir.model.fields,field_description:pms.field_pms_room__room_amenity_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_search model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_list model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_form -msgid "Room Amenities" -msgstr "Características de la habitación" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_amenity_type_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_amenity_type_view_list -msgid "Room Amenities Type" -msgstr "Tipo de características de la habitación" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_class_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_type_class_view_tree -msgid "Room Class" -msgstr "Clase de Habitación" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_closure_reason_form_tree model_terms:ir.ui.view,arch_db:pms.pms_room_closure_reason_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_closure_reason_view_tree -msgid "Room Closure Reason" -msgstr "Razón de cierre de la habitación" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Room Line" -msgstr "Línea de la habitación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__name model:ir.model.fields,help:pms.field_pms_room__name -msgid "Room Name" -msgstr "Nombre de la Habitación" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_reservation_line_rule_availability -msgid "Room Occupied" -msgstr "Habitación Ocupada" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Room Reservation" -msgstr "Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_room_services_set -msgid "Room Services Total" -msgstr "Servicios totales de la habitación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__room_source -msgid "Room Source" -msgstr "Habitación Origen" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__room_target -msgid "Room Target" -msgstr "Habitación destino" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_type_form_tree model:ir.model,name:pms.model_pms_room_type -#: model:ir.model.fields,field_description:pms.field_pms_availability__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pms_room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__room_type_ids -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__room_type_id model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -msgid "Room Type" -msgstr "Tipo de Habitación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__room_amenity_ids -msgid "Room Type Amenities" -msgstr "Características del tipo de habitación" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_type_class_form_tree model:ir.model,name:pms.model_pms_room_type_class -#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_class_form_tree -msgid "Room Type Class" -msgstr "Clase del Tipo de Habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__pms_room_type_id -msgid "Room Type for which this Board Service is available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__room_type_id -msgid "Room Type reserved" -msgstr "Tipo de habitación vendida" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__room_type_id -msgid "Room Type sold on the reservation,it doesn't necessarily correspond to the room actually assigned" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_kanban -msgid "Room Type:" -msgstr "Tipo de Habitación:" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__apply_pricelists_on__room_types -#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_form_tree -msgid "Room Types" -msgstr "Tipos de Habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__room_type_ids -msgid "Room Types that belong to this Room Type Class" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_amenity -msgid "Room amenity" -msgstr "Característica de la habitación" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_type_view_form -msgid "Room amenity Type" -msgstr "Tipo de característica de la habitación" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Room line Check In Date Should be less than the Check Out Date!" -msgstr "¡El checkin de la línea de habitación debe ser inferior que la fecha de salida!" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__reservation_ids -msgid "Room reservation detail" -msgstr "Detalles de la reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__reservation_id -msgid "Room to which the services will be applied" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability -msgid "Room type availability per day" -msgstr "Disponibilidad por día" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__default_code -msgid "Room type class identification code" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__room_type_id -msgid "Room type for which availability is indicated" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__room_type_id -msgid "Room type for which availability rule is applied" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_folio_availability_wizard -msgid "Room type line in Booking Engine" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__board_service_room_type_ids -msgid "Room type's board services" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Room {} not available." -msgstr "Habitación {} no disponible." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__rooms -msgid "Room/s" -msgstr "Habitación/es" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Rooming" -msgstr "Huéspedes/Rooming" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__room_ids model:ir.model.fields,field_description:pms.field_pms_room_type__room_ids -#: model:ir.model.fields,field_description:pms.field_pms_ubication__pms_room_ids model:ir.ui.menu,name:pms.menu_open_pms_room_form -#: model:ir.ui.menu,name:pms.pms_rooms_menu model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_bottom_tree -msgid "Rooms" -msgstr "Habitaciones" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__free_room_ids -msgid "Rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_ubication__pms_room_ids -msgid "Rooms found in this location" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__room_ids -msgid "Rooms that a property has." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__rooms -msgid "Rooms that are reserved" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__room_ids -msgid "Rooms that belong to room type." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__rules_to_overwrite -msgid "Rule to Overwrite" -msgstr "Reglas a sobreescribir" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form -msgid "Rules" -msgstr "Reglas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__rule_ids -msgid "Rules in a availability plan" -msgstr "Plan de Disponibilidad de la Reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__num_rules_to_overwrite -msgid "Rules to overwrite on massive changes" -msgstr "Reglas para sobrescribir en los cambios masivos" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_sale_channel_form_tree model:ir.model.fields,field_description:pms.field_pms_property__sale_channel_id -#: model:ir.model.fields,field_description:pms.field_res_partner__sale_channel_id model:ir.model.fields,field_description:pms.field_res_users__sale_channel_id -#: model_terms:ir.ui.view,arch_db:pms.pms_sale_channel_view_form model_terms:ir.ui.view,arch_db:pms.pms_sale_channel_view_tree -msgid "Sale Channel" -msgstr "Canal de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__name -msgid "Sale Channel Name" -msgstr "Nombre del Canal de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__channel_type -msgid "Sale Channel Type" -msgstr "Tipo del Canal de Venta" - -#. module: pms -#: code:addons/pms/models/res_partner.py:0 -#, python-format -msgid "Sale Channel for an agency must be indirect" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_partner.py:0 -#, python-format -msgid "Sale Channel must be entered" -msgstr "El Canal de Venta debe ser Indicado" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_open_pms_sale_channel_form_tree -msgid "Sale Channels" -msgstr "Canales de Venta" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.product_pricelist_item_view_tree -msgid "Sale Date End" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.product_pricelist_item_view_tree -msgid "Sale Date Start" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__date_types__sale_dates -msgid "Sale Dates" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__description_sale -msgid "Sale Description" -msgstr "Descipción de la Venta" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sale Details" -msgstr "Detalles de la Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__sale_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__sale_line_ids model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sale Lines" -msgstr "Líneas de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_order_count -msgid "Sale Order Count" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__pms_sale_channel_ids -msgid "Sale channel for which the pricelist is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__sale_line_ids -msgid "Sale lines" -msgstr "Líneas de Venta" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__sale_line_ids -msgid "Sale lines in folio. It correspond with reservation nights" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_sales_menu -msgid "Sales" -msgstr "Facturación" - -#. module: pms -#: model:ir.model,name:pms.model_pms_sale_channel model:ir.model.fields,field_description:pms.field_pms_service__channel_type -msgid "Sales Channel" -msgstr "Canales de Venta" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__channel_type_id model:ir.model.fields,help:pms.field_pms_reservation__channel_type_id -msgid "Sales Channel through which the reservation was managed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__description_sale -msgid "Sales Description" -msgstr "Descripciones de la Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__sale_line_ids model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sales Lines" -msgstr "Líneas de Ventas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_order_ids -msgid "Sales Order" -msgstr "Pedido de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_line_warn -msgid "Sales Order Line" -msgstr "Línea de Pedido de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__list_price -msgid "Sales Price" -msgstr "Precio de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__team_id -msgid "Sales Team" -msgstr "Equipo de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_warn -msgid "Sales Warnings" -msgstr "Advertencias de Venta" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__user_id model:ir.model.fields,field_description:pms.field_pms_property__user_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__user_id -msgid "Salesperson" -msgstr "Vendedor" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__date -msgid "Sate on which the product is to be consumed" -msgstr "Fecha de consumición del servicio" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Saturday" -msgstr "Sábado" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Search" -msgstr "Buscar" - -#. module: pms -#: model:pms.ubication,name:pms.pms_ubication_2 -msgid "Second Floor" -msgstr "Segundo Piso" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__lastname2 -msgid "Second Last Name" -msgstr "Segundo apellido" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lastname2 model:ir.model.fields,field_description:pms.field_res_partner__lastname2 -#: model:ir.model.fields,field_description:pms.field_res_users__lastname2 -msgid "Second last name" -msgstr "Segundo apellido" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__display_type__line_section -msgid "Section" -msgstr "Sección" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__access_token model:ir.model.fields,field_description:pms.field_pms_reservation__access_token -msgid "Security Token" -msgstr "Señal de Seguridad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__pms_amenity_type_id -msgid "Segment the amenities by categories (multimedia, comfort, etc ...)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__segmentation_ids -msgid "Segmentation" -msgstr "Segmentación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__segmentation_ids -msgid "Segmentation tags to classify checkin partners" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__segmentation_ids -msgid "Segmentation tags to classify folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__segmentation_ids -msgid "Segmentation tags to classify reservations" -msgstr "Etiquetas de segmentación para clasificar reservas" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Segmentation..." -msgstr "Segmentación..." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_type -msgid "Select a valid document type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__categ_id -msgid "Select category for the current product" -msgstr "Seleccione una categoría para el producto actual" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__num_rooms_selected -msgid "Selected rooms" -msgstr "Habitaciones Seleccionadas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__invoice_warn model:ir.model.fields,help:pms.field_pms_property__sale_warn -#: model:ir.model.fields,help:pms.field_pms_room_type__sale_line_warn -msgid "" -"Selecting the \"Warning\" option will notify user with the message, Selecting \"Blocking Message\" will throw an exception with the message and block the " -"flow. The Message has to be written in the next field." -msgstr "" -"La selección de la opción \"Advertencia\" notificará al usuario con el mensaje, la Selección de \"Mensaje de Bloqueo\" lanzará una excepción con el mensaje " -"y bloqueará el flujo. El mensaje debe escribirse en el siguiente campo." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__self -msgid "Self" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__sequence model:ir.model.fields,field_description:pms.field_pms_folio__sequence -#: model:ir.model.fields,field_description:pms.field_pms_room__sequence model:ir.model.fields,field_description:pms.field_pms_room_type__sequence -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__sequence model:ir.model.fields,field_description:pms.field_pms_service__sequence -#: model:ir.model.fields,field_description:pms.field_pms_ubication__sequence -msgid "Sequence" -msgstr "Secuencia" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__sequence -msgid "Sequence used to form the name of the folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Sequences" -msgstr "Secuencias" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__service_ids -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__service -#: model:ir.model.fields,field_description:pms.field_pms_service__product_id -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__apply_pricelists_on__service -#: model_terms:ir.ui.view,arch_db:pms.product_template_view_form -msgid "Service" -msgstr "Servicio" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_report_view_tree model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_tree -msgid "Service By Day" -msgstr "Servicio por día" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_order -msgid "Service Id" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_form -msgid "Service Line" -msgstr "Línea de servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__service_line_ids model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Service Lines" -msgstr "Líneas del servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_id -msgid "Service Reference" -msgstr "Referencia del Servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__service_id -msgid "Service Room" -msgstr "Habitación del Servicio" - -#. module: pms -#: model:ir.model,name:pms.model_pms_service_line -msgid "Service by day" -msgstr "Servicio por día" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__name model:ir.model.fields,help:pms.field_pms_service__name -msgid "Service description" -msgstr "Descripción del servicio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__service_id -msgid "Service identifier" -msgstr "Línea de servicio" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__state -msgid "Service status, it corresponds with folio status" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_service_line_form model:ir.actions.act_window,name:pms.action_pms_services_form -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__service_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__service_ids -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__service_ids model:ir.ui.menu,name:pms.menu_services_pms -#: model:ir.ui.menu,name:pms.pms_services_menu model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form model_terms:ir.ui.view,arch_db:pms.pms_service_line_graph -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_pivot model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_calendar -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_tree model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Services" -msgstr "Servicios" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_service_line model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services By Day" -msgstr "Servicios por día" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services NOT included in the room reservation price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_services -msgid "Services Total" -msgstr "Servicios totales" - -#. module: pms -#: model:ir.model,name:pms.model_pms_service -msgid "Services and its charges" -msgstr "Servicios y sus cargos" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_pms_service_line -msgid "Services by Day" -msgstr "Servicios por día" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__service_ids -msgid "Services detail provide to customer and it will include in main Invoice." -msgstr "El detalle de los servicios se proporciona al cliente y se incluir´a en la factura principal." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__services_discount -msgid "Services discount" -msgstr "Descuento Servicios" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__services_discount -msgid "Services discount (€)" -msgstr "Descuento Servicios (€)" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__service_ids -msgid "Services in which the Account Bank Statement Lines are included" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services included in the room reservation price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__board_service_line_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__board_service_line_ids -msgid "Services included in this Board Service" -msgstr "Servicios incluidos en el Régimen" - -#. module: pms -#: model:ir.model,name:pms.model_pms_board_service_line -msgid "Services on Board Service included" -msgstr "Servicios incluidos en el Régimen" - -#. module: pms -#: model:ir.model,name:pms.model_pms_board_service_room_type_line -msgid "Services on Board Service included in Room" -msgstr "Servicios del Régimen incluidos en la habitación" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Set to Done" -msgstr "Pasar a hecho" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Settings" -msgstr "Ajustes" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__service_id -msgid "Sevice included in folio sale line" -msgstr "Servicio de Habitación incluído en la Habitación" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_0 -msgid "Shampoo and Soap" -msgstr "Champú y Jabón" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_share -msgid "Share Partner" -msgstr "Cliente compartido" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__shared_folio -msgid "Shared Folio" -msgstr "Ficha compartida" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Shared Room" -msgstr "Habitación Compartida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__show_detail_report -msgid "Show Detail Report" -msgstr "Ver Informe" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Show all checkins for Tomorrow" -msgstr "Mostrar todos los checkin para mañana" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Show all checkins for enter tomorrow" -msgstr "Mostrar todos los checkin que entrarán mañana" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Show all future checkins" -msgstr "Mostrar todos los checkin para mañana" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Show all reservations for which date enter is before than 14 days" -msgstr "Mostrar todas las reservas las cuales la fecha de entrada es anterior a 14 días" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Show all reservations for which date enter is before than 7 days" -msgstr "Mostrar todas las reservas las cuales la fecha de entrada es anterior a 7 días" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Show all reservations for which date enter is before than aprox. 1 month" -msgstr "Mostrar todas las reservas en las que la fecha de entrada es anterior a 1 mes aprox" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__auto_qty -msgid "Show if the day qty was calculated automatically" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_expiration -msgid "Signup Expiration" -msgstr "Caducidad del Registro" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_token -msgid "Signup Token" -msgstr "Señal del Registro" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_type -msgid "Signup Token Type" -msgstr "Tipo de Señal del registro" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_valid -msgid "Signup Token is Valid" -msgstr "La Señal del Registro es Válida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_url -msgid "Signup URL" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sales_count -msgid "Sold" -msgstr "Vendido" - -#. module: pms -#: code:addons/pms/models/res_users.py:0 -#, python-format -msgid "Some properties do not belong to the allowed companies" -msgstr "Algunas propiedades no pertenecen a las compañías permitidas" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_spanish_residence -msgid "Spanish Residence permit" -msgstr "Permiso de residencia Español" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__board_service_room_type_id -msgid "Specify a Board services on Room Types." -msgstr "Especifica los regímenes disponibles en los tipos de habitación" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_late__days -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_noshow__days -msgid "Specify days" -msgstr "Días específicos" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__split -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Split reservation" -msgstr "Dividir la reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__splitted -msgid "Splitted" -msgstr "Dividida" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__staff -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__staff -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__staff model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Staff" -msgstr "Staff" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#, python-format -msgid "Stage" -msgstr "Estado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__date_start_consumption -msgid "Start Date Consumption" -msgstr "Fecha de Inicio consumición" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__start_date -msgid "Start date for creation of reservations and folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__date_start_consumption -msgid "Start date to apply daily pricelist items" -msgstr "Fecha de inicio para aplicar los items de tarifa diarios" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__state_id model:ir.model.fields,field_description:pms.field_pms_reservation__state -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__state model:ir.model.fields,field_description:pms.field_pms_service__state -#: model:ir.model.fields,field_description:pms.field_res_partner__state_id model:ir.model.fields,field_description:pms.field_res_users__state_id -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "State" -msgstr "Estado" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__invoice_status -msgid "State in which the service is with respect to invoices.It can be 'invoiced', 'to_invoice' or 'no'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__state -msgid "State of the reservation line." -msgstr "Estado de la línea de reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__state model:ir.model.fields,field_description:pms.field_pms_folio__state -msgid "Status" -msgstr "Estado" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_state model:ir.model.fields,help:pms.field_pms_property__activity_state -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_state model:ir.model.fields,help:pms.field_pms_room_type__activity_state -msgid "" -"Status based on activities\n" -"Overdue: Due date is already passed\n" -"Today: Activity date is today\n" -"Planned: Future activities." -msgstr "" -"Estado basado en actividades\n" -"Vencido: la fecha de vencimiento ya pasó\n" -"Hoy: la fecha de actividad es hoy\n" -"Planificado: actividades futuras." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__state -msgid "Status of the checkin partner regarding the reservation" -msgstr "Ningún checkin fue realizado en esta reserva" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__street -msgid "Street" -msgstr "Calle" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Street 2..." -msgstr "Calle 2..." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Street..." -msgstr "Calle" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__street2 -msgid "Street2" -msgstr "Calle2" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__service_line_ids -msgid "Subservices included in folio sale line service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__service_line_ids -msgid "Subservices included in this service" -msgstr "Servicio de Habitación incluído en la Habitación" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_service__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_subtotal -msgid "Subtotal" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_subtotal model:ir.model.fields,help:pms.field_pms_reservation__price_subtotal -#: model:ir.model.fields,help:pms.field_pms_service__price_subtotal model:ir.model.fields,help:pms.field_pms_service_line__price_day_subtotal -msgid "Subtotal price without taxes" -msgstr "Subtotal sin impuestos" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Sunday" -msgstr "Domingo" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__supplier_rank -msgid "Supplier Rank" -msgstr "Rango de los proveedores" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Supplier Taxes" -msgstr "Impuesto a los proveedores" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Suppliers" -msgstr "Proveedores" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Swap reservation rooms" -msgstr "Intercambiar habitaciones en reservas" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__swap -msgid "Swap rooms" -msgstr "Intercambiar habitaciones" - -#. module: pms -#. openerp-web -#: code:addons/pms/static/src/xml/pms_base_templates.xml:0 -#, python-format -msgid "Switch to this property" -msgstr "Cambiar a este Hotel" - -#. module: pms -#: model:ir.model,name:pms.model_ir_config_parameter -msgid "System Parameter" -msgstr "Parámetro del sistema" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "TRAVELER'S DOCUMENT" -msgstr "DOCUMENTO DEL VIAJERO" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Tables Detail" -msgstr "Detalles de la tabla" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__category_id -msgid "Tags" -msgstr "Etiquetas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__vat -msgid "Tax ID" -msgstr "ID del impuesto" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__tax_ids model:ir.model.fields,field_description:pms.field_pms_folio__amount_tax -#: model:ir.model.fields,field_description:pms.field_pms_reservation__tax_ids model:ir.model.fields,field_description:pms.field_pms_service__tax_ids -#: model:ir.model.fields,field_description:pms.field_pms_service_line__tax_ids model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Taxes" -msgstr "Impuestos" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_tax model:ir.model.fields,field_description:pms.field_pms_service__price_tax -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_tax -msgid "Taxes Amount" -msgstr "Cuenta de impuestos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__tax_ids -msgid "Taxes applied in the folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__tax_ids -msgid "Taxes applied in the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__tax_ids -msgid "Taxes applied in the service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__tax_ids -msgid "Taxes applied in the service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deposit_taxes_id -msgid "Taxes used for deposits" -msgstr "Tasas utilizadas para depósitos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__show_update_pricelist -msgid "" -"Technical Field, True if the pricelist was changed;\n" -" this will then display a recomputation button" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__valid_product_template_attribute_line_ids -msgid "Technical compute" -msgstr "Computación técnica" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_id -msgid "Technical field" -msgstr "Computación técnica" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__display_type -msgid "Technical field for UX purpose." -msgstr "Campo técnico para fines de UX." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__preconfirm -msgid "Technical field that indicates the reservation is not comfirm yet" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_checkin -msgid "Technical field, Indicates if there isn't a checkin_partner dataOnly can be true if checkin is today or was in the past" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_cancel -msgid "Technical field, Indicates that reservation can be cancelled,that happened when state is 'cancel', 'done', or 'departure_delayed'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_checkout -msgid "" -"Technical field, Indicates that reservation is ready for checkoutonly can be true if reservation state is 'onboard' or departure_delayedand checkout is " -"today or will be in the future" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__pricelist_id -msgid "Technical field. Used for searching on pricelists, not stored in database." -msgstr "Campo técnico. Usado para buscar e las tarifas, no se almacena en la base de datos." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__note -msgid "Terms and conditions" -msgstr "Términos y condiciones" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "The Property are mandatory in the reservation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "The Sale Channel does not correspond to the agency's" -msgstr "El canal de venta no corresponde con el de la agencia" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__vat -msgid "The Tax Identification Number. Complete it if the contact is subjected to government taxes. Used in some legal statements." -msgstr "El número de identificación fiscal. Complételo si el contacto está sujeto a impuestos gubernamentales. Utilizado en algunas declaraciones legales." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__invoice_count -msgid "The amount of invoices in out invoice and out refund status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__pending_amount -msgid "The amount that remains to be paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_pending_amount -msgid "The amount that remains to be paid from folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__untaxed_amount_invoiced -msgid "The amount to invoice without taxes in the line of folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__analytic_account_id -msgid "The analytic account related to a folio." -msgstr "La cuenta analítica relacionada con un folio." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__availability_plan_id -msgid "The availability plan that include the Availabilty Rule" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "The capacity of the room must be greater than 0." -msgstr "La capacidad de la habitación debe ser mayor que 0." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__checkin_partner_ids -msgid "The checkin partners on a folio" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_users.py:0 -#, python-format -msgid "The chosen property is not in the allowed properties for this user" -msgstr "La propiedad escogida no se encuentra en las propiedades permitidas para este usuario" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__closure_reason_id -msgid "The closure reason for a closure room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement__company_id -msgid "The company for Account Bank Statement" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_journal__company_id -msgid "The company for Account Jouarnal" -msgstr "La compañía por defecto para este usuario." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__company_id -msgid "The company for folio" -msgstr "La sociedad de la Ficha" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__company_id -msgid "The company in the folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__company_id -msgid "The company that owns or operates this property." -msgstr "La compañía que posee u opera esta propiedad." - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__currency_id -msgid "The currency for the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__currency_id -msgid "The currency of the property location" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__currency_id -msgid "The currency used in relation to the folio" -msgstr "La cuenta analítica relacionada con un folio." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__currency_id -msgid "The currency used in relation to the pricelist" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__currency_id -msgid "The currency used in relation to the service where it's included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__date -msgid "The date of the reservation in reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__default_pricelist_id -msgid "The default pricelist used in this property." -msgstr "La tarifa por defecto usada en esta propiedad." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__fiscal_position_id -msgid "The fiscal position depends on the location of the client" -msgstr "La posición fiscal determina las tasas/cuentas usadas para este contacto." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_position_id -msgid "The fiscal position determines the taxes/accounts used for this contact." -msgstr "La posición fiscal determina las tasas/cuentas usadas para este contacto." - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__fixed_amount -msgid "The fixed amount to be invoiced in advance, taxes excluded." -msgstr "La cantidad fija será facturada por adelantado, tasas excluidas." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_id -msgid "The folio customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_move_line__folio_line_ids -msgid "The folio lines in the account move lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_id -msgid "The folio where the reservations are included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__user_id -msgid "The internal user in charge of this contact." -msgstr "El usuario interno a cargo de este contacto." - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__untaxed_amount_to_invoice -msgid "The invoiced amount without taxes in the line of the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__capacity -msgid "The maximum number of people that can occupy a room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__name -msgid "The name of the sale channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_room_closure_reason__name -msgid "The name that identifies the room closure reason" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__total_rooms_count -msgid "The number of rooms in a room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__count_rooms_pending_arrival -msgid "The number of rooms left to occupy." -msgstr "" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "The ordered quantity has been updated." -msgstr "Se ha actualizado la cantidad pedida." - -#. module: pms -#: code:addons/pms/models/ir_config_parameter.py:0 -#, python-format -msgid "The parameter Advanced price rules cannot be modified" -msgstr "El parámetro de reglas de tarifa avanzadas no se puede modificar" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__has_unreconciled_entries -msgid "The partner has at least one unreconciled debit and credit since last time the invoices & payments matching was performed." -msgstr "El cliente tiene al menos un débito y un crédito no conciliados desde la última vez que se realizó la conciliación de facturas y pagos." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__reference -msgid "The payment communication of this sale order." -msgstr "La comunicación de pago de esta orden de venta." - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__amount -msgid "The percentage of amount to be invoiced in advance, taxes excluded." -msgstr "El porcentaje de la cantidad a facturar por adelantado, tasas/impuestos excluidos." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__price -msgid "The price in a reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_untaxed -msgid "The price without taxes on a folio" -msgstr "Precio sin impuestos" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "" -"The product used to invoice a down payment should\n" -" be of type 'Service'.\n" -" Please use another product or update this product." -msgstr "" -"El producto usado para facrurar un anticipo debe\n" -"\t\tser del tipo 'Servicio'.\n" -"\t\tPor favor, use otro producto o actualice este producto." - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "" -"The product used to invoice a down payment should\n" -" have an invoice policy set to \"Ordered quantities\".\n" -" Please update your deposit product to be able\n" -" to create a deposit invoice." -msgstr "" -"El producto utilizado para facturar un anticipo debe\n" -" tener una política de facturación establecida en \"Cantidades pequeñas\".\n" -" Por favor, actualice su producto de depósito(??) para poder\n" -" crear una factura de depósito." - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_users__pms_property_ids -msgid "The properties allowed for this user" -msgstr "La propiedad escogida no se encuentra en las propiedades permitidas para este usuario" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__pms_property_id -msgid "The property for folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_users__pms_property_id -msgid "The property that is selected within those allowed for the user" -msgstr "El Hotel escogida no se encuentra en los hoteles permitidos para este usuario" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "The qty (%s) is wrong. The quantity pending to invoice is %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__qty_to_invoice -msgid "" -"The quantity to invoice. If the invoice policy is order, the quantity to invoice is calculated from the ordered quantity. Otherwise, the quantity delivered " -"is used." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "The reservation type must be the same for all reservations in folio" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "The reservation units are required on shared rooms." -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "The room does not exist" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "The room is not available" -msgstr "La habitación no está disponible" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__room_id -msgid "The room of a reservation. " -msgstr "Habitación de una reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__sale_channel_id model:ir.model.fields,help:pms.field_res_partner__sale_channel_id -#: model:ir.model.fields,help:pms.field_res_users__sale_channel_id -msgid "The sale channel of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__lst_price -msgid "The sale price is managed from the product template. Click on the 'Configure Variants' button to set the extra attribute prices." -msgstr "" -"El precio de venta se gestiona desde la plantilla del producto. Haga click en el botón 'Configurar variantes' para establecer los precios de los atributos " -"adicionales." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__folio_sequence_id -msgid "The sequence that formed the name of the folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__reservation_sequence_id -msgid "The sequence that formed the name of the reservation." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__payment_state -msgid "The state of the payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__state -msgid "The state of the reservation. It can be 'Pre-reservation', 'Pending arrival', 'On Board', 'Out', 'Cancelled', 'Arrival Delayed' or 'Departure Delayed'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_payment_state -msgid "The status of the folio payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__state -msgid "The status of the folio related with folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__invoice_status -msgid "The status of the invoices in folio. Can be 'invoiced', 'to_invoice' or 'no'." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__price_total -msgid "The total price in the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__reservation_type model:ir.model.fields,help:pms.field_pms_folio__reservation_type -msgid "The type of the reservation. Can be 'Normal', 'Staff' or 'Out of Service'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__user_id -msgid "The user who created the folio" -msgstr "Usuario que creo la ficha" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "The value of the down payment amount must be positive." -msgstr "El valor del pago inicial debe ser positivo." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -msgid "There are currently no folios for your account." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "There are currently no reservations for your account." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "There are no checkins to print" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "There is a customer with this email or mobile, do you want to add it to the reservation?" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "" -"There is nothing to invoice!\n" -"\n" -" Reason(s) of this behavior could be:\n" -" - You should deliver your products before invoicing them: Click on the \"truck\"\n" -" icon (top-right of your screen) and follow instructions.\n" -" - You should modify the invoicing policy of your product: Open the product,\n" -" go to the \"Sales tab\" and modify invoicing policy from \"delivered quantities\"\n" -" to \"ordered quantities\".\n" -" " -msgstr "" -"¡No hay nada para facturar!\n" -"\n" -" La/s razón/es de este comportamiento pueden ser:\n" -" - Debe entregar sus productos antes de facturarlos: haga click en el icono del\n" -" \"???\" (arriba a la derecha de su pantalla) y siga las instrucciones.\n" -" - Debe modificar la política de privacidad de su producto: Abre el producto,\n" -" vaya a la pestaña \"Ventas\"y modifique la política de facturación de \"cantidades entregadas\"\n" -" a \"cantidades pedidas\".\n" -" " - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "There's no reservations lines with provided room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__reservation_line_ids model:ir.model.fields,help:pms.field_pms_reservation__reservation_line_ids -msgid "They are the lines of the reservation into a reservation,they corresponds to the nights" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_payable_id -msgid "This account will be used instead of the default one as the payable account for the current partner" -msgstr "Esta cuenta se usará en vez de la predeterminada como la cuenta para pagar del cliente actual" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_receivable_id -msgid "This account will be used instead of the default one as the receivable account for the current partner" -msgstr "Esta cuenta se usará en vez de la predeterminada como la cuenta para cobrar del cliente actual" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_datetime -msgid "This field is the day and time of arrival of the reservation.It is formed with the checkin and arrival_hour fields" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkout_datetime -msgid "This field is the day and time of departure of the reservation.It is formed with the checkout and departure_hour fields" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__tz -msgid "This field is used to determine de timezone of the property." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__email_normalized -msgid "This field is used to search on email address as the primary email field can contain more than strictly an email address." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "This guest is already registered in the room" -msgstr "El invitado ya está registrado en la habitación" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__price_extra -msgid "This is the sum of the extra price of all attributes" -msgstr "Esta es la suma del precio extra de todos los atributos" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__impacts_quota -msgid "This line has been taken into account in the avail quota" -msgstr "Este registro se tiene en cuenta para calcular la disponibilidad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_supplier_payment_term_id -msgid "This payment term will be used instead of the default one for purchase orders and vendor bills" -msgstr "Este término de pago será utilizado en lugar del predeterminado para las órdenes de compra y facturas de proveedores" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_payment_term_id -msgid "This payment term will be used instead of the default one for sales orders and customer invoices" -msgstr "Este término de pago será utilizado en lugar del predeterminado para los pedido de venta y las facturas de los clientes" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_product_pricelist -msgid "This pricelist will be used, instead of the default one, for sales to the current partner" -msgstr "Esta tarifa se utilizará, en lugar de la tarifa por defecto, para las ventas al cliente actual" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__occupies_availability -msgid "This record is taken into account to calculate availability" -msgstr "Este registro se tiene en cuenta para calcular la disponibilidad" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "This reservation cannot be cancelled" -msgstr "No se puede hacer el checkout de la reserva" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "This reservation cannot be check out" -msgstr "No se puede hacer el checkout de la reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -"This reservation has other reservantions and/or services in the\n" -" folio, you can check it in the" -msgstr "" -"Esta reserva tiene otras reservas y/o servicios en el\n" -"\t\tfolio, puedes comprobarlo/consultarlo en el" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -"This reservation is part of a splitted reservation, you can try to\n" -" join the reservation here" -msgstr "" -"Esta reserva forma parte de una reserva partida, puede intentar\n" -"\t\tunificar la reserva aquí" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "This will update all unit prices based on the currently set pricelist." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Thursday" -msgstr "Jueves" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__tz model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Timezone" -msgstr "Zona Horaria" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__tz_offset -msgid "Timezone offset" -msgstr "Desplazamiento de zona horaria" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__title -msgid "Title" -msgstr "Título" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__end_date -msgid "To" -msgstr "Hasta:" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__to_assign model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To Assign" -msgstr "Por Asignar" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__to_invoice -msgid "To Invoice" -msgstr "Por Facturar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_to_invoice -msgid "To Invoice Quantity" -msgstr "Cantidad a facturar" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To be paid" -msgstr "Por Pagar" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To enter" -msgstr "Por entrar" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "To invoice" -msgstr "Por Facturar" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_name -msgid "To whom the room is assigned" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__end_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkout -msgid "To:" -msgstr "Hasta:" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Today" -msgstr "Hoy" - -#. module: pms -#: model:pms.amenity.type,name:pms.pms_amenity_type_0 -msgid "Toiletries" -msgstr "Artículos de aseo" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Tomorrow" -msgstr "Mañana" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_total model:ir.model.fields,field_description:pms.field_pms_folio__amount_total -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_total model:ir.model.fields,field_description:pms.field_pms_service__price_total -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_total model_terms:ir.ui.view,arch_db:pms.portal_my_folio -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Total" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__total_invoiced -msgid "Total Invoiced" -msgstr "Total facturado" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__debit -msgid "Total Payable" -msgstr "Total a pagar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__total_price_folio -msgid "Total Price" -msgstr "Precio Total" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__credit -msgid "Total Receivable" -msgstr "Total por cobrar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__total_rooms_count -msgid "Total Rooms Count" -msgstr "Nº Total de habitaciones" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_tax -msgid "Total Tax" -msgstr "Impuestos totales" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree -msgid "Total amount" -msgstr "Importe total" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Total amount (Reservation Card):" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__credit -msgid "Total amount this customer owes you." -msgstr "Cantidad total que este cliente le debe." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_total -msgid "Total amount to be paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__debit -msgid "Total amount you have to pay to this vendor." -msgstr "Cantidad total que debe pagar al proveedor." - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree -msgid "Total debt" -msgstr "Deuda total" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_tax model:ir.model.fields,help:pms.field_pms_reservation__price_tax -msgid "Total of taxes in a reservation" -msgstr "Unificar la reserva" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__price_tax -msgid "Total of taxes in service" -msgstr "Causa de estar Fuera de Servicio" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__price_total -msgid "Total price" -msgstr "Precio Total" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__price_services -msgid "Total price from services of a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__total_price_folio -msgid "Total price of folio with taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__price_room_services_set -msgid "Total price of room and services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_total model:ir.model.fields,help:pms.field_pms_reservation__price_total -#: model:ir.model.fields,help:pms.field_pms_service__price_total model:ir.model.fields,help:pms.field_pms_service_line__price_day_total -msgid "Total price with taxes" -msgstr "Precio Total" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Tour Operator" -msgstr "Tour Operador" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__service_type -msgid "Track Service" -msgstr "Servicio de Seguimiento" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__transaction_ids -msgid "Transactions" -msgstr "Transacciones" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Traveler's signature" -msgstr "" - -#. module: pms -#: model:ir.actions.report,name:pms.action_traveller_report -msgid "Traveller Report" -msgstr "Informes de huéspedes" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_3 model:product.product,name:pms.pms_room_type_3_product_product -msgid "Triple" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__is_add_code_room_name -msgid "True if the Internal Reference should appear in the display name of the rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__show_detail_report -msgid "True if you want that board service detail to be shown on the report" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Tuesday" -msgstr "Martes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__reservation_type -#: model:ir.model.fields,field_description:pms.field_pms_folio__reservation_type model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Type" -msgstr "TIpo" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__reservation_type -msgid "Type of reservations. It can be 'normal', 'staff' or 'out of service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__channel_type -msgid "Type of sale channel; it can be 'direct'(if there isno intermediary) or 'indirect'(if there areintermediaries between partner and property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_property__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_room_type__activity_exception_decoration -msgid "Type of the exception activity on record." -msgstr "Tipo de actividad de excepcion/excepcional regsitrada./en un registro." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__room_type_ids -msgid "Types" -msgstr "Tipos" - -#. module: pms -#: model:ir.model,name:pms.model_pms_ubication model:ir.model.fields,field_description:pms.field_pms_room__ubication_id -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -msgid "Ubication" -msgstr "Zona" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_ubication__name model:ir.model.fields,help:pms.field_pms_ubication__name -msgid "Ubication Name" -msgstr "Nombre de la Zona" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_ubication_form_tree -msgid "Ubication Structure" -msgstr "Zonas del Hotel" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_open_pms_ubication_form_tree -msgid "Ubications" -msgstr "Zonas" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__default_code -msgid "Unique Board Service identification code per property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__room_type_id -msgid "Unique room type for the rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_unit -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_unit model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Unit Price" -msgstr "Precio unidad" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_unit -msgid "Unit Price of folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__per_day model:ir.model.fields,field_description:pms.field_product_product__per_day -#: model:ir.model.fields,field_description:pms.field_product_template__per_day -msgid "Unit increment per day" -msgstr "Unidad por unidad por día" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__per_person model:ir.model.fields,field_description:pms.field_product_product__per_person -#: model:ir.model.fields,field_description:pms.field_product_template__per_person -msgid "Unit increment per person" -msgstr "Unidad por persona" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom model:ir.model.fields,field_description:pms.field_pms_room_type__uom_id -msgid "Unit of Measure" -msgstr "Unidad de medida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_category_id -msgid "Unit of Measure Category" -msgstr "Nombre de unidad de medida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__uom_name -msgid "Unit of Measure Name" -msgstr "Nombre de unidad de medida" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__day_qty model:pms.room.type,uom_name:pms.demo_pms_room_type_0 -#: model:pms.room.type,uom_name:pms.demo_pms_room_type_1 model:pms.room.type,uom_name:pms.pms_room_type_0 model:pms.room.type,uom_name:pms.pms_room_type_1 -#: model:pms.room.type,uom_name:pms.pms_room_type_2 model:pms.room.type,uom_name:pms.pms_room_type_3 model:pms.room.type,uom_name:pms.pms_room_type_4 -#: model:product.product,uom_name:pms.demo_pms_room_type_0_product_product model:product.product,uom_name:pms.demo_pms_room_type_1_product_product -#: model:product.product,uom_name:pms.pms_room_type_0_product_product model:product.product,uom_name:pms.pms_room_type_1_product_product -#: model:product.product,uom_name:pms.pms_room_type_2_product_product model:product.product,uom_name:pms.pms_room_type_3_product_product -#: model:product.product,uom_name:pms.pms_room_type_4_product_product model:product.product,uom_name:pms.pms_service_0 -#: model:product.product,uom_name:pms.pms_service_1 model:product.product,uom_name:pms.pms_service_3 model:product.product,uom_name:pms.pms_service_4 -#: model:product.product,uom_name:pms.pms_service_5 model:product.product,uom_name:pms.pms_service_6 -#: model:product.template,uom_name:pms.pms_service_0_product_template model:product.template,uom_name:pms.pms_service_1_product_template -#: model:product.template,uom_name:pms.pms_service_3_product_template model:product.template,uom_name:pms.pms_service_4_product_template -#: model:product.template,uom_name:pms.pms_service_5_product_template model:product.template,uom_name:pms.pms_service_6_product_template -msgid "Units" -msgstr "Unidades" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__draft -msgid "Unkown Guest" -msgstr "Huésped desconocido" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_unread model:ir.model.fields,field_description:pms.field_pms_property__message_unread -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_unread -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_unread -msgid "Unread Messages" -msgstr "Mensajes no leídos" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_unread_counter -msgid "Unread Messages Counter" -msgstr "Nº de mensajes sin leer" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__amount_untaxed -msgid "Untaxed Amount" -msgstr "Importe no tributable" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_to_invoice -msgid "Untaxed Amount To Invoice" -msgstr "Importe no tributable a facturar" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_invoiced -msgid "Untaxed Invoiced Amount" -msgstr "Importe facturado no tributable" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "UoM" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Update Prices" -msgstr "Precio Único" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__upselling -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__upselling -msgid "Upselling Opportunity" -msgstr "Oportunidad de venta adiccional" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__barcode -msgid "Use a barcode to identify this contact." -msgstr "Use un código de barras para identificar a este contacto." - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__shared_folio -msgid "Used to notify is the reservation folio has other reservations/services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__user_id -msgid "User who manages the reservation" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_res_users -msgid "Users" -msgstr "Usuarios" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__currency_id -msgid "Utility field to express amount currency" -msgstr "Campo de utilidad para expresar la cantidad de moneda" - -#. module: pms -#: model:room.closure.reason,name:pms.pms_room_closure_reason_1 -msgid "VIP Privacy" -msgstr "Privacidad VIP" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__valid_product_template_attribute_line_ids -msgid "Valid Product Attribute Lines" -msgstr "Líneas de atributo de producto válidas" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number__valid_from -msgid "Valid from" -msgstr "Válido desde" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_partner_id_number__valid_from -msgid "Validation period stating date." -msgstr "Fecha de inicio del período de validación." - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__value -msgid "Value" -msgstr "Valor" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_1920 -msgid "Variant Image" -msgstr "Imagen de Variante" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_1024 -msgid "Variant Image 1024" -msgstr "Imagen de Variante 1024" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_128 -msgid "Variant Image 128" -msgstr "Imagen de Variante128" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_256 -msgid "Variant Image 256" -msgstr "Imagen de Variante 256" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_512 -msgid "Variant Image 512" -msgstr "Imagen de Variante 512" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__price_extra -msgid "Variant Price Extra" -msgstr "Precio de variante extra" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__variant_seller_ids -msgid "Variant Seller" -msgstr "Vendedor de variantes" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_supplier_payment_term_id -msgid "Vendor Payment Terms" -msgstr "Términos/Condiciones de pago del proveedor" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__supplier_taxes_id -msgid "Vendor Taxes" -msgstr "Tasas del proveedor" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__seller_ids -msgid "Vendors" -msgstr "Proveedores" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "View Customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__volume -msgid "Volume" -msgstr "Volumen" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__volume_uom_name -msgid "Volume unit of measure label" -msgstr "Etiqueta de unidad de medida de volumen" - -#. module: pms -#: code:addons/pms/models/pms_service.py:0 -#, python-format -msgid "Warning for %s" -msgstr "Advertencia para %s" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__cardex_warning -msgid "Warning in Cardex" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__web -msgid "Web" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__website -msgid "Website Link" -msgstr "Enlace del sitio web" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__website_message_ids -msgid "Website Messages" -msgstr "Mensajes del sitio web" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__website_message_ids model:ir.model.fields,help:pms.field_pms_property__website_message_ids -#: model:ir.model.fields,help:pms.field_pms_reservation__website_message_ids model:ir.model.fields,help:pms.field_pms_room_type__website_message_ids -msgid "Website communication history" -msgstr "Historial de comunicación del sitio web" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Wednesday" -msgstr "Miércoles" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__weight -msgid "Weight" -msgstr "Peso" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__weight_uom_name -msgid "Weight unit of measure label" -msgstr "Etiqueta de unidad de medida de peso" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_4 -msgid "Wi-Fi" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_advanced_filters_wizard -msgid "Wizard for advanced filters" -msgstr "Asistente de filtros avanzados" - -#. module: pms -#: model:ir.model,name:pms.model_pms_massive_changes_wizard -msgid "Wizard for massive changes on Availability Plans & Pricelists." -msgstr "Asistente de cambios masivos en los Planes de Disponibilidad y las Tarifas." - -#. module: pms -#: code:addons/pms/wizards/wizard_advanced_filters.py:0 -#, python-format -msgid "You must add filters to perform the search" -msgstr "Debe añadir filtros para realizar la búsqueda" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "You must assign a customer name" -msgstr "Debes asignar un nombre a la reserva" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "ZIP" -msgstr "Código Postal" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__zip -msgid "Zip" -msgstr "Código Postal" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__is_shared_room -msgid "allows you to reserve units smaller than the room itself (eg beds)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__free_room_ids -msgid "" -"allows you to send different parameters in the context (checkin(required), checkout(required), room_type_id, ubication_id, capacity, amenity_ids and / or " -"pricelist_id) and return rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__availability -msgid "" -"allows you to send different parameters in the context (checkin(required), checkout(required), room_type_id, ubication_id, capacity,amenity_ids and / or " -"pricelist_id) check the availability for the hotel" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "" -"availability rules\n" -" will be overwritten:" -msgstr "" -"Reglas de disponibilidad\n" -" que van a ser sobre escritas:" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "booking agency with wrong configuration: " -msgstr "Agencia de reservas con configuración incorrecta: " - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_split_join_swap_wizard__checkout -msgid "checkout in reservation" -msgstr "Checkout reserba" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__birthdate_date -msgid "host birthdate" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__firstname -msgid "host firstname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__gender -msgid "host gender" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__lastname -msgid "host lastname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__nationality_id -msgid "host nationality" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__lastname2 -msgid "host second lastname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__state_id -msgid "host state" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__partner_incongruences -msgid "indicates that some partner fields on the checkin do not correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_incongruences -msgid "indicates that some partner fields on the folio do not correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_incongruences -msgid "indicates that some partner fields on the reservation do not correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "mobile" -msgstr "móvil" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "or" -msgstr "o" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__partner_incongruences -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_incongruences -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_incongruences -msgid "partner_incongruences" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_form -msgid "pms Room" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "" -"pricelist items\n" -" will be overwritten:" -msgstr "" -"items de la tarifa\n" -" serán sobrescritas:" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__channel_type -msgid "sales channel through which the service was sold.It can be 'door', 'mail', 'phone', 'call' or 'web'" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "" -"these are the billing information associated with the\n" -" booking client or the company (if a company is\n" -" assigned). If you want to bill an independent contact,\n" -" you can select it in the billing assistant" -msgstr "" -"Estes son los datos de facturación con el\n" -" cliente de la reserva o con la compañía(Si una compañía es\n" -" asignada). Si quiere facturar un contacto independiente,\n" -" puede seleccionarlo en el asistente de facturación" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_room_room_property_unique -msgid "you cannot have more than one room with the same name in the same property" -msgstr "" diff --git a/pms/i18n/pms.pot b/pms/i18n/pms.pot deleted file mode 100644 index d603f01fe..000000000 --- a/pms/i18n/pms.pot +++ /dev/null @@ -1,10260 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pms -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: pms -#: model:room.closure.reason,description:pms.pms_room_closure_reason_1 -msgid "" -"\n" -" Used for closing of rooms for extra privacy.\n" -" " -msgstr "" - -#. module: pms -#: model:room.closure.reason,description:pms.pms_room_closure_reason_0 -msgid "" -"\n" -" Used for closing of rooms which require a maintenance. You can specify\n" -" the reason in the own reservation.\n" -" " -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_count -msgid "# Product Variants" -msgstr "" - -#. module: pms -#: model:mail.template,subject:pms.confirmed_reservation_email -msgid "" -"${object.company_id.name} has confirmed your reservation in " -"${object.pms_property_id.name}" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__penalty_late -msgid "% Penalty Late" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__penalty_noshow -msgid "% Penalty No Show" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "%s is not a valid %s identifier" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_service_line.py:0 -#, python-format -msgid "%s limit exceeded for %s" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "%s not found in checkins (%s)" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation_line.py:0 -#, python-format -msgid "%s: No room available in %s <-> %s." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation_line.py:0 -#, python-format -msgid "%s: No room type available" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "&nbsp;on&nbsp;" -msgstr "" - -#. module: pms -#: model:ir.actions.report,print_report_name:pms.action_report_folio -#: model:ir.actions.report,print_report_name:pms.action_traveller_report -msgid "" -"(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or " -"'Order - %s' % (object.name)" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid ", at" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Days:" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Rules to apply:" -msgstr "" - -#. module: pms -#: model:mail.template,body_html:pms.precheckin_invitation_email -msgid "" -"
\n" -" Do your check-in now and save time.\n" -"
\n" -" Access our quick registration system. In a few steps you will be able to register your data in an agile, simple and secure way, avoiding queues at reception.\n" -" If you register your data in our system, your passage through reception will be much faster, being able to enjoy the comfort of your room right away.\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
Check-in\n" -"
\n" -"
\"Hacer
\n" -"
\n" -"
\n" -"
\n" -" " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "" -"\n" -" Room Type:\n" -" " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "" -" Reservations by folio: " -"" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Send message" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid " Cancelled Reservation!" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Download" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_page_payment -msgid " Pay Now" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_page_payment -msgid " Paid" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_page_payment -msgid " Pending" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -"" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid " Print" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid " OverBooking" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Status:" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "" -"\n" -" Your reservation in ${object.pms_property_id.name} has been modified\n" -" \n" -"
\n" -" See you soon,
\n" -" \n" -"
\n" -" ${object.company_id.name}\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
Reservation Details
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
\n" -"
From ${object.checkin} At ${object.arrival_hour}
\n" -"
To ${object.checkout} At ${object.departure_hour}
\n" -"
TZ ${object.pms_property_id.tz}
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
Room: ${object.room_type_id.name}
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
Price: ${object.price_total} ${object.pms_property_id.country_id.currency_id.symbol}
\n" -"
\n" -"
\n" -"
\n" -" % if object.pms_property_id.mail_information\n" -"
\n" -"
Additional Information
\n" -"

${object.pms_property_id.mail_information|safe}

\n" -" % endif\n" -"
\n" -"
\n" -"
\n" -" \n" -"
\n" -" Questions about the reservation?\n" -"
Please contact with us:
\n" -"
    \n" -"
  • ${object.pms_property_id.name}
  • \n" -" % if object.pms_property_id.partner_id.email\n" -"
  • Mail: ${object.pms_property_id.partner_id.email}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.phone\n" -"
  • Phone: ${object.pms_property_id.partner_id.phone}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.mobile\n" -"
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • \n" -" % endif\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" % if object.pms_property_id.privacy_policy\n" -" \n" -" \n" -"
\n" -" ${object.pms_property_id.privacy_policy|safe}\n" -"
\n" -" % endif\n" -" \n" -" \n" -" % if object.company_id\n" -" \n" -" \n" -"
\n" -" Sent by ${object.company_id.name}\n" -"
\n" -"
\n" -" % endif\n" -" \n" -" \n" -" " -msgstr "" - -#. module: pms -#: model:mail.template,body_html:pms.confirmed_reservation_email -msgid "" -"\n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" % if object.pms_property_id.partner_id.street\n" -"

${object.pms_property_id.partner_id.street}

\n" -" % endif\n" -" % if object.pms_property_id.partner_id.street2\n" -"

${object.pms_property_id.partner_id.street2}

\n" -" % endif\n" -"

${object.pms_property_id.partner_id.zip}

\n" -"

${object.pms_property_id.partner_id.city}

\n" -"

${object.pms_property_id.partner_id.country_id.name}

\n" -"
\n" -"
\n" -"
\n" -"
\n" -" Hello ${object.partner_id.name or ''},
\n" -" We are happy to confirm your reservation in ${object.pms_property_id.name}\n" -"
\n" -"
\n" -" See you soon,
\n" -" \n" -"
\n" -" ${object.company_id.name}\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
Reservation Details
\n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
\n" -"
From ${object.checkin} At ${object.arrival_hour}
\n" -"
To ${object.checkout} At ${object.departure_hour}
\n" -"
TZ ${object.pms_property_id.tz}
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
Room: ${object.room_type_id.name}
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
Price: ${object.price_room_services_set} ${object.pms_property_id.country_id.currency_id.symbol}
\n" -"
\n" -"
\n" -"
\n" -" % if object.pms_property_id.mail_information\n" -"
\n" -"
Additional Information
\n" -" ${object.pms_property_id.mail_information|safe}\n" -" % endif\n" -"
\n" -"
\n" -"
\n" -"
\n" -" Do your check-in now and save time.\n" -"
\n" -" Access our quick registration system. In a few steps you will be able to register your data in an agile, simple and secure way, avoiding queues at reception.\n" -" If you register your data in our system, your passage through reception will be much faster, being able to enjoy the comfort of your room right away.\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
Check-in\n" -"
\n" -"
\"Hacer
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -"
\n" -" Questions about the reservation?\n" -"
Please contact with us:
\n" -"
    \n" -"
  • ${object.pms_property_id.name}
  • \n" -" % if object.pms_property_id.partner_id.email\n" -"
  • Mail: ${object.pms_property_id.partner_id.email}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.phone\n" -"
  • Phone: ${object.pms_property_id.partner_id.phone}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.mobile\n" -"
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • \n" -" % endif\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" % if object.pms_property_id.privacy_policy\n" -" \n" -" \n" -"
\n" -" ${object.pms_property_id.privacy_policy|safe}\n" -"
\n" -" % endif\n" -"
\n" -" % if object.company_id\n" -" \n" -" \n" -"
\n" -" Sent by ${object.company_id.name}\n" -"
\n" -"
\n" -" % endif\n" -"
\n" -" " -msgstr "" - -#. module: pms -#: model:mail.template,body_html:pms.cancelled_reservation_email -msgid "" -"\n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" % if object.pms_property_id.partner_id.street\n" -"

${object.pms_property_id.partner_id.street}

\n" -" % endif\n" -" % if object.pms_property_id.partner_id.street2\n" -"

${object.pms_property_id.partner_id.street2}

\n" -" % endif\n" -"

${object.pms_property_id.partner_id.zip}

\n" -"

${object.pms_property_id.partner_id.city}

\n" -"

${object.pms_property_id.partner_id.country_id.name}

\n" -"
\n" -"
\n" -"
\n" -"
\n" -" Hello ${object.partner_id.name or ''},
\n" -" Your reservation at ${object.pms_property_id.name} has been successfully canceled.\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
If you have questions please contact with us:
\n" -"
    \n" -"
  • ${object.pms_property_id.name}
  • \n" -" % if object.pms_property_id.partner_id.email\n" -"
  • Mail: ${object.pms_property_id.partner_id.email}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.phone\n" -"
  • Phone: ${object.pms_property_id.partner_id.phone}
  • \n" -" % endif\n" -" % if object.pms_property_id.partner_id.mobile\n" -"
  • Mobile: ${object.pms_property_id.partner_id.mobile}
  • \n" -" % endif\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" % if object.pms_property_id.privacy_policy\n" -" \n" -" \n" -"
\n" -" ${object.pms_property_id.privacy_policy}\n" -"
\n" -" % endif\n" -"
\n" -" % if object.company_id\n" -" \n" -" \n" -"
\n" -" Sent by ${object.company_id.name}\n" -"
\n" -"
\n" -" % endif\n" -"
\n" -" " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "A customer/s has this email or mobile, do you want to add it?" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__description_sale -msgid "" -"A description of the Product that you want to communicate to your " -"customers. This description will be copied to every Sales Order, Delivery " -"Order and Customer Invoice/Credit Note" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__description_sale -msgid "" -"A description of the Product that you want to communicate to your customers." -" This description will be copied to every Sales Order, Delivery Order and " -"Customer Invoice/Credit Note" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "A journal must be specified for the acquirer %s." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "A payment acquirer is required to create a transaction." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__advance_payment_method -msgid "" -"A standard invoice is issued with all the order lines ready " -"for invoicing, according to their invoicing policy" -" (based on ordered or delivered quantity)." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__type -msgid "" -"A storable product is a product for which you manage stock. The Inventory app has to be installed.\n" -"A consumable product is a product for which stock is not managed.\n" -"A service is a non-material product you provide." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "A transaction can't be linked to folios having different currencies." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "A transaction can't be linked to folios having different partners." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__user_ids -msgid "Accepted Users" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__access_warning -#: model:ir.model.fields,field_description:pms.field_pms_folio__access_warning -#: model:ir.model.fields,field_description:pms.field_pms_reservation__access_warning -msgid "Access warning" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_account_payable_id -msgid "Account Payable" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_account_receivable_id -msgid "Account Receivable" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deposit_account_id -msgid "Account used for deposits" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__action -msgid "Action" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_needaction -#: model:ir.model.fields,field_description:pms.field_pms_property__message_needaction -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_needaction -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_needaction -msgid "Action Needed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__active -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__active -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__active -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__active -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__active -#: model:ir.model.fields,field_description:pms.field_pms_property__active -#: model:ir.model.fields,field_description:pms.field_pms_room__active -#: model:ir.model.fields,field_description:pms.field_pms_room_type__active -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__active -msgid "Active" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__active_lang_count -msgid "Active Lang Count" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_ids -msgid "Activities" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_exception_decoration -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_exception_decoration -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_exception_decoration -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_exception_decoration -msgid "Activity Exception Decoration" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_state -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_state -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_state -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_state -msgid "Activity State" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_type_icon -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_type_icon -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_type_icon -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_type_icon -msgid "Activity Type Icon" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.several_partners_wizard -msgid "Add Customer" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Add a note" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Add a product" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Add a section" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Add customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__is_add_code_room_name -msgid "Add in room name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Add to Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__additional_info -msgid "Additional info" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__mail_information -msgid "Additional information of the mail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__type -msgid "Address Type" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Aditional Mail Information" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__adults -msgid "Adults" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_advanced_filters_wizard -#: model:ir.ui.menu,name:pms.menu_pms_advanced_filters -msgid "Advanced Filters" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Advanced filters" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__moment__after -msgid "After" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__product_template__consumed_on__after -msgid "After night" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__age -msgid "Age" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_agency_action -#: model:ir.ui.menu,name:pms.pms_agency_menu -msgid "Agencies" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__agency_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__agency_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__agency_id -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Agency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__agency_id -#: model:ir.model.fields,help:pms.field_pms_reservation__agency_id -msgid "Agency that made the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_late__all -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_noshow__all -msgid "All Days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "All days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__lang -msgid "" -"All the emails and documents sent to this contact will be translated in this" -" language." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__allowed_method_ids -msgid "Allowed Method" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form -msgid "Allowed Properties" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__allowed_reservation_ids -msgid "Allowed Reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__allowed_room_ids -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__allowed_room_ids -msgid "Allowed Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__allowed_board_service_product_ids -msgid "Allowed board service products" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__allowed_board_service_room_type_ids -msgid "Allowed board service room types" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__allowed_cancel -msgid "Allowed cancel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__allowed_checkin -msgid "Allowed checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__allowed_checkout -msgid "Allowed checkout" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__allowed_pricelist_ids -msgid "Allowed pricelists" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__allowed_rooms_sources -msgid "Allowed rooms source" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__allowed_rooms_target -msgid "Allowed rooms target" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__allowed_board_services -msgid "Allowed services" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_board_service.py:0 -#, python-format -msgid "Already exists another Board Service with the same code and properties" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room_type_class.py:0 -#, python-format -msgid "" -"Already exists another room type class with the same code and properties" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room_type.py:0 -#, python-format -msgid "Already exists another room type with the same code and properties" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_action_pms_room_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Amenities" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__pms_amenity_ids -msgid "Amenities In This Category" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity_type__pms_amenity_ids -msgid "Amenities included in this type" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_amenity -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Amenity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__pms_amenity_type_id -msgid "Amenity Category" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__name -#: model:ir.model.fields,help:pms.field_pms_amenity__name -msgid "Amenity Name" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_amenity_type -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_amenity_type_view_form -msgid "Amenity Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__name -#: model:ir.model.fields,help:pms.field_pms_amenity_type__name -msgid "Amenity Type Name" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_action_pms_room_amenity_type_view_form -msgid "Amenity Types" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__amount -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__amount -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__amount -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__amount -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__amount -msgid "Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__commission_amount -msgid "Amount corresponding to commission" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__invoices_paid -msgid "Amount of invoices paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__time -msgid "Amount of time" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__day_qty -msgid "Amount to be consumed per day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Amounts" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__analytic_account_id -msgid "Analytic Account" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__analytic_tag_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__analytic_tag_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__analytic_tag_ids -msgid "Analytic Tags" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__analytic_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__analytic_line_ids -msgid "Analytic lines" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.product_pricelist_item_view_tree -msgid "Applicable on" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_all_week -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_all_week -msgid "Apply Availability Rule for the whole week" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_friday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_friday -msgid "Apply Availability Rule on fridays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_monday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_monday -msgid "Apply Availability Rule on mondays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_saturday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_saturday -msgid "Apply Availability Rule on saturdays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_sunday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_sunday -msgid "Apply Availability Rule on sundays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_thursday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_thursday -msgid "Apply Availability Rule on thursdays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_tuesday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_tuesday -msgid "Apply Availability Rule on tuesdays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_wednesday -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__apply_on_wednesday -msgid "Apply Availability Rule on wednesdays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__apply_pricelist -#: model:ir.model.fields,field_description:pms.field_res_partner__apply_pricelist -#: model:ir.model.fields,field_description:pms.field_res_users__apply_pricelist -msgid "Apply Pricelist" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Apply and close" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Apply and continue" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__by_default -msgid "Apply by Default" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_closed -msgid "Apply changes to Closed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_closed_arrival -msgid "Apply changes to Closed Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_closed_departure -msgid "Apply changes to Closed Departure" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_max_avail -msgid "Apply changes to Max. Avail." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_max_stay -msgid "Apply changes to Max. Stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_max_stay_arrival -msgid "Apply changes to Max. Stay Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_min_stay -msgid "Apply changes to Min. Stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_min_stay_arrival -msgid "Apply changes to Min. Stay Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_quota -msgid "Apply changes to Quota" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_pricelists_on -msgid "Apply pricelists on" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__arrival_delayed -msgid "Arrival Delayed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__default_arrival_hour -#: model:ir.model.fields,field_description:pms.field_pms_reservation__arrival_hour -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Arrival Hour" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__arrival_hour -msgid "Arrival Hour (HH:MM)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__pms_folio_ids -#: model:ir.model.fields,help:pms.field_res_partner__pms_folio_ids -#: model:ir.model.fields,help:pms.field_res_users__pms_folio_ids -msgid "Associated Folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__pms_checkin_partner_ids -#: model:ir.model.fields,help:pms.field_res_partner__pms_checkin_partner_ids -#: model:ir.model.fields,help:pms.field_res_users__pms_checkin_partner_ids -msgid "Associated checkin partners" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__pms_reservation_ids -#: model:ir.model.fields,help:pms.field_res_partner__pms_reservation_ids -#: model:ir.model.fields,help:pms.field_res_users__pms_reservation_ids -msgid "Associated reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__ubication_id -msgid "At which ubication the room is located." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_attachment_count -#: model:ir.model.fields,field_description:pms.field_pms_property__message_attachment_count -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_attachment_count -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_attachment_count -msgid "Attachment Count" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_template_attribute_value_ids -msgid "Attribute Values" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_company__privacy_policy -msgid "Authorization by the user for themanage of their personal data" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_canceled_auto_mail -msgid "Auto Send Cancellation Mail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_confirmed_auto_mail -msgid "Auto Send Confirmation Mail" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Auto Send Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_modified_auto_mail -msgid "Auto Send Modification Mail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__preconfirm -msgid "Auto confirm to Save" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__automated_actions_id -msgid "Automated Actions" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_automated_mails_tree -#: model:ir.ui.menu,name:pms.menu_pms_automated_mails -#: model_terms:ir.ui.view,arch_db:pms.pms_automated_mails_view -#: model_terms:ir.ui.view,arch_db:pms.view_automated_mails_tree -msgid "Automated Mails" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.autocheckout_reservations_ir_actions_server -#: model:ir.cron,cron_name:pms.autocheckout_reservations -#: model:ir.cron,name:pms.autocheckout_reservations -msgid "Automatic Checkout on past reservations" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_automated_mails -msgid "Automatic Mails" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.nocheckout_reservations_ir_actions_server -#: model:ir.cron,cron_name:pms.nocheckout_reservations -#: model:ir.cron,name:pms.nocheckout_reservations -msgid "Automatic No Checkout Reservations" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.noshow_reservations_ir_actions_server -#: model:ir.cron,cron_name:pms.noshow_reservations -#: model:ir.cron,name:pms.noshow_reservations -msgid "Automatic No Show Reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__avail_id -msgid "Avail record" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__avail_rule_ids -msgid "Avail record rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__avail_id -msgid "Availability Day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__availability_plan_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist__availability_plan_id -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__massive_changes_on__availability_plan -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "Availability Plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__name -msgid "Availability Plan Name" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.availability_plan_rule_view_tree_action -msgid "Availability Plan Rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__availability_plan_id -msgid "Availability Plan for which the pricelist is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__availability_plan_ids -msgid "Availability Plan to apply massive changes" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.reservation_availability_plan_rules_menu -#: model_terms:ir.ui.view,arch_db:pms.availability_plan_rule_view_form -#: model_terms:ir.ui.view,arch_db:pms.availability_view_tree -msgid "Availability Plans" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__availability_results -#: model:ir.model.fields,help:pms.field_pms_booking_engine__availability_results -msgid "Availability Results" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__rule_ids -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form -msgid "Availability Rules" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.availability_plan_rule_view_tree -msgid "Availability rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__pms_sale_channel_ids -msgid "Available Channels" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__num_rooms_available -msgid "Available rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__avail_readonly -msgid "Avialability Readonly" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__bank_account_count -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Bank" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_ids -msgid "Bank Payments" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_account_bank_statement -msgid "Bank Statement" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_account_bank_statement_line -msgid "Bank Statement Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__bank_ids -msgid "Banks" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__barcode -#: model:ir.model.fields,field_description:pms.field_pms_room_type__barcode -msgid "Barcode" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__moment__before -msgid "Before" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__product_template__consumed_on__before -msgid "Before night" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__bill_rooms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__bill_rooms -msgid "Bill Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__bill_services -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__bill_services -msgid "Bill Services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_invoice_ids -msgid "Billing addresses" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__partner_invoice_id -msgid "Billing contact" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Birth Date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__birthdate_date -#: model:ir.model.fields,field_description:pms.field_pms_property__birthdate_date -#: model:ir.model.fields,field_description:pms.field_res_partner__birthdate_date -#: model:ir.model.fields,field_description:pms.field_res_users__birthdate_date -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Birthdate" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_blacklisted -msgid "Blacklist" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__mobile_blacklisted -msgid "Blacklisted Phone Is Mobile" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__phone_blacklisted -msgid "Blacklisted Phone is Phone" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_board_service_room_type_view -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__is_board_service -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__pms_board_service_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pms_board_service_id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__board_service_room_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__board_service_room_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__board_service_room_type_id -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_report_view_tree -msgid "Board Service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__default_code -msgid "Board Service Code" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_board_service_form -#: model_terms:ir.ui.view,arch_db:pms.pms_board_service_room_type_form -msgid "Board Service Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__board_service_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__board_service_line_ids -msgid "Board Service Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__name -#: model:ir.model.fields,help:pms.field_pms_board_service__name -msgid "Board Service Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__board_price -#: model:ir.model.fields,field_description:pms.field_product_product__board_price -msgid "Board Service Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__pms_board_service_room_type_id -msgid "Board Service Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__pms_board_service_room_type_id -msgid "Board Service Room Type in which this line is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__pms_board_service_id -msgid "Board Service corresponding to this Board Service Room Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_line__pms_board_service_id -msgid "Board Service in which this line is included" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_board_service_room_type -msgid "Board Service included in Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__board_service_room_type_ids -msgid "Board Service included in room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__board_service_room_id -#: model:ir.model.fields,help:pms.field_pms_reservation__board_service_room_id -msgid "Board Service included in the room" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_board_service_form_tree -#: model:ir.model,name:pms.model_pms_board_service -#: model:ir.model.fields,field_description:pms.field_pms_room_type__board_service_room_type_ids -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__apply_pricelists_on__board_services -#: model:ir.ui.menu,name:pms.menu_open_pms_board_service_form_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_board_service_view_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Board Services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__pms_board_service_room_type_ids -msgid "Board Services Room Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__pms_board_service_room_type_ids -msgid "" -"Board Services Room Type corresponding to this Board Service,One board " -"service for several room types" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__board_service -msgid "Board service" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_folio_changes.py:0 -#, python-format -msgid "Board service has been changed from folio" -msgstr "" - -#. module: pms -#. openerp-web -#: code:addons/pms/static/src/xml/reservation_group_button_views.xml:0 -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__booking_engine_id -#: model:ir.ui.menu,name:pms.menu_pms_booking_engine -#, python-format -msgid "Booking Engine" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_booking_engine -msgid "Booking engine" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__message_bounce -msgid "Bounce" -msgstr "" - -#. module: pms -#: model:pms.board.service,name:pms.pms_board_service_0 -msgid "BreakFast" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_0 -#: model:product.template,name:pms.pms_service_0_product_template -msgid "Breakfast Buffet" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "By Day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "By Month" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "By Week" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "CIF:" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__call -msgid "Call Center" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__can_image_1024_be_zoomed -msgid "Can Image 1024 be zoomed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__can_image_variant_1024_be_zoomed -msgid "Can Variant Image 1024 be zoomed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__purchase_ok -msgid "Can be Purchased" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_ok -msgid "Can be Sold" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__can_create_folio -msgid "Can create folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -#: model_terms:ir.ui.view,arch_db:pms.several_partners_wizard -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -#: model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form -msgid "Cancel" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Cancel Folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Cancel Reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__cancel_discount -msgid "Cancelation Discount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__cancel_discount -msgid "Cancelation Discount (%)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__cancelation_rule_id -msgid "Cancelation Policy" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__cancelation_rule_id -msgid "Cancelation Policy included in the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__name -msgid "Cancelation Rule" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_cancelation_rule -#: model:ir.model,name:pms.model_pms_cancelation_rule -#: model:ir.ui.menu,name:pms.menu_pms_cancelation_rule -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_view_tree -msgid "Cancelation Rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_canceled_template -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Cancellation Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_canceled_template -msgid "Cancellation email template" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__cancel -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__cancel -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__cancel -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Cancelled" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Cancelled Rooms" -msgstr "" - -#. module: pms -#: code:addons/pms/models/ir_config_parameter.py:0 -#, python-format -msgid "Cannot delete this parameter" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__capacity -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_kanban -msgid "Capacity" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.company_view_form -msgid "Cardex Settings" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Cash" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__statement_line_ids -msgid "Cash Payments" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__cancelled_reason -msgid "Cause of cancelled" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_room_closure_reason -#: model:ir.model.fields,field_description:pms.field_pms_reservation__out_service_description -msgid "Cause of out of service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Change" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__channel_type_id -msgid "Channel Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__channel_ids -msgid "Channels" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__check_adults -msgid "Check Adults" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__checkin -msgid "Check In" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkout -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__checkout -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Check Out" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__is_company -msgid "Check if the contact is a company, otherwise it is a person" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__employee -msgid "Check this box if this contact is an Employee." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Check-in hours" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__checkin -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__checkin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__pending_checkin_data -#: model:ir.model.fields,field_description:pms.field_pms_reservation__pending_checkin_data -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Checkin Data" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Checkin Date" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkin Detail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__checkin_partner_id -msgid "Checkin Partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__email -msgid "Checkin Partner Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__identifier -msgid "Checkin Partner Id" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__image_128 -msgid "Checkin Partner Image, it corresponds with Partner Image associated" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__mobile -msgid "Checkin Partner Mobile" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__checkin_partner_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_checkin_partner_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_checkin_partner_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_checkin_partner_ids -msgid "Checkin Partners" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_pending_count -msgid "Checkin Pending Num" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__checkin_sequence_id -msgid "Checkin Sequence" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkin by" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkin by Day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkin by Month" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkin by Week" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_count -msgid "Checkin counter" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__checkin -msgid "Checkin date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_split_join_swap_wizard__checkin -msgid "Checkin in reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__arrival -msgid "Checkin partner arrival date and time" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__departure -msgid "Checkin partner departure date and time" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__name -msgid "Checkin partner name" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#: model:ir.actions.act_window,name:pms.action_checkin_partner -#: model:ir.ui.menu,name:pms.menu_pms_checkin_partner -#, python-format -msgid "Checkins" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkins Today" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkins Tomorrow" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkins to 7 days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__checkout -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__checkout -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Checkout" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Checkout by" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkout by Day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkout by Month" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Checkout by Week" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__checkout -msgid "Checkout date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__child_avail_ids -msgid "Child Avails" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__child_ids -msgid "Child Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__child_avail_ids -msgid "Child availabilities for this availability" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__child_ids -msgid "Child rooms of the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__children -msgid "Children" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__children_occupying -msgid "Children occupying" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.several_partners_wizard -msgid "Choose a customer if you want to add it to the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__city -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "City" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__name -msgid "Class Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__class_id -msgid "Class to which the room type belongs" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_payment -msgid "Close" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__closed -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed -msgid "Closed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__closed_arrival -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed_arrival -msgid "Closed Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__closed_departure -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed_departure -msgid "Closed Departure" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__closure_reason_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__closure_reason_id -msgid "Closure Reason" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_pms_room_closure_reason_form_tree -msgid "Closure Reasons" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Closure reason" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_code -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__default_code -msgid "Code" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__color -#: model:ir.model.fields,field_description:pms.field_pms_room_type__color -msgid "Color Index" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__combination_indices -msgid "Combination Indices" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Comments about the customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__commercial_partner_id -msgid "Commercial Entity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__commission -#: model:ir.model.fields,field_description:pms.field_pms_property__default_commission -#: model:ir.model.fields,field_description:pms.field_res_partner__default_commission -#: model:ir.model.fields,field_description:pms.field_res_users__default_commission -msgid "Commission" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Commission Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__commission_amount -msgid "Commission amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__commission_percent -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Commission percent (%)" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_res_company -msgid "Companies" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__ref_company_ids -msgid "Companies that refers to partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement__company_id -#: model:ir.model.fields,field_description:pms.field_account_journal__company_id -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__company_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__company_id -#: model:ir.model.fields,field_description:pms.field_pms_property__company_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__company_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__company_id -#: model:ir.model.fields,field_description:pms.field_pms_service__company_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist__company_id -#: model:ir.model.fields,field_description:pms.field_product_product__company_id -#: model:ir.model.fields,field_description:pms.field_product_template__company_id -#: model:ir.model.fields,field_description:pms.field_res_partner__company_id -msgid "Company" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__company_name -msgid "Company Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__commercial_company_name -msgid "Company Name Entity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__company_type -msgid "Company Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_gid -msgid "Company database ID" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__company_id -msgid "Company to which the pricelist belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__company_id -msgid "Company to which the reservation belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__company_id -msgid "Company to which the service belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__contact_address -msgid "Complete Address" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__ratio_checkin_data -msgid "Complete cardex" -msgstr "" - -#. module: pms -#: model:pms.room.type.class,name:pms.pms_room_type_class_1 -msgid "Conference" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_4 -#: model:product.product,name:pms.pms_room_type_4_product_product -msgid "Conference Room" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_configuration_menu -msgid "Configuration" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Confirm" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "" -"Confirm\n" -" " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -msgid "" -"Confirm\n" -" " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Confirm Assigned Room" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Confirm Sale" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__confirmation_date -msgid "Confirmation Date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_confirmed_template -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Confirmation Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_confirmed_template -msgid "Confirmation email template" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__confirm -msgid "Confirmed" -msgstr "" - -#. module: pms -#: model:pms.amenity.type,name:pms.pms_amenity_type_1 -msgid "Connectivity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__consumed_on -#: model:ir.model.fields,field_description:pms.field_product_product__consumed_on -#: model:ir.model.fields,field_description:pms.field_product_template__consumed_on -msgid "Consumed" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__date_types__consumption_dates -msgid "Consumption Dates" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_res_partner -#: model:ir.model.fields,field_description:pms.field_pms_property__child_ids -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Contact" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -msgid "Contact Details" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Contact Invoiced" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Contact image" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_contacts_menu -msgid "Contacts" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__standard_price -msgid "Cost" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__cost_currency_id -msgid "Cost Currency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__payment_token_count -msgid "Count Payment Token" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__message_bounce -msgid "Counter of the number of bounced emails for this contact" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__country_id -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Country" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__state_id -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Country State" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Create Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__advance_payment_method -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "Create Invoice" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "Create and View Invoice" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Create by" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Create by Day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Create by Month" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Create by Week" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_view_folio_advance_payment_inv -msgid "Create invoices" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Created By" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__create_uid -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_amenity__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_folio__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_property__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_room__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_room_type__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_service__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_service_line__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_ubication__create_uid -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__create_uid -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__create_uid -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__create_uid -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__create_uid -msgid "Created by" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__create_date -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__create_date -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__create_date -#: model:ir.model.fields,field_description:pms.field_pms_amenity__create_date -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__create_date -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__create_date -#: model:ir.model.fields,field_description:pms.field_pms_availability__create_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__create_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__create_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service__create_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__create_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__create_date -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__create_date -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__create_date -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__create_date -#: model:ir.model.fields,field_description:pms.field_pms_folio__create_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__create_date -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__create_date -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__create_date -#: model:ir.model.fields,field_description:pms.field_pms_property__create_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation__create_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__create_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__create_date -#: model:ir.model.fields,field_description:pms.field_pms_room__create_date -#: model:ir.model.fields,field_description:pms.field_pms_room_type__create_date -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__create_date -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__create_date -#: model:ir.model.fields,field_description:pms.field_pms_service__create_date -#: model:ir.model.fields,field_description:pms.field_pms_service_line__create_date -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__create_date -#: model:ir.model.fields,field_description:pms.field_pms_ubication__create_date -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__create_date -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__create_date -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__create_date -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__create_date -msgid "Created on" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Creation Date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__credit_card_details -#: model:ir.model.fields,field_description:pms.field_pms_reservation__credit_card_details -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Credit Card Details" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__credit_limit -msgid "Credit Limit" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__currency_id -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_property__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_service__currency_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__currency_id -msgid "Currency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__currency_id -msgid "Currency used in invoices" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Current Booking" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form -msgid "Current Property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__partner_id -msgid "Current property" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Current state of this reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_custom_attribute_value_ids -msgid "Custom Values" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_move_line__name_changed_by_user -msgid "Custom label" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__folio_partner_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_id -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__email -#: model:ir.model.fields,help:pms.field_pms_reservation__email -msgid "Customer E-mail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__mobile -#: model:ir.model.fields,help:pms.field_pms_reservation__mobile -msgid "Customer Mobile" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_name -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_name -msgid "Customer Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_payment_term_id -msgid "Customer Payment Terms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__access_url -#: model:ir.model.fields,help:pms.field_pms_folio__access_url -#: model:ir.model.fields,help:pms.field_pms_reservation__access_url -msgid "Customer Portal URL" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__customer_rank -msgid "Customer Rank" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__partner_ref -msgid "Customer Ref" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__client_order_ref -msgid "Customer Reference" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__deposit_taxes_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__taxes_id -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Customer Taxes" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_customer_action -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__possible_existing_customer_ids -#: model:ir.ui.menu,name:pms.pms_customer_meu -msgid "Customers" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__product_pricelist__pricelist_type__daily -msgid "Daily Plan" -msgstr "" - -#. module: pms -#: code:addons/pms/models/product_pricelist.py:0 -#, python-format -msgid "" -"Daily Plan must have fixed price, only one property and its items must be " -"daily" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__daily_limit -#: model:ir.model.fields,field_description:pms.field_product_product__daily_limit -#: model:ir.model.fields,field_description:pms.field_product_template__daily_limit -msgid "Daily limit" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__pending_checkin_data -msgid "Data missing at checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__date_order -#: model:ir.model.fields,field_description:pms.field_pms_availability__date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__date -#: model:ir.model.fields,field_description:pms.field_pms_property__date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__date -#: model:ir.model.fields,field_description:pms.field_pms_service_line__date -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__date -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__date -msgid "Date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__date_order -msgid "Date Order" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__checkout -msgid "Date Reservation ends" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__checkin -msgid "Date Reservation starts " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__date -msgid "Date for which availability applies" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__date -msgid "Date for which availability rule applies" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_expedition_date -msgid "Date on which document_type was issued" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__date_order -msgid "Date on which folio is sold" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__confirmation_date -msgid "Date on which the folio is confirmed." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__date_types -msgid "Date types" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__time_type__day -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_tree -msgid "Days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_intime -msgid "Days Late" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__apply_on_late -msgid "" -"Days on which the cancelation rule applies when the reason is late arrival. " -"Can be first, all days or specify the days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__apply_on_noshow -msgid "" -"Days on which the cancelation rule applies when the reason is no show. Can " -"be first, all days or specify the days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__deduct_down_payments -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deduct_down_payments -msgid "Deduct down payments" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_max_avail -msgid "Default Max. Availability" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_res_users__pms_property_id -msgid "Default Property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_quota -msgid "Default Quota" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__default_commission -#: model:ir.model.fields,help:pms.field_res_partner__default_commission -#: model:ir.model.fields,help:pms.field_res_users__default_commission -msgid "Default commission" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__supplier_taxes_id -msgid "Default taxes used when buying the product." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__taxes_id -msgid "Default taxes used when selling the product." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__uom_id -msgid "Default unit of measure used for all stock operations." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__uom_po_id -msgid "" -"Default unit of measure used for purchase orders. It must be in the same " -"category as the default unit of measure." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__seller_ids -msgid "Define vendor pricelists." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__trust -msgid "Degree of trust you have in this debtor" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__default_departure_hour -#: model:ir.model.fields,field_description:pms.field_pms_reservation__departure_hour -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Departure Hour" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__departure_hour -msgid "Departure Hour (HH:MM)" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Departure date (%s) is prior to arrival on %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__departure_delayed -msgid "Departure delayed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__name -#: model:ir.model.fields,field_description:pms.field_pms_room_type__description -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__description -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Description" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__name -msgid "Description of folio sale line" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Descriptions" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Detail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__credit_card_details -msgid "Details of partner credit card" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__active -msgid "Determines if amenity is active" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity_type__active -msgid "Determines if amenity type is active" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__active -msgid "Determines if cancelation rule is active" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__active -msgid "Determines if room is active" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_num_rooms_selection -msgid "Dinamic Selection based on avails room" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_5 -#: model:product.template,name:pms.pms_service_5_product_template -msgid "Dinner" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_sale_channel__channel_type__direct -msgid "Direct" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__channel_type_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__channel_type_id -msgid "Direct Sale Channel" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Disc.%" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__discount -msgid "Discount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__discount -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__discount -#: model:ir.model.fields,field_description:pms.field_pms_service_line__discount -msgid "Discount (%)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__discount -#: model:ir.model.fields,field_description:pms.field_pms_service__discount -msgid "Discount (€)" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Discount Room" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Discount Services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__discount -msgid "Discount in the price of the service." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__discount -msgid "Discount of total price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__discount -msgid "Discount of total price in folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__discount -msgid "Discount of total price in reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__discount -msgid "Discount that be applied in total price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement__display_name -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__display_name -#: model:ir.model.fields,field_description:pms.field_account_journal__display_name -#: model:ir.model.fields,field_description:pms.field_account_move__display_name -#: model:ir.model.fields,field_description:pms.field_account_move_line__display_name -#: model:ir.model.fields,field_description:pms.field_account_payment__display_name -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__display_name -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__display_name -#: model:ir.model.fields,field_description:pms.field_ir_config_parameter__display_name -#: model:ir.model.fields,field_description:pms.field_ir_http__display_name -#: model:ir.model.fields,field_description:pms.field_mail_compose_message__display_name -#: model:ir.model.fields,field_description:pms.field_payment_transaction__display_name -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__display_name -#: model:ir.model.fields,field_description:pms.field_pms_amenity__display_name -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__display_name -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__display_name -#: model:ir.model.fields,field_description:pms.field_pms_availability__display_name -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__display_name -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__display_name -#: model:ir.model.fields,field_description:pms.field_pms_board_service__display_name -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__display_name -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__display_name -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__display_name -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__display_name -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__display_name -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__display_name -#: model:ir.model.fields,field_description:pms.field_pms_folio__display_name -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__display_name -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__display_name -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__display_name -#: model:ir.model.fields,field_description:pms.field_pms_property__display_name -#: model:ir.model.fields,field_description:pms.field_pms_reservation__display_name -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__display_name -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__display_name -#: model:ir.model.fields,field_description:pms.field_pms_room__display_name -#: model:ir.model.fields,field_description:pms.field_pms_room_type__display_name -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__display_name -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__display_name -#: model:ir.model.fields,field_description:pms.field_pms_service__display_name -#: model:ir.model.fields,field_description:pms.field_pms_service_line__display_name -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__display_name -#: model:ir.model.fields,field_description:pms.field_pms_ubication__display_name -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__display_name -#: model:ir.model.fields,field_description:pms.field_product_pricelist__display_name -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__display_name -#: model:ir.model.fields,field_description:pms.field_product_product__display_name -#: model:ir.model.fields,field_description:pms.field_product_template__display_name -#: model:ir.model.fields,field_description:pms.field_res_company__display_name -#: model:ir.model.fields,field_description:pms.field_res_partner__display_name -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number__display_name -#: model:ir.model.fields,field_description:pms.field_res_users__display_name -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__display_name -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__display_name -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__display_name -msgid "Display Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__display_type -msgid "Display Type" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Doc. Expedition Date/Doc. Validity Date" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Doc. Number" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Doc. Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__document_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__document_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__document_id -msgid "Document" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__document_number -#: model:ir.model.fields,field_description:pms.field_pms_folio__document_number -#: model:ir.model.fields,field_description:pms.field_pms_reservation__document_number -msgid "Document Number" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__document_type -#: model:ir.model.fields,field_description:pms.field_pms_folio__document_type -#: model:ir.model.fields,field_description:pms.field_pms_reservation__document_type -msgid "Document Type" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Document number" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Document number:" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Document_type has already exists" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_domain -msgid "Domain" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__door -msgid "Door" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_2 -#: model:product.product,name:pms.pms_room_type_2_product_product -msgid "Double" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "Down Payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__amount -msgid "Down Payment Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__fixed_amount -msgid "Down Payment Amount (Fixed)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__product_id -msgid "Down Payment Product" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "Down Payment: %s" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Down Payments" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__fixed -msgid "Down payment (fixed amount)" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__percentage -msgid "Down payment (percentage)" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "Down payment of %s%%" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__is_downpayment -msgid "" -"Down payments are made when creating invoices from a folio. They are not " -"copied when duplicating a folio." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "Download" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Draft" -msgstr "" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_driving_license -msgid "Driving License" -msgstr "" - -#. module: pms -#. openerp-web -#: code:addons/pms/static/src/xml/pms_base_templates.xml:0 -#, python-format -msgid "Dropdown menu" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation_line.py:0 -#, python-format -msgid "Duplicated reservation line date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__email -#: model:ir.model.fields,field_description:pms.field_pms_folio__email -#: model:ir.model.fields,field_description:pms.field_pms_reservation__email -msgid "E-mail" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_0 -#: model:product.product,name:pms.pms_room_type_0_product_product -msgid "Economic" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__partner_share -msgid "" -"Either customer (not a user), either shared user. Indicated the current " -"partner is a customer without access or with a limited access created for " -"sharing data." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__email -#: model:ir.model.fields,field_description:pms.field_res_partner__email -#: model:ir.model.fields,field_description:pms.field_res_users__email -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Email" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Email Configuration" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Email Templates" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_mail_compose_message -msgid "Email composition wizard" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__employee -msgid "Employee" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__date_end_consumption -msgid "End Date Consumption" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__end_date -msgid "End date for creation of reservations and folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__date_end_consumption -msgid "End date to apply daily pricelist items" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__arrival -msgid "Enter" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Entry date" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "" -"Error when evaluating the id_category validation code::\n" -" %s \n" -"(%s)" -msgstr "" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_european_residence -msgid "European Residence permit" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_datetime -msgid "Exact Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkout_datetime -msgid "Exact Departure" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__departure -msgid "Exit" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Exit date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__document_expedition_date -msgid "Expedition Date" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Expedition date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__property_account_expense_id -msgid "Expense Account" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__expense_policy -msgid "" -"Expenses and vendor bills can be re-invoiced to a customer.With this option," -" a validated expense can be re-invoice to a customer at its cost or sales " -"price." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_room_closure_reason__description -msgid "Explanation of the reason for closing a room" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_1 -#: model:product.template,name:pms.pms_service_1_product_template -msgid "Extra Bed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__extra_beds_allowed -msgid "Extra Beds Allowed" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Extra Service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Extra Services" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "Extra beds can't be greater than allowed beds for this room" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__gender__female -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Female" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__cancelled_reason -msgid "" -"Field indicating type of cancellation. It can be 'late', 'intime' or " -"'noshow'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__user_ids -msgid "Field related to res.users. Allowed users on the property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__splitted -msgid "" -"Field that indicates if the reservation is split. A reservation is split " -"when guests don't sleep in the same room every night" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__ratio_checkin_data -msgid "" -"Field that stores the number of checkin partners pending to checkin (with " -"the state = draft)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__reservation_order -msgid "Field to order by reservation id" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__date_order -msgid "Field to order by service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__service_order -msgid "Field to order by service id" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__sequence -msgid "" -"Field used to change the position of the room type classes in tree view." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__sequence -msgid "Field used to change the position of the room types in tree view." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__sequence -msgid "" -"Field used to change the position of the rooms in tree view.Changing the " -"position changes the sequence" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_ubication__sequence -msgid "" -"Field used to change the position of the ubications in tree view.Changing " -"the position changes the sequence" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__checkin_sequence_id -msgid "Field used to create the name of the checkin partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__phone_sanitized -msgid "" -"Field used to store sanitized phone number. Helps speeding up searches and " -"comparisons." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Filters" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_late__first -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_noshow__first -msgid "First Day" -msgstr "" - -#. module: pms -#: model:pms.ubication,name:pms.pms_ubication_1 -msgid "First Floor" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__first_checkin -msgid "First Folio Checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__firstname -msgid "First Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__firstname -#: model:ir.model.fields,field_description:pms.field_res_partner__firstname -#: model:ir.model.fields,field_description:pms.field_res_users__firstname -msgid "First name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__fiscal_position_id -#: model:ir.model.fields,field_description:pms.field_pms_property__property_account_position_id -msgid "Fiscal Position" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_folio1_form_tree_all -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__folio_id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__folio_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_id -#: model:ir.model.fields,field_description:pms.field_pms_service__folio_id -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__folio_id -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__folio_id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__folio_id -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree -msgid "Folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -msgid "Folio #" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_folio_advance_payment_inv -msgid "Folio Advance Payment Invoice" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_folio_changes -#: model:ir.model,name:pms.model_wizard_folio_changes -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Folio Changes" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Folio Form" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_move_line__folio_line_ids -msgid "Folio Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__name -msgid "Folio Number" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_tree -msgid "Folio Pending Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__folio_id -msgid "Folio Reference" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_folio_sale_line -msgid "Folio Sale Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__folio_sequence_id -msgid "Folio Sequence" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__state -msgid "Folio Status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__booking_engine_id -msgid "Folio Wizard ID" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__note -msgid "Folio billing terms and conditions" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_booking_engine -msgid "Folio creation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__folio_id -msgid "Folio in which are included new reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__folio_id -msgid "Folio in which the service is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__move_ids -msgid "Folio invoices related to account move." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__name -msgid "" -"Folio name. When creating a folio the name is automatically formed with a " -"sequence" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__move_line_ids -msgid "Folio payments" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__invoice_lines -msgid "Folio sale line invoice lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__state -msgid "" -"Folio status; it can be Quotation, Quotation Sent, Confirmed, Locked or " -"Cancelled" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__folio_id -msgid "Folio to which folio sale line belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__folio_id -msgid "Folio to which reservation of checkin partner belongs" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_partner_folios -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__folio_ids -#: model:ir.model.fields,field_description:pms.field_account_move__folio_ids -#: model:ir.model.fields,field_description:pms.field_account_move_line__folio_ids -#: model:ir.model.fields,field_description:pms.field_account_payment__folio_ids -#: model:ir.model.fields,field_description:pms.field_payment_transaction__folio_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_folio_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_folio_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_folio_ids -#: model:ir.ui.menu,name:pms.pms_folio_menu -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_pivot -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folios -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_folio -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Folios" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Folios related with this contact" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_move__folio_ids -msgid "Folios where the account move are included" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_folio -msgid "Folios/" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_follower_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__message_follower_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_follower_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_follower_ids -msgid "Followers" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_channel_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__message_channel_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_channel_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_channel_ids -msgid "Followers (Channels)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_partner_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__message_partner_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_partner_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_partner_ids -msgid "Followers (Partners)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_type_icon -#: model:ir.model.fields,help:pms.field_pms_property__activity_type_icon -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_type_icon -#: model:ir.model.fields,help:pms.field_pms_room_type__activity_type_icon -msgid "Font awesome icon e.g. fa-tasks" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_journal__allowed_pms_payments -msgid "For manual payments" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_property.py:0 -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Format Arrival Hour (HH:MM) Error: %s" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_property.py:0 -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Format Departure Hour (HH:MM) Error: %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__email_formatted -msgid "Format email address \"Name \"" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__email_formatted -msgid "Formatted Email" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_6 -#: model:product.template,name:pms.pms_service_6_product_template -msgid "Free Bar" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Friday" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__start_date -msgid "From" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__start_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkin -msgid "From:" -msgstr "" - -#. module: pms -#: model:pms.board.service,name:pms.pms_board_service_2 -msgid "FullBoard" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__invoiced -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__invoiced -msgid "Fully Invoiced" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Future" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__gender -#: model:ir.model.fields,field_description:pms.field_pms_property__gender -#: model:ir.model.fields,field_description:pms.field_res_partner__gender -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Gender" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "General Info" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "General Information" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__quota -#: model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__quota -msgid "Generic Quota assigned." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_latitude -msgid "Geo Latitude" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_longitude -msgid "Geo Longitude" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_folio_view_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_reservation_view_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_tree -msgid "Get in" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__board_price -#: model:ir.model.fields,help:pms.field_product_product__board_price -msgid "Get price on board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__packaging_ids -msgid "Gives the different ways to package the same product." -msgstr "" - -#. module: pms -#: model:pms.ubication,name:pms.pms_ubication_0 -msgid "Ground Floor" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Group By" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_search -msgid "Group By..." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Guest" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_requests -msgid "Guest requests" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_ids -msgid "Guests who will occupy the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__default_arrival_hour -#: model:ir.model.fields,help:pms.field_pms_property__default_departure_hour -msgid "HH:mm Format" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_ir_http -msgid "HTTP Routing" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_2 -msgid "Hair Dryer" -msgstr "" - -#. module: pms -#: model:pms.board.service,name:pms.pms_board_service_1 -msgid "Half Board" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_6 -msgid "Half-sized Refrigerator" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__has_folios_outstanding -#: model:ir.model.fields,field_description:pms.field_account_move__has_folios_outstanding -#: model:ir.model.fields,field_description:pms.field_account_payment__has_folios_outstanding -msgid "Has Folios Outstanding" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__show_update_pricelist -msgid "Has Pricelist Changed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__has_unreconciled_entries -msgid "Has Unreconciled Entries" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__has_down_payments -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__has_down_payments -msgid "Has down payments" -msgstr "" - -#. module: pms -#: model:mail.template,subject:pms.precheckin_invitation_email -msgid "" -"Hi ${object.firstname}, do your check-in now in " -"${object.pms_property_id.name}" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Hide Strangers" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_3 -msgid "High speed Wired Internet access" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_1 -msgid "High-quality Shampoo and Soap Essential Herbs" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "History" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Host" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_number -msgid "Host document number" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Hosted's Name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_graph -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_pivot -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_calendar -msgid "Hosts" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__time_type__hour -msgid "Hour" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement__id -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__id -#: model:ir.model.fields,field_description:pms.field_account_journal__id -#: model:ir.model.fields,field_description:pms.field_account_move__id -#: model:ir.model.fields,field_description:pms.field_account_move_line__id -#: model:ir.model.fields,field_description:pms.field_account_payment__id -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__id -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__id -#: model:ir.model.fields,field_description:pms.field_ir_config_parameter__id -#: model:ir.model.fields,field_description:pms.field_ir_http__id -#: model:ir.model.fields,field_description:pms.field_mail_compose_message__id -#: model:ir.model.fields,field_description:pms.field_payment_transaction__id -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_amenity__id -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__id -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__id -#: model:ir.model.fields,field_description:pms.field_pms_availability__id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__id -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__id -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__id -#: model:ir.model.fields,field_description:pms.field_pms_folio__id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__id -#: model:ir.model.fields,field_description:pms.field_pms_property__id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_room__id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__id -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__id -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__id -#: model:ir.model.fields,field_description:pms.field_pms_service__id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__id -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__id -#: model:ir.model.fields,field_description:pms.field_pms_ubication__id -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__id -#: model:ir.model.fields,field_description:pms.field_product_pricelist__id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__id -#: model:ir.model.fields,field_description:pms.field_product_product__id -#: model:ir.model.fields,field_description:pms.field_product_template__id -#: model:ir.model.fields,field_description:pms.field_res_company__id -#: model:ir.model.fields,field_description:pms.field_res_partner__id -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number__id -#: model:ir.model.fields,field_description:pms.field_res_users__id -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__id -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__id -msgid "ID" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__im_status -msgid "IM Status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_exception_icon -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_exception_icon -msgid "Icon" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_exception_icon -#: model:ir.model.fields,help:pms.field_pms_property__activity_exception_icon -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_exception_icon -#: model:ir.model.fields,help:pms.field_pms_room_type__activity_exception_icon -msgid "Icon to indicate an exception activity." -msgstr "" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_identification_document -msgid "Identification Document" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__id_numbers -msgid "Identification Numbers" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_code -msgid "Identification code for a room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__identifier -msgid "Identifier" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "" -"If a Folio is done, you cannot modify it manually anymore. However, you will" -" still be able to invoice. This is used to freeze the Folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_needaction -#: model:ir.model.fields,help:pms.field_pms_folio__message_unread -#: model:ir.model.fields,help:pms.field_pms_property__message_needaction -#: model:ir.model.fields,help:pms.field_pms_property__message_unread -#: model:ir.model.fields,help:pms.field_pms_reservation__message_needaction -#: model:ir.model.fields,help:pms.field_pms_reservation__message_unread -#: model:ir.model.fields,help:pms.field_pms_room_type__message_needaction -#: model:ir.model.fields,help:pms.field_pms_room_type__message_unread -msgid "If checked, new messages require your attention." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_has_error -#: model:ir.model.fields,help:pms.field_pms_folio__message_has_sms_error -#: model:ir.model.fields,help:pms.field_pms_property__message_has_error -#: model:ir.model.fields,help:pms.field_pms_property__message_has_sms_error -#: model:ir.model.fields,help:pms.field_pms_reservation__message_has_error -#: model:ir.model.fields,help:pms.field_pms_reservation__message_has_sms_error -#: model:ir.model.fields,help:pms.field_pms_room_type__message_has_error -#: model:ir.model.fields,help:pms.field_pms_room_type__message_has_sms_error -msgid "If checked, some messages have a delivery error." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__team_id -msgid "" -"If set, this Sales Team will be used for sales and assignments related to " -"this partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__is_blacklisted -msgid "" -"If the email address is on the blacklist, the contact won't receive mass " -"mailing anymore, from any list" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__phone_sanitized_blacklisted -msgid "" -"If the sanitized phone number is on the blacklist, the contact won't receive" -" mass mailing sms anymore, from any list" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__active -msgid "" -"If unchecked, it will allow you to hide the Availability plan without " -"removing it." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__active -msgid "" -"If unchecked, it will allow you to hide the product without removing it." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__active -msgid "If unchecked, it will allow you to hide the room type" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#, python-format -msgid "" -"If we store your payment information on our server, subscription payments " -"will be made automatically." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__image_128 -#: model:ir.model.fields,field_description:pms.field_pms_property__image_1920 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_1920 -msgid "Image" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_1024 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_1024 -msgid "Image 1024" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_128 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_128 -msgid "Image 128" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_256 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_256 -msgid "Image 256" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__image_512 -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_512 -msgid "Image 512" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_image -msgid "Image of the service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__impacts_quota -msgid "Impacts quota" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__standard_price -msgid "" -"In Standard Price & AVCO: value of the product (automatically computed in AVCO).\n" -" In FIFO: value of the last unit that left the stock (automatically computed).\n" -" Used to value the product when the purchase cost is not known (e.g. inventory adjustment).\n" -" Used to compute margins on sale orders." -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__moment__in_act -msgid "In the act" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_name -msgid "In the name of whom the reservation is made" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__intime -msgid "In time" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__partner_name -msgid "In whose name is the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__service_ids -msgid "Included services in the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__deposit_account_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__property_account_income_id -msgid "Income Account" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__overbooking -msgid "Indicate if exists overbooking" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__closed -msgid "Indicate if property is closed or not" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__cancelled_reason -msgid "Indicates cause of cancelled" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__daily_limit -#: model:ir.model.fields,help:pms.field_product_product__daily_limit -#: model:ir.model.fields,help:pms.field_product_template__daily_limit -msgid "Indicates how much products can consumed in one day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__mobile_blacklisted -msgid "" -"Indicates if a blacklisted sanitized phone number is a mobile number. Helps " -"distinguish which number is blacklisted when there is both a " -"mobile and phone field in a model." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__phone_blacklisted -msgid "" -"Indicates if a blacklisted sanitized phone number is a phone number. Helps " -"distinguish which number is blacklisted when there is both a " -"mobile and phone field in a model." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__invoice_to_agency -#: model:ir.model.fields,help:pms.field_res_partner__invoice_to_agency -#: model:ir.model.fields,help:pms.field_res_users__invoice_to_agency -msgid "Indicates if agency invoices partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__apply_pricelist -#: model:ir.model.fields,help:pms.field_res_partner__apply_pricelist -#: model:ir.model.fields,help:pms.field_res_users__apply_pricelist -msgid "Indicates if agency pricelist is applied to his reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__per_day -msgid "Indicates if service is sold by days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__is_crib -#: model:ir.model.fields,help:pms.field_product_product__is_crib -#: model:ir.model.fields,help:pms.field_product_template__is_crib -msgid "Indicates if that product is a crib" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__is_extra_bed -#: model:ir.model.fields,help:pms.field_product_product__is_extra_bed -#: model:ir.model.fields,help:pms.field_product_template__is_extra_bed -msgid "Indicates if that product is a extra bed, add +1 capacity in the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__active -msgid "Indicates if the automated mail is active" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__is_agency -#: model:ir.model.fields,help:pms.field_res_partner__is_agency -#: model:ir.model.fields,help:pms.field_res_users__is_agency -msgid "Indicates if the partner is an agency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__is_on_line -msgid "Indicates if the sale channel is on-line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__is_board_service -msgid "" -"Indicates if the service included in folio sale line is part of a board " -"service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__is_board_service -msgid "Indicates if the service is part of a board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__is_board_service -msgid "Indicates if the service line is part of a board service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__by_default -msgid "Indicates if this board service is applied by default in the room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__per_day -#: model:ir.model.fields,help:pms.field_product_product__per_day -#: model:ir.model.fields,help:pms.field_product_template__per_day -msgid "Indicates that the product is sold by days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__per_person -#: model:ir.model.fields,help:pms.field_product_product__per_person -#: model:ir.model.fields,help:pms.field_product_template__per_person -msgid "Indicates that the product is sold per person" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__parent_id -msgid "Indicates that this room is a child of another room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__out_service_description -msgid "Indicates the cause of out of service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__ready_for_checkin -msgid "" -"Indicates the reservations with checkin_partner data enought to checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__consumed_on -#: model:ir.model.fields,help:pms.field_product_product__consumed_on -#: model:ir.model.fields,help:pms.field_product_template__consumed_on -msgid "Indicates when the product is consumed" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_sale_channel__channel_type__indirect -msgid "Indirect" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__industry_id -msgid "Industry" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Information" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_board_service.py:0 -#, python-format -msgid "" -"Integrity error: There's multiple board services with the same code %s and " -"properties" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room_type.py:0 -#: code:addons/pms/models/pms_room_type_class.py:0 -#, python-format -msgid "" -"Integrity error: There's multiple room types with the same code %s and " -"properties" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_folio__internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_internal_comment -msgid "Internal Folio Notes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__internal_comment -#: model:ir.model.fields,help:pms.field_pms_folio__internal_comment -msgid "Internal Folio notes for Staff" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_internal_comment -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_internal_comment -msgid "Internal Partner Notes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_amenity__default_code -msgid "Internal Reference" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Internal comment Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_internal_comment -msgid "Internal comment for folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__check_adults -msgid "Internal field to force room capacity validations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_internal_comment -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_internal_comment -msgid "Internal notes of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__default_code -msgid "Internal unique identifier of the amenity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__barcode -msgid "International Article Number used for product identification." -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Invalid date for reservation line " -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of cancel" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of checkin" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain operator %s for left of checkout" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of cancel" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of checkin" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Invalid domain right operand %s for left of checkout" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Invalid reservation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Invalid token found! Token acquirer %s != %s" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Invalid token found! Token partner %s != %s" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "Invitation email sent" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_warn -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__invoice -msgid "Invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__type -msgid "" -"Invoice & Delivery addresses are used in sales orders. Private addresses are" -" only visible by authorized users." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_to_agency -#: model:ir.model.fields,field_description:pms.field_res_partner__invoice_to_agency -#: model:ir.model.fields,field_description:pms.field_res_users__invoice_to_agency -msgid "Invoice Agency" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Invoice Contact" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoice_count -msgid "Invoice Count" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "Invoice Folio Order" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__invoice_lines -msgid "Invoice Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_reservation__invoice_status -#: model:ir.model.fields,field_description:pms.field_pms_service__invoice_status -msgid "Invoice Status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__invoice_status -#: model:ir.model.fields,help:pms.field_pms_folio__invoice_status -msgid "Invoice Status; it can be: upselling, invoiced, to invoice, no" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_invoice_ids -msgid "Invoice address for current group." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__partner_invoice_id -msgid "Invoice address for current partner" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Invoiced" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_invoiced -msgid "Invoiced Quantity" -msgstr "" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "Invoiced Quantity: %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__move_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_ids -#: model:ir.ui.menu,name:pms.pms_invoice_menu -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Invoices" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv -msgid "" -"Invoices will be created in draft so that you can review\n" -" them before validation." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Invoicing" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__invoice_policy -msgid "Invoicing Policy" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__is_modified_reservation -msgid "Is A Modified Reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_agency -#: model:ir.model.fields,field_description:pms.field_res_partner__is_agency -#: model:ir.model.fields,field_description:pms.field_res_users__is_agency -msgid "Is Agency" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__is_board_service -#: model:ir.model.fields,field_description:pms.field_pms_service_line__is_board_service -msgid "Is Board Service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_property__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_is_follower -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_is_follower -msgid "Is Follower" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__overbooking -msgid "Is Overbooking" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_product_variant -msgid "Is Product Variant" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__is_company -msgid "Is a Company" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__is_shared_room -msgid "Is a Shared Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_crib -#: model:ir.model.fields,field_description:pms.field_product_product__is_crib -#: model:ir.model.fields,field_description:pms.field_product_template__is_crib -msgid "Is a baby crib" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__has_configurable_attributes -msgid "Is a configurable product" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__is_downpayment -msgid "Is a down payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_extra_bed -#: model:ir.model.fields,field_description:pms.field_product_product__is_extra_bed -#: model:ir.model.fields,field_description:pms.field_product_template__is_extra_bed -msgid "Is extra bed" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Is mandatory indicate the reservation on the checkin" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Is not possible to create the proposed check-in in this reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_late -msgid "" -"Is number of days late in the cancelation rule if the value of the " -"apply_on_late field is specify days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_noshow -msgid "" -"Is number of days no show in the cancelation rule if the value of the " -"apply_on_show field is specify days." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_wizard_reservation_lines_split__allowed_room_ids -msgid "It contains all available rooms for this line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_room_ids -msgid "It contains all available rooms for this reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__to_assign -msgid "" -"It is True if the room of the reservation has been assigned automatically, " -"False if it was confirmed by a person in charge" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "It is not yet checkin day!" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__qty_invoiced -msgid "It is the amount invoiced when an invoice is issued" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin -msgid "It is the checkin date of the reservation, " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkout -msgid "It is the checkout date of the reservation, " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__reservation_id -msgid "It is the reservation in a reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__preferred_room_id -msgid "" -"It's the preferred room assigned to reservation, empty if reservation is " -"splitted" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__item_ids -msgid "Items" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__item_ids -msgid "Items for which the pricelist is made up" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Its too late to checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__function -msgid "Job Position" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__join -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Join reservation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Join the reservation" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_account_journal -msgid "Journal" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_account_move -msgid "Journal Entry" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_account_move_line -msgid "Journal Item" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__journal_item_count -msgid "Journal Items" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__property_account_income_id -msgid "" -"Keep this field empty to use the default value from the product category." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__property_account_expense_id -msgid "" -"Keep this field empty to use the default value from the product category. If" -" anglo-saxon accounting with automated valuation method is configured, the " -"expense account on the product category will be used." -msgstr "" - -#. module: pms -#: model:pms.amenity.type,name:pms.pms_amenity_type_2 -msgid "Kitchen facilities" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_move_line__name -msgid "Label" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lang -#: model:ir.model.fields,field_description:pms.field_pms_reservation__lang -msgid "Language" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__last_checkout -msgid "Last Folio Checkout" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement____last_update -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line____last_update -#: model:ir.model.fields,field_description:pms.field_account_journal____last_update -#: model:ir.model.fields,field_description:pms.field_account_move____last_update -#: model:ir.model.fields,field_description:pms.field_account_move_line____last_update -#: model:ir.model.fields,field_description:pms.field_account_payment____last_update -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv____last_update -#: model:ir.model.fields,field_description:pms.field_folio_sale_line____last_update -#: model:ir.model.fields,field_description:pms.field_ir_config_parameter____last_update -#: model:ir.model.fields,field_description:pms.field_ir_http____last_update -#: model:ir.model.fields,field_description:pms.field_mail_compose_message____last_update -#: model:ir.model.fields,field_description:pms.field_payment_transaction____last_update -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_amenity____last_update -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan____last_update -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine____last_update -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule____last_update -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner____last_update -#: model:ir.model.fields,field_description:pms.field_pms_folio____last_update -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection____last_update -#: model:ir.model.fields,field_description:pms.field_pms_property____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_room____last_update -#: model:ir.model.fields,field_description:pms.field_pms_room_type____last_update -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class____last_update -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel____last_update -#: model:ir.model.fields,field_description:pms.field_pms_service____last_update -#: model:ir.model.fields,field_description:pms.field_pms_service_line____last_update -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard____last_update -#: model:ir.model.fields,field_description:pms.field_pms_ubication____last_update -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split____last_update -#: model:ir.model.fields,field_description:pms.field_product_pricelist____last_update -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item____last_update -#: model:ir.model.fields,field_description:pms.field_product_product____last_update -#: model:ir.model.fields,field_description:pms.field_product_template____last_update -#: model:ir.model.fields,field_description:pms.field_res_company____last_update -#: model:ir.model.fields,field_description:pms.field_res_partner____last_update -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number____last_update -#: model:ir.model.fields,field_description:pms.field_res_users____last_update -#: model:ir.model.fields,field_description:pms.field_room_closure_reason____last_update -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes____last_update -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio____last_update -msgid "Last Modified on" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__lastname -msgid "Last Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__write_uid -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_amenity__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_folio__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_property__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_room__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_room_type__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_service__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_service_line__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_ubication__write_uid -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__write_uid -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_uid -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__write_uid -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__write_date -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_amenity__write_date -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__write_date -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__write_date -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__write_date -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__write_date -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__write_date -#: model:ir.model.fields,field_description:pms.field_pms_folio__write_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__write_date -#: model:ir.model.fields,field_description:pms.field_pms_property__write_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation__write_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_room__write_date -#: model:ir.model.fields,field_description:pms.field_pms_room_type__write_date -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__write_date -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__write_date -#: model:ir.model.fields,field_description:pms.field_pms_service__write_date -#: model:ir.model.fields,field_description:pms.field_pms_service_line__write_date -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__write_date -#: model:ir.model.fields,field_description:pms.field_pms_ubication__write_date -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__write_date -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_date -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__write_date -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_date -msgid "Last Updated on" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lastname -#: model:ir.model.fields,field_description:pms.field_res_partner__lastname -#: model:ir.model.fields,field_description:pms.field_res_users__lastname -msgid "Last name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__last_time_entries_checked -msgid "" -"Last time the invoices & payments matching was performed for this partner. " -"It is set either if there's not at least an unreconciled debit and an " -"unreconciled credit or if you click the \"Done\" button." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Lastname" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Lastnames" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__late -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "Late" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_3 -#: model:product.template,name:pms.pms_service_3_product_template -msgid "Late Check-out" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Late Payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_late -msgid "Late apply on" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_late -msgid "Late first days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Lates and NoShows" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__last_time_entries_checked -msgid "Latest Invoices & Payments Matching Date" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_wizard_reservation_lines_split -msgid "Lines available to split" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__adults -msgid "List of adults there in guest list" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__room_amenity_ids -msgid "List of amenities included in room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__room_amenity_ids -msgid "List of amenities included in room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__done -msgid "Locked" -msgstr "" - -#. module: pms -#: model:product.product,name:pms.pms_service_4 -#: model:product.template,name:pms.pms_service_4_product_template -msgid "Lunch" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__mail -msgid "Mail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__mail_information -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Mail Information" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__is_mail_send -msgid "Mail Sent" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__privacy_policy -msgid "Mail privacy policy " -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_property__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_main_attachment_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_main_attachment_id -msgid "Main Attachment" -msgstr "" - -#. module: pms -#: model:room.closure.reason,name:pms.pms_room_closure_reason_0 -msgid "Maintenance" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__gender__male -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Male" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "Mandatory Firstname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__service_type -msgid "" -"Manually set quantities on order: Invoice based on the manually entered quantity, without creating an analytic account.\n" -"Timesheets on contract: Invoice based on the tracked hours on the related timesheet.\n" -"Create a task and track hours: Create a task on the sales order validation and track the work hours." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__prepaid_warning_days -msgid "" -"Margin in days to create a notice if a payment advance has " -"not been recorded" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_pms_room_massive_changes_wizard -msgid "Massive Changes" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form -#: model_terms:ir.ui.view,arch_db:pms.product_pricelist_view_form -msgid "Massive changes" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_wizard_massive_changes -msgid "Massive changes on Pricelist & Availability Plans" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_massive_changes.py:0 -#, python-format -msgid "Massive changes on Pricelist and Availability Plans" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__max_reservation_priority -#: model:ir.model.fields,help:pms.field_pms_folio__max_reservation_priority -msgid "Max reservation priority on the entire folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_avail -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_avail -msgid "Max. Availability" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_stay -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay -msgid "Max. Stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__max_stay_arrival -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay_arrival -msgid "Max. Stay Arrival" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay Arrival can't be less than Min. Stay Arrival" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay Arrival can't be less than zero" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay can't be less than Min. Stay" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Max. Stay can't be less than zero" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "Max. days InTime before Checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__days_intime -msgid "Maximum number of days for free cancellation before Checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_avail -msgid "Maximum simultaneous availability on own Booking Engine" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_max_avail -msgid "" -"Maximum simultaneous availability on own Booking Engine given no " -"availability rules. Use `-1` for using maximum simultaneous availability." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__max_avail -msgid "Maximum simultaneous availability on own Booking Engine." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_stay -msgid "Maximum stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__max_stay_arrival -msgid "Maximum stay if checkin is today" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_property__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_has_error -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_has_error -msgid "Message Delivery error" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_warn_msg -msgid "Message for Invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_warn_msg -msgid "Message for Sales Order" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_line_warn_msg -msgid "Message for Sales Order Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__message_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_ids -msgid "Messages" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_5 -msgid "Microwave oven" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_quantity -msgid "Min. Quantity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__min_stay -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_stay -msgid "Min. Stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__min_stay_arrival -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_stay_arrival -msgid "Min. Stay Arrival" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Min. Stay Arrival can't be less than zero" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability_plan_rule.py:0 -#, python-format -msgid "Min. Stay can't be less than zero" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__min_stay -msgid "Minimum stay" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__min_stay_arrival -msgid "Minimum stay if checkin is today" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__time_type__minutes -msgid "Minutes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__mobile -#: model:ir.model.fields,field_description:pms.field_pms_folio__mobile -#: model:ir.model.fields,field_description:pms.field_pms_property__mobile -#: model:ir.model.fields,field_description:pms.field_pms_reservation__mobile -#: model:ir.model.fields,field_description:pms.field_res_partner__mobile -#: model:ir.model.fields,field_description:pms.field_res_users__mobile -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Mobile" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Model" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_modified_template -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Modification Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_modified_template -msgid "Modification email template" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__moment -msgid "Moment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__moment -msgid "Moment in relation to the action in which the email will be sent" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Monday" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__time_type__month -msgid "Months" -msgstr "" - -#. module: pms -#: code:addons/pms/models/product_product.py:0 -#, python-format -msgid "More than one room found for the same product" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form -msgid "Multi Properties" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__my_activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_property__my_activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_reservation__my_activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_room_type__my_activity_date_deadline -msgid "My Activity Deadline" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "My Reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__name -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__name -#: model:ir.model.fields,field_description:pms.field_pms_property__name -#: model:ir.model.fields,field_description:pms.field_pms_room_type__name -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__name -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Name in reports" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__name -msgid "Name of availability plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__name -msgid "Name of the automated mail." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__name -msgid "Name of the room type class" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_id -msgid "Name of who made the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__nationality_id -#: model:ir.model.fields,field_description:pms.field_pms_property__nationality_id -#: model:ir.model.fields,field_description:pms.field_res_partner__nationality_id -#: model:ir.model.fields,field_description:pms.field_res_users__nationality_id -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Nationality" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#: code:addons/pms/models/pms_checkin_partner.py:0 -#: code:addons/pms/models/pms_checkin_partner.py:0 -#: code:addons/pms/models/pms_folio.py:0 code:addons/pms/models/pms_folio.py:0 -#: code:addons/pms/models/pms_folio.py:0 -#: code:addons/pms/models/pms_reservation.py:0 -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "New" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_board_service_id -msgid "New Board Service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_discount -msgid "New Discount %" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__new_price -msgid "New Price" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Next 7 days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_date_deadline -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_date_deadline -msgid "Next Activity Deadline" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_summary -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_summary -msgid "Next Activity Summary" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_type_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_type_id -msgid "Next Activity Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__nights -msgid "Nights" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No Checkins!" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__noshow -#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form -msgid "No Show" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_noshow -msgid "No Show apply on" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No checkin was made for this reservation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "No person from reserve %s has arrived" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_noshow -msgid "NoShow first days" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__normal -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__normal -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__normal -msgid "Normal" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__email_normalized -msgid "Normalized Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__not_paid -msgid "Not Paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__display_type__line_note -msgid "Note" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__comment -#: model:ir.model.fields,field_description:pms.field_res_partner__comment -#: model:ir.model.fields,field_description:pms.field_res_users__comment -msgid "Notes" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__no -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__no -msgid "Nothing to Invoice" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "Nothing to invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__cardex_warning -msgid "Notice under the signature on the traveler's ticket." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_needaction_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_needaction_counter -msgid "Number of Actions" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_cancelled_rooms -msgid "Number of Cancelled Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__folios_count -#: model:ir.model.fields,field_description:pms.field_res_partner__folios_count -#: model:ir.model.fields,field_description:pms.field_res_users__folios_count -msgid "Number of Folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__reservations_count -#: model:ir.model.fields,field_description:pms.field_res_partner__reservations_count -#: model:ir.model.fields,field_description:pms.field_res_users__reservations_count -msgid "Number of Reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_rooms -msgid "Number of Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__value_num_rooms_selected -msgid "Number of Rooms Selected" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__number_of_services -msgid "Number of Services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_cancelled_rooms -msgid "Number of cancelled rooms in folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_count -msgid "Number of checkin partners in a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_partner_pending_count -msgid "Number of checkin partners pending to checkin in a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__children_occupying -msgid "Number of children there in guest list whose presence counts" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_has_error_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_has_error_counter -msgid "Number of errors" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__extra_beds_allowed -msgid "Number of extra beds allowed in room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__folios_count -#: model:ir.model.fields,help:pms.field_res_partner__folios_count -#: model:ir.model.fields,help:pms.field_res_users__folios_count -msgid "Number of folios of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__count_pending_arrival -msgid "Number of guest with pending checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_needaction_counter -#: model:ir.model.fields,help:pms.field_pms_property__message_needaction_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_needaction_counter -#: model:ir.model.fields,help:pms.field_pms_room_type__message_needaction_counter -msgid "Number of messages which requires an action" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_has_error_counter -#: model:ir.model.fields,help:pms.field_pms_property__message_has_error_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_has_error_counter -#: model:ir.model.fields,help:pms.field_pms_room_type__message_has_error_counter -msgid "Number of messages with delivery error" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__nights -msgid "Number of nights of a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pricelist_item_count -msgid "Number of price rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__reservations_count -#: model:ir.model.fields,help:pms.field_res_partner__reservations_count -#: model:ir.model.fields,help:pms.field_res_users__reservations_count -msgid "Number of reservations of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__availability -msgid "Number of rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_rooms -msgid "Number of rooms in folio. Canceled rooms do not count." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__num_rooms_available -msgid "Number of rooms that are available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__number_of_services -msgid "Number of services in the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_qty -msgid "Number of services that were sold" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__message_unread_counter -#: model:ir.model.fields,help:pms.field_pms_property__message_unread_counter -#: model:ir.model.fields,help:pms.field_pms_reservation__message_unread_counter -#: model:ir.model.fields,help:pms.field_pms_room_type__message_unread_counter -msgid "Number of unread messages" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__children -msgid "" -"Number total of children there in guest list,whose presence counts or not" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__occupies_availability -msgid "Occupies" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__massive_changes_on -msgid "On" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__onboard -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__onboard -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "On Board" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "On Board Tomorrow" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__is_on_line -msgid "On Line" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Only Room" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Only Services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__agency_id -msgid "Only allowed if the field of partner is_agency is True" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__channel_type_id -msgid "Only allowed if the field of sale channel channel_type is 'direct'" -msgstr "" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_availability_room_type_registry_unique -msgid "" -"Only can exists one availability in the same day for" -" the same room type!" -msgstr "" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_availability_plan_rule_room_type_registry_unique -msgid "" -"Only can exists one availability rule in the same " -"day for the same room type!" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Only can payment by property" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_board_service_room_type.py:0 -#, python-format -msgid "Only can set one default board service" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_several_partners.py:0 -#, python-format -msgid "Only one customer can be added to the reservation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_bottom_tree -msgid "Open Reservation Room Detail" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_open_several_partners_wizard -msgid "Open Several Partners" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__operation -msgid "Operation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_split_join_swap_wizard__operation -msgid "Operation to be applied on the reservation" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_reservation_split_join_swap_wizard -msgid "Operations in reservations" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Order #" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__count -msgid "Order Count" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#: model:ir.model.fields,field_description:pms.field_pms_folio__date_order -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -#, python-format -msgid "Order Date" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__date_order -msgid "Order date of reservation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "Ordered Quantity: %(old_qty)s -> %(new_qty)s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__invoice_policy -msgid "" -"Ordered Quantity: Invoice quantities ordered by the customer.\n" -"Delivered Quantity: Invoice quantities delivered to the customer." -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__gender__other -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Other" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Other data" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 code:addons/pms/models/pms_folio.py:0 -#: code:addons/pms/models/pms_folio.py:0 -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#, python-format -msgid "Others" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__done -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__done -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Out" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__out -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__out -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__out -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Out of Service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Out service description" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__outstanding_folios_debits_widget -#: model:ir.model.fields,field_description:pms.field_account_move__outstanding_folios_debits_widget -#: model:ir.model.fields,field_description:pms.field_account_payment__outstanding_folios_debits_widget -msgid "Outstanding Folios Debits Widget" -msgstr "" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 -#, python-format -msgid "Outstanding credits in Folio" -msgstr "" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 -#, python-format -msgid "Outstanding debits" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Overbookings" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "PART OF TRAVELERS ENTRY" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_folio -msgid "PMS Folio" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_management_menu -msgid "PMS Management" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__paid -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__invoices_paid -msgid "Paid Out" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__parent_avail_id -msgid "Parent Avail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__parent_id -msgid "Parent Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__parent_avail_id -msgid "Parent availability for this availability" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__parent_name -msgid "Parent name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Partial" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__payment_state__partial -msgid "Partially Paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__partner_id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__partner_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__partner_id -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -#: model_terms:ir.ui.view,arch_db:pms.view_partner_data_form -msgid "Partner" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_checkin_partner -msgid "Partner Checkins" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__contract_ids -msgid "Partner Contracts" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_res_partner_id_number -msgid "Partner ID Number" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_several_partners_wizard -msgid "Partner Operations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_requests -msgid "Partner Requests" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__segmentation_ids -msgid "Partner Tags" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_partner_id_number.py:0 -#, python-format -msgid "Partner already has this document type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__partner_id -msgid "Partner associated with checkin partner" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Partner contact name is required" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__partner_name -msgid "Partner name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__partner_id -msgid "Partner who made the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__same_vat_partner_id -msgid "Partner with same Tax ID" -msgstr "" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_passport -msgid "Passport" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form -msgid "Pay" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#, python-format -msgid "Pay & Confirm" -msgstr "" - -#. module: pms -#: code:addons/pms/models/payment_transaction.py:0 -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_payment -#, python-format -msgid "Pay Now" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_folio_payment -msgid "Pay with" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__debit_limit -msgid "Payable Limit" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__payment -#: model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form -msgid "Payment" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_payment_folio -msgid "Payment Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_payment_method_id -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__payment_method_id -msgid "Payment Method" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Payment Mode" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Payment Pending" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__reference -msgid "Payment Ref." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_payment_state -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Payment State" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_state -msgid "Payment Status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_term_id -msgid "Payment Terms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__payment_token_ids -msgid "Payment Tokens" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_payment_transaction -msgid "Payment Transaction" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__payment_term_id -msgid "Payment terms for current folio." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Payment: %s by %s" -msgstr "" - -#. module: pms -#: code:addons/pms/models/account_move.py:0 -#: model:ir.model,name:pms.model_account_payment -#: model:ir.model,name:pms.model_wizard_payment_folio -#: model:ir.model.fields,field_description:pms.field_pms_folio__move_line_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#, python-format -msgid "Payments" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__payment_ids -msgid "Payments made by bank direct" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__statement_line_ids -msgid "Payments made by cash" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__transaction_ids -msgid "Payments made through payment acquirer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__pending_amount -#: model:ir.model.fields,field_description:pms.field_pms_reservation__folio_pending_amount -msgid "Pending Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__count_rooms_pending_arrival -#: model:ir.model.fields,field_description:pms.field_pms_reservation__count_pending_arrival -msgid "Pending Arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkins_ratio -msgid "Pending Arrival Ratio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__ratio_checkin_data -msgid "Pending Checkin Data" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__precheckin -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__confirm -msgid "Pending arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__per_day -msgid "Per Day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__commission_percent -msgid "Percentage corresponding to commission" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__penalty_late -msgid "" -"Percentage of the total price that partner has to pay in case of late " -"arrival" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__penalty_noshow -msgid "" -"Percentage of the total price that partner has to pay in case of no show" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "Personal data is missing for check-in" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Persons" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "Persons can't be higher than room capacity (%s)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__phone -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__phone -msgid "Phone" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__phone_sanitized_blacklisted -msgid "Phone Blacklisted" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__plan_avail -msgid "Plan Avail" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Please define an accounting sales journal for the company %s (%s)." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__pms_property_id -msgid "Pms Property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__access_url -#: model:ir.model.fields,field_description:pms.field_pms_folio__access_url -#: model:ir.model.fields,field_description:pms.field_pms_reservation__access_url -msgid "Portal Access URL" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__checkin_partner_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_partner__checkin_partner_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_users__checkin_partner_possible_customer_id -msgid "Possible Customer In Checkin Partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__folio_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_partner__folio_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_users__folio_possible_customer_id -msgid "Possible Customer In Folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__reservation_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_partner__reservation_possible_customer_id -#: model:ir.model.fields,field_description:pms.field_res_users__reservation_possible_customer_id -msgid "Possible Customer In Reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__possible_existing_customer_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__possible_existing_customer_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__possible_existing_customer_ids -msgid "Possible existing customer" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.several_partners_wizard -msgid "Possibles customers" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__draft -msgid "Pre-reservation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "PreCheckin for" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "PreCheckin in" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "Precheckin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_payment_method_id -msgid "" -"Preferred payment method when paying this vendor. This is used to filter " -"vendor bills by preferred payment method to register payments in mass. Use " -"cases: create bank files for batch wires, check runs." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__prepaid_warning_days -msgid "Prepaid Warning Days" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__price -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__price -#: model:ir.model.fields,field_description:pms.field_pms_room_type__price -msgid "Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce -msgid "Price Reduce" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce_taxexcl -msgid "Price Reduce Tax excl" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce_taxinc -msgid "Price Reduce Tax inc" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Price Total" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Price and Availability Plans" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__list_price -msgid "Price at which the product is sold to customers." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_line__amount -msgid "Price for this Board Service Line/Product" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__amount -msgid "Price for this Board Service Room Type Line/Product" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__amount -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__amount -msgid "" -"Price for this Board Service. It corresponds to the sum of his board service" -" lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__price_per_room -msgid "Price per room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__price_per_room -msgid "Price per room in folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__price_unit -msgid "Price per unit of service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce_taxinc -msgid "Price with discounts applied and taxes included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce_taxexcl -msgid "Price with discounts applied without taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_tax -msgid "Price with taxes on a folio" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_pricelist -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__pricelist_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_property__property_product_pricelist -#: model:ir.model.fields,field_description:pms.field_pms_reservation__pricelist_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pricelist_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__pricelist_id -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__massive_changes_on__pricelist -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Pricelist" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_items_to_overwrite -msgid "Pricelist Items to Override" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_readonly -msgid "Pricelist Readonly" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_pricelist_item -msgid "Pricelist Rule" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist__pricelist_type -msgid "Pricelist Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__pricelist_id -msgid "Pricelist applied in folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__pricelist_id -msgid "Pricelist for current folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__pricelist_id -msgid "Pricelist in which this item is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__num_pricelist_items_to_overwrite -msgid "Pricelist items to overwrite on massive changes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__pricelist_id -msgid "Pricelist that guides the prices of the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__pricelist_ids -msgid "Pricelist that use this rule" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_ids -msgid "Pricelist to apply massive changes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__pricelist_type -msgid "Pricelist types, it can be Daily Plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__pms_pricelist_ids -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__product_pricelist_ids -#: model:ir.ui.menu,name:pms.pricelist_menu -msgid "Pricelists" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.product_pricelist_item_action2 -msgid "Pricelists Items" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__product_pricelist_ids -msgid "Pricelists for a sale channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__pms_pricelist_ids -msgid "Pricelists of the availability plan " -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "" -"Prices have been recomputed according to pricelist %s\n" -" and room type %s" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_folio_changes.py:0 -#: code:addons/pms/wizards/wizard_folio_changes.py:0 -#, python-format -msgid "Prices/Discounts have been changed from folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_template -msgid "Print" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Print All Checkins" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form -msgid "Print in PDF" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Print in cardex" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__priority -msgid "Priority" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__priority -msgid "Priority of a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__privacy_policy -#: model:ir.model.fields,field_description:pms.field_res_company__privacy_policy -#: model_terms:ir.ui.view,arch_db:pms.company_view_form -msgid "Privacy Policy" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Procurement" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_product -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__product_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__product_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__product_id -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Product" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__attribute_line_ids -msgid "Product Attributes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__categ_id -msgid "Product Category" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__product_image -msgid "Product Image" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__packaging_ids -msgid "Product Packages" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__default_pricelist_id -msgid "Product Pricelist" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_id -msgid "Product Room Type" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_product_template -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_tmpl_id -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__product_tmpl_id -msgid "Product Template" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__type -msgid "Product Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_readonly -msgid "Product Uom Readonly" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__product_id -msgid "" -"Product associated with folio sale line, can be product associated with " -"service or product associated withreservation's room type, in other case " -"it's false" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__product_id -msgid "Product associated with the item" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_line__product_id -msgid "Product associated with this board service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__product_id -msgid "Product associated with this board service room type line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__product_id -msgid "Product associated with this service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__product_id -msgid "Product associated with this service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__product_id -msgid "Product identifier associated with room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__product_tmpl_id -msgid "Product template associated with the item" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_ids -msgid "Products" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.demo_pms_room_type_0 -#: model:product.product,name:pms.demo_pms_room_type_0_product_product -msgid "Prop. Demo Suite" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.demo_pms_room_type_1 -#: model:product.product,name:pms.demo_pms_room_type_1_product_product -msgid "Prop. Demo Views" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_property_action -#: model:ir.model.fields,field_description:pms.field_account_journal__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_amenity__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_line__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type_line__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_ubication__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_pricelist__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_product__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_product_template__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_company__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_room_closure_reason__pms_property_ids -#: model:ir.ui.menu,name:pms.general_property_menu -#: model:ir.ui.menu,name:pms.pms_property_menu -msgid "Properties" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement__pms_property_id -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__pms_property_id -#: model:ir.model.fields,help:pms.field_res_company__pms_property_ids -msgid "Properties with access to the element" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_journal__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_amenity__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_amenity_type__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_automated_mails__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_availability_plan__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_line__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type_line__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_cancelation_rule__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_property__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_room__pms_property_id -#: model:ir.model.fields,help:pms.field_pms_room_type__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_room_type_class__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_sale_channel__pms_property_ids -#: model:ir.model.fields,help:pms.field_pms_ubication__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_pricelist__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_pricelist_item__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_product__pms_property_ids -#: model:ir.model.fields,help:pms.field_product_template__pms_property_ids -#: model:ir.model.fields,help:pms.field_res_partner__pms_property_ids -#: model:ir.model.fields,help:pms.field_room_closure_reason__pms_property_ids -msgid "" -"Properties with access to the element; if not set, all properties can access" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__pms_property_id -msgid "Propertiy with access to the element;" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_property -#: model:ir.model.fields,field_description:pms.field_account_bank_statement__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_move__pms_property_id -#: model:ir.model.fields,field_description:pms.field_account_payment__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_availability__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_folio__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pms_property_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_room__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_service__pms_property_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__pms_property_id -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Property" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Property Configuration" -msgstr "" - -#. module: pms -#: model:res.groups,name:pms.group_pms_call -msgid "Property Management / CallCenter" -msgstr "" - -#. module: pms -#: model:res.groups,name:pms.group_pms_user -msgid "Property Management / User" -msgstr "" - -#. module: pms -#: model:res.groups,name:pms.group_pms_manager -msgid "Property Management/ Manager" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_room -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_tree -msgid "Property Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__room_type_id -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_tree -msgid "Property Room Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__class_id -msgid "Property Type Class" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_form -msgid "Property Ubication" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_tree -msgid "Property Ubications" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_ubication.py:0 -#, python-format -msgid "Property not allowed" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_availability.py:0 -#, python-format -msgid "Property not allowed on availability day compute" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_tree -msgid "Property settings summary" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__pms_property_id -msgid "Property to which the availability is directed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__pms_property_id -msgid "Property to which the folio associated belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__pms_property_id -msgid "Property to which the folio belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__pms_property_id -msgid "Property to which the reservation belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__pms_property_id -#: model:ir.model.fields,help:pms.field_pms_service_line__pms_property_id -msgid "Property to which the service belongs" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__pms_property_id -#: model:ir.model.fields,help:pms.field_account_move__pms_property_id -#: model:ir.model.fields,help:pms.field_account_payment__pms_property_id -msgid "Property with access to the element" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__pms_property_id -msgid "" -"Property with access to the element; if not set, all properties can access" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__ratio_checkin_data -msgid "Proportion of guest data complete at checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkins_ratio -msgid "Proportion of guest pending checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__lst_price -msgid "Public Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__description_purchase -msgid "Purchase Description" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__uom_po_id -msgid "Purchase Unit of Measure" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__auto_qty -msgid "Qty automated setted" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_qty -#: model:ir.model.fields,field_description:pms.field_pms_service__product_qty -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Quantity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__visible_qty_configurator -msgid "Quantity visible in configurator" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__quota -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__quota -msgid "Quota" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__default_quota -msgid "" -"Quota assigned to the own Booking Engine given no availability rules. Use " -"`-1` for managing no quota." -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__draft -msgid "Quotation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Quotation #" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__sent -msgid "Quotation Sent" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__expense_policy -msgid "Re-Invoice Expenses" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__visible_expense_policy -msgid "Re-Invoice Policy visible" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__ready_for_checkin -msgid "Ready for checkin" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__real_avail -msgid "Real Avail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__real_avail -msgid "Real availability" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.booking_engine -msgid "Reason" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__cancelled_reason -msgid "Reason of cancellation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__closure_reason_id -msgid "Reason why the reservation cannot be made" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_model_id -msgid "Recipients Model" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_model_name -msgid "Recipients Model Name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Recompute all prices based on this pricelist" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.priority_reservations_ir_actions_server -#: model:ir.cron,cron_name:pms.priority_reservations -#: model:ir.cron,name:pms.priority_reservations -msgid "Recompute priority on reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_reduce -msgid "Reduced price amount, that is, total price with discounts applied" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#: model:ir.model.fields,field_description:pms.field_pms_property__ref -#: model:ir.model.fields,field_description:pms.field_pms_room_type__code -#, python-format -msgid "Reference" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Register Checkins" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Register Partners" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "Register Payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__delivered -msgid "Regular invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__parent_id -msgid "Related Company" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__folio_partner_id -msgid "Related customer with Folio Sale Line" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Remove some of the leftover assigned checkins first" -msgstr "" - -#. module: pms -#: model:ir.actions.report,name:pms.action_report_folio -msgid "Report Folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "Resend Invitation" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_resend_cancellation_email -msgid "Resend cancellation email" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_resend_confirmation_email -msgid "Resend confirmation email" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_resend_modification_email -msgid "Resend modification email" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_reservation_form_tree_all -#: model:ir.model,name:pms.model_pms_reservation -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_service_line__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_several_partners_wizard__reservation_id -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_tree -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Reservation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Reservation #" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.availability_action -msgid "Reservation Availability Plans" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservation Detail" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Details" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_order -#: model:ir.model.fields,field_description:pms.field_pms_reservation__name -msgid "Reservation Id" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_availability__reservation_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_line_ids -msgid "Reservation Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__name -msgid "Reservation Name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Notes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__reservation_id -msgid "Reservation Reference" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_reservation_rooms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Reservation Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__reservation_sequence_id -msgid "Reservation Sequence" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_search -msgid "Reservation Service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Reservation Total" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_type -msgid "Reservation Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__reservation_wizard_id -msgid "Reservation Wizard" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability_plan -msgid "Reservation availability plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__cancel -msgid "Reservation cancellation" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__creation -msgid "Reservation creation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Reservation dates should be consecutives" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#: code:addons/pms/wizards/pms_booking_engine.py:0 -#, python-format -msgid "Reservation from " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__reservation_id -msgid "Reservation in which the service is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__reservation_line_ids -msgid "" -"Reservation lines associated with folio sale line, they corresponds with " -"nights" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_automated_mails__action__write -msgid "Reservation modification" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_view_reservation_operations -msgid "Reservation operations" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability_plan_rule -msgid "Reservation rule by day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__reservation_id -msgid "Reservation to which checkin partners belong" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__reservation_id -msgid "Reservation to which folio sale line belongs" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.pms_partner_reservations -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_ids -#: model:ir.model.fields,field_description:pms.field_res_partner__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_res_users__pms_reservation_ids -#: model:ir.model.fields,field_description:pms.field_wizard_folio_changes__reservation_ids -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__reservation_ids -#: model:ir.ui.menu,name:pms.menu_reservations -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_graph -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_pivot -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_reservation -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservations -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__reservation_lines_to_change -msgid "Reservations Lines To Change" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_reservation_line -msgid "Reservations by day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__reservation_ids -msgid "Reservations in which the Account Bank Statement Lines are included" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form -msgid "Reservations related with this contact" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 1 month" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 14 days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Reservations to 7 days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_home_menu_reservation -msgid "Reservations/" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_property__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__activity_user_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__activity_user_id -msgid "Responsible User" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.revenue_management_menu -msgid "Revenue Management" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__preferred_room_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__room_id -#: model:ir.model.fields,field_description:pms.field_pms_service__reservation_id -#: model:ir.model.fields,field_description:pms.field_pms_wizard_reservation_lines_split__room_id -#: model:pms.room.type.class,name:pms.pms_room_type_class_0 -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Room" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_view_form -#: model:ir.model.fields,field_description:pms.field_pms_room__room_amenity_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_search -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_list -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_view_form -msgid "Room Amenities" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_amenity_type_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_amenity_type_view_list -msgid "Room Amenities Type" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_class_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_type_class_view_tree -msgid "Room Class" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_closure_reason_form_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_room_closure_reason_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_closure_reason_view_tree -msgid "Room Closure Reason" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Room Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__name -#: model:ir.model.fields,help:pms.field_pms_room__name -msgid "Room Name" -msgstr "" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_reservation_line_rule_availability -msgid "Room Occupied" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view -msgid "Room Reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_room_services_set -msgid "Room Services Total" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__room_source -msgid "Room Source" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_split_join_swap_wizard__room_target -msgid "Room Target" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_type_form_tree -#: model:ir.model,name:pms.model_pms_room_type -#: model:ir.model.fields,field_description:pms.field_pms_availability__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_availability_plan_rule__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pms_room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__room_type_ids -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__room_type_id -#: model:ir.model.fields,field_description:pms.field_pms_room_type__room_type_id -#: model:ir.model.fields,field_description:pms.field_product_product__room_type_id -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -msgid "Room Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__room_amenity_ids -msgid "Room Type Amenities" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_room_type_class_form_tree -#: model:ir.model,name:pms.model_pms_room_type_class -#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_class_form_tree -msgid "Room Type Class" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__pms_room_type_id -msgid "Room Type for which this Board Service is available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__room_type_id -msgid "Room Type reserved" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__room_type_id -msgid "" -"Room Type sold on the reservation,it doesn't necessarily correspond to the " -"room actually assigned" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_kanban -msgid "Room Type:" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__apply_pricelists_on__room_types -#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_form_tree -msgid "Room Types" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__room_type_ids -msgid "Room Types that belong to this Room Type Class" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_amenity -msgid "Room amenity" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_type_view_form -msgid "Room amenity Type" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "" -"Room line Check In Date Should be less than the Check " -"Out Date!" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__reservation_ids -msgid "Room reservation detail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__reservation_id -msgid "Room to which the services will be applied" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_availability -msgid "Room type availability per day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type_class__default_code -msgid "Room type class identification code" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__room_type_id -msgid "Room type for which availability is indicated" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__room_type_id -msgid "Room type for which availability rule is applied" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_folio_availability_wizard -msgid "Room type line in Booking Engine" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__board_service_room_type_ids -msgid "Room type's board services" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "Room {} not available." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__rooms -msgid "Room/s" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Rooming" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__room_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__room_ids -#: model:ir.model.fields,field_description:pms.field_pms_ubication__pms_room_ids -#: model:ir.ui.menu,name:pms.menu_open_pms_room_form -#: model:ir.ui.menu,name:pms.pms_rooms_menu -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_bottom_tree -msgid "Rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__free_room_ids -msgid "Rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_ubication__pms_room_ids -msgid "Rooms found in this location" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__room_ids -msgid "Rooms that a property has." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__rooms -msgid "Rooms that are reserved" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__room_ids -msgid "Rooms that belong to room type." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__rules_to_overwrite -msgid "Rule to Overwrite" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.availability_view_form -msgid "Rules" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan__rule_ids -msgid "Rules in a availability plan" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__num_rules_to_overwrite -msgid "Rules to overwrite on massive changes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_has_sms_error -#: model:ir.model.fields,field_description:pms.field_pms_property__message_has_sms_error -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_has_sms_error -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_has_sms_error -msgid "SMS Delivery error" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_sale_channel_form_tree -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_channel_id -#: model:ir.model.fields,field_description:pms.field_res_partner__sale_channel_id -#: model:ir.model.fields,field_description:pms.field_res_users__sale_channel_id -#: model_terms:ir.ui.view,arch_db:pms.pms_sale_channel_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_sale_channel_view_tree -msgid "Sale Channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__name -msgid "Sale Channel Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_sale_channel__channel_type -msgid "Sale Channel Type" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_partner.py:0 -#, python-format -msgid "Sale Channel for an agency must be indirect" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_partner.py:0 -#, python-format -msgid "Sale Channel must be entered" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_open_pms_sale_channel_form_tree -msgid "Sale Channels" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.product_pricelist_item_view_tree -msgid "Sale Date End" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.product_pricelist_item_view_tree -msgid "Sale Date Start" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__date_types__sale_dates -msgid "Sale Dates" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room__description_sale -msgid "Sale Description" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sale Details" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__sale_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__sale_line_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sale Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_order_count -msgid "Sale Order Count" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist__pms_sale_channel_ids -msgid "Sale channel for which the pricelist is included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__sale_line_ids -msgid "Sale lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__sale_line_ids -msgid "Sale lines in folio. It correspond with reservation nights" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.pms_sales_menu -msgid "Sales" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_sale_channel -#: model:ir.model.fields,field_description:pms.field_pms_service__channel_type -msgid "Sales Channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__channel_type_id -#: model:ir.model.fields,help:pms.field_pms_reservation__channel_type_id -msgid "Sales Channel through which the reservation was managed" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__description_sale -msgid "Sales Description" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__sale_line_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Sales Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_order_ids -msgid "Sales Order" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_line_warn -msgid "Sales Order Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__list_price -msgid "Sales Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__team_id -msgid "Sales Team" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__sale_warn -msgid "Sales Warnings" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__user_id -#: model:ir.model.fields,field_description:pms.field_pms_property__user_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__user_id -msgid "Salesperson" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__phone_sanitized -msgid "Sanitized Number" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__date -msgid "Sate on which the product is to be consumed" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Saturday" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard -msgid "Search" -msgstr "" - -#. module: pms -#: model:pms.ubication,name:pms.pms_ubication_2 -msgid "Second Floor" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__lastname2 -msgid "Second Last Name" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Second Lastname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__lastname2 -#: model:ir.model.fields,field_description:pms.field_res_partner__lastname2 -#: model:ir.model.fields,field_description:pms.field_res_users__lastname2 -msgid "Second last name" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__display_type__line_section -msgid "Section" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__access_token -#: model:ir.model.fields,field_description:pms.field_pms_folio__access_token -#: model:ir.model.fields,field_description:pms.field_pms_reservation__access_token -msgid "Security Token" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__pms_amenity_type_id -msgid "Segment the amenities by categories (multimedia, comfort, etc ...)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__segmentation_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__segmentation_ids -msgid "Segmentation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__segmentation_ids -msgid "Segmentation tags to classify checkin partners" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__segmentation_ids -msgid "Segmentation tags to classify folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__segmentation_ids -msgid "Segmentation tags to classify reservations" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Segmentation..." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_type -msgid "Select a valid document type" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_precheckin_detail -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Select an option" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__categ_id -msgid "Select category for the current product" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__num_rooms_selected -msgid "Selected rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__invoice_warn -#: model:ir.model.fields,help:pms.field_pms_property__sale_warn -#: model:ir.model.fields,help:pms.field_pms_room_type__sale_line_warn -msgid "" -"Selecting the \"Warning\" option will notify user with the message, " -"Selecting \"Blocking Message\" will throw an exception with the message and " -"block the flow. The Message has to be written in the next field." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__self -msgid "Self" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.send_cancelation_email_folio_ir_actions_server -#: model:ir.cron,cron_name:pms.send_cancelation_email_folio -#: model:ir.cron,name:pms.send_cancelation_email_folio -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Send Cancellation Email" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.send_confirmation_email_folio_ir_actions_server -#: model:ir.cron,cron_name:pms.send_confirmation_email_folio -#: model:ir.cron,name:pms.send_confirmation_email_folio -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Send Confirmation Email" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "Send Confirmed Reservation Mail " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "Send Invitation" -msgstr "" - -#. module: pms -#: model:ir.actions.server,name:pms.send_modification_email_folio_ir_actions_server -#: model:ir.cron,cron_name:pms.send_modification_email_folio -#: model:ir.cron,name:pms.send_modification_email_folio -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Send Modification Email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__sequence -#: model:ir.model.fields,field_description:pms.field_pms_folio__sequence -#: model:ir.model.fields,field_description:pms.field_pms_room__sequence -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sequence -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__sequence -#: model:ir.model.fields,field_description:pms.field_pms_service__sequence -#: model:ir.model.fields,field_description:pms.field_pms_ubication__sequence -msgid "Sequence" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__sequence -msgid "Sequence used to form the name of the folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Sequences" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__service_ids -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__service -#: model:ir.model.fields,field_description:pms.field_pms_service__product_id -#: model:ir.model.fields.selection,name:pms.selection__pms_massive_changes_wizard__apply_pricelists_on__service -#: model_terms:ir.ui.view,arch_db:pms.product_template_view_form -msgid "Service" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_report_view_tree -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_tree -msgid "Service By Day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_order -msgid "Service Id" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_form -msgid "Service Line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_line_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__service_line_ids -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Service Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__service_id -msgid "Service Reference" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__service_id -msgid "Service Room" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_service_line -msgid "Service by day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service__name -#: model:ir.model.fields,help:pms.field_pms_service__name -msgid "Service description" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__service_id -msgid "Service identifier" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__state -msgid "Service status, it corresponds with folio status" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_service_line_form -#: model:ir.actions.act_window,name:pms.action_pms_services_form -#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__service_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__service_ids -#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__service_ids -#: model:ir.ui.menu,name:pms.menu_services_pms -#: model:ir.ui.menu,name:pms.pms_services_menu -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_graph -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_pivot -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_calendar -#: model_terms:ir.ui.view,arch_db:pms.pms_service_view_tree -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_detail -msgid "Services" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_service_line -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services By Day" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services NOT included in the room reservation price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_services -msgid "Services Total" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_service -msgid "Services and its charges" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_pms_service_line -msgid "Services by Day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__service_ids -msgid "" -"Services detail provide to customer and it will include in main Invoice." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__services_discount -msgid "Services discount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__services_discount -msgid "Services discount (€)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement_line__service_ids -msgid "Services in which the Account Bank Statement Lines are included" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Services included in the room reservation price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__board_service_line_ids -#: model:ir.model.fields,help:pms.field_pms_board_service_room_type__board_service_line_ids -msgid "Services included in this Board Service" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_board_service_line -msgid "Services on Board Service included" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_board_service_room_type_line -msgid "Services on Board Service included in Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__overnight_room -#: model:ir.model.fields,help:pms.field_pms_reservation_line__overnight_room -#: model:ir.model.fields,help:pms.field_pms_room_type__overnight_room -#: model:ir.model.fields,help:pms.field_pms_room_type_class__overnight -msgid "Set False if if these types of spaces are not used for overnight stays" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "Set to Done" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Settings" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__service_id -msgid "Sevice included in folio sale line" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_0 -msgid "Shampoo and Soap" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__partner_share -msgid "Share Partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__shared_folio -msgid "Shared Folio" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -msgid "Shared Room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_board_service__show_detail_report -msgid "Show Detail Report" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -msgid "Show all checkins for Tomorrow" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Show all checkins for enter tomorrow" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -msgid "Show all future checkins" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Show all reservations for which date enter is before than 14 days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Show all reservations for which date enter is before than 7 days" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "" -"Show all reservations for which date enter is before than aprox. 1 month" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__auto_qty -msgid "Show if the day qty was calculated automatically" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_expiration -msgid "Signup Expiration" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_token -msgid "Signup Token" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_type -msgid "Signup Token Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_valid -msgid "Signup Token is Valid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__signup_url -msgid "Signup URL" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_1 -#: model:product.product,name:pms.pms_room_type_1_product_product -msgid "Single" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__sales_count -msgid "Sold" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_users.py:0 -#, python-format -msgid "Some properties do not belong to the allowed companies" -msgstr "" - -#. module: pms -#: model:res.partner.id_category,name:pms.document_type_spanish_residence -msgid "Spanish Residence permit" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__board_service_room_type_id -msgid "Specify a Board services on Room Types." -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_late__days -#: model:ir.model.fields.selection,name:pms.selection__pms_cancelation_rule__apply_on_noshow__days -msgid "Specify days" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__split -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Split reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__splitted -msgid "Splitted" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_booking_engine__reservation_type__staff -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__staff -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__reservation_type__staff -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "Staff" -msgstr "" - -#. module: pms -#: code:addons/pms/controllers/pms_portal.py:0 -#, python-format -msgid "Stage" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__date_start_consumption -msgid "Start Date Consumption" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__start_date -msgid "Start date for creation of reservations and folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_product_pricelist_item__date_start_consumption -msgid "Start date to apply daily pricelist items" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__state_id -#: model:ir.model.fields,field_description:pms.field_pms_reservation__state -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__state -#: model:ir.model.fields,field_description:pms.field_pms_service__state -#: model:ir.model.fields,field_description:pms.field_res_partner__state_id -#: model:ir.model.fields,field_description:pms.field_res_users__state_id -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "State" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__invoice_status -msgid "" -"State in which the service is with respect to invoices.It can be 'invoiced'," -" 'to_invoice' or 'no'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__state -msgid "State of the reservation line." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__state -#: model:ir.model.fields,field_description:pms.field_pms_folio__state -msgid "Status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_state -#: model:ir.model.fields,help:pms.field_pms_property__activity_state -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_state -#: model:ir.model.fields,help:pms.field_pms_room_type__activity_state -msgid "" -"Status based on activities\n" -"Overdue: Due date is already passed\n" -"Today: Activity date is today\n" -"Planned: Future activities." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__state -msgid "Status of the checkin partner regarding the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__street -msgid "Street" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Street 2..." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Street..." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__street2 -msgid "Street2" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__service_line_ids -msgid "Subservices included in folio sale line service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__service_line_ids -msgid "Subservices included in this service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_service__price_subtotal -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_subtotal -msgid "Subtotal" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_subtotal -#: model:ir.model.fields,help:pms.field_pms_reservation__price_subtotal -#: model:ir.model.fields,help:pms.field_pms_service__price_subtotal -#: model:ir.model.fields,help:pms.field_pms_service_line__price_day_subtotal -msgid "Subtotal price without taxes" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Sunday" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__supplier_rank -msgid "Supplier Rank" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Supplier Taxes" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form -msgid "Suppliers" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "Swap reservation rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation_split_join_swap_wizard__operation__swap -msgid "Swap rooms" -msgstr "" - -#. module: pms -#. openerp-web -#: code:addons/pms/static/src/xml/pms_base_templates.xml:0 -#, python-format -msgid "Switch to this property" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_ir_config_parameter -msgid "System Parameter" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "TRAVELER'S DOCUMENT" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Tables Detail" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__category_id -msgid "Tags" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__vat -msgid "Tax ID" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__tax_ids -#: model:ir.model.fields,field_description:pms.field_pms_folio__amount_tax -#: model:ir.model.fields,field_description:pms.field_pms_reservation__tax_ids -#: model:ir.model.fields,field_description:pms.field_pms_service__tax_ids -#: model:ir.model.fields,field_description:pms.field_pms_service_line__tax_ids -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_tax -#: model:ir.model.fields,field_description:pms.field_pms_service__price_tax -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_tax -msgid "Taxes Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__tax_ids -msgid "Taxes applied in the folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__tax_ids -msgid "Taxes applied in the reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__tax_ids -msgid "Taxes applied in the service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__tax_ids -msgid "Taxes applied in the service line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deposit_taxes_id -msgid "Taxes used for deposits" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__show_update_pricelist -msgid "" -"Technical Field, True if the pricelist was changed;\n" -" this will then display a recomputation button" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__valid_product_template_attribute_line_ids -msgid "Technical compute" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__document_id -msgid "Technical field" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__display_type -msgid "Technical field for UX purpose." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__preconfirm -msgid "Technical field that indicates the reservation is not comfirm yet" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_checkin -msgid "" -"Technical field, Indicates if there isn't a checkin_partner dataOnly can be " -"true if checkin is today or was in the past" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_cancel -msgid "" -"Technical field, Indicates that reservation can be cancelled,that happened " -"when state is 'cancel', 'done', or 'departure_delayed'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__allowed_checkout -msgid "" -"Technical field, Indicates that reservation is ready for checkoutonly can be" -" true if reservation state is 'onboard' or departure_delayedand checkout is " -"today or will be in the future" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__pricelist_id -msgid "" -"Technical field. Used for searching on pricelists, not stored in database." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__template_id -msgid "Template" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__note -msgid "Terms and conditions" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "The Property are mandatory in the reservation" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "The Sale Channel does not correspond to the agency's" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__vat -msgid "" -"The Tax Identification Number. Complete it if the contact is subjected to " -"government taxes. Used in some legal statements." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__action -msgid "The action that will cause the email to be sent " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__invoice_count -msgid "The amount of invoices in out invoice and out refund status" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__pending_amount -msgid "The amount that remains to be paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_pending_amount -msgid "The amount that remains to be paid from folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__untaxed_amount_invoiced -msgid "The amount to invoice without taxes in the line of folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__analytic_account_id -msgid "The analytic account related to a folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability_plan_rule__availability_plan_id -msgid "The availability plan that include the Availabilty Rule" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "" -"The capacity of the room must be greater than 0." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__checkin_partner_ids -msgid "The checkin partners on a folio" -msgstr "" - -#. module: pms -#: code:addons/pms/models/res_users.py:0 -#, python-format -msgid "The chosen property is not in the allowed properties for this user" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__closure_reason_id -msgid "The closure reason for a closure room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_bank_statement__company_id -msgid "The company for Account Bank Statement" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_journal__company_id -msgid "The company for Account Jouarnal" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__company_id -msgid "The company for folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__company_id -msgid "The company in the folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__company_id -msgid "The company that owns or operates this property." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__currency_id -msgid "The currency for the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__currency_id -msgid "The currency of the property location" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__currency_id -msgid "The currency used in relation to the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__currency_id -msgid "The currency used in relation to the pricelist" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service_line__currency_id -msgid "The currency used in relation to the service where it's included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__date -msgid "The date of the reservation in reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__default_pricelist_id -msgid "The default pricelist used in this property." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__fiscal_position_id -msgid "The fiscal position depends on the location of the client" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_position_id -msgid "" -"The fiscal position determines the taxes/accounts used for this contact." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__fixed_amount -msgid "The fixed amount to be invoiced in advance, taxes excluded." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_id -msgid "The folio customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_move_line__folio_line_ids -msgid "The folio lines in the account move lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_id -msgid "The folio where the reservations are included" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__user_id -msgid "The internal user in charge of this contact." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__untaxed_amount_to_invoice -msgid "The invoiced amount without taxes in the line of the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__capacity -msgid "The maximum number of people that can occupy a room" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_automated_mails.py:0 -#: code:addons/pms/models/pms_automated_mails.py:0 -#, python-format -msgid "The moment for this action cannot be 'Before'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__name -msgid "The name of the sale channel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_room_closure_reason__name -msgid "The name that identifies the room closure reason" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__total_rooms_count -msgid "The number of rooms in a room type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__count_rooms_pending_arrival -msgid "The number of rooms left to occupy." -msgstr "" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "The ordered quantity has been updated." -msgstr "" - -#. module: pms -#: code:addons/pms/models/ir_config_parameter.py:0 -#, python-format -msgid "The parameter Advanced price rules cannot be modified" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__has_unreconciled_entries -msgid "" -"The partner has at least one unreconciled debit and credit since last time " -"the invoices & payments matching was performed." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__reference -msgid "The payment communication of this sale order." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__amount -msgid "The percentage of amount to be invoiced in advance, taxes excluded." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__price -msgid "The price in a reservation line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_untaxed -msgid "The price without taxes on a folio" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "" -"The product used to invoice a down payment should\n" -" be of type 'Service'.\n" -" Please use another product or update this product." -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "" -"The product used to invoice a down payment should\n" -" have an invoice policy set to \"Ordered quantities\".\n" -" Please update your deposit product to be able\n" -" to create a deposit invoice." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_users__pms_property_ids -msgid "The properties allowed for this user" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__pms_property_id -msgid "The property for folios" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_users__pms_property_id -msgid "The property that is selected within those allowed for the user" -msgstr "" - -#. module: pms -#: code:addons/pms/models/folio_sale_line.py:0 -#, python-format -msgid "The qty (%s) is wrong. The quantity pending to invoice is %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__qty_to_invoice -msgid "" -"The quantity to invoice. If the invoice policy is order, the quantity to " -"invoice is calculated from the ordered quantity. Otherwise, the quantity " -"delivered is used." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "The reservation type must be the same for all reservations in folio" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_room.py:0 -#, python-format -msgid "" -"The reservation units are required on shared rooms." -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "The room does not exist" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "The room is not available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__room_id -msgid "The room of a reservation. " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__sale_channel_id -#: model:ir.model.fields,help:pms.field_res_partner__sale_channel_id -#: model:ir.model.fields,help:pms.field_res_users__sale_channel_id -msgid "The sale channel of the partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__lst_price -msgid "" -"The sale price is managed from the product template. Click on the 'Configure" -" Variants' button to set the extra attribute prices." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__folio_sequence_id -msgid "The sequence that formed the name of the folio." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__reservation_sequence_id -msgid "The sequence that formed the name of the reservation." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__payment_state -msgid "The state of the payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__state -msgid "" -"The state of the reservation. It can be 'Pre-reservation', 'Pending " -"arrival', 'On Board', 'Out', 'Cancelled', 'Arrival Delayed' or 'Departure " -"Delayed'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__folio_payment_state -msgid "The status of the folio payment" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__state -msgid "The status of the folio related with folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__invoice_status -msgid "" -"The status of the invoices in folio. Can be 'invoiced', 'to_invoice' or " -"'no'." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__template_id -msgid "The template that will be sent by email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio_availability_wizard__price_total -msgid "The total price in the folio" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__reservation_type -#: model:ir.model.fields,help:pms.field_pms_folio__reservation_type -msgid "" -"The type of the reservation. Can be 'Normal', 'Staff' or 'Out of Service'" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__user_id -msgid "The user who created the folio" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 -#, python-format -msgid "The value of the down payment amount must be positive." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -msgid "There are currently no folios for your account." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation_precheckin -msgid "" -"There are currently no precheckins in this reservation for your account." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "There are currently no reservations for your account." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio_precheckin -msgid "There are currently no reservations in this folio for your account." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "There are no checkins to print" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "" -"There is nothing to invoice!\n" -"\n" -" Reason(s) of this behavior could be:\n" -" - You should deliver your products before invoicing them: Click on the \"truck\"\n" -" icon (top-right of your screen) and follow instructions.\n" -" - You should modify the invoicing policy of your product: Open the product,\n" -" go to the \"Sales tab\" and modify invoicing policy from \"delivered quantities\"\n" -" to \"ordered quantities\".\n" -" " -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0 -#, python-format -msgid "There's no reservations lines with provided room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_availability__reservation_line_ids -#: model:ir.model.fields,help:pms.field_pms_reservation__reservation_line_ids -msgid "" -"They are the lines of the reservation into a reservation,they corresponds to" -" the nights" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_payable_id -msgid "" -"This account will be used instead of the default one as the payable account " -"for the current partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_account_receivable_id -msgid "" -"This account will be used instead of the default one as the receivable " -"account for the current partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkin_datetime -msgid "" -"This field is the day and time of arrival of the reservation.It is formed " -"with the checkin and arrival_hour fields" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__checkout_datetime -msgid "" -"This field is the day and time of departure of the reservation.It is formed " -"with the checkout and departure_hour fields" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__tz -msgid "This field is used to determine de timezone of the property." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__email_normalized -msgid "" -"This field is used to search on email address as the primary email field can" -" contain more than strictly an email address." -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_checkin_partner.py:0 -#, python-format -msgid "This guest is already registered in the room" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room_type__price_extra -msgid "This is the sum of the extra price of all attributes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__impacts_quota -msgid "This line has been taken into account in the avail quota" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_supplier_payment_term_id -msgid "" -"This payment term will be used instead of the default one for purchase " -"orders and vendor bills" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_payment_term_id -msgid "" -"This payment term will be used instead of the default one for sales orders " -"and customer invoices" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__property_product_pricelist -msgid "" -"This pricelist will be used, instead of the default one, for sales to the " -"current partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_line__occupies_availability -msgid "This record is taken into account to calculate availability" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "This reservation cannot be cancelled" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "This reservation cannot be check out" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -"This reservation has other reservantions and/or services in the\n" -" folio, you can check it in the" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "" -"This reservation is part of a splitted reservation, you can try to\n" -" join the reservation here" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "This will update all unit prices based on the currently set pricelist." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Thursday" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__time -msgid "Time" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_automated_mails__time_type -msgid "Time Range" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__tz -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "Timezone" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__tz_offset -msgid "Timezone offset" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__title -msgid "Title" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__end_date -msgid "To" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__to_assign -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To Assign" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_folio__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__to_invoice -#: model:ir.model.fields.selection,name:pms.selection__pms_service__invoice_status__to_invoice -msgid "To Invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_to_invoice -msgid "To Invoice Quantity" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To be paid" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_folio_search -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_search -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search -msgid "To enter" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "To invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_name -msgid "To whom the room is assigned" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__end_date -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkout -msgid "To:" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Today" -msgstr "" - -#. module: pms -#: model:pms.amenity.type,name:pms.pms_amenity_type_0 -msgid "Toiletries" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search -msgid "Tomorrow" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_total -#: model:ir.model.fields,field_description:pms.field_pms_folio__amount_total -#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_total -#: model:ir.model.fields,field_description:pms.field_pms_service__price_total -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_day_total -#: model_terms:ir.ui.view,arch_db:pms.portal_my_folio -#: model_terms:ir.ui.view,arch_db:pms.portal_my_reservation -msgid "Total" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__total_invoiced -msgid "Total Invoiced" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__debit -msgid "Total Payable" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__total_price_folio -msgid "Total Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__credit -msgid "Total Receivable" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__total_rooms_count -msgid "Total Rooms Count" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_tax -msgid "Total Tax" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree -msgid "Total amount" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Total amount (Reservation Card):" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__credit -msgid "Total amount this customer owes you." -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__amount_total -msgid "Total amount to be paid" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__debit -msgid "Total amount you have to pay to this vendor." -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree -msgid "Total debt" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_tax -#: model:ir.model.fields,help:pms.field_pms_reservation__price_tax -msgid "Total of taxes in a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__price_tax -msgid "Total of taxes in service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__price_total -msgid "Total price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__price_services -msgid "Total price from services of a reservation" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_booking_engine__total_price_folio -msgid "Total price of folio with taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__price_room_services_set -msgid "Total price of room and services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_total -#: model:ir.model.fields,help:pms.field_pms_reservation__price_total -#: model:ir.model.fields,help:pms.field_pms_service__price_total -#: model:ir.model.fields,help:pms.field_pms_service_line__price_day_total -msgid "Total price with taxes" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search -msgid "Tour Operator" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__service_type -msgid "Track Service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__transaction_ids -msgid "Transactions" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Traveler's signature" -msgstr "" - -#. module: pms -#: model:ir.actions.report,name:pms.action_traveller_report -msgid "Traveller Report" -msgstr "" - -#. module: pms -#: model:pms.room.type,name:pms.pms_room_type_3 -#: model:product.product,name:pms.pms_room_type_3_product_product -msgid "Triple" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_amenity__is_add_code_room_name -msgid "" -"True if the Internal Reference should appear in the display name of the " -"rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__show_detail_report -msgid "True if you want that board service detail to be shown on the report" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Tuesday" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_booking_engine__reservation_type -#: model:ir.model.fields,field_description:pms.field_pms_folio__reservation_type -#: model_terms:ir.ui.view,arch_db:pms.traveller_report -msgid "Type" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__time_type -msgid "Type of date range" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__reservation_type -msgid "Type of reservations. It can be 'normal', 'staff' or 'out of service" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_sale_channel__channel_type -msgid "" -"Type of sale channel; it can be 'direct'(if there isno intermediary) or " -"'indirect'(if there areintermediaries between partner and property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_property__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_reservation__activity_exception_decoration -#: model:ir.model.fields,help:pms.field_pms_room_type__activity_exception_decoration -msgid "Type of the exception activity on record." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__room_type_ids -msgid "Types" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_ubication -#: model:ir.model.fields,field_description:pms.field_pms_room__ubication_id -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_search -msgid "Ubication" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_ubication__name -#: model:ir.model.fields,help:pms.field_pms_ubication__name -msgid "Ubication Name" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.open_pms_ubication_form_tree -msgid "Ubication Structure" -msgstr "" - -#. module: pms -#: model:ir.ui.menu,name:pms.menu_open_pms_ubication_form_tree -msgid "Ubications" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_board_service__default_code -msgid "Unique Board Service identification code per property" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__room_type_id -msgid "Unique room type for the rooms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_unit -#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_unit -#: model_terms:ir.ui.view,arch_db:pms.folio_portal_content -#: model_terms:ir.ui.view,arch_db:pms.report_folio_document -msgid "Unit Price" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_folio_sale_line__price_unit -msgid "Unit Price of folio sale line" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__per_day -#: model:ir.model.fields,field_description:pms.field_product_product__per_day -#: model:ir.model.fields,field_description:pms.field_product_template__per_day -msgid "Unit increment per day" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__per_person -#: model:ir.model.fields,field_description:pms.field_product_product__per_person -#: model:ir.model.fields,field_description:pms.field_product_template__per_person -msgid "Unit increment per person" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom -#: model:ir.model.fields,field_description:pms.field_pms_room_type__uom_id -msgid "Unit of Measure" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_category_id -msgid "Unit of Measure Category" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__uom_name -msgid "Unit of Measure Name" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_service_line__day_qty -#: model:pms.room.type,uom_name:pms.demo_pms_room_type_0 -#: model:pms.room.type,uom_name:pms.demo_pms_room_type_1 -#: model:pms.room.type,uom_name:pms.pms_room_type_0 -#: model:pms.room.type,uom_name:pms.pms_room_type_1 -#: model:pms.room.type,uom_name:pms.pms_room_type_2 -#: model:pms.room.type,uom_name:pms.pms_room_type_3 -#: model:pms.room.type,uom_name:pms.pms_room_type_4 -#: model:product.product,uom_name:pms.demo_pms_room_type_0_product_product -#: model:product.product,uom_name:pms.demo_pms_room_type_1_product_product -#: model:product.product,uom_name:pms.pms_room_type_0_product_product -#: model:product.product,uom_name:pms.pms_room_type_1_product_product -#: model:product.product,uom_name:pms.pms_room_type_2_product_product -#: model:product.product,uom_name:pms.pms_room_type_3_product_product -#: model:product.product,uom_name:pms.pms_room_type_4_product_product -#: model:product.product,uom_name:pms.pms_service_0 -#: model:product.product,uom_name:pms.pms_service_1 -#: model:product.product,uom_name:pms.pms_service_3 -#: model:product.product,uom_name:pms.pms_service_4 -#: model:product.product,uom_name:pms.pms_service_5 -#: model:product.product,uom_name:pms.pms_service_6 -#: model:product.template,uom_name:pms.pms_service_0_product_template -#: model:product.template,uom_name:pms.pms_service_1_product_template -#: model:product.template,uom_name:pms.pms_service_3_product_template -#: model:product.template,uom_name:pms.pms_service_4_product_template -#: model:product.template,uom_name:pms.pms_service_5_product_template -#: model:product.template,uom_name:pms.pms_service_6_product_template -msgid "Units" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__draft -msgid "Unkown Guest" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_unread -#: model:ir.model.fields,field_description:pms.field_pms_property__message_unread -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_unread -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_unread -msgid "Unread Messages" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_property__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_reservation__message_unread_counter -#: model:ir.model.fields,field_description:pms.field_pms_room_type__message_unread_counter -msgid "Unread Messages Counter" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__amount_untaxed -msgid "Untaxed Amount" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_to_invoice -msgid "Untaxed Amount To Invoice" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_invoiced -msgid "Untaxed Invoiced Amount" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "UoM" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "Update Prices" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__invoice_status__upselling -#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__invoice_status__upselling -msgid "Upselling Opportunity" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__barcode -msgid "Use a barcode to identify this contact." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_reservation__overnight_room -#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__overnight_room -#: model:ir.model.fields,field_description:pms.field_pms_room_type__overnight_room -#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__overnight -msgid "Use for overnight stays" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_account_journal__allowed_pms_payments -msgid "Use to pay for reservations" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__shared_folio -msgid "" -"Used to notify is the reservation folio has other reservations/services" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__user_id -msgid "User who manages the reservation" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_res_users -msgid "Users" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__currency_id -msgid "Utility field to express amount currency" -msgstr "" - -#. module: pms -#: model:room.closure.reason,name:pms.pms_room_closure_reason_1 -msgid "VIP Privacy" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__valid_product_template_attribute_line_ids -msgid "Valid Product Attribute Lines" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_res_partner_id_number__valid_from -msgid "Valid from" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_res_partner_id_number__valid_from -msgid "Validation period stating date." -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__value -msgid "Value" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_1920 -msgid "Variant Image" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_1024 -msgid "Variant Image 1024" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_128 -msgid "Variant Image 128" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_256 -msgid "Variant Image 256" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_512 -msgid "Variant Image 512" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__price_extra -msgid "Variant Price Extra" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__variant_seller_ids -msgid "Variant Seller" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__property_supplier_payment_term_id -msgid "Vendor Payment Terms" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__supplier_taxes_id -msgid "Vendor Taxes" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__seller_ids -msgid "Vendors" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "View Customer" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__volume -msgid "Volume" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__volume_uom_name -msgid "Volume unit of measure label" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_service.py:0 -#, python-format -msgid "Warning for %s" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__cardex_warning -msgid "Warning in Cardex" -msgstr "" - -#. module: pms -#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__web -msgid "Web" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__website -msgid "Website Link" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_folio__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_property__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_reservation__website_message_ids -#: model:ir.model.fields,field_description:pms.field_pms_room_type__website_message_ids -msgid "Website Messages" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__website_message_ids -#: model:ir.model.fields,help:pms.field_pms_property__website_message_ids -#: model:ir.model.fields,help:pms.field_pms_reservation__website_message_ids -#: model:ir.model.fields,help:pms.field_pms_room_type__website_message_ids -msgid "Website communication history" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.wizard_folio_changes_view_form -msgid "Wednesday" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__weight -msgid "Weight" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_room_type__weight_uom_name -msgid "Weight unit of measure label" -msgstr "" - -#. module: pms -#: model:pms.amenity,name:pms.pms_amenity_4 -msgid "Wi-Fi" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_advanced_filters_wizard -msgid "Wizard for advanced filters" -msgstr "" - -#. module: pms -#: model:ir.model,name:pms.model_pms_massive_changes_wizard -msgid "Wizard for massive changes on Availability Plans & Pricelists." -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_advanced_filters.py:0 -#, python-format -msgid "You must add filters to perform the search" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_folio.py:0 -#, python-format -msgid "You must assign a customer name" -msgstr "" - -#. module: pms -#: code:addons/pms/wizards/wizard_several_partners.py:0 -#, python-format -msgid "You must select a client to be able to add it to the reservation " -msgstr "" - -#. module: pms -#: model:mail.template,subject:pms.cancelled_reservation_email -msgid "Your reservation in ${object.pms_property_id.name} has been cancelled" -msgstr "" - -#. module: pms -#: model:mail.template,subject:pms.modified_reservation_email -msgid "Your reservation in ${object.pms_property_id.name} has been modified" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form -msgid "ZIP" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_property__zip -msgid "Zip" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_room__is_shared_room -msgid "allows you to reserve units smaller than the room itself (eg beds)" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__free_room_ids -msgid "" -"allows you to send different parameters in the context (checkin(required), " -"checkout(required), room_type_id, ubication_id, capacity, amenity_ids and / " -"or pricelist_id) and return rooms available" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_property__availability -msgid "" -"allows you to send different parameters in the context (checkin(required), " -"checkout(required), room_type_id, ubication_id, capacity,amenity_ids and / " -"or pricelist_id) check the availability for the hotel" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_automated_mails__automated_actions_id -msgid "automated action that is created when creating automated emails " -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "" -"availability rules\n" -" will be overwritten:" -msgstr "" - -#. module: pms -#: code:addons/pms/models/pms_reservation.py:0 -#, python-format -msgid "booking agency with wrong configuration: " -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation_split_join_swap_wizard__checkout -msgid "checkout in reservation" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "email" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__birthdate_date -msgid "host birthdate" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__firstname -msgid "host firstname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__gender -msgid "host gender" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__lastname -msgid "host lastname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__nationality_id -msgid "host nationality" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__lastname2 -msgid "host second lastname" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__state_id -msgid "host state" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_checkin_partner__partner_incongruences -msgid "" -"indicates that some partner fields on the checkin do not " -"correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_folio__partner_incongruences -msgid "" -"indicates that some partner fields on the folio do not " -"correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_reservation__partner_incongruences -msgid "" -"indicates that some partner fields on the reservation do not " -"correspond to that of the associated partner" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form -msgid "mobile" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard -msgid "or" -msgstr "" - -#. module: pms -#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__partner_incongruences -#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_incongruences -#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_incongruences -msgid "partner_incongruences" -msgstr "" - -#. module: pms -#: model:ir.actions.act_window,name:pms.action_pms_room_form -msgid "pms Room" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard -msgid "" -"pricelist items\n" -" will be overwritten:" -msgstr "" - -#. module: pms -#: model:ir.model.fields,help:pms.field_pms_service__channel_type -msgid "" -"sales channel through which the service was sold.It can be 'door', 'mail', " -"'phone', 'call' or 'web'" -msgstr "" - -#. module: pms -#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form -msgid "" -"these are the billing information associated with the\n" -" booking client or the company (if a company is\n" -" assigned). If you want to bill an independent contact,\n" -" you can select it in the billing assistant" -msgstr "" - -#. module: pms -#: model:ir.model.constraint,message:pms.constraint_pms_room_room_property_unique -msgid "" -"you cannot have more than one room with the same name in the same property" -msgstr "" diff --git a/pms/init_hook.py b/pms/init_hook.py deleted file mode 100644 index 5592fe58f..000000000 --- a/pms/init_hook.py +++ /dev/null @@ -1,16 +0,0 @@ -from odoo import SUPERUSER_ID -from odoo.api import Environment - - -def pre_init_hook(cr): - with Environment.manage(): - env = Environment(cr, SUPERUSER_ID, {}) - ResConfig = env["res.config.settings"] - default_values = ResConfig.default_get(list(ResConfig.fields_get())) - default_values.update( - {"group_product_pricelist": True, "group_sale_pricelist": True} - ) - ResConfig.sudo().create(default_values).execute() - env["ir.config_parameter"].sudo().set_param( - "product.product_pricelist_setting", "advanced" - ) diff --git a/pms/models/__init__.py b/pms/models/__init__.py deleted file mode 100644 index 5ab14a432..000000000 --- a/pms/models/__init__.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2018 Alexandre Díaz -# Copyright 2018 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from . import ir_http -from . import ir_config_parameter - -# from . import payment_return -from . import pms_board_service_room_type -from . import pms_property -from . import res_users -from . import pms_ubication -from . import pms_folio -from . import pms_reservation -from . import pms_room -from . import pms_amenity -from . import pms_amenity_type -from . import pms_room_type -from . import pms_service -from . import account_move -from . import product_template -from . import product_product -from . import res_company -from . import account_payment -from . import pms_availability_plan -from . import pms_availability_plan_rule -from . import pms_reservation_line -from . import pms_checkin_partner -from . import product_pricelist -from . import product_pricelist_item -from . import res_partner -from . import pms_sale_channel - -from . import mail_compose_message -from . import pms_room_type_class -from . import pms_room_closure_reason -from . import pms_service_line -from . import pms_board_service -from . import pms_board_service_room_type_line -from . import pms_board_service_line -from . import account_move_line -from . import pms_cancelation_rule -from . import folio_sale_line -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 -from . import pms_automated_mails -from . import payment_transaction diff --git a/pms/models/account_bank_statement.py b/pms/models/account_bank_statement.py deleted file mode 100644 index b01042797..000000000 --- a/pms/models/account_bank_statement.py +++ /dev/null @@ -1,16 +0,0 @@ -from odoo import fields, models - - -class AccountBankStatement(models.Model): - _inherit = "account.bank.statement" - - pms_property_id = fields.Many2one( - string="Property", - help="Properties with access to the element", - copy=False, - comodel_name="pms.property", - ) - company_id = fields.Many2one( - string="Company", - help="The company for Account Bank Statement", - ) diff --git a/pms/models/account_bank_statement_line.py b/pms/models/account_bank_statement_line.py deleted file mode 100644 index 3a4c76050..000000000 --- a/pms/models/account_bank_statement_line.py +++ /dev/null @@ -1,46 +0,0 @@ -from odoo import api, fields, models - - -class AccountBankStatementLine(models.Model): - _inherit = "account.bank.statement.line" - - folio_ids = fields.Many2many( - string="Folios", - comodel_name="pms.folio", - ondelete="cascade", - relation="account_bank_statement_folio_rel", - column1="account_journal_id", - column2="folio_id", - ) - reservation_ids = fields.Many2many( - string="Reservations", - help="Reservations in which the Account Bank Statement Lines are included", - comodel_name="pms.reservation", - ondelete="cascade", - relation="account_bank_statement_reservation_rel", - column1="account_bank_statement_id", - column2="reservation_id", - ) - service_ids = fields.Many2many( - string="Services", - help="Services in which the Account Bank Statement Lines are included", - comodel_name="pms.service", - ondelete="cascade", - relation="account_bank_statement_service_rel", - column1="account_bank_statement_id", - column2="service_id", - ) - - @api.model - def _prepare_move_line_default_vals(self, counterpart_account_id=None): - line_vals_list = super( - AccountBankStatementLine, self - )._prepare_move_line_default_vals(counterpart_account_id) - if self.folio_ids: - for line in line_vals_list: - line.update( - { - "folio_ids": [(6, 0, self.folio_ids.ids)], - } - ) - return line_vals_list diff --git a/pms/models/account_journal.py b/pms/models/account_journal.py deleted file mode 100644 index c7afb21cf..000000000 --- a/pms/models/account_journal.py +++ /dev/null @@ -1,25 +0,0 @@ -from odoo import fields, models - - -class AccountJournal(models.Model): - _inherit = "account.journal" - - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - ondelete="restrict", - relation="account_journal_pms_property_rel", - column1="account_journal_id", - column2="pms_property_id", - ) - company_id = fields.Many2one( - string="Company", - help="The company for Account Jouarnal", - check_pms_properties=True, - ) - allowed_pms_payments = fields.Boolean( - string="For manual payments", - help="Use to pay for reservations", - ) diff --git a/pms/models/account_move.py b/pms/models/account_move.py deleted file mode 100644 index d9ac60d18..000000000 --- a/pms/models/account_move.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) -import json - -from odoo import _, fields, models -from odoo.tools import float_is_zero - - -class AccountMove(models.Model): - _inherit = "account.move" - - # Field Declarations - folio_ids = fields.Many2many( - string="Folios", - help="Folios where the account move are included", - comodel_name="pms.folio", - compute="_compute_folio_origin", - relation="account_move_folio_ids_rel", - column1="account_move_id", - column2="folio_ids_id", - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property with access to the element", - comodel_name="pms.property", - ) - outstanding_folios_debits_widget = fields.Text( - compute="_compute_get_outstanding_folios_JSON" - ) - has_folios_outstanding = fields.Boolean( - compute="_compute_get_outstanding_folios_JSON" - ) - - def _compute_folio_origin(self): - for inv in self: - inv.folio_ids = False - folios = inv.mapped("invoice_line_ids.folio_ids") - if folios: - inv.folio_ids = [(6, 0, folios.ids)] - - def _compute_get_outstanding_folios_JSON(self): - self.ensure_one() - self.outstanding_folios_debits_widget = json.dumps(False) - if self.from_folio: - payment_ids = self.folio_ids.mapped("payment_ids.id") - if self.state == "open": - account_partner = ( - self.env["res.partner"]._find_accounting_partner(self.partner_id).id - ) - domain = [ - ("account_id", "=", self.account_id.id), - ("partner_id", "!=", account_partner), - ("reconciled", "=", False), - ("payment_id", "in", payment_ids), - "|", - "&", - ("amount_residual_currency", "!=", 0.0), - ("currency_id", "!=", None), - "&", - ("amount_residual_currency", "=", 0.0), - "&", - ("currency_id", "=", None), - ("amount_residual", "!=", 0.0), - ] - if self.type in ("out_invoice", "in_refund"): - domain.extend([("credit", ">", 0), ("debit", "=", 0)]) - type_payment = _("Outstanding credits in Folio") - else: - domain.extend([("credit", "=", 0), ("debit", ">", 0)]) - type_payment = _("Outstanding debits") - info = { - "title": "", - "outstanding": True, - "content": [], - "move_id": self.id, - } - lines = self.env["account.move.line"].search(domain) - currency_id = self.currency_id - if len(lines) != 0: - for line in lines: - # get the outstanding residual value in inv. currency - if line.currency_id and line.currency_id == self.currency_id: - amount_to_show = abs(line.amount_residual_currency) - else: - amount_to_show = line.company_id.currency_id.with_context( - date=line.date - ).compute(abs(line.amount_residual), self.currency_id) - if float_is_zero( - amount_to_show, precision_rounding=self.currency_id.rounding - ): - continue - if line.ref: - title = "{} : {}".format(line.move_id.name, line.ref) - else: - title = line.move_id.name - info["content"].append( - { - "journal_name": line.ref or line.move_id.name, - "title": title, - "amount": amount_to_show, - "currency": currency_id.symbol, - "id": line.id, - "position": currency_id.position, - "digits": [69, self.currency_id.decimal_places], - } - ) - info["title"] = type_payment - self.outstanding_folios_debits_widget = json.dumps(info) - self.has_folio_outstanding = True - - def action_folio_payments(self): - self.ensure_one() - sales = self.mapped("invoice_line_ids.sale_line_ids.order_id") - folios = self.env["pms.folio"].search([("order_id.id", "in", sales.ids)]) - payments_obj = self.env["account.payment"] - payments = payments_obj.search([("folio_id", "in", folios.ids)]) - payment_ids = payments.mapped("id") - return { - "name": _("Payments"), - "view_type": "form", - "view_mode": "tree,form", - "res_model": "account.payment", - "target": "new", - "type": "ir.actions.act_window", - "domain": [("id", "in", payment_ids)], - } diff --git a/pms/models/account_move_line.py b/pms/models/account_move_line.py deleted file mode 100644 index 515edf5d6..000000000 --- a/pms/models/account_move_line.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) -from odoo import api, fields, models - - -class AccountMoveLine(models.Model): - _inherit = "account.move.line" - - # Fields declaration - # TODO: REVIEW why not a Many2one? - folio_line_ids = fields.Many2many( - string="Folio Lines", - help="The folio lines in the account move lines", - copy=False, - comodel_name="folio.sale.line", - relation="folio_sale_line_invoice_rel", - column1="invoice_line_id", - column2="sale_line_id", - ) - folio_ids = fields.Many2many( - string="Folios", - comodel_name="pms.folio", - relation="payment_folio_rel", - column1="move_id", - column2="folio_id", - ) - name_changed_by_user = fields.Boolean( - string="Custom label", - readonly=False, - default=False, - store=True, - compute="_compute_name_changed_by_user", - ) - - @api.depends("name") - def _compute_name_changed_by_user(self): - for record in self: - # if not record._context.get("auto_name"): - if not self._context.get("auto_name"): - record.name_changed_by_user = True - else: - record.name_changed_by_user = False - - name = fields.Char( - compute="_compute_name", - store=True, - readonly=False, - ) - - @api.depends("quantity") - def _compute_name(self): - for record in self: - record.name = self.env["folio.sale.line"].generate_folio_sale_name( - record.folio_line_ids.reservation_id, - record.product_id, - record.folio_line_ids.service_id, - record.folio_line_ids.reservation_line_ids, - record.folio_line_ids.service_line_ids, - qty=record.quantity, - ) - # TODO: check why this code doesn't work - # if not record.name_changed_by_user: - # record.with_context(auto_name=True).name = self - # .env["folio.sale.line"].generate_folio_sale_name( - # record.folio_line_ids.service_id, - # record.folio_line_ids.reservation_line_ids, - # record.product_id, - # qty=record.quantity) - # record.with_context(auto_name=True) - # ._compute_name_changed_by_user() - - def _copy_data_extend_business_fields(self, values): - super(AccountMoveLine, self)._copy_data_extend_business_fields(values) - values["folio_line_ids"] = [(6, None, self.folio_line_ids.ids)] diff --git a/pms/models/account_payment.py b/pms/models/account_payment.py deleted file mode 100644 index 197b7c575..000000000 --- a/pms/models/account_payment.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class AccountPayment(models.Model): - _inherit = "account.payment" - - # Fields declaration - folio_ids = fields.Many2many( - string="Folios", - comodel_name="pms.folio", - ondelete="cascade", - relation="account_payment_folio_rel", - column1="payment_id", - column2="folio_id", - ) - - def _prepare_move_line_default_vals(self, write_off_line_vals=None): - line_vals_list = super(AccountPayment, self)._prepare_move_line_default_vals( - write_off_line_vals - ) - if self.folio_ids: - for line in line_vals_list: - line.update( - { - "folio_ids": [(6, 0, self.folio_ids.ids)], - } - ) - return line_vals_list - - # Business methods - - # def modify(self): - # self.cancel() - # vals = { - # "journal_id": self.journal_id, - # "partner_id": self.partner_id, - # "amount": self.amount, - # "payment_date": self.payment_date, - # "communication": self.communication, - # "state": "draft", - # } - # self.update(vals) - # self.with_context({"ignore_notification_post": True}).post() - # self._compute_folio_amount() - # if self.folio_id: - # msg = _("Payment %s modified: \n") % (self.communication) - # if self.save_amount and self.save_amount != self.amount: - # msg += _("Amount from %s to %s %s \n") % ( - # self.save_amount, - # self.amount, - # self.currency_id.symbol, - # ) - # if self.save_date and self.save_date != self.payment_date: - # msg += _("Date from %s to %s \n") % (self.save_date, self.payment_date) - # if self.save_journal_id and self.save_journal_id != self.journal_id.id: - # msg += _("Journal from %s to %s") % ( - # self.env["account.journal"].browse(self.save_journal_id).name, - # self.journal_id.name, - # ) - # self.folio_id.message_post(subject=_("Payment"), body=msg) - - # def delete(self): - # msg = False - # if self.folio_id: - # msg = _("Deleted payment: %s %s ") % (self.amount, self.currency_id.symbol) - # self.cancel() - # self.move_name = "" - # self.unlink() - # if msg: - # self.folio_id.message_post(subject=_("Payment Deleted"), body=msg) - - # def post(self): - # rec = super(AccountPayment, self).post() - # if rec and not self._context.get("ignore_notification_post", False): - # for pay in self: - # if pay.folio_id: - # msg = _( - # "Payment of %s %s registered from %s \ - # using %s payment method" - # ) % ( - # pay.amount, - # pay.currency_id.symbol, - # pay.communication, - # pay.journal_id.name, - # ) - # pay.folio_id.message_post(subject=_("Payment"), body=msg) - - # def modify_payment(self): - # self.ensure_one() - # view_form_id = self.env.ref("pms.account_payment_view_form_folio").id - # # moves = self.mapped('move_ids.id') - # return { - # "name": _("Payment"), - # "view_type": "form", - # "views": [(view_form_id, "form")], - # "view_mode": "tree,form", - # "res_model": "account.payment", - # "target": "new", - # "init_mode": "edit", - # "type": "ir.actions.act_window", - # "res_id": self.id, - # } diff --git a/pms/models/folio_sale_line.py b/pms/models/folio_sale_line.py deleted file mode 100644 index 5910bd8af..000000000 --- a/pms/models/folio_sale_line.py +++ /dev/null @@ -1,1012 +0,0 @@ -# Copyright 2020 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from math import ceil - -from odoo import _, api, fields, models -from odoo.osv import expression -from odoo.tools import float_compare, float_is_zero - - -class FolioSaleLine(models.Model): - _name = "folio.sale.line" - _description = "Folio Sale Line" - _order = "folio_id, sequence, reservation_order desc, service_order, date_order" - - _check_company_auto = True - - folio_id = fields.Many2one( - string="Folio Reference", - help="Folio to which folio sale line belongs", - required=True, - index=True, - copy=False, - comodel_name="pms.folio", - ondelete="cascade", - ) - reservation_id = fields.Many2one( - string="Reservation Reference", - help="Reservation to which folio sale line belongs", - index=True, - copy=False, - comodel_name="pms.reservation", - ondelete="cascade", - ) - service_id = fields.Many2one( - string="Service Reference", - help="Sevice included in folio sale line", - index=True, - copy=False, - comodel_name="pms.service", - ondelete="cascade", - ) - is_board_service = fields.Boolean( - string="Board Service", - help="Indicates if the service included in " - "folio sale line is part of a board service", - store=True, - related="service_id.is_board_service", - ) - - name = fields.Text( - string="Description", - help="Description of folio sale line", - readonly=False, - store=True, - compute="_compute_name", - ) - reservation_line_ids = fields.Many2many( - string="Nights", - help="Reservation lines associated with folio sale line," - " they corresponds with nights", - comodel_name="pms.reservation.line", - ) - service_line_ids = fields.Many2many( - string="Service Lines", - help="Subservices included in folio sale line service", - comodel_name="pms.service.line", - ) - sequence = fields.Integer(string="Sequence", help="", default=10) - - invoice_lines = fields.Many2many( - string="Invoice Lines", - copy=False, - help="Folio sale line invoice lines", - comodel_name="account.move.line", - relation="folio_sale_line_invoice_rel", - column1="sale_line_id", - column2="invoice_line_id", - ) - invoice_status = fields.Selection( - string="Invoice Status", - help="Invoice Status; it can be: upselling, invoiced, to invoice, no", - readonly=True, - store=True, - selection=[ - ("upselling", "Upselling Opportunity"), - ("invoiced", "Fully Invoiced"), - ("to_invoice", "To Invoice"), - ("no", "Nothing to Invoice"), - ], - compute="_compute_invoice_status", - ) - price_unit = fields.Float( - string="Unit Price", - help="Unit Price of folio sale line", - digits="Product Price", - ) - - price_subtotal = fields.Monetary( - string="Subtotal", - help="Subtotal price without taxes", - readonly=True, - store=True, - compute="_compute_amount", - ) - price_tax = fields.Float( - string="Total Tax", - help="Total of taxes in a reservation", - readonly=True, - store=True, - compute="_compute_amount", - ) - price_total = fields.Monetary( - string="Total", - help="Total price with taxes", - readonly=True, - store=True, - compute="_compute_amount", - ) - price_reduce = fields.Float( - string="Price Reduce", - help="Reduced price amount, that is, total price with discounts applied", - readonly=True, - store=True, - digits="Product Price", - compute="_compute_get_price_reduce", - ) - tax_ids = fields.Many2many( - string="Taxes", - help="Taxes applied in the folio sale line", - store=True, - comodel_name="account.tax", - compute="_compute_tax_ids", - domain=["|", ("active", "=", False), ("active", "=", True)], - ) - price_reduce_taxinc = fields.Monetary( - string="Price Reduce Tax inc", - help="Price with discounts applied and taxes included", - readonly=True, - store=True, - compute="_compute_get_price_reduce_tax", - ) - price_reduce_taxexcl = fields.Monetary( - string="Price Reduce Tax excl", - help="Price with discounts applied without taxes", - readonly=True, - store=True, - compute="_compute_get_price_reduce_notax", - ) - - discount = fields.Float( - string="Discount (%)", - help="Discount of total price in folio sale line", - readonly=False, - store=True, - digits="Discount", - compute="_compute_discount", - ) - - product_id = fields.Many2one( - string="Product", - help="Product associated with folio sale line, " - "can be product associated with service " - "or product associated with" - "reservation's room type, in other case it's false", - store=True, - comodel_name="product.product", - domain="[('sale_ok', '=', True),\ - '|', ('company_id', '=', False), \ - ('company_id', '=', company_id)]", - ondelete="restrict", - compute="_compute_product_id", - check_company=True, - change_default=True, - ) - product_uom_qty = fields.Float( - string="Quantity", - help="", - readonly=False, - store=True, - digits="Product Unit of Measure", - compute="_compute_product_uom_qty", - ) - product_uom = fields.Many2one( - string="Unit of Measure", - help="", - comodel_name="uom.uom", - domain="[('category_id', '=', product_uom_category_id)]", - ) - product_uom_category_id = fields.Many2one( - string="Unit of Measure Category", - help="", - readonly=True, - related="product_id.uom_id.category_id", - ) - product_uom_readonly = fields.Boolean( - string="", help="", compute="_compute_product_uom_readonly" - ) - - product_custom_attribute_value_ids = fields.One2many( - string="Custom Values", - copy=True, - comodel_name="product.attribute.custom.value", - inverse_name="sale_order_line_id", - ) - - qty_to_invoice = fields.Float( - string="To Invoice Quantity", - help="The quantity to invoice. If the invoice policy is order, " - "the quantity to invoice is calculated from the ordered quantity. " - "Otherwise, the quantity delivered is used.", - readonly=True, - store=True, - digits="Product Unit of Measure", - compute="_compute_get_to_invoice_qty", - ) - qty_invoiced = fields.Float( - string="Invoiced Quantity", - help="It is the amount invoiced when an invoice is issued", - readonly=True, - store=True, - digits="Product Unit of Measure", - compute="_compute_get_invoice_qty", - compute_sudo=True, - ) - - untaxed_amount_invoiced = fields.Monetary( - string="Untaxed Invoiced Amount", - help="The amount to invoice without taxes in the line of folio", - store=True, - compute="_compute_untaxed_amount_invoiced", - compute_sudo=True, - ) - untaxed_amount_to_invoice = fields.Monetary( - string="Untaxed Amount To Invoice", - help="The invoiced amount without taxes in the line of the folio", - store=True, - compute="_compute_untaxed_amount_to_invoice", - compute_sudo=True, - ) - - currency_id = fields.Many2one( - string="Currency", - help="The currency for the folio", - readonly=True, - store=True, - depends=["folio_id.currency_id"], - related="folio_id.currency_id", - ) - company_id = fields.Many2one( - string="Company", - help="The company in the folio sale line", - readonly=True, - store=True, - index=True, - related="folio_id.company_id", - check_pms_properties=True, - ) - folio_partner_id = fields.Many2one( - string="Customer", - help="Related customer with Folio Sale Line", - readonly=False, - store=True, - related="folio_id.partner_id", - ) - analytic_tag_ids = fields.Many2many( - string="Analytic Tags", - comodel_name="account.analytic.tag", - domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", - ) - analytic_line_ids = fields.One2many( - string="Analytic lines", - comodel_name="account.analytic.line", - inverse_name="so_line", - ) - is_downpayment = fields.Boolean( - string="Is a down payment", - help="Down payments are made when creating invoices from a folio." - " They are not copied when duplicating a folio.", - ) - - state = fields.Selection( - string="Folio Status", - help="The status of the folio related with folio sale line", - readonly=True, - copy=False, - store=True, - related="folio_id.state", - ) - - display_type = fields.Selection( - string="Display Type", - help="Technical field for UX purpose.", - selection=[("line_section", "Section"), ("line_note", "Note")], - default=False, - ) - - service_order = fields.Integer( - string="Service Id", - help="Field to order by service id", - readonly=True, - store=True, - compute="_compute_service_order", - ) - - reservation_order = fields.Integer( - string="Reservation Id", - help="Field to order by reservation id", - readonly=True, - store=True, - compute="_compute_reservation_order", - ) - - date_order = fields.Date( - string="Date", - help="Field to order by service", - readonly=True, - store=True, - compute="_compute_date_order", - ) - - @api.depends("qty_to_invoice") - def _compute_service_order(self): - for record in self: - record.service_order = ( - record.service_id - if record.service_id - else -1 - if record.display_type - else 0 - ) - - @api.depends("service_order") - def _compute_date_order(self): - for record in self: - if record.display_type: - record.date_order = 0 - elif record.reservation_id and not record.service_id: - record.date_order = ( - min(record.reservation_line_ids.mapped("date")) - if record.reservation_line_ids - else 0 - ) - elif record.reservation_id and record.service_id: - record.date_order = ( - min(record.service_line_ids.mapped("date")) - if record.service_line_ids - else 0 - ) - else: - record.date_order = 0 - - @api.depends("date_order") - def _compute_reservation_order(self): - for record in self: - record.reservation_order = ( - record.reservation_id if record.reservation_id else 0 - ) - - @api.depends("reservation_line_ids", "service_line_ids", "service_line_ids.day_qty") - def _compute_product_uom_qty(self): - for line in self: - if line.reservation_line_ids: - line.product_uom_qty = len(line.reservation_line_ids) - elif line.service_line_ids: - line.product_uom_qty = sum(line.service_line_ids.mapped("day_qty")) - elif not line.product_uom_qty: - line.product_uom_qty = False - - @api.depends("state") - def _compute_product_uom_readonly(self): - for line in self: - line.product_uom_readonly = line.state in ["sale", "done", "cancel"] - - @api.depends( - "invoice_lines", - "invoice_lines.price_total", - "invoice_lines.move_id.state", - "invoice_lines.move_id.move_type", - ) - def _compute_untaxed_amount_invoiced(self): - """Compute the untaxed amount already invoiced from - the sale order line, taking the refund attached - the so line into account. This amount is computed as - SUM(inv_line.price_subtotal) - SUM(ref_line.price_subtotal) - where - `inv_line` is a customer invoice line linked to the SO line - `ref_line` is a customer credit note (refund) line linked to the SO line - """ - for line in self: - amount_invoiced = 0.0 - for invoice_line in line.invoice_lines: - if invoice_line.move_id.state == "posted": - invoice_date = ( - invoice_line.move_id.invoice_date or fields.Date.today() - ) - if invoice_line.move_id.move_type == "out_invoice": - amount_invoiced += invoice_line.currency_id._convert( - invoice_line.price_subtotal, - line.currency_id, - line.company_id, - invoice_date, - ) - elif invoice_line.move_id.move_type == "out_refund": - amount_invoiced -= invoice_line.currency_id._convert( - invoice_line.price_subtotal, - line.currency_id, - line.company_id, - invoice_date, - ) - line.untaxed_amount_invoiced = amount_invoiced - - @api.depends( - "state", - "price_reduce", - "product_id", - "untaxed_amount_invoiced", - "product_uom_qty", - ) - def _compute_untaxed_amount_to_invoice(self): - """Total of remaining amount to invoice on the sale order line (taxes excl.) as - total_sol - amount already invoiced - where Total_sol depends on the invoice policy of the product. - - Note: Draft invoice are ignored on purpose, the 'to invoice' amount should - come only from the SO lines. - """ - for line in self: - amount_to_invoice = 0.0 - if line.state != "draft": - # Note: do not use price_subtotal field as it returns - # zero when the ordered quantity is zero. - # It causes problem for expense line (e.i.: ordered qty = 0, - # deli qty = 4, price_unit = 20 ; subtotal is zero), - # but when you can invoice the line, - # you see an amount and not zero. - # Since we compute untaxed amount, we can use directly the price - # reduce (to include discount) without using `compute_all()` - # method on taxes. - price_subtotal = 0.0 - price_subtotal = line.price_reduce * line.product_uom_qty - if len(line.tax_ids.filtered(lambda tax: tax.price_include)) > 0: - # As included taxes are not excluded from the computed subtotal, - # `compute_all()` method has to be called to retrieve - # the subtotal without them. - # `price_reduce_taxexcl` cannot be used as it is computed from - # `price_subtotal` field. (see upper Note) - price_subtotal = line.tax_ids.compute_all( - price_subtotal, - currency=line.folio_id.currency_id, - quantity=line.product_uom_qty, - product=line.product_id, - partner=line.folio_id.partner_id, - )["total_excluded"] - - if any( - line.invoice_lines.mapped(lambda l: l.discount != line.discount) - ): - # In case of re-invoicing with different - # discount we try to calculate manually the - # remaining amount to invoice - amount = 0 - for inv_line in line.invoice_lines: - if ( - len( - inv_line.tax_ids.filtered(lambda tax: tax.price_include) - ) - > 0 - ): - amount += inv_line.tax_ids.compute_all( - inv_line.currency_id._convert( - inv_line.price_unit, - line.currency_id, - line.company_id, - inv_line.date or fields.Date.today(), - round=False, - ) - * inv_line.quantity - )["total_excluded"] - else: - amount += ( - inv_line.currency_id._convert( - inv_line.price_unit, - line.currency_id, - line.company_id, - inv_line.date or fields.Date.today(), - round=False, - ) - * inv_line.quantity - ) - - amount_to_invoice = max(price_subtotal - amount, 0) - else: - amount_to_invoice = price_subtotal - line.untaxed_amount_invoiced - - line.untaxed_amount_to_invoice = amount_to_invoice - - @api.depends("state", "product_uom_qty", "qty_to_invoice", "qty_invoiced") - def _compute_invoice_status(self): - """ - Compute the invoice status of a SO line: - Its if compute based on reservations/services associated status - """ - precision = self.env["decimal.precision"].precision_get( - "Product Unit of Measure" - ) - for line in self: - if line.state == "draft": - line.invoice_status = "no" - # REVIEW: if qty_to_invoice < 0 (invoice qty > sale qty), - # why status to_invoice?? this behavior is copied from sale order - # https://github.com/OCA/OCB/blob/14.0/addons/sale/models/sale.py#L1160 - elif not float_is_zero(line.qty_to_invoice, precision_digits=precision): - line.invoice_status = "to_invoice" - elif ( - float_compare( - line.qty_invoiced, - line.product_uom_qty, - precision_digits=precision, - ) - >= 0 - ): - line.invoice_status = "invoiced" - else: - line.invoice_status = "no" - - @api.depends("reservation_line_ids", "service_line_ids", "service_id") - def _compute_name(self): - for record in self: - record.name = self.generate_folio_sale_name( - record.reservation_id, - record.product_id, - record.service_id, - record.reservation_line_ids, - record.service_line_ids, - ) - - @api.depends("product_uom_qty", "discount", "price_unit", "tax_ids") - def _compute_amount(self): - """ - Compute the amounts of the Sale line. - """ - for line in self: - price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) - taxes = line.tax_ids.compute_all( - price, - line.folio_id.currency_id, - line.product_uom_qty, - product=line.product_id, - ) - line.update( - { - "price_tax": sum( - t.get("amount", 0.0) for t in taxes.get("taxes", []) - ), - "price_total": taxes["total_included"], - "price_subtotal": taxes["total_excluded"], - } - ) - if self.env.context.get( - "import_file", False - ) and not self.env.user.user_has_groups("account.group_account_manager"): - line.tax_ids.invalidate_cache( - ["invoice_repartition_line_ids"], [line.tax_ids.id] - ) - - @api.depends("reservation_id.tax_ids", "service_id.tax_ids") - def _compute_tax_ids(self): - for record in self: - record.tax_ids = ( - record.service_id.tax_ids - if record.service_id - else record.reservation_id.tax_ids - ) - - @api.depends( - "service_id", - "service_id.service_line_ids", - "service_id.service_line_ids.discount", - ) - def _compute_discount(self): - """ - Only in services without room we compute discount, - and this services only have one service line - """ - for record in self: - if record.service_id and not record.service_id.reservation_id: - record.discount = record.service_id.service_line_ids.mapped("discount")[ - 0 - ] - elif not record.discount: - record.discount = 0 - - @api.depends("reservation_id.room_type_id", "service_id.product_id") - def _compute_product_id(self): - for record in self: - if record.reservation_id and not record.service_id: - record.product_id = record.reservation_id.room_type_id.product_id - elif record.service_id: - record.product_id = record.service_id.product_id - else: - record.product_id = False - - # @api.depends('product_id', 'folio_id.state', 'qty_invoiced', 'qty_delivered') - # def _compute_product_updatable(self): - # for line in self: - # if line.state in ['done', 'cancel'] or ( - # line.state == 'sale' and ( - # line.qty_invoiced > 0 or line.qty_delivered > 0)): - # line.product_updatable = False - # else: - # line.product_updatable = True - - # no trigger product_id.invoice_policy to avoid retroactively changing SO - @api.depends("qty_invoiced", "product_uom_qty", "folio_id.state") - def _compute_get_to_invoice_qty(self): - """ - Compute the quantity to invoice. - If the invoice policy is order, the quantity to invoice is - calculated from the ordered quantity. - Otherwise, the quantity delivered is used. - """ - for line in self: - if line.folio_id.state not in ["draft"]: - line.qty_to_invoice = line.product_uom_qty - line.qty_invoiced - else: - line.qty_to_invoice = 0 - - @api.depends( - "invoice_lines.move_id.state", - "invoice_lines.quantity", - "untaxed_amount_to_invoice", - ) - def _compute_get_invoice_qty(self): - """ - Compute the quantity invoiced. If case of a refund, - the quantity invoiced is decreased. Note - that this is the case only if the refund is - generated from the Folio and that is intentional: if - a refund made would automatically decrease the invoiced quantity, - then there is a risk of reinvoicing - it automatically, which may not be wanted at all. - That's why the refund has to be created from the Folio - """ - for line in self: - qty_invoiced = 0.0 - for invoice_line in line.invoice_lines: - if invoice_line.move_id.state != "cancel": - if invoice_line.move_id.move_type == "out_invoice": - qty_invoiced += invoice_line.product_uom_id._compute_quantity( - invoice_line.quantity, line.product_uom - ) - elif invoice_line.move_id.move_type == "out_refund": - if ( - not line.is_downpayment - or line.untaxed_amount_to_invoice == 0 - ): - qty_invoiced -= ( - invoice_line.product_uom_id._compute_quantity( - invoice_line.quantity, line.product_uom - ) - ) - line.qty_invoiced = qty_invoiced - - @api.depends("price_unit", "discount") - def _compute_get_price_reduce(self): - for line in self: - line.price_reduce = line.price_unit * (1.0 - line.discount / 100.0) - - @api.depends("price_total", "product_uom_qty") - def _compute_get_price_reduce_tax(self): - for line in self: - line.price_reduce_taxinc = ( - line.price_total / line.product_uom_qty if line.product_uom_qty else 0.0 - ) - - @api.depends("price_subtotal", "product_uom_qty") - def _compute_get_price_reduce_notax(self): - for line in self: - line.price_reduce_taxexcl = ( - line.price_subtotal / line.product_uom_qty - if line.product_uom_qty - else 0.0 - ) - - # @api.model - # def _prepare_add_missing_fields(self, values): - # """ Deduce missing required fields from the onchange """ - # res = {} - # onchange_fields = ['name', 'price_unit', 'product_uom', 'tax_ids'] - # if values.get('folio_id') and values.get('product_id') and any( - # f not in values for f in onchange_fields - # ): - # line = self.new(values) - # line.product_id_change() - # for field in onchange_fields: - # if field not in values: - # res[field] = line._fields[field].convert_to_write( - # line[field], line - # ) - # return res - - # @api.model_create_multi - # def create(self, vals_list): - # for values in vals_list: - # if values.get('display_type', self.default_get( - # ['display_type'])['display_type'] - # ): - # values.update(product_id=False, price_unit=0, - # product_uom_qty=0, product_uom=False, - # customer_lead=0) - - # values.update(self._prepare_add_missing_fields(values)) - - # lines = super().create(vals_list) - # for line in lines: - # if line.product_id and line.folio_id.state == 'sale': - # msg = _("Extra line with %s ") % (line.product_id.display_name,) - # line.folio_id.message_post(body=msg) - # # create an analytic account if at least an expense product - # if line.product_id.expense_policy not in [False, 'no'] and \ - # not line.folio_id.analytic_account_id: - # line.folio_id._create_analytic_account() - # return lines - - # _sql_constraints = [ - # ('accountable_required_fields', - # "CHECK(display_type IS NOT NULL OR \ - # (product_id IS NOT NULL AND product_uom IS NOT NULL))", - # "Missing required fields on accountable sale order line."), - # ('non_accountable_null_fields', - # "CHECK(display_type IS NULL OR (product_id IS NULL AND \ - # price_unit = 0 AND product_uom_qty = 0 AND \ - # product_uom IS NULL AND customer_lead = 0))", - # "Forbidden values on non-accountable sale order line"), - # ] - @api.model - def _name_search( - self, name, args=None, operator="ilike", limit=100, name_get_uid=None - ): - if operator in ("ilike", "like", "=", "=like", "=ilike"): - args = expression.AND( - [ - args or [], - ["|", ("folio_id.name", operator, name), ("name", operator, name)], - ] - ) - return super(FolioSaleLine, self)._name_search( - name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid - ) - - def name_get(self): - result = [] - for so_line in self.sudo(): - name = "{} - {}".format( - so_line.folio_id.name, - so_line.name and so_line.name.split("\n")[0] or so_line.product_id.name, - ) - result.append((so_line.id, name)) - return result - - @api.model - def generate_folio_sale_name( - self, - reservation_id, - product_id, - service_id, - reservation_line_ids, - service_line_ids, - qty=False, - ): - if reservation_line_ids: - month = False - name = False - lines = reservation_line_ids.sorted(key="date") - for index, date in enumerate(lines.mapped("date")): - if qty and index > (qty - 1): - break - if date.month != month: - name = name + "\n" if name else "" - name += date.strftime("%B-%Y") + ": " - name += date.strftime("%d") - month = date.month - else: - name += ", " + date.strftime("%d") - - return "{} ({}).".format(product_id.name, name) - elif service_line_ids: - month = False - name = False - lines = service_line_ids.filtered( - lambda x: x.service_id == service_id - ).sorted(key="date") - - for index, date in enumerate(lines.mapped("date")): - if qty and index > (ceil(qty / reservation_id.adults) - 1): - break - if date.month != month: - name = name + "\n" if name else "" - name += date.strftime("%B-%Y") + ": " - name += date.strftime("%d") - month = date.month - else: - name += ", " + date.strftime("%d") - return "{} ({}).".format(service_id.name, name) - else: - return service_id.name - - def _get_invoice_line_sequence(self, new=0, old=0): - """ - Method intended to be overridden in third-party - module if we want to prevent the resequencing of invoice lines. - - :param int new: the new line sequence - :param int old: the old line sequence - - :return: the sequence of the SO line, by default the new one. - """ - return new or old - - def _update_line_quantity(self, values): - folios = self.mapped("folio_id") - for order in folios: - order_lines = self.filtered(lambda x: x.folio_id == order) - msg = "" + _("The ordered quantity has been updated.") + "
    " - for line in order_lines: - msg += "
  • %s:
    " % line.product_id.display_name - msg += ( - _( - "Ordered Quantity: %(old_qty)s -> %(new_qty)s", - old_qty=line.product_uom_qty, - new_qty=values["product_uom_qty"], - ) - + "
    " - ) - # if line.product_id.type in ('consu', 'product'): - # msg += _("Delivered Quantity: %s", line.qty_delivered) + "
    " - msg += _("Invoiced Quantity: %s", line.qty_invoiced) + "
    " - msg += "
" - order.message_post(body=msg) - - # def write(self, values): - # if 'display_type' in values and self.filtered( - # lambda line: line.display_type != values.get('display_type')): - # raise UserError(_("You cannot change the type of a sale order line.\ - # Instead you should delete the current line and create \ - # a new line of the proper type.")) - - # if 'product_uom_qty' in values: - # precision = self.env['decimal.precision'].precision_get( - # 'Product Unit of Measure' - # ) - # self.filtered( - # lambda r: r.state == 'sale' and \ - # float_compare( - # r.product_uom_qty, - # values['product_uom_qty'], - # precision_digits=precision) != 0)._update_line_quantity( - # values - # ) - - # # Prevent writing on a locked SO. - # protected_fields = self._get_protected_fields() - # if 'done' in self.mapped('folio_id.state') and any( - # f in values.keys() for f in protected_fields - # ): - # protected_fields_modified = list(set(protected_fields) & set( - # values.keys() - # )) - # fields = self.env['ir.model.fields'].search([ - # ('name', 'in', protected_fields_modified), - # ('model', '=', self._name) - # ]) - # raise UserError( - # _('It is forbidden to modify the following \ - # fields in a locked order:\n%s') - # % '\n'.join(fields.mapped('field_description')) - # ) - - # result = super(SaleOrderLine, self).write(values) - # return resul def _prepare_invoice_line(self, qty=False, **optional_values): - def _prepare_invoice_line(self, qty=False, **optional_values): - """ - Prepare the dict of values to create the new invoice line for a folio sale line. - - :param qty: float quantity to invoice - :param optional_values: any parameter that - should be added to the returned invoice line - """ - self.ensure_one() - if (qty > self.qty_to_invoice or qty < 1) and not self.display_type: - raise ValueError( - _( - "The qty (%s) is wrong." % qty - + " The quantity pending to invoice is %s" % self.qty_to_invoice - ) - ) - res = { - "display_type": self.display_type, - "sequence": self.sequence, - "name": self.name, - "product_id": self.product_id.id, - "product_uom_id": self.product_uom.id, - "quantity": qty if qty else self.qty_to_invoice, - "discount": self.discount, - "price_unit": self.price_unit, - "tax_ids": [(6, 0, self.tax_ids.ids)], - "analytic_account_id": self.folio_id.analytic_account_id.id, - "analytic_tag_ids": [(6, 0, self.analytic_tag_ids.ids)], - "folio_line_ids": [(6, 0, [self.id])], - } - if optional_values: - res.update(optional_values) - if self.display_type: - res["account_id"] = False - return res - - def _check_line_unlink(self): - """ - Check wether a line can be deleted or not. - - Lines cannot be deleted if the folio is confirmed; downpayment - lines who have not yet been invoiced bypass that exception. - :rtype: recordset folio.sale.line - :returns: set of lines that cannot be deleted - """ - return self.filtered( - lambda line: line.state not in ("draft") - and (line.invoice_lines or not line.is_downpayment) - ) - - # def unlink(self): - # if self._check_line_unlink(): - # raise UserError( - # _("""You can not remove an sale line once the sales - # folio is confirmed.\n - # You should rather set the quantity to 0.""") - # ) - # return super(FolioSaleLine, self).unlink() - - def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id): - """Retrieve the price before applying the pricelist - :param obj product: object of current product record - :parem float qty: total quentity of product - :param tuple price_and_rule: tuple(price, suitable_rule) - coming from pricelist computation - :param obj uom: unit of measure of current folio line - :param integer pricelist_id: pricelist id of folio""" - PricelistItem = self.env["product.pricelist.item"] - field_name = "lst_price" - currency_id = None - product_currency = product.currency_id - if rule_id: - pricelist_item = PricelistItem.browse(rule_id) - if pricelist_item.pricelist_id.discount_policy == "without_discount": - while ( - pricelist_item.base == "pricelist" - and pricelist_item.base_pricelist_id - and pricelist_item.base_pricelist_id.discount_policy - == "without_discount" - ): - price, rule_id = pricelist_item.base_pricelist_id.with_context( - uom=uom.id - ).get_product_price_rule(product, qty, self.folio_id.partner_id) - pricelist_item = PricelistItem.browse(rule_id) - - if pricelist_item.base == "standard_price": - field_name = "standard_price" - product_currency = product.cost_currency_id - elif ( - pricelist_item.base == "pricelist" and pricelist_item.base_pricelist_id - ): - field_name = "price" - product = product.with_context( - pricelist=pricelist_item.base_pricelist_id.id - ) - product_currency = pricelist_item.base_pricelist_id.currency_id - currency_id = pricelist_item.pricelist_id.currency_id - - if not currency_id: - currency_id = product_currency - cur_factor = 1.0 - else: - if currency_id.id == product_currency.id: - cur_factor = 1.0 - else: - cur_factor = currency_id._get_conversion_rate( - product_currency, - currency_id, - self.company_id or self.env.company, - self.folio_id.date_order or fields.Date.today(), - ) - - product_uom = self.env.context.get("uom") or product.uom_id.id - if uom and uom.id != product_uom: - # the unit price is in a different uom - uom_factor = uom._compute_price(1.0, product.uom_id) - else: - uom_factor = 1.0 - - return product[field_name] * uom_factor * cur_factor, currency_id - - def _get_protected_fields(self): - return [ - "product_id", - "name", - "price_unit", - "product_uom", - "product_uom_qty", - "tax_ids", - "analytic_tag_ids", - ] diff --git a/pms/models/ir_config_parameter.py b/pms/models/ir_config_parameter.py deleted file mode 100644 index a561369ac..000000000 --- a/pms/models/ir_config_parameter.py +++ /dev/null @@ -1,22 +0,0 @@ -from odoo import _, api, models -from odoo.exceptions import ValidationError - - -class IrConfigParameter(models.Model): - _inherit = "ir.config_parameter" - - def unlink(self): - for record in self: - if ( - record.key == "product.product_pricelist_setting" - and record.value == "advanced" - ): - raise ValidationError(_("Cannot delete this parameter")) - return super().unlink() - - @api.constrains("key", "value") - def check_value(self): - if self.key == "product.product_pricelist_setting" and self.value != "advanced": - raise ValidationError( - _("The parameter Advanced price rules cannot be modified") - ) diff --git a/pms/models/ir_http.py b/pms/models/ir_http.py deleted file mode 100644 index 603a58c16..000000000 --- a/pms/models/ir_http.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2019 Pablo Quesada -# Copyright 2019 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import models -from odoo.http import request - - -class IrHttp(models.AbstractModel): - _inherit = "ir.http" - - def session_info(self): - res = super().session_info() - user = request.env.user - res.update( - { - # current_pms_property should be default_property - "user_pms_properties": { - "current_pms_property": ( - user.pms_property_id.id, - user.pms_property_id.name, - ), - # TODO: filter all properties based on - # the current set of active companies - "allowed_pms_properties": [ - (property.id, property.name) - for property in user.pms_property_ids - ], - }, - "display_switch_pms_property_menu": len(user.pms_property_ids) > 1, - } - ) - # TODO: This user context update should be placed in other function ¿? - res["user_context"].update( - { - "allowed_pms_property_ids": [ - (property.id) for property in user.pms_property_ids - ] - } - ) - # TODO: update current_company based on current_pms_property - # if user.pms_property_id.company_id in user.company_ids: - # user.company_id = user.pms_property_id.company_id - # res['company_id'] = user.pms_property_id.company_id.id - # else: - # raise MissingError( - # _("Wrong property and company access settings for this user. " - # "Please review property and company for user %s") % user.name) - - return res diff --git a/pms/models/mail_compose_message.py b/pms/models/mail_compose_message.py deleted file mode 100644 index 0e74c8757..000000000 --- a/pms/models/mail_compose_message.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import api, models - - -class MailComposeMessage(models.TransientModel): - _inherit = "mail.compose.message" - - @api.model - def default_get(self, fields): - res = super(MailComposeMessage, self).default_get(fields) - template = self.env["mail.template"].browse(self._context.get("template_id")) - res.update( - { - "composition_mode": "comment", - "attachment_ids": False, - "template_id": template.id, - } - ) - return res - - def send_mail(self, auto_commit=False): - # if ( - # self._context.get("default_model") == "pms.folio" - # and self._context.get("default_res_id") - # and self._context.get("mark_so_as_sent") - # ): - # # TODO: WorkFlow Mails - # folio = self.env["pms.folio"].browse([self._context["default_res_id"]]) - # if folio: - # cmds = [ - # (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids - # ] - # if any(cmds): - # folio.reservation_ids = cmds - res = super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) - if self._context.get("record_id"): - folio = self.env["pms.folio"].search( - [("id", "=", self._context.get("record_id"))] - ) - reservations = folio.reservation_ids - for reservation in reservations: - reservation.is_mail_send = True - return res diff --git a/pms/models/payment_return.py b/pms/models/payment_return.py deleted file mode 100644 index f3fd43634..000000000 --- a/pms/models/payment_return.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from openerp import fields, models - - -class PaymentReturn(models.Model): - _inherit = "payment.return" - - # Fields declaration - folio_id = fields.Many2one( - string="Folio", help="Folio in payment return", comodel_name="pms.folio" - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property with access to the element", - store=True, - readonly=True, - comodel_name="pms.property", - related="folio_id.pms_property_id", - ) - company_id = fields.Many2one( - string="Company", - help="The company for Payment Return", - check_pms_properties=True, - ) - - def action_confirm(self): - pay = super(PaymentReturn, self).action_confirm() - if pay: - folio_ids = [] - folios = self.env["pms.folio"].browse(folio_ids) - for line in self.line_ids: - payments = self.env["account.payment"].search( - [("move_line_ids", "in", line.move_line_ids.ids)] - ) - folios_line = self.env["pms.folio"].browse( - payments.mapped("folio_id.id") - ) - # for folio in folios_line: - # if self.id not in folio.return_ids.ids: - # folio.update({"return_ids": [(4, self.id)]}) - # msg = _("Return of %s registered") % (line.amount) - # folio.message_post(subject=_("Payment Return"), body=msg) - folios += folios_line - folios.compute_amount() diff --git a/pms/models/payment_transaction.py b/pms/models/payment_transaction.py deleted file mode 100644 index fff13a0e4..000000000 --- a/pms/models/payment_transaction.py +++ /dev/null @@ -1,43 +0,0 @@ -from odoo import _, fields, models - - -class PaymentTransaction(models.Model): - _inherit = "payment.transaction" - - folio_ids = fields.Many2many( - string="Folios", - comodel_name="pms.folio", - ondelete="cascade", - relation="payment_transaction_folio_rel", - column1="payment_transaction_id", - column2="folio_id", - ) - - def _create_payment(self, add_payment_vals=False): - self.ensure_one() - if not add_payment_vals: - add_payment_vals = {} - if self.folio_ids: - add_payment_vals["folio_ids"] = [(6, 0, self.folio_ids.ids)] - return super(PaymentTransaction, self)._create_payment(add_payment_vals) - - def render_folio_button(self, folio, submit_txt=None, render_values=None): - self.reference = folio.name - values = { - "partner_id": folio.partner_id.id, - "type": self.type, - } - if render_values: - values.update(render_values) - return ( - self.acquirer_id.with_context( - submit_class="btn btn-primary", submit_txt=submit_txt or _("Pay Now") - ) - .sudo() - .render( - self.reference, - folio.pending_amount, - folio.currency_id.id, - values=values, - ) - ) diff --git a/pms/models/pms_amenity.py b/pms/models/pms_amenity.py deleted file mode 100644 index b0224e74c..000000000 --- a/pms/models/pms_amenity.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class PmsRoomAmenity(models.Model): - _name = "pms.amenity" - _description = "Room amenity" - _check_pms_properties_auto = True - - active = fields.Boolean( - string="Active", - help="Determines if amenity is active", - default=True, - ) - name = fields.Char( - string="Amenity Name", - help="Amenity Name", - required=True, - translate=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - ondelete="restrict", - relation="pms_amenity_pms_property_rel", - column1="amenity_id", - column2="pms_property_id", - check_pms_properties=True, - ) - pms_amenity_type_id = fields.Many2one( - string="Amenity Category", - help="Segment the amenities by categories (multimedia, comfort, etc ...)", - comodel_name="pms.amenity.type", - check_pms_properties=True, - ) - default_code = fields.Char( - string="Internal Reference", help="Internal unique identifier of the amenity" - ) - is_add_code_room_name = fields.Boolean( - string="Add in room name", - help="True if the Internal Reference should appear in the display name of the rooms", - ) diff --git a/pms/models/pms_amenity_type.py b/pms/models/pms_amenity_type.py deleted file mode 100644 index ec982d55d..000000000 --- a/pms/models/pms_amenity_type.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class PmsRoomAmenityType(models.Model): - _name = "pms.amenity.type" - _description = "Amenity Type" - _check_pms_properties_auto = True - - active = fields.Boolean( - string="Active", - help="Determines if amenity type is active", - default=True, - ) - name = fields.Char( - string="Amenity Type Name", - help="Amenity Type Name", - required=True, - translate=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - ondelete="restrict", - relation="pms_amenity_type_pms_property_rel", - column1="amenity_type_id", - column2="pms_property_id", - check_pms_properties=True, - ) - pms_amenity_ids = fields.One2many( - string="Amenities In This Category", - help="Amenities included in this type", - comodel_name="pms.amenity", - inverse_name="pms_amenity_type_id", - check_pms_properties=True, - ) diff --git a/pms/models/pms_automated_mails.py b/pms/models/pms_automated_mails.py deleted file mode 100644 index 175a8b661..000000000 --- a/pms/models/pms_automated_mails.py +++ /dev/null @@ -1,367 +0,0 @@ -from odoo import _, api, fields, models -from odoo.exceptions import UserError - - -class PmsAutomatedMails(models.Model): - _name = "pms.automated.mails" - _description = "Automatic Mails" - - name = fields.Char(string="Name", help="Name of the automated mail.", required=True) - - pms_property_ids = fields.Many2many( - string="Property", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - ) - - automated_actions_id = fields.Many2one( - string="Automated Actions", - help="automated action that is created when creating automated emails ", - comodel_name="base.automation", - ) - - time = fields.Integer(string="Time", help="Amount of time") - - time_type = fields.Selection( - string="Time Range", - help="Type of date range", - selection=[ - ("minutes", "Minutes"), - ("hour", "Hour"), - ("day", "Days"), - ("month", "Months"), - ], - default="day", - ) - template_id = fields.Many2one( - string="Template", - help="The template that will be sent by email", - comodel_name="mail.template", - required=True, - ) - - action = fields.Selection( - string="Action", - help="The action that will cause the email to be sent ", - selection=[ - ("creation", "Reservation creation"), - ("write", "Reservation modification"), - ("cancel", "Reservation cancellation"), - ("checkin", "Checkin"), - ("checkout", "Checkout"), - ("payment", "Payment"), - ("invoice", "Invoice"), - ], - default="creation", - required=True, - ) - - moment = fields.Selection( - string="Moment", - help="Moment in relation to the action in which the email will be sent", - selection=[ - ("before", "Before"), - ("after", "After"), - ("in_act", "In the act"), - ], - default="before", - ) - - active = fields.Boolean( - string="Active", help="Indicates if the automated mail is active", default=True - ) - - @api.model - def create(self, vals): - name = vals.get("name") - action = vals.get("action") - time = vals.get("time") - date_range_type = vals.get("time_type") - template_id = vals.get("template_id") - active = vals.get("active") - moment = vals.get("moment") - properties = vals.get("pms_property_ids") - is_create = True - if action in ("creation", "write", "cancel", "invoice") and moment == "before": - raise UserError(_("The moment for this action cannot be 'Before'")) - dict_val = self._prepare_automated_actions_id( - action, time, moment, properties, is_create - ) - action_server_vals = { - "name": name, - "state": "email", - "usage": "ir_cron", - "model_id": dict_val["model_id"], - } - action_server = self.env["ir.actions.server"].create(action_server_vals) - automated_actions_vals = { - "active": active, - "action_server_id": action_server.id, - "trigger": dict_val["trigger"], - "filter_domain": dict_val["filter_domain"], - "filter_pre_domain": dict_val["filter_pre_domain"], - "trg_date_range": dict_val["time"], - "trg_date_range_type": date_range_type, - "template_id": template_id, - } - model_field = dict_val["model_field"] - if model_field: - automated_actions_vals.update( - { - "trg_date_id": dict_val["model_field"].id, - } - ) - trigger_field = dict_val["trigger_fields"] - if trigger_field: - automated_actions_vals.update( - { - "trigger_field_ids": dict_val["trigger_fields"].ids, - } - ) - automated_action = self.env["base.automation"].create(automated_actions_vals) - vals.update({"automated_actions_id": automated_action.id}) - return super(PmsAutomatedMails, self).create(vals) - - def write(self, vals): - result = super(PmsAutomatedMails, self).write(vals) - is_create = False - if ( - self.action in ("creation", "write", "cancel", "invoice") - and self.moment == "before" - ): - raise UserError(_("The moment for this action cannot be 'Before'")) - dict_val = self._prepare_automated_actions_id( - self.action, self.time, self.moment, self.pms_property_ids, is_create - ) - automated_actions_id = self.automated_actions_id - action_server = automated_actions_id.action_server_id - action_server_vals = { - "name": self.name, - "state": "email", - "usage": "ir_cron", - "model_id": dict_val["model_id"], - } - action_server.write(action_server_vals) - automated_actions_vals = { - "active": self.active, - "action_server_id": action_server.id, - "trigger": dict_val["trigger"], - "filter_domain": dict_val["filter_domain"], - "filter_pre_domain": dict_val["filter_pre_domain"], - "trg_date_range": dict_val["time"], - "trg_date_range_type": self.time_type, - "template_id": self.template_id, - } - model_field = dict_val["model_field"] - if model_field: - automated_actions_vals.update( - { - "trg_date_id": dict_val["model_field"].id, - } - ) - trigger_field = dict_val["trigger_fields"] - if trigger_field: - automated_actions_vals.update( - { - "trigger_field_ids": dict_val["trigger_fields"].ids, - } - ) - automated_actions_id.write(automated_actions_vals) - vals.update({"automated_actions_id": automated_actions_id.id}) - return result - - def unlink(self): - automated_actions_id = self.automated_actions_id - action_server = automated_actions_id.action_server_id - automated_actions_id.unlink() - action_server.unlink() - return super(PmsAutomatedMails, self).unlink() - - @api.model - def _get_auto_action_fields_in_creation_action(self, moment, time): - model_field = False - model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id - if moment == "in_act": - trigger = "on_create" - time = 0 - else: - trigger = "on_time" - model_field = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "create_date")] - ) - result = { - "model_id": model_id, - "trigger": trigger, - "model_field": model_field, - "time": time, - } - return result - - @api.model - def _get_auto_action_fields_in_write_or_cancel_action(self, moment, time): - model_field = False - model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id - if moment == "in_act": - trigger = "on_write" - time = 0 - else: - trigger = "on_time" - model_field = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "write_date")] - ) - result = { - "model_id": model_id, - "trigger": trigger, - "model_field": model_field, - "time": time, - } - return result - - @api.model - def _get_auto_action_fields_in_checkin_action(self, moment, time): - model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id - trigger = "on_time" - model_field = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "checkin")] - ) - if moment == "before": - time = time * (-1) - if moment == "in_act": - trigger = "on_write" - time = 0 - result = { - "model_id": model_id, - "trigger": trigger, - "model_field": model_field, - "time": time, - } - return result - - @api.model - def _get_auto_action_fields_in_checkout_action(self, moment, time): - model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id - trigger = "on_time" - model_field = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "checkout")] - ) - if moment == "before": - time = time * (-1) - if moment == "in_act": - trigger = "on_write" - time = 0 - result = { - "model_id": model_id, - "trigger": trigger, - "model_field": model_field, - "time": time, - } - return result - - @api.model - def _get_auto_action_fields_in_payment_action(self, moment, time): - model_field = False - model_id = ( - self.env["ir.model"] - .search([("model", "=", "account.payment"), ("transient", "=", False)]) - .id - ) - if moment == "in_act": - trigger = "on_create" - time = 0 - else: - trigger = "on_time" - model_field = self.env["ir.model.fields"].search( - [("model", "=", "account.payment"), ("name", "=", "date")] - ) - if moment == "before": - time = time * (-1) - result = { - "model_id": model_id, - "trigger": trigger, - "model_field": model_field, - "time": time, - } - return result - - @api.model - def _get_auto_action_fields_in_invoice_action(self, moment, time): - trigger = False - model_id = self.env["ir.model"].search([("model", "=", "account.move")]).id - if moment == "in_act": - trigger = "on_create" - time = 0 - result = { - "model_id": model_id, - "time": time, - "trigger": trigger, - "model_field": False, - } - return result - - def _prepare_automated_actions_id( - self, action, time, moment, properties, is_create - ): - filter_domain = [] - filter_pre_domain = [] - trigger_fields = False - dict_val = {} - if action == "creation": - dict_val = self._get_auto_action_fields_in_creation_action(moment, time) - elif action == "write" or action == "cancel": - dict_val = self._get_auto_action_fields_in_write_or_cancel_action( - moment, time - ) - if action == "cancel": - filter_domain = [ - ("state", "=", "cancelled"), - ] - elif action == "checkin": - dict_val = self._get_auto_action_fields_in_checkin_action(moment, time) - if moment == "in_act": - trigger_fields = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "state")] - ) - filter_pre_domain = [("state", "=", "confirm")] - filter_domain = [ - ("state", "=", "onboard"), - ] - elif action == "checkout": - dict_val = self._get_auto_action_fields_in_checkout_action(moment, time) - if moment == "in_act": - trigger_fields = self.env["ir.model.fields"].search( - [("model", "=", "pms.reservation"), ("name", "=", "state")] - ) - filter_pre_domain = [("state", "=", "onboard")] - filter_domain = [ - ("state", "=", "out"), - ] - elif action == "payment": - dict_val = self._get_auto_action_fields_in_payment_action(moment, time) - elif action == "invoice": - dict_val = self._get_auto_action_fields_in_invoice_action(moment, time) - filter_domain = [ - ("folio_ids", "!=", False), - ] - pms_property_ids = self._get_pms_property_ids(properties, is_create) - if pms_property_ids: - filter_domain.append(("pms_property_id", "in", pms_property_ids)) - result = { - "trigger": dict_val["trigger"], - "model_field": dict_val["model_field"], - "trigger_fields": trigger_fields, - "filter_pre_domain": filter_pre_domain, - "filter_domain": filter_domain, - "time": dict_val["time"], - "model_id": dict_val["model_id"], - } - return result - - def _get_pms_property_ids(self, properties, is_create): - pms_property_ids = [] - if is_create: - pms_property_ids = properties[0][2] - else: - for pms_property in properties: - pms_property_ids.append(pms_property.id) - return pms_property_ids diff --git a/pms/models/pms_availability.py b/pms/models/pms_availability.py deleted file mode 100644 index 3e35770ee..000000000 --- a/pms/models/pms_availability.py +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright 2021 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import datetime - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsAvailability(models.Model): - _name = "pms.availability" - _description = "Room type availability per day" - _check_pms_properties_auto = True - - room_type_id = fields.Many2one( - string="Room Type", - help="Room type for which availability is indicated", - readonly=True, - required=True, - comodel_name="pms.room.type", - ondelete="cascade", - check_pms_properties=True, - ) - date = fields.Date( - string="Date", - help="Date for which availability applies", - readonly=True, - required=True, - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property to which the availability is directed", - readonly=True, - required=True, - comodel_name="pms.property", - ondelete="restrict", - check_pms_properties=True, - ) - reservation_line_ids = fields.One2many( - string="Reservation Lines", - help="They are the lines of the reservation into a reservation," - "they corresponds to the nights", - readonly=True, - comodel_name="pms.reservation.line", - inverse_name="avail_id", - check_pms_properties=True, - ) - avail_rule_ids = fields.One2many( - string="Avail record rules", - comodel_name="pms.availability.plan.rule", - inverse_name="avail_id", - check_pms_properties=True, - ) - real_avail = fields.Integer( - string="Real Avail", - help="", - store=True, - readonly=True, - compute="_compute_real_avail", - ) - parent_avail_id = fields.Many2one( - string="Parent Avail", - help="Parent availability for this availability", - comodel_name="pms.availability", - ondelete="restrict", - compute="_compute_parent_avail_id", - store=True, - check_pms_properties=True, - ) - child_avail_ids = fields.One2many( - string="Child Avails", - help="Child availabilities for this availability", - comodel_name="pms.availability", - inverse_name="parent_avail_id", - compute="_compute_child_avail_ids", - store=True, - check_pms_properties=True, - ) - - _sql_constraints = [ - ( - "room_type_registry_unique", - "unique(room_type_id, date, pms_property_id)", - "Only can exists one availability in the same \ - day for the same room type!", - ) - ] - - @api.depends( - "reservation_line_ids", - "reservation_line_ids.occupies_availability", - "room_type_id.total_rooms_count", - "parent_avail_id", - "parent_avail_id.reservation_line_ids", - "parent_avail_id.reservation_line_ids.occupies_availability", - "child_avail_ids", - "child_avail_ids.reservation_line_ids", - "child_avail_ids.reservation_line_ids.occupies_availability", - ) - def _compute_real_avail(self): - for record in self: - Rooms = self.env["pms.room"] - total_rooms = Rooms.search_count( - [ - ("room_type_id", "=", record.room_type_id.id), - ("pms_property_id", "=", record.pms_property_id.id), - ] - ) - room_ids = record.room_type_id.mapped("room_ids.id") - count_rooms_not_avail = len( - record.get_rooms_not_avail( - checkin=record.date, - checkout=record.date + datetime.timedelta(1), - room_ids=room_ids, - pms_property_id=record.pms_property_id.id, - ) - ) - record.real_avail = total_rooms - count_rooms_not_avail - - @api.depends("reservation_line_ids", "reservation_line_ids.room_id") - def _compute_parent_avail_id(self): - for record in self: - parent_rooms = record.room_type_id.mapped("room_ids.parent_id.id") - if parent_rooms: - for room_id in parent_rooms: - room = self.env["pms.room"].browse(room_id) - parent_avail = self.env["pms.availability"].search( - [ - ("date", "=", record.date), - ("room_type_id", "=", room.room_type_id.id), - ("pms_property_id", "=", record.pms_property_id.id), - ] - ) - if parent_avail: - record.parent_avail_id = parent_avail - else: - record.parent_avail_id = self.env["pms.availability"].create( - { - "date": record.date, - "room_type_id": room.room_type_id.id, - "pms_property_id": record.pms_property_id.id, - } - ) - else: - record.parent_avail_id = False - - @api.depends("reservation_line_ids", "reservation_line_ids.room_id") - def _compute_child_avail_ids(self): - for record in self: - child_rooms = record.room_type_id.mapped("room_ids.child_ids.id") - if child_rooms: - for room_id in child_rooms: - room = self.env["pms.room"].browse(room_id) - child_avail = self.env["pms.availability"].search( - [ - ("date", "=", record.date), - ("room_type_id", "=", room.room_type_id.id), - ("pms_property_id", "=", record.pms_property_id.id), - ] - ) - if child_avail: - record.child_avail_ids = [(4, child_avail.id)] - else: - record.child_avail_ids = [ - ( - 0, - 0, - { - "date": record.date, - "room_type_id": room.room_type_id.id, - "pms_property_id": record.pms_property_id.id, - }, - ) - ] - else: - record.child_avail_ids = False - - @api.model - def get_rooms_not_avail( - self, checkin, checkout, room_ids, pms_property_id, current_lines=False - ): - RoomLines = self.env["pms.reservation.line"] - rooms = self.env["pms.room"].browse(room_ids) - occupied_room_ids = [] - for room in rooms.filtered("parent_id"): - if self.get_occupied_parent_rooms( - room=room.parent_id, - checkin=checkin, - checkout=checkout, - pms_property_id=room.pms_property_id.id, - ): - occupied_room_ids.append(room.id) - for room in rooms.filtered("child_ids"): - if self.get_occupied_child_rooms( - rooms=room.child_ids, - checkin=checkin, - checkout=checkout, - pms_property_id=room.pms_property_id.id, - ): - occupied_room_ids.append(room.id) - occupied_room_ids.extend( - RoomLines.search( - [ - ("date", ">=", checkin), - ("date", "<=", checkout - datetime.timedelta(1)), - ("room_id", "in", room_ids), - ("pms_property_id", "=", pms_property_id), - ("occupies_availability", "=", True), - ("id", "not in", current_lines if current_lines else []), - ] - ).mapped("room_id.id") - ) - return occupied_room_ids - - @api.model - def get_occupied_parent_rooms(self, room, checkin, checkout, pms_property_id): - RoomLines = self.env["pms.reservation.line"] - if ( - RoomLines.search_count( - [ - ("date", ">=", checkin), - ("date", "<=", checkout - datetime.timedelta(1)), - ("room_id", "=", room.id), - ("pms_property_id", "=", pms_property_id), - ("occupies_availability", "=", True), - ] - ) - > 0 - ): - return True - if room.parent_id: - return self.get_occupied_parent_rooms( - room=room.parent_room_id, - checkin=checkin, - checkout=checkout, - ) - return False - - @api.model - def get_occupied_child_rooms(self, rooms, checkin, checkout, pms_property_id): - RoomLines = self.env["pms.reservation.line"] - if ( - RoomLines.search_count( - [ - ("date", ">=", checkin), - ("date", "<=", checkout - datetime.timedelta(1)), - ("room_id", "in", rooms.ids), - ("pms_property_id", "=", pms_property_id), - ("occupies_availability", "=", True), - ] - ) - > 0 - ): - return True - for room in rooms.filtered("child_ids"): - if self.get_occupied_child_rooms( - rooms=room.child_ids, - checkin=checkin, - checkout=checkout, - ): - return True - return False - - @api.constrains( - "room_type_id", - "pms_property_id", - ) - def _check_property_integrity(self): - for rec in self: - if rec.pms_property_id and rec.room_type_id: - if ( - rec.room_type_id.pms_property_ids.ids - and rec.pms_property_id.id - not in rec.room_type_id.pms_property_ids.ids - ): - raise ValidationError( - _("Property not allowed on availability day compute") - ) diff --git a/pms/models/pms_availability_plan.py b/pms/models/pms_availability_plan.py deleted file mode 100644 index 5052ecc4b..000000000 --- a/pms/models/pms_availability_plan.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import datetime - -from odoo import api, fields, models -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT - - -class PmsAvailabilityPlan(models.Model): - """The room type availability is used as a daily availability plan for room types - and therefore is related only with one property.""" - - _name = "pms.availability.plan" - _description = "Reservation availability plan" - _check_pms_properties_auto = True - - @api.model - def _get_default_pms_property(self): - return self.env.user.get_active_property_ids()[0] or None - - name = fields.Char( - string="Availability Plan Name", help="Name of availability plan", required=True - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - ondelete="restrict", - relation="pms_availability_plan_pms_property_rel", - column1="availability_plan_id", - column2="pms_property_id", - check_pms_properties=True, - ) - pms_pricelist_ids = fields.One2many( - string="Pricelists", - help="Pricelists of the availability plan ", - comodel_name="product.pricelist", - inverse_name="availability_plan_id", - check_pms_properties=True, - ) - - rule_ids = fields.One2many( - string="Availability Rules", - help="Rules in a availability plan", - comodel_name="pms.availability.plan.rule", - inverse_name="availability_plan_id", - check_pms_properties=True, - ) - - active = fields.Boolean( - string="Active", - help="If unchecked, it will allow you to hide the " - "Availability plan without removing it.", - default=True, - ) - - @classmethod - def any_rule_applies(cls, checkin, checkout, item): - if isinstance(checkin, str): - checkin = datetime.datetime.strptime( - checkin, DEFAULT_SERVER_DATE_FORMAT - ).date() - if isinstance(checkout, str): - checkout = datetime.datetime.strptime( - checkout, DEFAULT_SERVER_DATE_FORMAT - ).date() - reservation_len = (checkout - checkin).days - return any( - [ - (0 < item.max_stay < reservation_len), - (0 < item.min_stay > reservation_len), - (0 < item.max_stay_arrival < reservation_len and checkin == item.date), - (0 < item.min_stay_arrival > reservation_len and checkin == item.date), - item.closed, - (item.closed_arrival and checkin == item.date), - (item.closed_departure and checkout == item.date), - (item.quota == 0 or item.max_avail == 0), - ] - ) - - @api.model - def update_quota(self, pricelist_id, room_type_id, date, impacts_quota_id=False): - if pricelist_id and room_type_id and date: - rule = self.env["pms.availability.plan.rule"].search( - [ - ("availability_plan_id.pms_pricelist_ids", "=", pricelist_id.id), - ("room_type_id", "=", room_type_id.id), - ("date", "=", date), - ] - ) - # applies a rule - if rule: - rule.ensure_one() - if rule and rule.quota != -1 and rule.quota > 0: - - # the line has no rule item applied before - if not impacts_quota_id: - rule.quota -= 1 - return rule.id - - # the line has a rule item applied before - elif impacts_quota_id != rule.id: - - # decrement quota on current rule item - rule.quota -= 1 - - # check old rule item - old_rule = self.env["pms.availability.plan.rule"].search( - [("id", "=", impacts_quota_id)] - ) - - # restore quota in old rule item - if old_rule: - old_rule.quota += 1 - - return rule.id - - # in any case, check old rule item - if impacts_quota_id: - old_rule = self.env["pms.availability.plan.rule"].search( - [("id", "=", impacts_quota_id)] - ) - # and restore quota in old rule item - if old_rule: - old_rule.quota += 1 - - return False - - # Action methods - def open_massive_changes_wizard(self): - - if self.ensure_one(): - return { - "view_type": "form", - "view_mode": "form", - "name": "Massive changes on Availability Plan: " + self.name, - "res_model": "pms.massive.changes.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": { - "availability_plan_id": self.id, - }, - } diff --git a/pms/models/pms_availability_plan_rule.py b/pms/models/pms_availability_plan_rule.py deleted file mode 100644 index 728952350..000000000 --- a/pms/models/pms_availability_plan_rule.py +++ /dev/null @@ -1,192 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsAvailabilityPlanRule(models.Model): - _name = "pms.availability.plan.rule" - _description = "Reservation rule by day" - _check_pms_properties_auto = True - - availability_plan_id = fields.Many2one( - string="Availability Plan", - help="The availability plan that include the Availabilty Rule", - index=True, - comodel_name="pms.availability.plan", - ondelete="cascade", - check_pms_properties=True, - ) - room_type_id = fields.Many2one( - string="Room Type", - help="Room type for which availability rule is applied", - required=True, - comodel_name="pms.room.type", - ondelete="cascade", - check_pms_properties=True, - ) - date = fields.Date( - string="Date", - help="Date for which availability rule applies", - ) - - min_stay = fields.Integer( - string="Min. Stay", - help="Minimum stay", - default=0, - ) - min_stay_arrival = fields.Integer( - string="Min. Stay Arrival", - help="Minimum stay if checkin is today", - default=0, - ) - max_stay = fields.Integer( - string="Max. Stay", - help="Maximum stay", - default=0, - ) - max_stay_arrival = fields.Integer( - string="Max. Stay Arrival", - help="Maximum stay if checkin is today", - default=0, - ) - closed = fields.Boolean( - string="Closed", - help="Indicate if property is closed or not", - default=False, - ) - closed_departure = fields.Boolean( - string="Closed Departure", - help="", - default=False, - ) - closed_arrival = fields.Boolean( - string="Closed Arrival", - help="", - default=False, - ) - quota = fields.Integer( - string="Quota", - help="Generic Quota assigned.", - readonly=False, - store=True, - compute="_compute_quota", - ) - max_avail = fields.Integer( - string="Max. Availability", - help="Maximum simultaneous availability on own Booking Engine", - readonly=False, - store=True, - compute="_compute_max_avail", - ) - pms_property_id = fields.Many2one( - string="Property", - help="Properties with access to the element", - ondelete="restrict", - required=True, - comodel_name="pms.property", - check_pms_properties=True, - ) - avail_id = fields.Many2one( - string="Avail record", - comodel_name="pms.availability", - compute="_compute_avail_id", - store=True, - readonly=False, - ondelete="restrict", - check_pms_properties=True, - ) - real_avail = fields.Integer( - string="Real availability", - related="avail_id.real_avail", - store="True", - ) - plan_avail = fields.Integer( - compute="_compute_plan_avail", - store="True", - ) - - _sql_constraints = [ - ( - "room_type_registry_unique", - "unique(availability_plan_id, room_type_id, date, pms_property_id)", - "Only can exists one availability rule in the same \ - day for the same room type!", - ) - ] - - @api.depends("room_type_id", "date", "pms_property_id") - def _compute_avail_id(self): - for record in self: - if record.room_type_id and record.pms_property_id and record.date: - avail = self.env["pms.availability"].search( - [ - ("date", "=", record.date), - ("room_type_id", "=", record.room_type_id.id), - ("pms_property_id", "=", record.pms_property_id.id), - ] - ) - if avail: - record.avail_id = avail.id - else: - record.avail_id = self.env["pms.availability"].create( - { - "date": record.date, - "room_type_id": record.room_type_id.id, - "pms_property_id": record.pms_property_id.id, - } - ) - else: - record.avail_id = False - - @api.depends("quota", "max_avail", "real_avail") - def _compute_plan_avail(self): - for record in self: - real_avail = record.real_avail - plan_avail = min( - [ - record.max_avail if record.max_avail >= 0 else real_avail, - record.quota if record.quota >= 0 else real_avail, - real_avail, - ] - ) - if not record.plan_avail or record.plan_avail != plan_avail: - record.plan_avail = plan_avail - - @api.depends("room_type_id") - def _compute_quota(self): - for record in self: - if not record.quota: - record.quota = record.room_type_id.default_quota - - @api.depends("room_type_id") - def _compute_max_avail(self): - for record in self: - if not record.max_avail: - record.max_avail = record.room_type_id.default_max_avail - - @api.constrains("min_stay", "min_stay_arrival", "max_stay", "max_stay_arrival") - def _check_min_max_stay(self): - for record in self: - if record.min_stay < 0: - raise ValidationError(_("Min. Stay can't be less than zero")) - elif record.min_stay_arrival < 0: - raise ValidationError(_("Min. Stay Arrival can't be less than zero")) - elif record.max_stay < 0: - raise ValidationError(_("Max. Stay can't be less than zero")) - elif record.max_stay_arrival < 0: - raise ValidationError(_("Max. Stay Arrival can't be less than zero")) - elif ( - record.min_stay != 0 - and record.max_stay != 0 - and record.min_stay > record.max_stay - ): - raise ValidationError(_("Max. Stay can't be less than Min. Stay")) - elif ( - record.min_stay_arrival != 0 - and record.max_stay_arrival != 0 - and record.min_stay_arrival > record.max_stay_arrival - ): - raise ValidationError( - _("Max. Stay Arrival can't be less than Min. Stay Arrival") - ) diff --git a/pms/models/pms_board_service.py b/pms/models/pms_board_service.py deleted file mode 100644 index 2287dc0ca..000000000 --- a/pms/models/pms_board_service.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsBoardService(models.Model): - _name = "pms.board.service" - _description = "Board Services" - _check_pms_properties_auto = True - - name = fields.Char( - string="Board Service Name", - help="Board Service Name", - required=True, - index=True, - size=64, - translate=True, - ) - default_code = fields.Char( - string="Board Service Code", - help="Unique Board Service identification code per property", - required=True, - ) - board_service_line_ids = fields.One2many( - string="Board Service Lines", - help="Services included in this Board Service", - comodel_name="pms.board.service.line", - inverse_name="pms_board_service_id", - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - ondelete="restrict", - comodel_name="pms.property", - relation="pms_board_service_pms_property_rel", - column1="board_service_id", - column2="pms_property_id", - check_pms_properties=True, - ) - pms_board_service_room_type_ids = fields.One2many( - string="Board Services Room Type", - help="Board Services Room Type corresponding to this Board Service," - "One board service for several room types", - comodel_name="pms.board.service.room.type", - inverse_name="pms_board_service_id", - ) - amount = fields.Float( - string="Amount", - help="Price for this Board Service. " - "It corresponds to the sum of his board service lines", - store=True, - digits=("Product Price"), - compute="_compute_board_amount", - ) - - show_detail_report = fields.Boolean( - string="Show Detail Report", - help="True if you want that board service detail to be shown on the report", - ) - - @api.depends("board_service_line_ids.amount") - def _compute_board_amount(self): - for record in self: - total = 0 - for service in record.board_service_line_ids: - total += service.amount - record.update({"amount": total}) - - @api.model - def get_unique_by_property_code(self, pms_property_id, default_code=None): - """ - :param pms_property_id: property ID - :param default_code: board service code (optional) - :return: - recordset of - - all the pms.board.service of the pms_property_id - if default_code not defined - - one or 0 pms.board.service if default_code defined - - ValidationError if more than one default_code found by - the same pms_property_id - """ - # TODO: similiar code as room.type -> unify - domain = [] - if default_code: - domain += ["&", ("default_code", "=", default_code)] - domain += [ - "|", - ("pms_property_ids", "in", pms_property_id), - ("pms_property_ids", "=", False), - ] - records = self.search(domain) - res, res_priority = {}, {} - for rec in records: - res_priority.setdefault(rec.default_code, -1) - priority = rec.pms_property_ids and 1 or 0 - if priority > res_priority[rec.default_code]: - res.setdefault(rec.default_code, rec.id) - res[rec.default_code], res_priority[rec.default_code] = rec.id, priority - elif priority == res_priority[rec.default_code]: - raise ValidationError( - _( - "Integrity error: There's multiple board services " - "with the same code %s and properties" - ) - % rec.default_code - ) - return self.browse(list(res.values())) - - @api.constrains("default_code", "pms_property_ids") - def _check_code_property_uniqueness(self): - # TODO: similiar code as room.type -> unify - msg = _( - "Already exists another Board Service with the same code and properties" - ) - for rec in self: - if not rec.pms_property_ids: - if self.search( - [ - ("id", "!=", rec.id), - ("default_code", "=", rec.default_code), - ("pms_property_ids", "=", False), - ] - ): - raise ValidationError(msg) - else: - for pms_property in rec.pms_property_ids: - other = rec.get_unique_by_property_code( - pms_property.id, rec.default_code - ) - if other and other != rec: - raise ValidationError(msg) diff --git a/pms/models/pms_board_service_line.py b/pms/models/pms_board_service_line.py deleted file mode 100644 index 9be0d7d3c..000000000 --- a/pms/models/pms_board_service_line.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models - - -class PmsBoardServiceLine(models.Model): - _name = "pms.board.service.line" - _description = "Services on Board Service included" - _check_pms_properties_auto = True - - pms_board_service_id = fields.Many2one( - string="Board Service", - help="Board Service in which this line is included", - required=True, - comodel_name="pms.board.service", - ondelete="cascade", - check_pms_properties=True, - ) - product_id = fields.Many2one( - string="Product", - help="Product associated with this board service line", - required=True, - comodel_name="product.product", - check_pms_properties=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="pms_board_service_line_pms_property_rel", - column1="pms_board_service_line_id", - column2="pms_property_id", - store=True, - check_pms_properties=True, - ) - amount = fields.Float( - string="Amount", - help="Price for this Board Service Line/Product", - default=lambda self: self._get_default_price(), - digits=("Product Price"), - ) - - def _get_default_price(self): - if self.product_id: - return self.product_id.list_price - - @api.onchange("product_id") - def onchange_product_id(self): - if self.product_id: - self.update({"amount": self.product_id.list_price}) - - @api.model - def create(self, vals): - properties = False - if "pms_board_service_id" in vals: - board_service = self.env["pms.board.service"].browse( - vals["pms_board_service_id"] - ) - properties = board_service.pms_property_ids - if properties: - vals.update( - { - "pms_property_ids": properties, - } - ) - return super(PmsBoardServiceLine, self).create(vals) - - def write(self, vals): - properties = False - if "pms_board_service_id" in vals: - board_service = self.env["pms.board.service"].browse( - vals["pms_board_service_id"] - ) - properties = board_service.pms_property_ids - if properties: - vals.update( - { - "pms_property_ids": properties, - } - ) - return super(PmsBoardServiceLine, self).write(vals) diff --git a/pms/models/pms_board_service_room_type.py b/pms/models/pms_board_service_room_type.py deleted file mode 100644 index 8beefc95e..000000000 --- a/pms/models/pms_board_service_room_type.py +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright 2017 Dario -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import UserError - - -class PmsBoardServiceRoomType(models.Model): - _name = "pms.board.service.room.type" - _table = "pms_board_service_room_type_rel" - _rec_name = "pms_board_service_id" - _log_access = False - _description = "Board Service included in Room" - _check_pms_properties_auto = True - - pms_board_service_id = fields.Many2one( - string="Board Service", - help="Board Service corresponding to this Board Service Room Type", - required=True, - index=True, - comodel_name="pms.board.service", - ondelete="cascade", - check_pms_properties=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - ondelete="restrict", - comodel_name="pms.property", - relation="pms_board_service_room_type_pms_property_rel", - column1="pms_board_service_room_type_id", - column2="pms_property_id", - check_pms_properties=True, - compute="_compute_pms_property_ids", - store=True, - ) - pms_room_type_id = fields.Many2one( - string="Room Type", - help="Room Type for which this Board Service is available", - required=True, - index=True, - comodel_name="pms.room.type", - ondelete="cascade", - check_pms_properties=True, - ) - board_service_line_ids = fields.One2many( - string="Board Service Lines", - help="Services included in this Board Service", - comodel_name="pms.board.service.room.type.line", - inverse_name="pms_board_service_room_type_id", - required=True, - ) - amount = fields.Float( - string="Amount", - help="Price for this Board Service. " - "It corresponds to the sum of his board service lines", - store=True, - digits=("Product Price"), - compute="_compute_board_amount", - ) - by_default = fields.Boolean( - string="Apply by Default", - help="Indicates if this board service is applied by default in the room type", - ) - - @api.depends( - "pms_room_type_id", - "pms_room_type_id.pms_property_ids", - "pms_board_service_id", - "pms_board_service_id.pms_property_ids", - ) - def _compute_pms_property_ids(self): - for record in self: - if ( - record.pms_room_type_id.pms_property_ids - and record.pms_board_service_id.pms_property_ids - ): - record.pms_property_ids = self.env["pms.property"].search( - [ - ( - "id", - "in", - list( - set(record.pms_room_type_id.pms_property_ids.ids) - & set(record.pms_board_service_id.pms_property_ids.ids) - ), - ) - ] - ) - elif ( - record.pms_room_type_id.pms_property_ids - and not record.pms_board_service_id.pms_property_ids - ): - record.pms_property_ids = record.pms_room_type_id.pms_property_ids - elif ( - not record.pms_room_type_id.pms_property_ids - and record.pms_board_service_id.pms_property_ids - ): - record.pms_property_ids = record.pms_board_service_id.pms_property_ids - else: - record.pms_property_ids = False - - @api.depends("board_service_line_ids.amount") - def _compute_board_amount(self): - for record in self: - total = 0 - for service in record.board_service_line_ids: - total += service.amount - record.update({"amount": total}) - - def name_get(self): - res = [] - for record in self: - name = "{} - {}".format( - record.pms_board_service_id.name, record.pms_room_type_id.name - ) - res.append((record.id, name)) - return res - - @api.constrains("by_default") - def constrains_duplicated_board_defaul(self): - for record in self: - default_boards = ( - record.pms_room_type_id.board_service_room_type_ids.filtered( - "by_default" - ) - ) - # TODO Check properties (with different propertys is allowed) - if any(default_boards.filtered(lambda l: l.id != record.id)): - raise UserError(_("""Only can set one default board service""")) - - def open_board_lines_form(self): - action = ( - self.env.ref("pms.action_pms_board_service_room_type_view").sudo().read()[0] - ) - action["views"] = [ - (self.env.ref("pms.pms_board_service_room_type_form").id, "form") - ] - action["res_id"] = self.id - action["target"] = "new" - return action - - def init(self): - self._cr.execute( - "SELECT indexname FROM pg_indexes WHERE indexname = %s", - ("pms_board_service_id_pms_room_type_id",), - ) - if not self._cr.fetchone(): - self._cr.execute( - "CREATE INDEX pms_board_service_id_pms_room_type_id \ - ON pms_board_service_room_type_rel \ - (pms_board_service_id, pms_room_type_id)" - ) - - @api.model - def create(self, vals): - # properties = False - if "pms_board_service_id" in vals: - vals.update( - self.prepare_board_service_reservation_ids(vals["pms_board_service_id"]) - ) - return super(PmsBoardServiceRoomType, self).create(vals) - - def write(self, vals): - if "pms_board_service_id" in vals: - vals.update( - self.prepare_board_service_reservation_ids(vals["pms_board_service_id"]) - ) - return super(PmsBoardServiceRoomType, self).write(vals) - - @api.model - def prepare_board_service_reservation_ids(self, board_service_id): - """ - Prepare line to price products config - """ - cmds = [(5, 0, 0)] - board_service = self.env["pms.board.service"].browse(board_service_id) - for line in board_service.board_service_line_ids: - cmds.append( - (0, False, {"product_id": line.product_id.id, "amount": line.amount}) - ) - return {"board_service_line_ids": cmds} diff --git a/pms/models/pms_board_service_room_type_line.py b/pms/models/pms_board_service_room_type_line.py deleted file mode 100644 index fb5038190..000000000 --- a/pms/models/pms_board_service_room_type_line.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models - - -class PmsBoardServiceRoomTypeLine(models.Model): - _name = "pms.board.service.room.type.line" - _description = "Services on Board Service included in Room" - _check_pms_properties_auto = True - - # Fields declaration - pms_board_service_room_type_id = fields.Many2one( - string="Board Service Room", - help="Board Service Room Type in which this line is included", - required=True, - comodel_name="pms.board.service.room.type", - ondelete="cascade", - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="pms_board_service_room_type_line_pms_property_rel", - column1="pms_board_service_room_type_id", - column2="pms_property_id", - check_pms_properties=True, - ) - product_id = fields.Many2one( - string="Product", - help="Product associated with this board service room type line", - comodel_name="product.product", - readonly=True, - check_pms_properties=True, - ) - # TODO def default_amount "amount of service" - amount = fields.Float( - string="Amount", - help="Price for this Board Service Room Type Line/Product", - default=0.0, - digits=("Product Price"), - ) - - @api.model - def create(self, vals): - properties = False - if "pms_board_service_room_type_id" in vals: - board_service = self.env["pms.board.service.room.type"].browse( - vals["pms_board_service_room_type_id"] - ) - properties = board_service.pms_property_ids - if properties: - vals.update( - { - "pms_property_ids": properties, - } - ) - return super(PmsBoardServiceRoomTypeLine, self).create(vals) - - def write(self, vals): - properties = False - if "pms_board_service_room_type_id" in vals: - board_service = self.env["pms.board.service.room.type"].browse( - vals["pms_board_service_room_type_id"] - ) - properties = board_service.pms_property_ids - if properties: - vals.update( - { - "pms_property_ids": properties, - } - ) - return super(PmsBoardServiceRoomTypeLine, self).write(vals) diff --git a/pms/models/pms_cancelation_rule.py b/pms/models/pms_cancelation_rule.py deleted file mode 100644 index 6e5bfd776..000000000 --- a/pms/models/pms_cancelation_rule.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class PmsCancelationRule(models.Model): - _name = "pms.cancelation.rule" - _description = "Cancelation Rules" - _check_pms_properties_auto = True - - name = fields.Char( - string="Cancelation Rule", - required=True, - translate=True, - ) - pricelist_ids = fields.One2many( - string="Pricelist", - help="Pricelist that use this rule", - comodel_name="product.pricelist", - inverse_name="cancelation_rule_id", - check_pms_properties=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - comodel_name="pms.property", - relation="pms_cancelation_rule_pms_property_rel", - column1="pms_cancelation_rule_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - active = fields.Boolean( - string="Active", help="Determines if cancelation rule is active", default=True - ) - days_intime = fields.Integer( - string="Days Late", - help="Maximum number of days for free cancellation before Checkin", - ) - penalty_late = fields.Integer( - string="% Penalty Late", - help="Percentage of the total price that partner has " - "to pay in case of late arrival", - default="100", - ) - apply_on_late = fields.Selection( - string="Late apply on", - help="Days on which the cancelation rule applies when " - "the reason is late arrival. " - "Can be first, all days or specify the days.", - default="first", - selection=[ - ("first", "First Day"), - ("all", "All Days"), - ("days", "Specify days"), - ], - ) - days_late = fields.Integer( - string="Late first days", - help="Is number of days late in the cancelation rule " - "if the value of the apply_on_late field is specify days.", - default="2", - ) - penalty_noshow = fields.Integer( - string="% Penalty No Show", - help="Percentage of the total price that partner has to pay in case of no show", - default="100", - ) - apply_on_noshow = fields.Selection( - string="No Show apply on", - help="Days on which the cancelation rule applies when" - " the reason is no show. Can be first, all days or specify the days.", - selection=[ - ("first", "First Day"), - ("all", "All Days"), - ("days", "Specify days"), - ], - default="all", - ) - days_noshow = fields.Integer( - string="NoShow first days", - help="Is number of days no show in the cancelation rule " - "if the value of the apply_on_show field is specify days.", - default="2", - ) diff --git a/pms/models/pms_checkin_partner.py b/pms/models/pms_checkin_partner.py deleted file mode 100644 index 074c31625..000000000 --- a/pms/models/pms_checkin_partner.py +++ /dev/null @@ -1,792 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# Copyright 2018 Alexandre Diaz -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import json -from datetime import datetime - -from dateutil.relativedelta import relativedelta - -from odoo import _, api, fields, models -from odoo.exceptions import UserError, ValidationError -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT -from odoo.tools.safe_eval import safe_eval - - -class PmsCheckinPartner(models.Model): - _name = "pms.checkin.partner" - _description = "Partner Checkins" - _inherit = ["portal.mixin"] - _rec_name = "identifier" - _check_pms_properties_auto = True - - identifier = fields.Char( - string="Identifier", - help="Checkin Partner Id", - readonly=True, - index=True, - default=lambda self: _("New"), - ) - 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", - help="Reservation to which checkin partners belong", - comodel_name="pms.reservation", - check_pms_properties=True, - ) - folio_id = fields.Many2one( - string="Folio", - help="Folio to which reservation of checkin partner belongs", - store=True, - comodel_name="pms.folio", - compute="_compute_folio_id", - check_pms_properties=True, - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property to which the folio associated belongs", - readonly=True, - store=True, - comodel_name="pms.property", - related="folio_id.pms_property_id", - check_pms_properties=True, - ) - name = fields.Char( - string="Name", help="Checkin partner name", related="partner_id.name" - ) - email = fields.Char( - string="E-mail", - help="Checkin Partner Email", - readonly=False, - store=True, - compute="_compute_email", - ) - mobile = fields.Char( - string="Mobile", - help="Checkin Partner Mobile", - readonly=False, - store=True, - compute="_compute_mobile", - ) - image_128 = fields.Image( - string="Image", - help="Checkin Partner Image, it corresponds with Partner Image associated", - related="partner_id.image_128", - ) - segmentation_ids = fields.Many2many( - string="Segmentation", - help="Segmentation tags to classify checkin partners", - readonly=True, - related="reservation_id.segmentation_ids", - ) - checkin = fields.Date( - string="Checkin", - help="Checkin date", - store=True, - related="reservation_id.checkin", - depends=["reservation_id.checkin"], - ) - checkout = fields.Date( - string="Checkout", - help="Checkout date", - store=True, - related="reservation_id.checkout", - depends=["reservation_id.checkout"], - ) - arrival = fields.Datetime("Enter", help="Checkin partner arrival date and time") - departure = fields.Datetime( - string="Exit", help="Checkin partner departure date and time" - ) - state = fields.Selection( - string="Status", - help="Status of the checkin partner regarding the reservation", - readonly=True, - store=True, - selection=[ - ("draft", "Unkown Guest"), - ("precheckin", "Pending arrival"), - ("onboard", "On Board"), - ("done", "Out"), - ("cancel", "Cancelled"), - ], - compute="_compute_state", - ) - - 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", - help="host nationality", - readonly=False, - store=True, - compute="_compute_nationality_id", - comodel_name="res.country", - ) - # TODO: Use new partner contact "other or "private" with - # personal contact address complete?? - # to avoid user country_id on companies contacts. - # View to res.partner state_id inherit - state_id = fields.Many2one( - string="Country State", - help="host state", - readonly=False, - store=True, - compute="_compute_state_id", - comodel_name="res.country.state", - ) - 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", - ) - - partner_incongruences = fields.Char( - string="partner_incongruences", - help="indicates that some partner fields \ - on the checkin do not correspond to that of \ - the associated partner", - compute="_compute_partner_incongruences", - ) - - possible_existing_customer_ids = fields.One2many( - string="Possible existing customer", - readonly=False, - store=True, - compute="_compute_possible_existing_customer_ids", - comodel_name="res.partner", - inverse_name="checkin_partner_possible_customer_id", - ) - - @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 not record.document_expedition_date: - record.document_expedition_date = False - if record.partner_id and record.partner_id.id_numbers: - 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_id(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("partner_id") - def _compute_state_id(self): - for record in self: - if not record.state_id and record.partner_id.state_id: - record.state_id = record.partner_id.state_id - elif not record.state_id: - record.state_id = False - - @api.depends("reservation_id", "reservation_id.folio_id") - def _compute_folio_id(self): - for record in self.filtered("reservation_id"): - record.folio_id = record.reservation_id.folio_id - - @api.depends(lambda self: self._checkin_mandatory_fields(depends=True)) - def _compute_state(self): - for record in self: - if not record.state: - record.state = "draft" - if record.reservation_id.state == "cancel": - record.state = "cancel" - elif record.state in ("draft", "precheckin", "cancel"): - if any( - not getattr(record, field) - for field in record._checkin_mandatory_fields( - country=record.nationality_id - ) - ): - record.state = "draft" - else: - record.state = "precheckin" - - @api.depends( - "partner_id", - "partner_id.name", - "reservation_id", - "reservation_id.preferred_room_id", - ) - def _compute_name(self): - for record in self: - if not record.name or record.partner_id.name: - record.name = record.partner_id.name - - @api.depends("partner_id") - def _compute_email(self): - for record in self: - if not record.email or record.partner_id.email: - record.email = record.partner_id.email - - @api.depends("partner_id") - def _compute_mobile(self): - for record in self: - 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("email", "mobile") - def _compute_possible_existing_customer_ids(self): - for record in self: - possible_customer = self.env[ - "pms.folio" - ]._apply_possible_existing_customer_ids(record.email, record.mobile) - if possible_customer: - record.possible_existing_customer_ids = possible_customer - else: - record.possible_existing_customer_ids = False - - @api.depends( - "firstname", - "lastname", - "lastname2", - "gender", - "birthdate_date", - "nationality_id", - "email", - "mobile", - "partner_id", - ) - def _compute_partner_incongruences(self): - for record in self: - incongruous_fields = False - if record.partner_id: - for field in record._checkin_partner_fields(): - if ( - record.partner_id[field] - and record.partner_id[field] != record[field] - ): - if not incongruous_fields: - incongruous_fields = record._fields[field].string - else: - incongruous_fields += ", " + record._fields[field].string - if incongruous_fields: - record.partner_incongruences = ( - incongruous_fields + " field/s don't correspond to saved host" - ) - else: - record.partner_incongruences = False - else: - record.partner_incongruences = False - - def _compute_access_url(self): - super(PmsCheckinPartner, self)._compute_access_url() - for checkin in self: - checkin.access_url = "/my/precheckin/%s" % (checkin.id) - - # Constraints and onchanges - - @api.constrains("departure", "arrival") - def _check_departure(self): - for record in self: - if record.departure and record.arrival > record.departure: - raise ValidationError( - _("Departure date (%s) is prior to arrival on %s") - % (record.departure, record.arrival) - ) - - @api.constrains("partner_id") - def _check_partner_id(self): - for record in self: - if record.partner_id: - indoor_partner_ids = record.reservation_id.checkin_partner_ids.filtered( - lambda r: r.id != record.id - ).mapped("partner_id.id") - if indoor_partner_ids.count(record.partner_id.id) > 1: - record.partner_id = None - raise ValidationError( - _("This guest is already registered in the room") - ) - - # REVIEW: Redesign email & mobile control (res.partner? other module in OCA?) - # @api.constrains("email") - # def check_email_pattern(self): - # for record in self: - # if record.email: - # if not re.search( - # r"^[a-zA-Z0-9]([a-zA-z0-9\-\_]*[\.]?[a-zA-Z0-9\-\_]+)*" - # r"@([a-zA-z0-9\-]+([\.][a-zA-Z0-9\-\_]+)?\.[a-zA-Z0-9]+)+$", - # record.email, - # ): - # raise ValidationError(_("'%s' is not a valid email", record.email)) - - # @api.constrains("mobile") - # def check_phone_pattern(self): - - # for record in self: - # if record.mobile: - - # if not re.search( - # r"^(\d{3}[\-\s]?\d{2}[\-\s]?\d{2}[\-\s]?\d{2}[\-\s]?|" - # r"\d{3}[\-\s]?\d{3}[\-\s]?\d{3})$", - # str(record.mobile), - # ): - # 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")) - - def _validation_eval_context(self, id_number): - self.ensure_one() - return {"self": self, "id_number": id_number} - - @api.constrains("document_number", "document_type") - def validate_id_number(self): - """Validate the given ID number - The method raises an odoo.exceptions.ValidationError if the eval of - python validation code fails - """ - for record in self: - if record.document_number and record.document_type: - id_number = self.env["res.partner.id_number"].new( - { - "name": record.document_number, - "category_id": record.document_type, - } - ) - if ( - self.env.context.get("id_no_validate") - or not record.document_type.validation_code - ): - return - eval_context = record._validation_eval_context(id_number) - try: - safe_eval( - record.document_type.validation_code, - eval_context, - mode="exec", - nocopy=True, - ) - except Exception as e: - raise UserError( - _( - "Error when evaluating the id_category validation code:" - ":\n %s \n(%s)" - ) - % (self.name, e) - ) - if eval_context.get("failed", False): - raise ValidationError( - _("%s is not a valid %s identifier") - % (record.document_number, record.document_type.name) - ) - - @api.model - def create(self, vals): - # The checkin records are created automatically from adult depends - # if you try to create one manually, we update one unassigned checkin - reservation_id = vals.get("reservation_id") - if reservation_id: - reservation = self.env["pms.reservation"].browse(reservation_id) - else: - raise ValidationError( - _("Is mandatory indicate the reservation on the checkin") - ) - draft_checkins = reservation.checkin_partner_ids.filtered( - lambda c: c.state == "draft" - ) - if len(reservation.checkin_partner_ids) < reservation.adults: - if vals.get("identifier", _("New")) == _("New") or "identifier" not in vals: - pms_property_id = ( - self.env.user.get_active_property_ids()[0] - if "pms_property_id" not in vals - else vals["pms_property_id"] - ) - pms_property = self.env["pms.property"].browse(pms_property_id) - vals["identifier"] = pms_property.checkin_sequence_id._next_do() - return super(PmsCheckinPartner, self).create(vals) - if len(draft_checkins) > 0: - draft_checkins[0].write(vals) - return draft_checkins[0] - raise ValidationError( - _("Is not possible to create the proposed check-in in this reservation") - ) - - def unlink(self): - reservations = self.mapped("reservation_id") - res = super().unlink() - reservations._compute_checkin_partner_ids() - return res - - @api.model - def _checkin_mandatory_fields(self, country=False, depends=False): - mandatory_fields = [ - "name", - ] - # api.depends need "reservation_id.state" in the lambda function - if depends: - mandatory_fields.extend(["reservation_id.state", "name"]) - - return mandatory_fields - - @api.model - def _checkin_partner_fields(self): - checkin_fields = [ - "firstname", - "lastname", - "lastname2", - "mobile", - "email", - "gender", - "nationality_id", - "birthdate_date", - ] - return checkin_fields - - @api.model - def import_room_list_json(self, roomlist_json): - roomlist_json = json.loads(roomlist_json) - for checkin_dict in roomlist_json: - identifier = checkin_dict["identifier"] - reservation_id = checkin_dict["reservation_id"] - checkin = self.env["pms.checkin.partner"].search( - [("identifier", "=", identifier)] - ) - reservation = self.env["pms.reservation"].browse(reservation_id) - if not checkin: - raise ValidationError( - _("%s not found in checkins (%s)"), identifier, reservation.name - ) - checkin_vals = {} - for key, value in checkin_dict.items(): - if key in ("reservation_id", "folio_id", "identifier"): - continue - checkin_vals[key] = value - checkin.write(checkin_vals) - - @api.model - def calculate_doc_type_expedition_date_from_validity_date( - self, doc_type, doc_date, birthdate - ): - today = fields.datetime.today() - datetime_doc_date = datetime.strptime(doc_date, DEFAULT_SERVER_DATE_FORMAT) - if datetime_doc_date < today: - return datetime_doc_date - datetime_birthdate = datetime.strptime(birthdate, DEFAULT_SERVER_DATE_FORMAT) - age = today.year - datetime_birthdate.year - document_type = self.env["res.partner.id_category"].search( - [("id", "=", doc_type)] - ) - document_expedition_date = False - if document_type.code == "D" or document_type.code == "P": - if age < 30: - document_expedition_date = datetime_doc_date - relativedelta(years=5) - else: - document_expedition_date = datetime_doc_date - relativedelta(years=10) - if document_type.code == "C": - if age < 70: - document_expedition_date = datetime_doc_date - relativedelta(years=10) - return document_expedition_date - - def action_on_board(self): - for record in self: - if record.reservation_id.checkin > fields.Date.today(): - 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() - ): - raise ValidationError(_("Personal data is missing for check-in")) - vals = { - "state": "onboard", - "arrival": fields.Datetime.now(), - } - record.update(vals) - record.reservation_id.state = "onboard" - - def action_done(self): - for record in self.filtered(lambda c: c.state == "onboard"): - vals = { - "state": "done", - "departure": fields.Datetime.now(), - } - record.update(vals) - return True - - def open_partner(self): - """ Utility method used to add an "View Customer" button in checkin partner views """ - self.ensure_one() - partner_form_id = self.env.ref("pms.view_partner_data_form").id - return { - "type": "ir.actions.act_window", - "res_model": "res.partner", - "view_mode": "form", - "views": [(partner_form_id, "form")], - "res_id": self.partner_id.id, - "target": "new", - "flags": {"form": {"action_buttons": True}}, - } - - def open_wizard_several_partners(self): - ctx = dict( - checkin_partner_id=self.id, - possible_existing_customer_ids=self.possible_existing_customer_ids.ids, - ) - return { - "view_type": "form", - "view_mode": "form", - "name": "Several Customers", - "res_model": "pms.several.partners.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": ctx, - } - - def _save_data_from_portal(self, values): - checkin_partner = self.env["pms.checkin.partner"].browse(int(values.get("id"))) - if values.get("nationality_id"): - nationality_id = self.env["res.country"].search( - [("id", "=", values.get("nationality_id"))] - ) - values.update({"nationality_id": nationality_id.id}) - else: - values.update({"nationality_id": False}) - if not values.get("document_type"): - values.update({"document_type": False}) - if values.get("state"): - state_id = self.env["res.country.state"].search( - [("id", "=", values.get("state"))] - ) - values.update({"state_id": state_id}) - values.pop("state") - if values.get("document_expedition_date"): - doc_type = values.get("document_type") - doc_date = values.get("document_expedition_date") - birthdate = values.get("birthdate_date") - document_expedition_date = ( - self.calculate_doc_type_expedition_date_from_validity_date( - doc_type, doc_date, birthdate - ) - ) - values.update({"document_expedition_date": document_expedition_date}) - checkin_partner.sudo().write(values) - - def send_portal_invitation_email(self, invitation_firstname=None, email=None): - template = self.sudo().env.ref( - "pms.precheckin_invitation_email", raise_if_not_found=False - ) - subject = template._render_field( - "subject", [6, 0, self.id], compute_lang=True, post_process=True - )[self.id] - body = template._render_field( - "body_html", [6, 0, self.id], compute_lang=True, post_process=True - )[self.id] - invitation_mail = ( - self.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": self.pms_property_id.partner_id.email, - "email_to": email, - } - ) - ) - - invitation_mail.send() diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py deleted file mode 100644 index 98e5e3006..000000000 --- a/pms/models/pms_folio.py +++ /dev/null @@ -1,2207 +0,0 @@ -# Copyright 2017-2018 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import logging -from itertools import groupby - -from odoo import _, api, fields, models -from odoo.exceptions import AccessError, UserError, ValidationError -from odoo.tools import float_is_zero - -_logger = logging.getLogger(__name__) - - -class PmsFolio(models.Model): - _name = "pms.folio" - _description = "PMS Folio" - _inherit = ["mail.thread", "mail.activity.mixin", "portal.mixin"] - _order = "date_order" - _check_company_auto = True - _check_pms_properties_auto = True - - name = fields.Char( - string="Folio Number", - help="Folio name. When creating a folio the " - "name is automatically formed with a sequence", - readonly=True, - index=True, - default=lambda self: _("New"), - ) - pms_property_id = fields.Many2one( - string="Property", - help="The property for folios", - comodel_name="pms.property", - required=True, - default=lambda self: self.env.user.get_active_property_ids()[0], - check_pms_properties=True, - ) - partner_id = fields.Many2one( - string="Partner", - help="The folio customer", - readonly=False, - store=True, - tracking=True, - compute="_compute_partner_id", - comodel_name="res.partner", - ondelete="restrict", - check_pms_properties=True, - ) - reservation_ids = fields.One2many( - string="Reservations", - help="Room reservation detail", - readonly=False, - states={"done": [("readonly", True)]}, - comodel_name="pms.reservation", - inverse_name="folio_id", - check_company=True, - check_pms_properties=True, - ) - number_of_rooms = fields.Integer( - string="Number of Rooms", - help="Number of rooms in folio. Canceled rooms do not count.", - store="True", - compute="_compute_number_of_rooms", - ) - number_of_cancelled_rooms = fields.Integer( - string="Number of Cancelled Rooms", - help="Number of cancelled rooms in folio.", - store="True", - compute="_compute_number_of_cancelled_rooms", - ) - number_of_services = fields.Integer( - string="Number of Services", - help="Number of services in the folio", - store="True", - compute="_compute_number_of_services", - ) - service_ids = fields.One2many( - string="Service", - help="Services detail provide to customer and it will " - "include in main Invoice.", - readonly=False, - states={"done": [("readonly", True)]}, - comodel_name="pms.service", - inverse_name="folio_id", - check_company=True, - check_pms_properties=True, - ) - sale_line_ids = fields.One2many( - string="Sale lines", - help="Sale lines in folio. It correspond with reservation nights", - store="True", - compute="_compute_sale_line_ids", - compute_sudo=True, - comodel_name="folio.sale.line", - inverse_name="folio_id", - ) - invoice_count = fields.Integer( - string="Invoice Count", - help="The amount of invoices in out invoice and out refund status", - readonly=True, - compute="_compute_get_invoiced", - ) - company_id = fields.Many2one( - string="Company", - help="The company for folio", - store=True, - comodel_name="res.company", - compute="_compute_company_id", - ) - move_line_ids = fields.Many2many( - string="Payments", - help="Folio payments", - readonly=True, - comodel_name="account.move.line", - relation="payment_folio_rel", - column1="folio_id", - column2="move_id", - ) - analytic_account_id = fields.Many2one( - string="Analytic Account", - help="The analytic account related to a folio.", - readonly=True, - states={"draft": [("readonly", False)], "sent": [("readonly", False)]}, - copy=False, - comodel_name="account.analytic.account", - ) - currency_id = fields.Many2one( - string="Currency", - help="The currency of the property location", - readonly=True, - required=True, - related="pricelist_id.currency_id", - ondelete="restrict", - ) - pricelist_id = fields.Many2one( - string="Pricelist", - help="Pricelist for current folio.", - readonly=False, - store=True, - comodel_name="product.pricelist", - ondelete="restrict", - check_pms_properties=True, - compute="_compute_pricelist_id", - ) - commission = fields.Float( - string="Commission", - readonly=True, - store=True, - compute="_compute_commission", - ) - user_id = fields.Many2one( - string="Salesperson", - help="The user who created the folio", - readonly=False, - index=True, - store=True, - comodel_name="res.users", - ondelete="restrict", - compute="_compute_user_id", - tracking=True, - ) - agency_id = fields.Many2one( - string="Agency", - help="Only allowed if the field of partner is_agency is True", - comodel_name="res.partner", - domain=[("is_agency", "=", True)], - ondelete="restrict", - check_pms_properties=True, - ) - channel_type_id = fields.Many2one( - string="Direct Sale Channel", - help="Only allowed if the field of sale channel channel_type is 'direct'", - readonly=False, - store=True, - comodel_name="pms.sale.channel", - domain=[("channel_type", "=", "direct")], - ondelete="restrict", - compute="_compute_channel_type_id", - check_pms_properties=True, - ) - transaction_ids = fields.Many2many( - string="Transactions", - help="Payments made through payment acquirer", - readonly=True, - copy=False, - comodel_name="payment.transaction", - relation="payment_transaction_folio_rel", - column1="folio_id", - column2="payment_transaction_id", - ) - payment_ids = fields.Many2many( - string="Bank Payments", - help="Payments made by bank direct", - readonly=True, - copy=False, - comodel_name="account.payment", - relation="account_payment_folio_rel", - column1="folio_id", - column2="payment_id", - ) - statement_line_ids = fields.Many2many( - string="Cash Payments", - help="Payments made by cash", - readonly=True, - copy=False, - comodel_name="account.bank.statement.line", - relation="account_bank_statement_folio_rel", - column1="folio_id", - column2="account_journal_id", - ) - payment_term_id = fields.Many2one( - string="Payment Terms", - help="Payment terms for current folio.", - readonly=False, - store=True, - comodel_name="account.payment.term", - ondelete="restrict", - compute="_compute_payment_term_id", - ) - checkin_partner_ids = fields.One2many( - string="Checkin Partners", - help="The checkin partners on a folio", - comodel_name="pms.checkin.partner", - inverse_name="folio_id", - ) - count_rooms_pending_arrival = fields.Integer( - string="Pending Arrival", - help="The number of rooms left to occupy.", - store=True, - compute="_compute_count_rooms_pending_arrival", - ) - pending_checkin_data = fields.Integer( - string="Checkin Data", - compute="_compute_pending_checkin_data", - store=True, - ) - ratio_checkin_data = fields.Integer( - string="Pending Checkin Data", - help="Field that stores the number of checkin partners pending " - "to checkin (with the state = draft)", - compute="_compute_ratio_checkin_data", - ) - move_ids = fields.Many2many( - string="Invoices", - help="Folio invoices related to account move.", - readonly=True, - copy=False, - comodel_name="account.move", - compute="_compute_get_invoiced", - search="_search_invoice_ids", - ) - payment_state = fields.Selection( - string="Payment Status", - help="The state of the payment", - copy=False, - readonly=True, - store=True, - selection=[ - ("not_paid", "Not Paid"), - ("paid", "Paid"), - ("partial", "Partially Paid"), - ], - compute="_compute_amount", - tracking=True, - ) - partner_invoice_ids = fields.Many2many( - string="Billing addresses", - help="Invoice address for current group.", - readonly=False, - store=True, - comodel_name="res.partner", - relation="pms_folio_partner_rel", - column1="folio", - column2="partner", - compute="_compute_partner_invoice_ids", - check_pms_properties=True, - ) - # REVIEW THIS - # partner_invoice_state_id = fields.Many2one(related="partner_invoice_id.state_id") - # partner_invoice_country_id = fields.Many2one( - # related="partner_invoice_id.country_id" - # ) - fiscal_position_id = fields.Many2one( - string="Fiscal Position", - help="The fiscal position depends on the location of the client", - comodel_name="account.fiscal.position", - ) - closure_reason_id = fields.Many2one( - string="Closure Reason", - help="The closure reason for a closure room", - comodel_name="room.closure.reason", - check_pms_properties=True, - ) - segmentation_ids = fields.Many2many( - string="Segmentation", - help="Segmentation tags to classify folios", - comodel_name="res.partner.category", - ondelete="restrict", - ) - client_order_ref = fields.Char(string="Customer Reference", help="", copy=False) - reservation_type = fields.Selection( - string="Type", - help="The type of the reservation. " - "Can be 'Normal', 'Staff' or 'Out of Service'", - default=lambda *a: "normal", - selection=[("normal", "Normal"), ("staff", "Staff"), ("out", "Out of Service")], - ) - date_order = fields.Datetime( - string="Order Date", - help="Date on which folio is sold", - readonly=True, - required=True, - index=True, - default=fields.Datetime.now, - states={"draft": [("readonly", False)], "sent": [("readonly", False)]}, - copy=False, - ) - confirmation_date = fields.Datetime( - string="Confirmation Date", - help="Date on which the folio is confirmed.", - readonly=True, - index=True, - copy=False, - ) - state = fields.Selection( - string="Status", - help="Folio status; it can be Quotation, " - "Quotation Sent, Confirmed, Locked or Cancelled", - readonly=True, - index=True, - default="draft", - copy=False, - selection=[ - ("draft", "Quotation"), - ("sent", "Quotation Sent"), - ("confirm", "Confirmed"), - ("done", "Locked"), - ("cancel", "Cancelled"), - ], - tracking=True, - ) - partner_name = fields.Char( - string="Customer Name", - help="In the name of whom the reservation is made", - store=True, - readonly=False, - compute="_compute_partner_name", - ) - email = fields.Char( - string="E-mail", - help="Customer E-mail", - store=True, - readonly=False, - compute="_compute_email", - ) - mobile = fields.Char( - string="Mobile", - help="Customer Mobile", - store=True, - readonly=False, - compute="_compute_mobile", - ) - partner_incongruences = fields.Char( - string="partner_incongruences", - help="indicates that some partner fields \ - on the folio do not correspond to that of \ - the associated partner", - compute="_compute_partner_incongruences", - ) - partner_internal_comment = fields.Text( - string="Internal Partner Notes", - help="Internal notes of the partner", - related="partner_id.comment", - store=True, - readonly=False, - ) - credit_card_details = fields.Text( - string="Credit Card Details", - help="Details of partner credit card", - ) - - pending_amount = fields.Monetary( - string="Pending Amount", - help="The amount that remains to be paid", - store=True, - compute="_compute_amount", - ) - # refund_amount = fields.Monetary( - # compute="_compute_amount", store=True, string="Payment Returns" - # ) - invoices_paid = fields.Monetary( - string="Paid Out", - help="Amount of invoices paid", - store=True, - compute="_compute_amount", - tracking=True, - ) - amount_untaxed = fields.Monetary( - string="Untaxed Amount", - help="The price without taxes on a folio", - readonly=True, - store=True, - compute="_compute_amount_all", - tracking=True, - ) - amount_tax = fields.Monetary( - string="Taxes", - help="Price with taxes on a folio", - readonly=True, - store=True, - compute="_compute_amount_all", - ) - amount_total = fields.Monetary( - string="Total", - help="Total amount to be paid", - readonly=True, - store=True, - compute="_compute_amount_all", - tracking=True, - ) - max_reservation_priority = fields.Integer( - string="Max reservation priority on the entire folio", - help="Max reservation priority on the entire folio", - compute="_compute_max_reservation_priority", - store=True, - ) - invoice_status = fields.Selection( - string="Invoice Status", - help="Invoice Status; it can be: upselling, invoiced, to invoice, no", - readonly=True, - default="no", - store=True, - selection=[ - ("invoiced", "Fully Invoiced"), - ("to_invoice", "To Invoice"), - ("no", "Nothing to Invoice"), - ], - compute="_compute_get_invoice_status", - compute_sudo=True, - ) - internal_comment = fields.Text( - string="Internal Folio Notes", - help="Internal Folio notes for Staff", - ) - cancelled_reason = fields.Text( - string="Cause of cancelled", - help="Indicates cause of cancelled", - ) - prepaid_warning_days = fields.Integer( - string="Prepaid Warning Days", - help="Margin in days to create a notice if a payment \ - advance has not been recorded", - ) - sequence = fields.Integer( - string="Sequence", - help="Sequence used to form the name of the folio", - default=10, - ) - note = fields.Text( - string="Terms and conditions", - help="Folio billing terms and conditions", - default=lambda self: self._default_note(), - ) - reference = fields.Char( - string="Payment Ref.", - help="The payment communication of this sale order.", - copy=False, - ) - document_number = fields.Char( - string="Document Number", - readonly=False, - store=True, - compute="_compute_document_number", - ) - document_type = fields.Many2one( - string="Document Type", - readonly=False, - store=True, - comodel_name="res.partner.id_category", - compute="_compute_document_type", - ) - - document_id = fields.Many2one( - string="Document", - readonly=False, - store=True, - comodel_name="res.partner.id_number", - compute="_compute_document_id", - ondelete="restrict", - ) - - possible_existing_customer_ids = fields.One2many( - string="Possible existing customer", - readonly=False, - store=True, - compute="_compute_possible_existing_customer_ids", - comodel_name="res.partner", - inverse_name="folio_possible_customer_id", - ) - - first_checkin = fields.Date( - string="First Folio Checkin", - readonly=False, - store=True, - compute="_compute_first_checkin", - ) - - last_checkout = fields.Date( - string="Last Folio Checkout", - readonly=False, - store=True, - compute="_compute_last_checkout", - ) - - def name_get(self): - result = [] - for folio in self: - name = folio.name - if len(folio.reservation_ids) > 1: - name += " (%s)" % len(folio.reservation_ids) - result.append((folio.id, name)) - return result - - def _default_note(self): - return ( - self.env["ir.config_parameter"] - .sudo() - .get_param("account.use_invoice_terms") - and self.env.company.invoice_terms - or "" - ) - - def _get_report_base_filename(self): - self.ensure_one() - return "Folio %s" % self.name - - def _get_invoice_grouping_keys(self): - return ["company_id", "partner_id", "currency_id"] - - def get_invoice_vals_list( - self, final=False, lines_to_invoice=False, partner_invoice_id=False - ): - precision = self.env["decimal.precision"].precision_get( - "Product Unit of Measure" - ) - invoice_vals_list = [] - invoice_item_sequence = 0 - for order in self: - order = order.with_company(order.company_id) - current_section_vals = None - down_payments = order.env["folio.sale.line"] - - # Invoice values. - invoice_vals = order._prepare_invoice(partner_invoice_id=partner_invoice_id) - - # Invoice line values (keep only necessary sections). - invoice_lines_vals = [] - for line in order.sale_line_ids.filtered( - lambda l: l.id in list(lines_to_invoice.keys()) - ): - if line.display_type == "line_section": - current_section_vals = line._prepare_invoice_line( - sequence=invoice_item_sequence + 1 - ) - continue - if line.display_type != "line_note" and float_is_zero( - line.qty_to_invoice, precision_digits=precision - ): - continue - if ( - line.qty_to_invoice > 0 - or (line.qty_to_invoice < 0 and final) - or line.display_type == "line_note" - ): - if line.is_downpayment: - down_payments += line - continue - if current_section_vals: - invoice_item_sequence += 1 - invoice_lines_vals.append(current_section_vals) - current_section_vals = None - invoice_item_sequence += 1 - prepared_line = line._prepare_invoice_line( - sequence=invoice_item_sequence, qty=lines_to_invoice[line.id] - ) - invoice_lines_vals.append(prepared_line) - - # If down payments are present in SO, group them under common section - if down_payments: - invoice_item_sequence += 1 - down_payments_section = order._prepare_down_payment_section_line( - sequence=invoice_item_sequence - ) - invoice_lines_vals.append(down_payments_section) - for down_payment in down_payments: - invoice_item_sequence += 1 - invoice_down_payment_vals = down_payment._prepare_invoice_line( - sequence=invoice_item_sequence - ) - invoice_lines_vals.append(invoice_down_payment_vals) - - if not any( - new_line["display_type"] is False for new_line in invoice_lines_vals - ): - raise self._nothing_to_invoice_error() - - invoice_vals["invoice_line_ids"] = [ - (0, 0, invoice_line_id) for invoice_line_id in invoice_lines_vals - ] - - invoice_vals_list.append(invoice_vals) - return invoice_vals_list - - def _get_tax_amount_by_group(self): - self.ensure_one() - res = {} - for line in self.sale_line_ids: - price_reduce = line.price_total - product = line.product_id - taxes = line.tax_ids.compute_all(price_reduce, quantity=1, product=product)[ - "taxes" - ] - for tax in line.tax_ids: - group = tax.tax_group_id - res.setdefault(group, {"amount": 0.0, "base": 0.0}) - for t in taxes: - if t["id"] == tax.id or t["id"] in tax.children_tax_ids.ids: - res[group]["amount"] += t["amount"] - res[group]["base"] += t["base"] - res = sorted(res.items(), key=lambda line: line[0].sequence) - res = [ - (line[0].name, line[1]["amount"], line[1]["base"], len(res)) for line in res - ] - return res - - @api.depends("reservation_ids", "reservation_ids.state") - def _compute_number_of_rooms(self): - for folio in self: - folio.number_of_rooms = len( - folio.reservation_ids.filtered(lambda a: a.state != "cancel") - ) - - @api.depends("reservation_ids", "reservation_ids.state") - def _compute_number_of_cancelled_rooms(self): - for folio in self: - folio.number_of_cancelled_rooms = len( - folio.reservation_ids.filtered(lambda a: a.state == "cancel") - ) - - @api.depends("service_ids", "service_ids.product_qty") - def _compute_number_of_services(self): - for folio in self: - folio.number_of_services = sum(folio.service_ids.mapped("product_qty")) - - @api.depends( - "reservation_ids", - "service_ids", - "service_ids.reservation_id", - "service_ids.service_line_ids.price_day_total", - "service_ids.service_line_ids.discount", - "service_ids.service_line_ids.cancel_discount", - "service_ids.service_line_ids.day_qty", - "service_ids.service_line_ids.tax_ids", - "reservation_ids.reservation_line_ids", - "reservation_ids.reservation_line_ids.price", - "reservation_ids.reservation_line_ids.discount", - "reservation_ids.reservation_line_ids.cancel_discount", - "reservation_ids.tax_ids", - ) - def _compute_sale_line_ids(self): - for folio in self: - if folio.reservation_type == "normal": - for reservation in folio.reservation_ids: - # RESERVATION LINES - # res = self.env['pms.reservation'].browse(reservation.id) - self.generate_reservation_lines_sale_lines(folio, reservation) - - # RESERVATION SERVICES - self.generate_reservation_services_sale_lines(folio, reservation) - - # FOLIO SERVICES - self.generate_folio_services_sale_lines(folio) - else: - for reservation in folio.reservation_ids: - reservation.sale_line_ids = False - - @api.depends("pms_property_id") - def _compute_company_id(self): - for record in self: - record.company_id = record.pms_property_id.company_id - - @api.depends( - "partner_id", "agency_id", "reservation_ids", "reservation_ids.pricelist_id" - ) - def _compute_pricelist_id(self): - for folio in self: - if folio.reservation_type in ("out", "staff"): - folio.pricelist_id = False - elif len(folio.reservation_ids.pricelist_id) == 1: - folio.pricelist_id = folio.reservation_ids.pricelist_id - elif folio.agency_id and folio.agency_id.apply_pricelist: - folio.pricelist_id = folio.agency_id.property_product_pricelist - elif folio.partner_id and folio.partner_id.property_product_pricelist: - folio.pricelist_id = folio.partner_id.property_product_pricelist - elif not folio.pricelist_id: - folio.pricelist_id = folio.pms_property_id.default_pricelist_id - - @api.depends( - "agency_id", - "reservation_type", - "document_number", - "document_type", - "partner_name", - "email", - "mobile", - ) - def _compute_partner_id(self): - for folio in self: - if folio.reservation_type == "out": - folio.partner_id = False - elif folio.agency_id and folio.agency_id.invoice_to_agency: - folio.partner_id = folio.agency_id.id - elif folio.document_number and folio.document_type: - self._create_partner(folio) - elif not folio.partner_id: - folio.partner_id = False - - @api.depends("partner_id") - def _compute_user_id(self): - for folio in self: - if not folio.user_id: - folio.user_id = (folio.partner_id.user_id.id or self.env.uid,) - - @api.depends( - "partner_id", - "reservation_ids", - "reservation_ids.partner_id", - "reservation_ids.checkin_partner_ids", - "reservation_ids.checkin_partner_ids.partner_id", - ) - def _compute_partner_invoice_ids(self): - for folio in self: - if folio.partner_id: - addr = folio.partner_id.address_get(["invoice"]) - if not addr["invoice"] in folio.partner_invoice_ids.ids: - folio.partner_invoice_ids = [(4, addr["invoice"])] - for reservation in folio.reservation_ids: - if reservation.partner_id: - addr = reservation.partner_id.address_get(["invoice"]) - if not addr["invoice"] in folio.partner_invoice_ids.ids: - folio.partner_invoice_ids = [(4, addr["invoice"])] - for checkin in reservation.checkin_partner_ids: - if checkin.partner_id: - addr = checkin.partner_id.address_get(["invoice"]) - if not addr["invoice"] in folio.partner_invoice_ids.ids: - folio.partner_invoice_ids = [(4, addr["invoice"])] - self.filtered(lambda f: not f.partner_invoice_ids).partner_invoice_ids = False - - @api.depends("partner_id") - def _compute_payment_term_id(self): - self.payment_term_id = False - for folio in self: - folio.payment_term_id = ( - folio.partner_id.property_payment_term_id - and folio.partner_id.property_payment_term_id.id - or False - ) - - @api.depends("reservation_ids", "reservation_ids.commission_amount") - def _compute_commission(self): - for folio in self: - for reservation in folio.reservation_ids: - if reservation.commission_amount != 0: - folio.commission += reservation.commission_amount - else: - folio.commission = 0 - - @api.depends("agency_id") - def _compute_channel_type_id(self): - for folio in self: - if folio.agency_id: - folio.channel_type_id = folio.agency_id.sale_channel_id.id - - @api.depends("sale_line_ids.invoice_lines") - def _compute_get_invoiced(self): - # The invoice_ids are obtained thanks to the invoice lines of the SO - # lines, and we also search for possible refunds created directly from - # existing invoices. This is necessary since such a refund is not - # directly linked to the SO. - for order in self: - invoices = order.sale_line_ids.invoice_lines.move_id.filtered( - lambda r: r.move_type in ("out_invoice", "out_refund") - ) - order.move_ids = invoices - order.invoice_count = len(invoices) - - # @api.depends( - # "reservation_ids", - # "reservation_ids.currency_id" - # ) - # def _compute_currency_id(self): - # if len(self.reservation_ids.mapped("currency_id")) == 1: - # self.currency_id = self.reservation_ids.mapped("currency_id") - # else: - # raise UserError(_("Some reservations have different currency")) - - # is_checkin = fields.Boolean() - - def _compute_access_url(self): - super(PmsFolio, self)._compute_access_url() - for folio in self: - folio.access_url = "/my/folios/%s" % (folio.id) - - @api.depends("state", "sale_line_ids.invoice_status") - def _compute_get_invoice_status(self): - """ - Compute the invoice status of a Folio. Possible statuses: - - no: if the Folio is in status 'draft', we consider that there is nothing to - invoice. This is also the default value if the conditions of no - other status is met. - - to_invoice: if any SO line is 'to_invoice', the whole SO is 'to_invoice' - - invoiced: if all SO lines are invoiced, the SO is invoiced. - """ - unconfirmed_orders = self.filtered(lambda so: so.state in ["draft"]) - unconfirmed_orders.invoice_status = "no" - confirmed_orders = self - unconfirmed_orders - if not confirmed_orders: - return - line_invoice_status_all = [ - (d["folio_id"][0], d["invoice_status"]) - for d in self.env["folio.sale.line"].read_group( - [ - ("folio_id", "in", confirmed_orders.ids), - ("is_downpayment", "=", False), - ("display_type", "=", False), - ], - ["folio_id", "invoice_status"], - ["folio_id", "invoice_status"], - lazy=False, - ) - ] - for order in confirmed_orders: - line_invoice_status = [ - d[1] for d in line_invoice_status_all if d[0] == order.id - ] - if order.state in ("draft"): - order.invoice_status = "no" - elif any( - invoice_status == "to_invoice" for invoice_status in line_invoice_status - ): - order.invoice_status = "to_invoice" - elif line_invoice_status and all( - invoice_status == "invoiced" for invoice_status in line_invoice_status - ): - order.invoice_status = "invoiced" - elif line_invoice_status and all( - invoice_status in ("invoiced", "upselling") - for invoice_status in line_invoice_status - ): - order.invoice_status = "upselling" - else: - order.invoice_status = "no" - - @api.depends("partner_id", "partner_id.name", "agency_id", "reservation_type") - def _compute_partner_name(self): - for record in self: - self._apply_partner_name(record) - - @api.depends("partner_id", "partner_id.email", "agency_id") - def _compute_email(self): - for record in self: - self._apply_email(record) - - @api.depends("partner_id", "partner_id.mobile", "agency_id") - def _compute_mobile(self): - for record in self: - self._apply_mobile(record) - - @api.depends( - "partner_name", - "email", - "mobile", - "partner_id", - ) - def _compute_partner_incongruences(self): - fields_mapping = { - "partner_name": "name", - "email": "email", - "mobile": "mobile", - } - for record in self: - incongruous_fields = False - if record.partner_id: - for k, v in fields_mapping.items(): - if record.partner_id[v] and record.partner_id[v] != record[k]: - if not incongruous_fields: - incongruous_fields = v - else: - incongruous_fields += ", " + v - if incongruous_fields: - record.partner_incongruences = ( - incongruous_fields + " field/s don't correspond to saved host" - ) - else: - record.partner_incongruences = False - else: - record.partner_incongruences = False - - @api.depends("sale_line_ids.price_total") - def _compute_amount_all(self): - """ - Compute the total amounts of the SO. - """ - for folio in self: - amount_untaxed = amount_tax = 0.0 - for line in folio.sale_line_ids: - amount_untaxed += line.price_subtotal - amount_tax += line.price_tax - folio.update( - { - "amount_untaxed": amount_untaxed, - "amount_tax": amount_tax, - "amount_total": amount_untaxed + amount_tax, - } - ) - - @api.depends("reservation_ids", "reservation_ids.state") - def _compute_count_rooms_pending_arrival(self): - self.count_rooms_pending_arrival = 0 - for folio in self.filtered("reservation_ids"): - folio.count_rooms_pending_arrival = len( - folio.reservation_ids.filtered( - lambda c: c.state in ("draf", "confirm", "arrival_delayed") - ) - ) - - @api.depends("checkin_partner_ids", "checkin_partner_ids.state") - def _compute_pending_checkin_data(self): - for folio in self: - if folio.reservation_type != "out": - folio.pending_checkin_data = len( - folio.checkin_partner_ids.filtered(lambda c: c.state == "draft") - ) - - @api.depends("pending_checkin_data") - def _compute_ratio_checkin_data(self): - self.ratio_checkin_data = 0 - for folio in self.filtered("reservation_ids"): - if folio.reservation_type != "out": - folio.ratio_checkin_data = ( - ( - sum(folio.reservation_ids.mapped("adults")) - - folio.pending_checkin_data - ) - * 100 - / sum(folio.reservation_ids.mapped("adults")) - ) - - # TODO: Add return_ids to depends - @api.depends( - "amount_total", - "reservation_type", - "state", - "move_line_ids", - "move_line_ids.parent_state", - "sale_line_ids.invoice_lines", - "sale_line_ids.invoice_lines.move_id.payment_state", - ) - def _compute_amount(self): - for record in self: - if record.reservation_type in ("staff", "out"): - record.amount_total = 0 - vals = { - "payment_state": False, - "pending_amount": 0, - "invoices_paid": 0, - } - record.update(vals) - else: - journals = record.pms_property_id._get_payment_methods( - automatic_included=True - ) - paid_out = 0 - for journal in journals: - paid_out += sum( - self.env["account.move.line"] - .search( - [ - ("folio_ids", "in", record.id), - ( - "account_id", - "in", - tuple( - journal.default_account_id.ids - + journal.payment_debit_account_id.ids - + journal.payment_credit_account_id.ids - ), - ), - ( - "display_type", - "not in", - ("line_section", "line_note"), - ), - ("move_id.state", "!=", "cancel"), - ] - ) - .mapped("balance") - ) - total = record.amount_total - # REVIEW: Must We ignored services in cancelled folios - # pending amount? - if record.state == "cancel": - total = total - sum(record.service_ids.mapped("price_total")) - # Compute 'payment_state'. - if total <= paid_out: - payment_state = "paid" - elif paid_out <= 0: - payment_state = "not_paid" - else: - payment_state = "partial" - vals = { - "pending_amount": total - paid_out, - "invoices_paid": paid_out, - "payment_state": payment_state, - } - record.update(vals) - - @api.depends("reservation_ids", "reservation_ids.priority") - def _compute_max_reservation_priority(self): - for record in self.filtered("reservation_ids"): - reservation_priors = record.reservation_ids.mapped("priority") - record.max_reservation_priority = max(reservation_priors) - - def _compute_checkin_partner_count(self): - for record in self: - if record.reservation_type == "normal" and record.reservation_ids: - filtered_reservs = record.reservation_ids.filtered( - lambda x: x.state != "cancel" - ) - mapped_checkin_partner = filtered_reservs.mapped( - "checkin_partner_ids.id" - ) - record.checkin_partner_count = len(mapped_checkin_partner) - mapped_checkin_partner_count = filtered_reservs.mapped( - lambda x: (x.adults + x.children) - len(x.checkin_partner_ids) - ) - record.checkin_partner_pending_count = sum(mapped_checkin_partner_count) - - @api.depends("partner_id") - def _compute_document_number(self): - for record in self: - self._apply_document_number(record) - - @api.depends("partner_id") - def _compute_document_type(self): - for record in self: - self._apply_document_type(record) - - @api.depends("partner_id") - def _compute_document_id(self): - for record in self: - self._apply_document_id(record) - - @api.depends("email", "mobile", "partner_name") - def _compute_possible_existing_customer_ids(self): - for record in self: - if record.partner_name: - possible_customer = self._apply_possible_existing_customer_ids( - record.email, record.mobile, record.partner_id - ) - if possible_customer: - record.possible_existing_customer_ids = possible_customer - else: - record.possible_existing_customer_ids = False - - @api.depends("reservation_ids", "reservation_ids.checkin") - def _compute_first_checkin(self): - for record in self: - if record.reservation_ids: - checkins = record.reservation_ids.mapped("checkin") - record.first_checkin = min(checkins) - - @api.depends("reservation_ids", "reservation_ids.checkout") - def _compute_last_checkout(self): - for record in self: - if record.reservation_ids: - checkouts = record.reservation_ids.mapped("checkout") - record.last_checkout = max(checkouts) - - def _search_invoice_ids(self, operator, value): - if operator == "in" and value: - self.env.cr.execute( - """ - SELECT array_agg(so.id) - FROM pms_folio so - JOIN folio_sale_line sol ON sol.folio_id = so.id - JOIN folio_sale_line_invoice_rel soli_rel ON \ - soli_rel.sale_line_ids = sol.id - JOIN account_move_line aml ON aml.id = soli_rel.invoice_line_id - JOIN account_move am ON am.id = aml.move_id - WHERE - am.move_type in ('out_invoice', 'out_refund') AND - am.id = ANY(%s) - """, - (list(value),), - ) - so_ids = self.env.cr.fetchone()[0] or [] - return [("id", "in", so_ids)] - return [ - "&", - ( - "sale_line_ids.invoice_lines.move_id.move_type", - "in", - ("out_invoice", "out_refund"), - ), - ("sale_line_ids.invoice_lines.move_id", operator, value), - ] - - @api.constrains("agency_id", "channel_type_id") - def _check_only_one_channel(self): - for record in self: - if ( - record.agency_id - and record.channel_type_id.channel_type - != record.agency_id.sale_channel_id.channel_type - ): - raise models.ValidationError( - _("The Sale Channel does not correspond to the agency's") - ) - - @api.constrains("name") - def _check_required_partner_name(self): - for record in self: - if not record.partner_name: - raise models.ValidationError(_("You must assign a customer name")) - - @api.model - def create(self, vals): - if vals.get("name", _("New")) == _("New") or "name" not in vals: - pms_property_id = ( - self.env.user.get_active_property_ids()[0] - if "pms_property_id" not in vals - else vals["pms_property_id"] - ) - pms_property = self.env["pms.property"].browse(pms_property_id) - vals["name"] = pms_property.folio_sequence_id._next_do() - result = super(PmsFolio, self).create(vals) - result.access_token = result._portal_ensure_token() - return result - - def action_pay(self): - self.ensure_one() - self.ensure_one() - partner = self.partner_id.id - amount = self.pending_amount - view_id = self.env.ref("pms.wizard_payment_folio_view_form").id - return { - "name": _("Register Payment"), - "view_type": "form", - "view_mode": "form", - "res_model": "wizard.payment.folio", - "type": "ir.actions.act_window", - "view_id": view_id, - "context": { - "default_folio_id": self.id, - "default_amount": amount, - "default_partner_id": partner, - }, - "target": "new", - } - - def open_partner(self): - """ Utility method used to add an "View Customer" button in folio views """ - self.ensure_one() - partner_form_id = self.env.ref("pms.view_partner_data_form").id - return { - "type": "ir.actions.act_window", - "res_model": "res.partner", - "view_mode": "form", - "views": [(partner_form_id, "form")], - "res_id": self.partner_id.id, - "target": "new", - "flags": {"form": {"action_buttons": True}}, - } - - def open_moves_folio(self): - invoices = self.mapped("move_ids") - action = self.env.ref("account.action_move_out_invoice_type").sudo().read()[0] - if len(invoices) > 1: - action["domain"] = [("id", "in", invoices.ids)] - elif len(invoices) == 1: - action["views"] = [(self.env.ref("account.view_move_form").id, "form")] - action["res_id"] = invoices.ids[0] - else: - action = {"type": "ir.actions.act_window_close"} - return action - - def folio_multi_changes(self): - self.ensure_one() - reservation_ids = self.reservation_ids.ids - action = self.env.ref("pms.action_folio_changes").sudo().read()[0] - action["context"] = ({"default_reservation_ids": [(6, 0, reservation_ids)]},) - return action - - # def action_return_payments(self): - # self.ensure_one() - # return_move_ids = [] - # acc_pay_obj = self.env["account.payment"] - # payments = acc_pay_obj.search( - # ["|", ("move_ids", "in", self.move_ids.ids), ("folio_id", "=", self.id)] - # ) - # return_move_ids += self.move_ids.filtered( - # lambda invoice: invoice.type == "out_refund" - # ).mapped("payment_move_line_ids.move_id.id") - # return_lines = self.env["payment.return.line"].search( - # [("move_line_ids", "in", payments.mapped("move_line_ids.id")),] - # ) - # return_move_ids += return_lines.mapped("return_id.move_id.id") - - # return { - # "name": _("Returns"), - # "view_type": "form", - # "view_mode": "tree,form", - # "res_model": "account.move", - # "type": "ir.actions.act_window", - # "domain": [("id", "in", return_move_ids)], - # } - - def action_checks(self): - self.ensure_one() - rooms = self.mapped("reservation_ids.id") - return { - "name": _("Checkins"), - "view_type": "form", - "view_mode": "tree,form", - "res_model": "pms.checkin.partner", - "type": "ir.actions.act_window", - "domain": [("reservation_id", "in", rooms)], - "search_view_id": [ - self.env.ref("pms.pms_checkin_partner_view_folio_search").id, - "search", - ], - "target": "new", - } - - def action_to_arrive(self): - self.ensure_one() - reservations = self.reservation_ids.filtered( - lambda c: c.state in ("draf", "confirm", "arrival_delayed") - ) - action = self.env.ref("pms.open_pms_reservation_form_tree_all").read()[0] - action["domain"] = [("id", "in", reservations.ids)] - return action - - def action_done(self): - reservation_ids = self.mapped("reservation_ids") - for line in reservation_ids: - if line.state == "onboard": - line.action_reservation_checkout() - - def action_cancel(self): - for folio in self: - for reservation in folio.reservation_ids.filtered( - lambda res: res.state != "cancel" - ): - reservation.action_cancel() - self.write( - { - "state": "cancel", - } - ) - return True - - def action_confirm(self): - self.filtered(lambda x: x.state != "confirm").write( - {"state": "confirm", "confirmation_date": fields.Datetime.now()} - ) - - if self.env.context.get("confirm_all_reservations"): - self.reservation_ids.confirm() - - return True - - # CHECKIN/OUT PROCESS - - @api.model - def send_confirmation_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_confirmed_auto_mail - for is_confirmed_auto_mail in folios.pms_property_id.mapped( - "is_confirmed_auto_mail" - ) - ): - for folio in folios: - create_date = folio.create_date.date() - if ( - folio.state in "confirm" - and create_date == fields.Date.today() - and all( - not mail_send - for mail_send in folio.reservation_ids.mapped("is_mail_send") - ) - and all( - not is_modified_reservation - for is_modified_reservation in folio.reservation_ids.mapped( - "is_modified_reservation" - ) - ) - ): - template = folio.pms_property_id.property_confirmed_template - subject = template._render_field( - "subject", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - body = template._render_field( - "body_html", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - invitation_mail = ( - folio.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, - } - ) - ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True - - @api.model - def send_modification_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_modified_auto_mail - for is_modified_auto_mail in folios.pms_property_id.mapped( - "is_modified_auto_mail" - ) - ): - for folio in folios: - if ( - folio.state in ("confirm", "onboard") - and any( - not mail_send - for mail_send in folio.reservation_ids.mapped("is_mail_send") - ) - and any( - is_modified_reservation - for is_modified_reservation in folio.reservation_ids.mapped( - "is_modified_reservation" - ) - ) - ): - template = folio.pms_property_id.property_modified_template - subject = template._render_field( - "subject", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - body = template._render_field( - "body_html", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - invitation_mail = ( - folio.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, - } - ) - ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True - - @api.model - def send_cancelation_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_canceled_auto_mail - for is_canceled_auto_mail in folios.pms_property_id.mapped( - "is_canceled_auto_mail" - ) - ): - for folio in folios: - reservations = folio.reservation_ids.filtered( - lambda r: r.state in "cancel" - ) - for reservation in reservations: - if not reservation.is_mail_send: - template = ( - reservation.pms_property_id.property_canceled_template - ) - subject = template._render_field( - "subject", - [6, 0, reservation.id], - compute_lang=True, - post_process=True, - )[reservation.id] - body = template._render_field( - "body_html", - [6, 0, reservation.id], - compute_lang=True, - post_process=True, - )[reservation.id] - invitation_mail = ( - folio.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, - } - ) - ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True - - def action_view_invoice(self): - invoices = self.mapped("move_ids") - action = self.env["ir.actions.actions"]._for_xml_id( - "account.action_move_out_invoice_type" - ) - if len(invoices) > 1: - action["domain"] = [("id", "in", invoices.ids)] - elif len(invoices) == 1: - form_view = [(self.env.ref("account.view_move_form").id, "form")] - if "views" in action: - action["views"] = form_view + [ - (state, view) for state, view in action["views"] if view != "form" - ] - else: - action["views"] = form_view - action["res_id"] = invoices.id - else: - action = {"type": "ir.actions.act_window_close"} - - context = { - "default_move_type": "out_invoice", - } - if len(self) == 1: - context.update( - { - "default_partner_id": self.partner_id.id, - "default_invoice_payment_term_id": self.payment_term_id.id - or self.partner_id.property_payment_term_id.id - or self.env["account.move"] - .default_get(["invoice_payment_term_id"]) - .get("invoice_payment_term_id"), - "default_invoice_origin": self.mapped("name"), - "default_user_id": self.user_id.id, - } - ) - action["context"] = context - return action - - def preview_folio(self): - self.ensure_one() - return { - "type": "ir.actions.act_url", - "target": "self", - "url": self.get_portal_url(), - } - - def _create_invoices( - self, - grouped=False, - final=False, - date=None, - lines_to_invoice=False, - partner_invoice_id=False, - ): - """ - Create the invoice associated to the Folio. - :param grouped: if True, invoices are grouped by Folio id. - If False, invoices are grouped by - (partner_invoice_ids, currency) - :param final: if True, refunds will be generated if necessary - :param lines_to_invoice: invoice specific lines dict(key=id, value=qty). - if False, invoice all - :returns: list of created invoices - """ - if not self.env["account.move"].check_access_rights("create", False): - try: - self.check_access_rights("write") - self.check_access_rule("write") - except AccessError: - return self.env["account.move"] - # 1) Create invoices. - if not lines_to_invoice: - lines_to_invoice = dict() - for line in self.sale_line_ids: - lines_to_invoice[line.id] = ( - 0 if line.display_type else line.qty_to_invoice - ) - invoice_vals_list = self.get_invoice_vals_list( - final=final, - lines_to_invoice=lines_to_invoice, - partner_invoice_id=partner_invoice_id, - ) - - if not invoice_vals_list: - raise self._nothing_to_invoice_error() - - # 2) Manage 'grouped' parameter: group by (partner_id, currency_id). - if not grouped: - new_invoice_vals_list = [] - invoice_grouping_keys = self._get_invoice_grouping_keys() - for _grouping_keys, invoices in groupby( - invoice_vals_list, - key=lambda x: [ - x.get(grouping_key) for grouping_key in invoice_grouping_keys - ], - ): - origins = set() - payment_refs = set() - refs = set() - ref_invoice_vals = None - for invoice_vals in invoices: - if not ref_invoice_vals: - ref_invoice_vals = invoice_vals - else: - ref_invoice_vals["invoice_line_ids"] += invoice_vals[ - "invoice_line_ids" - ] - origins.add(invoice_vals["invoice_origin"]) - payment_refs.add(invoice_vals["payment_reference"]) - refs.add(invoice_vals["ref"]) - ref_invoice_vals.update( - { - "ref": ", ".join(refs)[:2000], - "invoice_origin": ", ".join(origins), - "payment_reference": len(payment_refs) == 1 - and payment_refs.pop() - or False, - } - ) - new_invoice_vals_list.append(ref_invoice_vals) - invoice_vals_list = new_invoice_vals_list - - # 3) Create invoices. - - # As part of the invoice creation, we make sure the - # sequence of multiple SO do not interfere - # in a single invoice. Example: - # Folio 1: - # - Section A (sequence: 10) - # - Product A (sequence: 11) - # Folio 2: - # - Section B (sequence: 10) - # - Product B (sequence: 11) - # - # If Folio 1 & 2 are grouped in the same invoice, - # the result will be: - # - Section A (sequence: 10) - # - Section B (sequence: 10) - # - Product A (sequence: 11) - # - Product B (sequence: 11) - # - # Resequencing should be safe, however we resequence only - # if there are less invoices than orders, meaning a grouping - # might have been done. This could also mean that only a part - # of the selected SO are invoiceable, but resequencing - # in this case shouldn't be an issue. - if len(invoice_vals_list) < len(self): - FolioSaleLine = self.env["folio.sale.line"] - for invoice in invoice_vals_list: - sequence = 1 - for line in invoice["invoice_line_ids"]: - line[2]["sequence"] = FolioSaleLine._get_invoice_line_sequence( - new=sequence, old=line[2]["sequence"] - ) - sequence += 1 - - # Manage the creation of invoices in sudo because - # a salesperson must be able to generate an invoice from a - # sale order without "billing" access rights. - # However, he should not be able to create an invoice from scratch. - moves = ( - self.env["account.move"] - .sudo() - .with_context(default_move_type="out_invoice", auto_name=True) - .create(invoice_vals_list) - ) - - # 4) Some moves might actually be refunds: convert - # them if the total amount is negative - # We do this after the moves have been created - # since we need taxes, etc. to know if the total - # is actually negative or not - if final: - moves.sudo().filtered( - lambda m: m.amount_total < 0 - ).action_switch_invoice_into_refund_credit_note() - for move in moves: - move.message_post_with_view( - "mail.message_origin_link", - values={ - "self": move, - "origin": move.line_ids.mapped("folio_line_ids.folio_id"), - }, - subtype_id=self.env.ref("mail.mt_note").id, - ) - return moves - - def _prepare_invoice(self, partner_invoice_id=False): - """ - Prepare the dict of values to create the new invoice for a folio. - This method may be overridden to implement custom invoice generation - (making sure to call super() to establish a clean extension chain). - """ - self.ensure_one() - journal = ( - self.env["account.move"] - .with_context(default_move_type="out_invoice") - ._get_default_journal() - ) - if not journal: - raise UserError( - _("Please define an accounting sales journal for the company %s (%s).") - % (self.company_id.name, self.company_id.id) - ) - - if not partner_invoice_id: - partner_invoice_id = ( - self.partner_invoice_ids[0].id if self.partner_invoice_ids else False - ) - - invoice_vals = { - "ref": self.client_order_ref or "", - "move_type": "out_invoice", - "narration": self.note, - "currency_id": self.pricelist_id.currency_id.id, - # 'campaign_id': self.campaign_id.id, - # 'medium_id': self.medium_id.id, - # 'source_id': self.source_id.id, - "invoice_user_id": self.user_id and self.user_id.id, - "partner_id": partner_invoice_id, - "partner_bank_id": self.company_id.partner_id.bank_ids[:1].id, - "journal_id": journal.id, # company comes from the journal - "invoice_origin": self.name, - "invoice_payment_term_id": self.payment_term_id.id, - "payment_reference": self.reference, - "transaction_ids": [(6, 0, self.transaction_ids.ids)], - "folio_ids": [(6, 0, [self.id])], - "invoice_line_ids": [], - "company_id": self.company_id.id, - } - return invoice_vals - - def do_payment( - self, - journal, - receivable_account, - user, - amount, - folio, - reservations=False, - services=False, - partner=False, - date=False, - pay_type=False, - ): - """ - create folio payment - type: set cash to use statement or bank to use account.payment, - by default, use the journal type - """ - if not pay_type: - pay_type = journal.type - if pay_type == "cash": - line = self._get_statement_line_vals( - journal=journal, - receivable_account=receivable_account, - user=user, - amount=amount, - folios=folio, - reservations=reservations, - services=services, - partner=partner, - date=date, - ) - self.env["account.bank.statement.line"].sudo().create(line) - else: - vals = { - "journal_id": journal.id, - "partner_id": partner.id, - "amount": amount, - "date": fields.Date.today(), - "ref": folio.name, - "folio_ids": [(6, 0, [folio.id])], - "payment_type": "inbound", - "partner_type": "customer", - "state": "draft", - } - pay = self.env["account.payment"].create(vals) - pay.action_post() - - folio.message_post( - body=_( - """Payment: %s by %s""", - amount, - journal.display_name, - ) - ) - for reservation in folio.reservation_ids: - reservation.message_post( - body=_( - """Payment: %s by %s""", - amount, - journal.display_name, - ) - ) - return True - - def open_wizard_several_partners(self): - ctx = dict( - folio_id=self.id, - possible_existing_customer_ids=self.possible_existing_customer_ids.ids, - ) - return { - "view_type": "form", - "view_mode": "form", - "name": "Several Customers", - "res_model": "pms.several.partners.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": ctx, - } - - @api.model - def _get_statement_line_vals( - self, - journal, - receivable_account, - user, - amount, - folios, - reservations=False, - services=False, - partner=False, - date=False, - ): - property_folio_id = folios.mapped("pms_property_id.id") - if len(property_folio_id) != 1: - raise ValidationError(_("Only can payment by property")) - ctx = dict(self.env.context, company_id=folios[0].company_id.id) - statement = ( - self.env["account.bank.statement"] - .sudo() - .search( - [ - ("journal_id", "=", journal.id), - ("pms_property_id", "=", property_folio_id[0]), - ("state", "=", "open"), - ] - ) - ) - reservation_ids = reservations.ids if reservations else [] - service_ids = services.ids if services else [] - if not statement: - # TODO: cash control option - st_values = { - "journal_id": journal.id, - "user_id": self.env.user.id, - "pms_property_id": property_folio_id[0], - "name": str(fields.Datetime.now()), - } - statement = ( - self.env["account.bank.statement"] - .with_context(ctx) - .sudo() - .create(st_values) - ) - return { - "date": date, - "amount": amount, - "partner_id": partner.id if partner else False, - "folio_ids": [(6, 0, folios.ids)], - "reservation_ids": [(6, 0, reservation_ids)], - "service_ids": [(6, 0, service_ids)], - "payment_ref": folios.mapped("name"), - "statement_id": statement.id, - "journal_id": statement.journal_id.id, - "counterpart_account_id": receivable_account.id, - } - - @api.model - def generate_reservation_lines_sale_lines(self, folio, reservation): - if not reservation.sale_line_ids.filtered(lambda x: x.name == reservation.name): - reservation.sale_line_ids = [ - ( - 0, - 0, - { - "name": reservation.name, - "display_type": "line_section", - "folio_id": folio.id, - }, - ) - ] - expected_reservation_lines = self.env["pms.reservation.line"].read_group( - [ - ("reservation_id", "=", reservation.id), - ("cancel_discount", "<", 100), - ], - ["price", "discount", "cancel_discount"], - ["price", "discount", "cancel_discount"], - lazy=False, - ) - current_sale_line_ids = reservation.sale_line_ids.filtered( - lambda x: x.reservation_id.id == reservation.id - and not x.display_type - and not x.service_id - ) - - for index, item in enumerate(expected_reservation_lines): - lines_to = self.env["pms.reservation.line"].search(item["__domain"]) - final_discount = self.concat_discounts( - item["discount"], item["cancel_discount"] - ) - - if current_sale_line_ids and index <= (len(current_sale_line_ids) - 1): - current_sale_line_ids[index].price_unit = item["price"] - current_sale_line_ids[index].discount = final_discount - current_sale_line_ids[index].reservation_line_ids = lines_to.ids - else: - new = { - "reservation_id": reservation.id, - "price_unit": item["price"], - "discount": final_discount, - "folio_id": folio.id, - "reservation_line_ids": [(6, 0, lines_to.ids)], - } - reservation.sale_line_ids = [(0, 0, new)] - if len(expected_reservation_lines) < len(current_sale_line_ids): - folio_sale_lines_to_remove = [ - value.id - for index, value in enumerate(current_sale_line_ids) - if index > (len(expected_reservation_lines) - 1) - ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() - - @api.model - def _prepare_down_payment_section_line(self, **optional_values): - """ - Prepare the dict of values to create a new down - payment section for a sales order line. - :param optional_values: any parameter that should - be added to the returned down payment section - """ - down_payments_section_line = { - "display_type": "line_section", - "name": _("Down Payments"), - "product_id": False, - "product_uom_id": False, - "quantity": 0, - "discount": 0, - "price_unit": 0, - "account_id": False, - } - if optional_values: - down_payments_section_line.update(optional_values) - return down_payments_section_line - - @api.model - def _nothing_to_invoice_error(self): - msg = _( - """There is nothing to invoice!\n - Reason(s) of this behavior could be: - - You should deliver your products before invoicing them: Click on the "truck" - icon (top-right of your screen) and follow instructions. - - You should modify the invoicing policy of your product: Open the product, - go to the "Sales tab" and modify invoicing policy from "delivered quantities" - to "ordered quantities". - """ - ) - return UserError(msg) - - @api.model - def generate_reservation_services_sale_lines(self, folio, reservation): - for service in reservation.service_ids: - expected_reservation_services = self.env["pms.service.line"].read_group( - [ - ("reservation_id", "=", reservation.id), - ("service_id", "=", service.id), - ("cancel_discount", "<", 100), - ], - ["price_unit", "discount", "cancel_discount"], - ["price_unit", "discount", "cancel_discount"], - lazy=False, - ) - current_sale_service_ids = reservation.sale_line_ids.filtered( - lambda x: x.reservation_id.id == reservation.id - and not x.display_type - and x.service_id.id == service.id - ) - - for index, item in enumerate(expected_reservation_services): - lines_to = self.env["pms.service.line"].search(item["__domain"]) - final_discount = self.concat_discounts( - item["discount"], item["cancel_discount"] - ) - - if current_sale_service_ids and index <= ( - len(current_sale_service_ids) - 1 - ): - current_sale_service_ids[index].price_unit = item["price_unit"] - current_sale_service_ids[index].discount = final_discount - current_sale_service_ids[index].service_line_ids = lines_to.ids - else: - new = { - "service_id": service.id, - "price_unit": item["price_unit"], - "discount": final_discount, - "folio_id": folio.id, - "service_line_ids": [(6, 0, lines_to.ids)], - } - reservation.sale_line_ids = [(0, 0, new)] - if len(expected_reservation_services) < len(current_sale_service_ids): - folio_sale_lines_to_remove = [ - value.id - for index, value in enumerate(current_sale_service_ids) - if index > (len(expected_reservation_services) - 1) - ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() - - @api.model - def generate_folio_services_sale_lines(self, folio): - folio_services = folio.service_ids.filtered(lambda x: not x.reservation_id) - if folio_services: - if not folio.sale_line_ids.filtered(lambda x: x.name == _("Others")): - folio.sale_line_ids = [ - ( - 0, - False, - { - "display_type": "line_section", - "name": _("Others"), - }, - ) - ] - for folio_service in folio_services: - expected_folio_services = self.env["pms.service.line"].read_group( - [ - ("service_id.folio_id", "=", folio.id), - ("service_id", "=", folio_service.id), - ("reservation_id", "=", False), - ("cancel_discount", "<", 100), - ], - ["price_unit", "discount", "cancel_discount"], - ["price_unit", "discount", "cancel_discount"], - lazy=False, - ) - current_folio_service_ids = folio.sale_line_ids.filtered( - lambda x: x.service_id.folio_id.id == folio.id - and not x.display_type - and not x.reservation_id - and x.service_id.id == folio_service.id - ) - - for index, item in enumerate(expected_folio_services): - lines_to = self.env["pms.service.line"].search(item["__domain"]) - final_discount = self.concat_discounts( - item["discount"], item["cancel_discount"] - ) - if current_folio_service_ids and index <= ( - len(current_folio_service_ids) - 1 - ): - current_folio_service_ids[index].price_unit = item["price_unit"] - current_folio_service_ids[index].discount = final_discount - current_folio_service_ids[index].service_line_ids = lines_to.ids - else: - new = { - "service_id": folio_service.id, - "price_unit": item["price_unit"], - "discount": final_discount, - "folio_id": folio.id, - "service_line_ids": [(6, 0, lines_to.ids)], - } - folio.sale_line_ids = [(0, 0, new)] - if len(expected_folio_services) < len(current_folio_service_ids): - folio_sale_lines_to_remove = [ - value.id - for index, value in enumerate(current_folio_service_ids) - if index > (len(expected_folio_services) - 1) - ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() - else: - to_unlink = folio.sale_line_ids.filtered(lambda x: x.name == _("Others")) - to_unlink.unlink() - - @api.model - def concat_discounts(self, discount, cancel_discount): - discount_factor = 1.0 - for discount in [discount, cancel_discount]: - discount_factor = discount_factor * ((100.0 - discount) / 100.0) - final_discount = 100.0 - (discount_factor * 100.0) - return final_discount - - @api.model - def _apply_partner_name(self, record): - if record.partner_id: - record.partner_name = record.partner_id.name - elif ( - record.agency_id - and not record.agency_id.invoice_to_agency - and not record.partner_name - ): - # if the customer not is the agency but we dont know the customer's name, - # set the name provisional - record.partner_name = _("Reservation from ") + record.agency_id.name - elif not record.partner_name: - record.partner_name = False - - @api.model - def _apply_mobile(self, record): - if record.partner_id and not record.mobile: - record.mobile = record.partner_id.mobile - elif not record.mobile: - record.mobile = False - - @api.model - def _apply_email(self, record): - if record.partner_id and not record.email: - record.email = record.partner_id.email - elif not record.email: - record.email = False - - @api.model - def _apply_possible_existing_customer_ids( - self, email=False, mobile=False, partner=False - ): - possible_customer = False - if email and not partner: - possible_customer = self.env["res.partner"].search([("email", "=", email)]) - if mobile and not partner: - possible_customer = self.env["res.partner"].search( - [("mobile", "=", mobile)] - ) - return possible_customer - - @api.model - def _apply_document_id(self, record): - 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.model - def _apply_document_number(self, record): - if record.partner_id and record.partner_id.id_numbers: - if not record.document_number: - if record.partner_id.id_numbers: - record.document_number = record.partner_id.id_numbers[0].name - - @api.model - def _apply_document_type(self, record): - 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.model - def _create_partner(self, record): - 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.partner_name and record.document_number and record.document_type: - partner_values = { - "name": record.partner_name, - "email": record.email, - "mobile": record.mobile, - } - partner = self.env["res.partner"].create(partner_values) - number_values = { - "partner_id": partner.id, - "name": record.document_number, - "category_id": record.document_type.id, - } - self.env["res.partner.id_number"].create(number_values) - record.partner_id = partner - - def _create_payment_transaction(self, vals): - # Ensure the currencies are the same. - currency = self[0].currency_id - if any(folio.currency_id != currency for folio in self): - raise ValidationError( - _( - "A transaction can't be linked to folios having different currencies." - ) - ) - - # Ensure the partner are the same. - partner = self[0].partner_id - if any(folio.partner_id != partner for folio in self): - raise ValidationError( - _("A transaction can't be linked to folios having different partners.") - ) - - # Try to retrieve the acquirer. However, fallback to the token's acquirer. - acquirer_id = vals.get("acquirer_id") - acquirer = None - payment_token_id = vals.get("payment_token_id") - - if payment_token_id: - payment_token = self.env["payment.token"].sudo().browse(payment_token_id) - - # Check payment_token/acquirer matching or take the acquirer from token - if acquirer_id: - acquirer = self.env["payment.acquirer"].browse(acquirer_id) - if payment_token and payment_token.acquirer_id != acquirer: - raise ValidationError( - _("Invalid token found! Token acquirer %s != %s") - % (payment_token.acquirer_id.name, acquirer.name) - ) - if payment_token and payment_token.partner_id != partner: - raise ValidationError( - _("Invalid token found! Token partner %s != %s") - % (payment_token.partner.name, partner.name) - ) - else: - acquirer = payment_token.acquirer_id - - # Check an acquirer is there. - if not acquirer_id and not acquirer: - raise ValidationError( - _("A payment acquirer is required to create a transaction.") - ) - - if not acquirer: - acquirer = self.env["payment.acquirer"].browse(acquirer_id) - - # Check a journal is set on acquirer. - if not acquirer.journal_id: - raise ValidationError( - _("A journal must be specified for the acquirer %s.", acquirer.name) - ) - - if not acquirer_id and acquirer: - vals["acquirer_id"] = acquirer.id - - vals.update( - { - "amount": sum(self.mapped("amount_total")), - "currency_id": currency.id, - "partner_id": partner.id, - "folio_ids": [(6, 0, self.ids)], - } - ) - transaction = self.env["payment.transaction"].create(vals) - - # Process directly if payment_token - if transaction.payment_token_id: - transaction.s2s_do_transaction() - - return transaction diff --git a/pms/models/pms_property.py b/pms/models/pms_property.py deleted file mode 100644 index 7f2be5011..000000000 --- a/pms/models/pms_property.py +++ /dev/null @@ -1,492 +0,0 @@ -# Copyright 2019 Pablo Quesada -# Copyright 2019 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import datetime -import time - -import pytz - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT - -from odoo.addons.base.models.res_partner import _tz_get - - -class PmsProperty(models.Model): - _name = "pms.property" - _description = "Property" - _inherits = {"res.partner": "partner_id"} - _check_company_auto = True - - partner_id = fields.Many2one( - string="Property", - help="Current property", - comodel_name="res.partner", - required=True, - ondelete="cascade", - ) - company_id = fields.Many2one( - string="Company", - help="The company that owns or operates this property.", - comodel_name="res.company", - required=True, - check_pms_properties=True, - ) - user_ids = fields.Many2many( - string="Accepted Users", - help="Field related to res.users. Allowed users on the property", - comodel_name="res.users", - relation="pms_property_users_rel", - column1="pms_property_id", - column2="user_id", - ) - room_ids = fields.One2many( - string="Rooms", - help="Rooms that a property has.", - comodel_name="pms.room", - inverse_name="pms_property_id", - ) - default_pricelist_id = fields.Many2one( - string="Product Pricelist", - help="The default pricelist used in this property.", - comodel_name="product.pricelist", - required=True, - default=lambda self: self.env.ref("product.list0").id, - ) - default_arrival_hour = fields.Char( - string="Arrival Hour", help="HH:mm Format", default="14:00" - ) - default_departure_hour = fields.Char( - string="Departure Hour", help="HH:mm Format", default="12:00" - ) - folio_sequence_id = fields.Many2one( - string="Folio Sequence", - help="The sequence that formed the name of the folio.", - check_company=True, - copy=False, - comodel_name="ir.sequence", - ) - reservation_sequence_id = fields.Many2one( - string="Reservation Sequence", - help="The sequence that formed the name of the reservation.", - check_company=True, - copy=False, - comodel_name="ir.sequence", - ) - checkin_sequence_id = fields.Many2one( - string="Checkin Sequence", - help="Field used to create the name of the checkin partner", - check_company=True, - copy=False, - comodel_name="ir.sequence", - ) - - tz = fields.Selection( - string="Timezone", - help="This field is used to determine de timezone of the property.", - required=True, - default=lambda self: self.env.user.tz or "UTC", - 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.", - ) - free_room_ids = fields.One2many( - string="Rooms available", - help="allows you to send different parameters in the context " - "(checkin(required), checkout(required), room_type_id, ubication_id, capacity, " - "amenity_ids and / or pricelist_id) and return rooms available", - comodel_name="pms.room", - compute="_compute_free_room_ids", - ) - availability = fields.Integer( - string="Number of rooms available", - help="allows you to send different parameters in the context " - "(checkin(required), checkout(required), room_type_id, ubication_id, capacity," - "amenity_ids and / or pricelist_id) check the availability for the hotel", - compute="_compute_availability", - ) - - mail_information = fields.Html( - string="Mail Information", help="Additional information of the mail" - ) - - privacy_policy = fields.Html(string="Privacy Policy", help="Mail privacy policy ") - - property_confirmed_template = fields.Many2one( - string="Confirmation Email", - help="Confirmation email template", - comodel_name="mail.template", - ) - - property_modified_template = fields.Many2one( - string="Modification Email", - help="Modification email template", - comodel_name="mail.template", - ) - - property_canceled_template = fields.Many2one( - string="Cancellation Email", - help="Cancellation email template", - comodel_name="mail.template", - ) - - is_confirmed_auto_mail = fields.Boolean(string="Auto Send Confirmation Mail") - is_modified_auto_mail = fields.Boolean(string="Auto Send Modification Mail") - is_canceled_auto_mail = fields.Boolean(string="Auto Send Cancellation Mail") - - @api.depends_context( - "checkin", - "checkout", - "real_avail", - "room_type_id", - "ubication_id", - "capacity", - "amenity_ids", - "pricelist_id", - "class_id", - "overnight_rooms", - "current_lines", - ) - def _compute_free_room_ids(self): - checkin = self._context["checkin"] - checkout = self._context["checkout"] - - if isinstance(checkin, str): - checkin = datetime.datetime.strptime( - checkin, DEFAULT_SERVER_DATE_FORMAT - ).date() - if isinstance(checkout, str): - checkout = datetime.datetime.strptime( - checkout, DEFAULT_SERVER_DATE_FORMAT - ).date() - current_lines = self.env.context.get("current_lines", False) - if current_lines and not isinstance(current_lines, list): - current_lines = [current_lines] - - pricelist_id = self.env.context.get("pricelist_id", False) - room_type_id = self.env.context.get("room_type_id", False) - class_id = self._context.get("class_id", False) - real_avail = self._context.get("real_avail", False) - overnight_rooms = self._context.get("overnight_rooms", False) - for pms_property in self: - free_rooms = pms_property.get_real_free_rooms( - checkin, checkout, current_lines - ) - if pricelist_id and not real_avail: - # TODO: only closed_departure take account checkout date! - domain_rules = [ - ("date", ">=", checkin), - ("date", "<=", checkout), - ("pms_property_id", "=", pms_property.id), - ] - if room_type_id: - domain_rules.append(("room_type_id", "=", room_type_id)) - - pricelist = self.env["product.pricelist"].browse(pricelist_id) - if pricelist.availability_plan_id: - domain_rules.append( - ("availability_plan_id", "=", pricelist.availability_plan_id.id) - ) - rule_items = self.env["pms.availability.plan.rule"].search( - domain_rules - ) - - if len(rule_items) > 0: - room_types_to_remove = [] - for item in rule_items: - if pricelist.availability_plan_id.any_rule_applies( - checkin, checkout, item - ): - room_types_to_remove.append(item.room_type_id.id) - free_rooms = free_rooms.filtered( - lambda x: x.room_type_id.id not in room_types_to_remove - ) - if class_id: - free_rooms = free_rooms.filtered( - lambda x: x.room_type_id.class_id.id == class_id - ) - if overnight_rooms: - free_rooms = free_rooms.filtered( - lambda x: x.room_type_id.overnight_room - ) - if len(free_rooms) > 0: - pms_property.free_room_ids = free_rooms.ids - else: - pms_property.free_room_ids = False - - def get_real_free_rooms(self, checkin, checkout, current_lines=False): - self.ensure_one() - Avail = self.env["pms.availability"] - target_rooms = self.env["pms.room"].search([("pms_property_id", "=", self.id)]) - - room_type_id = self.env.context.get("room_type_id", False) - if room_type_id: - target_rooms = target_rooms.filtered( - lambda r: r.room_type_id.id == room_type_id - ) - capacity = self.env.context.get("capacity", False) - if capacity: - target_rooms = target_rooms.filtered(lambda r: r.capacity >= capacity) - - ubication_id = self.env.context.get("ubication_id", False) - if ubication_id: - target_rooms = target_rooms.filtered( - lambda r: r.ubication_id.id == ubication_id - ) - - amenity_ids = self.env.context.get("amenity_ids", False) - if amenity_ids: - if amenity_ids and not isinstance(amenity_ids, list): - amenity_ids = [amenity_ids] - target_rooms = target_rooms.filtered( - lambda r: len(set(amenity_ids) - set(r.room_amenity_ids.ids)) == 0 - ) - - if not current_lines: - current_lines = [] - - rooms_not_avail_ids = Avail.get_rooms_not_avail( - checkin=checkin, - checkout=checkout, - room_ids=target_rooms.ids, - pms_property_id=self.id, - current_lines=current_lines, - ) - domain_rooms = [("id", "in", target_rooms.ids)] - if rooms_not_avail_ids: - domain_rooms.append( - ("id", "not in", rooms_not_avail_ids), - ) - return self.env["pms.room"].search(domain_rooms) - - @api.depends_context( - "checkin", - "checkout", - "real_avail", - "room_type_id", - "ubication_id", - "capacity", - "amenity_ids", - "pricelist_id", - "class_id", - "overnight_rooms", - "current_lines", - ) - def _compute_availability(self): - for record in self: - checkin = self._context["checkin"] - checkout = self._context["checkout"] - if isinstance(checkin, str): - checkin = datetime.datetime.strptime( - checkin, DEFAULT_SERVER_DATE_FORMAT - ).date() - if isinstance(checkout, str): - checkout = datetime.datetime.strptime( - checkout, DEFAULT_SERVER_DATE_FORMAT - ).date() - room_type_id = self.env.context.get("room_type_id", False) - pricelist_id = self.env.context.get("pricelist_id", False) - current_lines = self.env.context.get("current_lines", []) - class_id = self._context.get("class_id", False) - real_avail = self._context.get("real_avail", False) - overnight_rooms = self._context.get("overnight_rooms", False) - pms_property = record.with_context( - checkin=checkin, - checkout=checkout, - room_type_id=room_type_id, - current_lines=current_lines, - pricelist_id=pricelist_id, - class_id=class_id, - real_avail=real_avail, - overnight_rooms=overnight_rooms, - ) - count_free_rooms = len(pms_property.free_room_ids) - if current_lines and not isinstance(current_lines, list): - current_lines = [current_lines] - - domain_rules = [ - ("date", ">=", checkin), - ("date", "<=", checkout), - ("pms_property_id", "=", pms_property.id), - ] - if room_type_id: - domain_rules.append(("room_type_id", "=", room_type_id)) - - pricelist = False - if pricelist_id: - pricelist = self.env["product.pricelist"].browse(pricelist_id) - if pricelist and pricelist.availability_plan_id and not real_avail: - domain_rules.append( - ("availability_plan_id", "=", pricelist.availability_plan_id.id) - ) - rule_groups = self.env["pms.availability.plan.rule"].read_group( - domain_rules, - ["plan_avail:sum"], - ["date:day"], - lazy=False, - ) - if len(rule_groups) > 0: - # If in the group per day, some room type has the sale blocked, - # we must subtract from that day the availability of that room type - for group in rule_groups: - items = self.env["pms.availability.plan.rule"].search( - group["__domain"] - ) - for item in items: - if pricelist.availability_plan_id.any_rule_applies( - checkin, checkout, item - ): - group["plan_avail"] -= item.plan_avail - count_free_rooms = min(i["plan_avail"] for i in rule_groups) - record.availability = count_free_rooms - - @api.model - def splitted_availability( - self, - checkin, - checkout, - pms_property_id, - room_type_id=False, - current_lines=False, - pricelist=False, - ): - if isinstance(checkin, str): - checkin = datetime.datetime.strptime( - checkin, DEFAULT_SERVER_DATE_FORMAT - ).date() - if isinstance(checkout, str): - checkout = datetime.datetime.strptime( - checkout, DEFAULT_SERVER_DATE_FORMAT - ).date() - for date_iterator in [ - checkin + datetime.timedelta(days=x) - for x in range(0, (checkout - checkin).days) - ]: - pms_property = self.env["pms.property"].browse(pms_property_id) - pms_property = pms_property.with_context( - checkin=date_iterator, - checkout=date_iterator + datetime.timedelta(1), - room_type_id=room_type_id, - current_lines=current_lines, - pricelist_id=pricelist.id, - ) - - if len(pms_property.free_room_ids) < 1: - return False - return True - - @api.constrains("default_arrival_hour") - def _check_arrival_hour(self): - for record in self: - try: - time.strptime(record.default_arrival_hour, "%H:%M") - return True - except ValueError: - raise ValidationError( - _( - "Format Arrival Hour (HH:MM) Error: %s", - record.default_arrival_hour, - ) - ) - - @api.constrains("default_departure_hour") - def _check_departure_hour(self): - for record in self: - try: - time.strptime(record.default_departure_hour, "%H:%M") - return True - except ValueError: - raise ValidationError( - _( - "Format Departure Hour (HH:MM) Error: %s", - record.default_departure_hour, - ) - ) - - def date_property_timezone(self, dt): - self.ensure_one() - if self.env.user: - tz_property = self.tz - dt = pytz.timezone(tz_property).localize(dt) - dt = dt.replace(tzinfo=None) - dt = pytz.timezone(self.env.user.tz).localize(dt) - dt = dt.astimezone(pytz.utc) - dt = dt.replace(tzinfo=None) - return dt - - def _get_payment_methods(self, automatic_included=False): - # We use automatic_included to True to see absolutely - # all the journals with associated payments, if it is - # false, we will only see those journals that can be used - # to pay manually - self.ensure_one() - payment_methods = self.env["account.journal"].search( - [ - ("type", "in", ["cash", "bank"]), - "|", - ("pms_property_ids", "in", self.id), - "|", - "&", - ("pms_property_ids", "=", False), - ("company_id", "=", self.company_id.id), - "&", - ("pms_property_ids", "=", False), - ("company_id", "=", False), - ] - ) - if not automatic_included: - payment_methods = payment_methods.filtered(lambda p: p.allowed_pms_payments) - return payment_methods - - @api.model - def create(self, vals): - name = vals.get("name") - if "folio_sequence_id" not in vals or not vals.get("folio_sequence_id"): - folio_sequence = self.env["ir.sequence"].create( - { - "name": "PMS Folio " + name, - "code": "pms.folio", - "prefix": "F/%(y)s", - "suffix": "%(sec)s", - "padding": 4, - "company_id": vals.get("company_id"), - } - ) - vals.update({"folio_sequence_id": folio_sequence.id}) - if "reservation_sequence_id" not in vals or not vals.get( - "reservation_sequence_id" - ): - reservation_sequence = self.env["ir.sequence"].create( - { - "name": "PMS Reservation " + name, - "code": "pms.reservation", - "prefix": "R/%(y)s", - "suffix": "%(sec)s", - "padding": 4, - "company_id": vals.get("company_id"), - } - ) - vals.update({"reservation_sequence_id": reservation_sequence.id}) - if "checkin_sequence_id" not in vals or not vals.get("checkin_sequence_id"): - checkin_sequence = self.env["ir.sequence"].create( - { - "name": "PMS Checkin " + name, - "code": "pms.checkin.partner", - "prefix": "C/%(y)s", - "suffix": "%(sec)s", - "padding": 4, - "company_id": vals.get("company_id"), - } - ) - vals.update({"checkin_sequence_id": checkin_sequence.id}) - record = super(PmsProperty, self).create(vals) - return record diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py deleted file mode 100644 index a215ecf82..000000000 --- a/pms/models/pms_reservation.py +++ /dev/null @@ -1,2054 +0,0 @@ -# Copyright 2017-2018 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import datetime -import logging -import time - -from odoo import _, api, fields, models -from odoo.exceptions import UserError, ValidationError - -_logger = logging.getLogger(__name__) - - -class PmsReservation(models.Model): - _name = "pms.reservation" - _description = "Reservation" - _inherit = ["mail.thread", "mail.activity.mixin", "portal.mixin"] - _order = "priority asc, create_date desc, write_date desc" - # TODO: - # consider near_to_checkin & pending_notifications to order - _check_pms_properties_auto = True - _check_company_auto = True - - name = fields.Text( - string="Reservation Id", - help="Reservation Name", - readonly=True, - ) - priority = fields.Integer( - string="Priority", - help="Priority of a reservation", - index=True, - store="True", - compute="_compute_priority", - ) - preferred_room_id = fields.Many2one( - string="Room", - help="It's the preferred room assigned to reservation, " - "empty if reservation is splitted", - copy=False, - comodel_name="pms.room", - ondelete="restrict", - domain="[" - "('id', 'in', allowed_room_ids)," - "('pms_property_id', '=', pms_property_id)," - "]", - tracking=True, - check_pms_properties=True, - ) - allowed_room_ids = fields.Many2many( - string="Allowed Rooms", - help="It contains all available rooms for this reservation", - comodel_name="pms.room", - compute="_compute_allowed_room_ids", - ) - folio_id = fields.Many2one( - string="Folio", - help="The folio where the reservations are included", - copy=False, - comodel_name="pms.folio", - ondelete="restrict", - tracking=True, - check_company=True, - ) - sale_line_ids = fields.One2many( - comodel_name="folio.sale.line", - inverse_name="reservation_id", - string="Sale Lines", - copy=False, - ) - board_service_room_id = fields.Many2one( - string="Board Service", - help="Board Service included in the room", - readonly=False, - store=True, - comodel_name="pms.board.service.room.type", - compute="_compute_board_service_room_id", - tracking=True, - check_pms_properties=True, - ) - room_type_id = fields.Many2one( - string="Room Type", - help="Room Type sold on the reservation," - "it doesn't necessarily correspond to" - " the room actually assigned", - readonly=False, - copy=False, - store=True, - comodel_name="pms.room.type", - ondelete="restrict", - compute="_compute_room_type_id", - tracking=True, - check_pms_properties=True, - ) - partner_id = fields.Many2one( - string="Customer", - help="Name of who made the reservation", - readonly=False, - store=True, - comodel_name="res.partner", - ondelete="restrict", - compute="_compute_partner_id", - tracking=True, - check_pms_properties=True, - ) - agency_id = fields.Many2one( - string="Agency", - help="Agency that made the reservation", - readonly=False, - store=True, - related="folio_id.agency_id", - depends=["folio_id.agency_id"], - tracking=True, - ) - channel_type_id = fields.Many2one( - string="Channel Type", - help="Sales Channel through which the reservation was managed", - readonly=False, - store=True, - related="folio_id.channel_type_id", - tracking=True, - ) - closure_reason_id = fields.Many2one( - string="Closure Reason", - help="Reason why the reservation cannot be made", - related="folio_id.closure_reason_id", - check_pms_properties=True, - ) - company_id = fields.Many2one( - string="Company", - help="Company to which the reservation belongs", - readonly=True, - store=True, - related="folio_id.company_id", - ) - pms_property_id = fields.Many2one( - string="Pms Property", - help="Property to which the reservation belongs", - store=True, - readonly=False, - default=lambda self: self.env.user.get_active_property_ids()[0], - related="folio_id.pms_property_id", - comodel_name="pms.property", - check_pms_properties=True, - ) - reservation_line_ids = fields.One2many( - string="Reservation Lines", - help="They are the lines of the reservation into a reservation," - "they corresponds to the nights", - readonly=False, - copy=False, - store=True, - compute="_compute_reservation_line_ids", - comodel_name="pms.reservation.line", - inverse_name="reservation_id", - check_pms_properties=True, - ) - service_ids = fields.One2many( - string="Services", - help="Included services in the reservation", - readonly=False, - store=True, - comodel_name="pms.service", - inverse_name="reservation_id", - compute="_compute_service_ids", - check_company=True, - check_pms_properties=True, - ) - pricelist_id = fields.Many2one( - string="Pricelist", - help="Pricelist that guides the prices of the reservation", - readonly=False, - store=True, - comodel_name="product.pricelist", - ondelete="restrict", - compute="_compute_pricelist_id", - tracking=True, - check_pms_properties=True, - ) - user_id = fields.Many2one( - string="Salesperson", - help="User who manages the reservation", - readonly=False, - store=True, - related="folio_id.user_id", - depends=["folio_id.user_id"], - default=lambda self: self.env.user.id, - ) - show_update_pricelist = fields.Boolean( - string="Has Pricelist Changed", - help="Technical Field, True if the pricelist was changed;\n" - " this will then display a recomputation button", - store=True, - compute="_compute_show_update_pricelist", - ) - commission_percent = fields.Float( - string="Commission percent (%)", - help="Percentage corresponding to commission", - readonly=False, - store=True, - compute="_compute_commission_percent", - tracking=True, - ) - commission_amount = fields.Float( - string="Commission amount", - help="Amount corresponding to commission", - store=True, - compute="_compute_commission_amount", - ) - checkin_partner_ids = fields.One2many( - string="Checkin Partners", - help="Guests who will occupy the room", - readonly=False, - copy=False, - store=True, - compute="_compute_checkin_partner_ids", - comodel_name="pms.checkin.partner", - inverse_name="reservation_id", - check_pms_properties=True, - ) - count_pending_arrival = fields.Integer( - string="Pending Arrival", - help="Number of guest with pending checkin", - store=True, - compute="_compute_count_pending_arrival", - ) - checkins_ratio = fields.Integer( - string="Pending Arrival Ratio", - help="Proportion of guest pending checkin", - compute="_compute_checkins_ratio", - ) - pending_checkin_data = fields.Integer( - string="Checkin Data", - help="Data missing at checkin", - store=True, - compute="_compute_pending_checkin_data", - ) - ratio_checkin_data = fields.Integer( - string="Complete cardex", - help="Proportion of guest data complete at checkin", - compute="_compute_ratio_checkin_data", - ) - ready_for_checkin = fields.Boolean( - string="Ready for checkin", - help="Indicates the reservations with checkin_partner data enought to checkin", - compute="_compute_ready_for_checkin", - ) - allowed_checkin = fields.Boolean( - string="Allowed checkin", - help="Technical field, Indicates if there isn't a checkin_partner data" - "Only can be true if checkin is today or was in the past", - compute="_compute_allowed_checkin", - search="_search_allowed_checkin", - ) - - allowed_checkout = fields.Boolean( - string="Allowed checkout", - help="Technical field, Indicates that reservation is ready for checkout" - "only can be true if reservation state is 'onboard' or departure_delayed" - "and checkout is today or will be in the future", - compute="_compute_allowed_checkout", - search="_search_allowed_checkout", - ) - - allowed_cancel = fields.Boolean( - string="Allowed cancel", - help="Technical field, Indicates that reservation can be cancelled," - "that happened when state is 'cancel', 'done', or 'departure_delayed'", - compute="_compute_allowed_cancel", - search="_search_allowed_cancel", - ) - - segmentation_ids = fields.Many2many( - string="Segmentation", - help="Segmentation tags to classify reservations", - default=lambda self: self._get_default_segmentation(), - comodel_name="res.partner.category", - ondelete="restrict", - ) - currency_id = fields.Many2one( - string="Currency", - help="The currency used in relation to the pricelist", - readonly=True, - store=True, - related="pricelist_id.currency_id", - depends=["pricelist_id"], - ) - tax_ids = fields.Many2many( - string="Taxes", - help="Taxes applied in the reservation", - readonly="False", - store=True, - compute="_compute_tax_ids", - comodel_name="account.tax", - domain=["|", ("active", "=", False), ("active", "=", True)], - ) - adults = fields.Integer( - string="Adults", - help="List of adults there in guest list", - readonly=False, - store=True, - compute="_compute_adults", - tracking=True, - ) - children_occupying = fields.Integer( - string="Children occupying", - help="Number of children there in guest list whose presence counts", - ) - children = fields.Integer( - string="Children", - help="Number total of children there in guest list," - "whose presence counts or not", - readonly=False, - tracking=True, - ) - to_assign = fields.Boolean( - string="To Assign", - help="It is True if the room of the reservation has been assigned " - "automatically, False if it was confirmed by a person in charge", - default=True, - ) - state = fields.Selection( - string="State", - help="The state of the reservation. " - "It can be 'Pre-reservation', 'Pending arrival', 'On Board', 'Out', " - "'Cancelled', 'Arrival Delayed' or 'Departure Delayed'", - readonly=True, - index=True, - default=lambda *a: "draft", - copy=False, - selection=[ - ("draft", "Pre-reservation"), - ("confirm", "Pending arrival"), - ("onboard", "On Board"), - ("done", "Out"), - ("cancel", "Cancelled"), - ("arrival_delayed", "Arrival Delayed"), - ("departure_delayed", "Departure delayed"), - ], - tracking=True, - ) - reservation_type = fields.Selection( - string="Reservation Type", - help="Type of reservations. It can be 'normal', 'staff' or 'out of service", - store=True, - readonly=False, - compute="_compute_reservation_type", - selection=[("normal", "Normal"), ("staff", "Staff"), ("out", "Out of Service")], - ) - splitted = fields.Boolean( - string="Splitted", - help="Field that indicates if the reservation is split. " - "A reservation is split when guests don't sleep in the same room every night", - store=True, - compute="_compute_splitted", - ) - rooms = fields.Char( - string="Room/s", - help="Rooms that are reserved", - compute="_compute_rooms", - store=True, - tracking=True, - ) - credit_card_details = fields.Text( - string="Credit Card Details", help="", related="folio_id.credit_card_details" - ) - cancelled_reason = fields.Selection( - string="Reason of cancellation", - help="Field indicating type of cancellation. " - "It can be 'late', 'intime' or 'noshow'", - copy=False, - compute="_compute_cancelled_reason", - readonly=False, - store=True, - selection=[("late", "Late"), ("intime", "In time"), ("noshow", "No Show")], - tracking=True, - ) - out_service_description = fields.Text( - string="Cause of out of service", - help="Indicates the cause of out of service", - ) - checkin = fields.Date( - string="Check In", - help="It is the checkin date of the reservation, ", - compute="_compute_checkin", - readonly=False, - store=True, - copy=False, - tracking=True, - ) - checkout = fields.Date( - string="Check Out", - help="It is the checkout date of the reservation, ", - compute="_compute_checkout", - readonly=False, - store=True, - copy=False, - tracking=True, - ) - arrival_hour = fields.Char( - string="Arrival Hour", - help="Arrival Hour (HH:MM)", - readonly=False, - store=True, - compute="_compute_arrival_hour", - ) - departure_hour = fields.Char( - string="Departure Hour", - help="Departure Hour (HH:MM)", - readonly=False, - store=True, - compute="_compute_departure_hour", - ) - checkin_datetime = fields.Datetime( - string="Exact Arrival", - help="This field is the day and time of arrival of the reservation." - "It is formed with the checkin and arrival_hour fields", - compute="_compute_checkin_datetime", - ) - checkout_datetime = fields.Datetime( - string="Exact Departure", - help="This field is the day and time of departure of the reservation." - "It is formed with the checkout and departure_hour fields", - compute="_compute_checkout_datetime", - ) - checkin_partner_count = fields.Integer( - string="Checkin counter", - help="Number of checkin partners in a reservation", - compute="_compute_checkin_partner_count", - ) - checkin_partner_pending_count = fields.Integer( - string="Checkin Pending Num", - help="Number of checkin partners pending to checkin in a reservation", - compute="_compute_checkin_partner_count", - search="_search_checkin_partner_pending", - ) - overbooking = fields.Boolean( - string="Is Overbooking", - help="Indicate if exists overbooking", - default=False, - copy=False, - ) - nights = fields.Integer( - string="Nights", - help="Number of nights of a reservation", - compute="_compute_nights", - store=True, - ) - folio_pending_amount = fields.Monetary( - string="Pending Amount", - help="The amount that remains to be paid from folio", - related="folio_id.pending_amount", - tracking=True, - ) - folio_payment_state = fields.Selection( - string="Payment State", - help="The status of the folio payment", - store=True, - related="folio_id.payment_state", - tracking=True, - ) - shared_folio = fields.Boolean( - string="Shared Folio", - help="Used to notify is the reservation folio has other reservations/services", - compute="_compute_shared_folio", - ) - partner_name = fields.Char( - string="Customer Name", - help="To whom the room is assigned", - store=True, - readonly=False, - compute="_compute_partner_name", - ) - email = fields.Char( - string="E-mail", - help="Customer E-mail", - store=True, - readonly=False, - compute="_compute_email", - ) - mobile = fields.Char( - string="Mobile", - help="Customer Mobile", - store=True, - readonly=False, - compute="_compute_mobile", - ) - partner_internal_comment = fields.Text( - string="Internal Partner Notes", - help="Internal notes of the partner", - related="partner_id.comment", - store=True, - readonly=False, - ) - partner_incongruences = fields.Char( - string="partner_incongruences", - help="indicates that some partner fields \ - on the reservation do not correspond to that of \ - the associated partner", - compute="_compute_partner_incongruences", - ) - partner_requests = fields.Text( - string="Partner Requests", - help="Guest requests", - ) - folio_internal_comment = fields.Text( - string="Internal Folio Notes", - help="Internal comment for folio", - related="folio_id.internal_comment", - store=True, - readonly=False, - ) - preconfirm = fields.Boolean( - string="Auto confirm to Save", - help="Technical field that indicates the reservation is not comfirm yet", - default=True, - ) - invoice_status = fields.Selection( - string="Invoice Status", - help="The status of the invoices in folio. Can be 'invoiced'," - " 'to_invoice' or 'no'.", - store=True, - readonly=True, - selection=[ - ("upselling", "Upselling Opportunity"), - ("invoiced", "Fully Invoiced"), - ("to_invoice", "To Invoice"), - ("no", "Nothing to Invoice"), - ], - compute="_compute_invoice_status", - ) - analytic_tag_ids = fields.Many2many( - string="Analytic Tags", - comodel_name="account.analytic.tag", - relation="pms_reservation_account_analytic_tag", - column1="reservation_id", - column2="account_analytic_tag_id", - domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", - ) - analytic_line_ids = fields.One2many( - string="Analytic lines", - comodel_name="account.analytic.line", - inverse_name="so_line", - ) - price_subtotal = fields.Monetary( - string="Subtotal", - help="Subtotal price without taxes", - readonly=True, - store=True, - compute="_compute_amount_reservation", - ) - price_total = fields.Monetary( - string="Total", - help="Total price with taxes", - readonly=True, - store=True, - compute="_compute_amount_reservation", - tracking=True, - ) - price_tax = fields.Float( - string="Taxes Amount", - help="Total of taxes in a reservation", - readonly=True, - store=True, - compute="_compute_amount_reservation", - ) - price_services = fields.Monetary( - string="Services Total", - help="Total price from services of a reservation", - readonly=True, - store=True, - compute="_compute_price_services", - ) - price_room_services_set = fields.Monetary( - string="Room Services Total", - help="Total price of room and services", - readonly=True, - store=True, - compute="_compute_price_room_services_set", - ) - discount = fields.Float( - string="Discount (€)", - help="Discount of total price in reservation", - readonly=False, - store=True, - digits=("Discount"), - compute="_compute_discount", - tracking=True, - ) - - services_discount = fields.Float( - string="Services discount (€)", - help="Services discount", - readonly=False, - store=True, - digits=("Discount"), - compute="_compute_services_discount", - tracking=True, - ) - date_order = fields.Datetime( - string="Date Order", - help="Order date of reservation", - default=fields.Datetime.now, - store=True, - readonly=False, - ) - - check_adults = fields.Boolean( - help="Internal field to force room capacity validations", - compute="_compute_check_adults", - readonly=False, - store=True, - ) - - document_number = fields.Char( - string="Document Number", - readonly=False, - store=True, - compute="_compute_document_number", - ) - document_type = fields.Many2one( - string="Document Type", - readonly=False, - store=True, - comodel_name="res.partner.id_category", - compute="_compute_document_type", - ) - - document_id = fields.Many2one( - string="Document", - readonly=False, - store=True, - comodel_name="res.partner.id_number", - compute="_compute_document_id", - ondelete="restrict", - ) - - possible_existing_customer_ids = fields.One2many( - string="Possible existing customer", - readonly=False, - store=True, - compute="_compute_possible_existing_customer_ids", - comodel_name="res.partner", - inverse_name="reservation_possible_customer_id", - ) - is_mail_send = fields.Boolean(string="Mail Sent", default=False) - - is_modified_reservation = fields.Boolean( - string="Is A Modified Reservation", - compute="_compute_is_modified_reservation", - readonly=False, - store=True, - ) - overnight_room = fields.Boolean( - related="room_type_id.overnight_room", - store=True, - ) - lang = fields.Many2one( - string="Language", comodel_name="res.lang", compute="_compute_lang" - ) - - def _compute_date_order(self): - for record in self: - record.date_order = datetime.datetime.today() - - @api.depends( - "service_ids", - "service_ids.service_line_ids", - "service_ids.service_line_ids.product_id", - "service_ids.service_line_ids.day_qty", - "reservation_line_ids", - "reservation_line_ids.room_id", - ) - def _compute_check_adults(self): - for record in self: - record.check_adults = True - - @api.depends( - "checkin", - "checkout", - "state", - "folio_payment_state", - "to_assign", - ) - def _compute_priority(self): - # TODO: Notifications priority - for record in self: - if record.to_assign or record.state in ( - "arrival_delayed", - "departure_delayed", - ): - record.priority = 1 - elif record.state == "cancel": - record.priority = record.cancel_priority() - elif record.state == "onboard": - record.priority = record.onboard_priority() - elif record.state in ("draf", "confirm"): - record.priority = record.reservations_future_priority() - elif record.state == "done": - record.priority = record.reservations_past_priority() - - def cancel_priority(self): - self.ensure_one() - if self.folio_pending_amount > 0: - return 2 - elif self.checkout >= fields.date.today(): - return 100 - else: - return 1000 * (fields.date.today() - self.checkout).days - - def onboard_priority(self): - self.ensure_one() - days_for_checkout = (self.checkout - fields.date.today()).days - if self.folio_pending_amount > 0: - return days_for_checkout - else: - return 3 * days_for_checkout - - def reservations_future_priority(self): - self.ensure_one() - days_for_checkin = (self.checkin - fields.date.today()).days - if days_for_checkin < 3: - return 2 * days_for_checkin - elif days_for_checkin < 20: - return 3 * days_for_checkin - else: - return 4 * days_for_checkin - - def reservations_past_priority(self): - self.ensure_one() - if self.folio_pending_amount > 0: - return 3 - days_from_checkout = (fields.date.today() - self.checkout).days - if days_from_checkout <= 1: - return 6 - elif days_from_checkout < 15: - return 5 * days_from_checkout - elif days_from_checkout <= 90: - return 10 * days_from_checkout - elif days_from_checkout > 90: - return 100 * days_from_checkout - - @api.depends("pricelist_id", "room_type_id") - def _compute_board_service_room_id(self): - for reservation in self: - if reservation.pricelist_id and reservation.room_type_id: - board_service_default = self.env["pms.board.service.room.type"].search( - [ - ("pms_room_type_id", "=", reservation.room_type_id.id), - ("by_default", "=", True), - ] - ) - if ( - not reservation.board_service_room_id - or not reservation.board_service_room_id.pms_room_type_id - == reservation.room_type_id - ): - reservation.board_service_room_id = ( - board_service_default.id if board_service_default else False - ) - elif not reservation.board_service_room_id: - reservation.board_service_room_id = False - - @api.depends("preferred_room_id") - def _compute_room_type_id(self): - """ - This method set False to_assign when the user - directly chooses the preferred_room_id, - otherwise, action_assign will be used when the user manually confirms - or changes the preferred_room_id of the reservation - """ - for reservation in self: - if reservation.preferred_room_id and not reservation.room_type_id: - reservation.room_type_id = reservation.preferred_room_id.room_type_id.id - elif not reservation.room_type_id: - reservation.room_type_id = False - - @api.depends("checkin", "arrival_hour") - def _compute_checkin_datetime(self): - for reservation in self: - checkin_hour = int(reservation.arrival_hour[0:2]) - checkin_minut = int(reservation.arrival_hour[3:5]) - checkin_time = datetime.time(checkin_hour, checkin_minut) - checkin_datetime = datetime.datetime.combine( - reservation.checkin, checkin_time - ) - reservation.checkin_datetime = ( - reservation.pms_property_id.date_property_timezone(checkin_datetime) - ) - - @api.depends("checkout", "departure_hour") - def _compute_checkout_datetime(self): - for reservation in self: - checkout_hour = int(reservation.departure_hour[0:2]) - checkout_minut = int(reservation.departure_hour[3:5]) - checkout_time = datetime.time(checkout_hour, checkout_minut) - checkout_datetime = datetime.datetime.combine( - reservation.checkout, checkout_time - ) - reservation.checkout_datetime = ( - reservation.pms_property_id.date_property_timezone(checkout_datetime) - ) - - @api.depends( - "reservation_line_ids.date", - "reservation_line_ids.room_id", - "reservation_line_ids.occupies_availability", - "preferred_room_id", - "room_type_id", - "pricelist_id", - "pms_property_id", - ) - def _compute_allowed_room_ids(self): - for reservation in self: - if reservation.checkin and reservation.checkout: - if reservation.overbooking or reservation.state in ("cancel"): - reservation.allowed_room_ids = self.env["pms.room"].search( - [ - ("active", "=", True), - ] - ) - return - pms_property = reservation.pms_property_id - pms_property = pms_property.with_context( - checkin=reservation.checkin, - checkout=reservation.checkout, - room_type_id=False, # Allows to choose any available room - current_lines=reservation.reservation_line_ids.ids, - pricelist_id=reservation.pricelist_id.id, - class_id=reservation.room_type_id.class_id.id - if reservation.room_type_id - else False, - real_avail=True, - ) - reservation.allowed_room_ids = pms_property.free_room_ids - else: - reservation.allowed_room_ids = False - - @api.depends( - "reservation_type", - "agency_id", - "folio_id", - "folio_id.agency_id", - "document_number", - "document_type", - "partner_name", - "email", - "mobile", - ) - def _compute_partner_id(self): - for reservation in self: - if not reservation.partner_id: - if reservation.reservation_type == "out": - reservation.partner_id = False - elif reservation.folio_id and reservation.folio_id.partner_id: - reservation.partner_id = reservation.folio_id.partner_id - elif reservation.agency_id and reservation.agency_id.invoice_to_agency: - reservation.partner_id = reservation.agency_id - elif reservation.document_number and reservation.document_type: - self.env["pms.folio"]._create_partner(reservation) - elif not reservation.partner_id: - reservation.partner_id = False - - @api.depends("checkin", "checkout") - def _compute_reservation_line_ids(self): - for reservation in self: - cmds = [] - if reservation.checkout and reservation.checkin: - days_diff = (reservation.checkout - reservation.checkin).days - for i in range(0, days_diff): - idate = reservation.checkin + datetime.timedelta(days=i) - old_line = reservation.reservation_line_ids.filtered( - lambda r: r.date == idate - ) - if not old_line: - cmds.append( - ( - 0, - False, - {"date": idate}, - ) - ) - reservation.reservation_line_ids -= ( - reservation.reservation_line_ids.filtered_domain( - [ - "|", - ("date", ">=", reservation.checkout), - ("date", "<", reservation.checkin), - ] - ) - ) - reservation.reservation_line_ids = cmds - else: - if not reservation.reservation_line_ids: - reservation.reservation_line_ids = False - reservation.check_in_out_dates() - - @api.depends("board_service_room_id") - def _compute_service_ids(self): - for reservation in self: - board_services = [] - old_board_lines = reservation.service_ids.filtered_domain( - [ - ("is_board_service", "=", True), - ] - ) - # Avoid recalculating services if the boardservice has not changed - if ( - old_board_lines - and reservation.board_service_room_id - == reservation._origin.board_service_room_id - ): - return - if reservation.board_service_room_id: - board = self.env["pms.board.service.room.type"].browse( - reservation.board_service_room_id.id - ) - for line in board.board_service_line_ids: - res = { - "product_id": line.product_id.id, - "is_board_service": True, - "folio_id": reservation.folio_id.id, - "reservation_id": reservation.id, - } - board_services.append((0, False, res)) - reservation.service_ids -= old_board_lines - reservation.service_ids = board_services - elif old_board_lines: - reservation.service_ids -= old_board_lines - - @api.depends("partner_id", "agency_id") - def _compute_pricelist_id(self): - for reservation in self: - if reservation.reservation_type in ("out", "staff"): - reservation.pricelist_id = False - elif reservation.agency_id and reservation.agency_id.apply_pricelist: - reservation.pricelist_id = ( - reservation.agency_id.property_product_pricelist - ) - elif ( - reservation.partner_id - and reservation.partner_id.property_product_pricelist - ): - reservation.pricelist_id = ( - reservation.partner_id.property_product_pricelist - ) - elif not reservation.pricelist_id.id: - if reservation.folio_id and reservation.folio_id.pricelist_id: - reservation.pricelist_id = reservation.folio_id.pricelist_id - else: - reservation.pricelist_id = ( - reservation.pms_property_id.default_pricelist_id - ) - - @api.depends("pricelist_id", "room_type_id") - def _compute_show_update_pricelist(self): - for reservation in self: - if ( - sum(reservation.reservation_line_ids.mapped("price")) > 0 - and ( - reservation.pricelist_id - and reservation._origin.pricelist_id != reservation.pricelist_id - ) - or ( - reservation.room_type_id - and reservation._origin.room_type_id != reservation.room_type_id - ) - ): - reservation.show_update_pricelist = True - else: - reservation.show_update_pricelist = False - - @api.depends("adults") - def _compute_checkin_partner_ids(self): - for reservation in self: - assigned_checkins = reservation.checkin_partner_ids.filtered( - lambda c: c.state in ("precheckin", "onboard", "done") - ) - unassigned_checkins = reservation.checkin_partner_ids.filtered( - lambda c: c.state == "draft" - ) - leftover_unassigneds_count = ( - len(assigned_checkins) + len(unassigned_checkins) - reservation.adults - ) - if len(assigned_checkins) > reservation.adults: - raise UserError( - _("Remove some of the leftover assigned checkins first") - ) - elif leftover_unassigneds_count > 0: - for i in range(0, leftover_unassigneds_count): - reservation.checkin_partner_ids = [(2, unassigned_checkins[i].id)] - elif reservation.adults > len(reservation.checkin_partner_ids): - checkins_lst = [] - count_new_checkins = reservation.adults - len( - reservation.checkin_partner_ids - ) - for _i in range(0, count_new_checkins): - checkins_lst.append( - ( - 0, - False, - { - "reservation_id": reservation.id, - }, - ) - ) - reservation.checkin_partner_ids = checkins_lst - elif reservation.adults == 0: - reservation.checkin_partner_ids = False - - @api.depends("checkin_partner_ids", "checkin_partner_ids.state") - def _compute_count_pending_arrival(self): - for reservation in self: - reservation.count_pending_arrival = len( - reservation.checkin_partner_ids.filtered( - lambda c: c.state in ("draft", "precheckin") - ) - ) - - @api.depends("count_pending_arrival") - def _compute_checkins_ratio(self): - self.checkins_ratio = 0 - for reservation in self.filtered(lambda r: r.adults > 0): - reservation.checkins_ratio = ( - (reservation.adults - reservation.count_pending_arrival) - * 100 - / reservation.adults - ) - - @api.depends("checkin_partner_ids", "checkin_partner_ids.state") - def _compute_pending_checkin_data(self): - for reservation in self: - reservation.pending_checkin_data = len( - reservation.checkin_partner_ids.filtered(lambda c: c.state == "draft") - ) - - @api.depends("pending_checkin_data") - def _compute_ratio_checkin_data(self): - self.ratio_checkin_data = 0 - for reservation in self.filtered( - lambda r: r.adults > 0 and r.state != "cancel" - ): - reservation.ratio_checkin_data = ( - (reservation.adults - reservation.pending_checkin_data) - * 100 - / reservation.adults - ) - - def _compute_allowed_checkin(self): - # Reservations still pending entry today - for record in self: - record.allowed_checkin = ( - True - if ( - record.reservation_type != "out" - and record.overnight_room - and record.state in ["draft", "confirm", "arrival_delayed"] - and record.checkin <= fields.Date.today() - ) - else False - ) - - def _compute_allowed_checkout(self): - # Reservations still pending checkout today - for record in self: - record.allowed_checkout = ( - True - if ( - record.state in ["onboard", "departure_delayed"] - and record.checkout >= fields.Date.today() - ) - else False - ) - - def _compute_allowed_cancel(self): - # Reservations can be cancelled - for record in self: - record.allowed_cancel = ( - True - if (record.state not in ["cancel", "done", "departure_delayed"]) - else False - ) - - def _compute_ready_for_checkin(self): - # Reservations with hosts data enought to checkin - for record in self: - record.ready_for_checkin = ( - record.allowed_checkin - and len( - record.checkin_partner_ids.filtered( - lambda c: c.state == "precheckin" - ) - ) - >= 1 - ) - - def _compute_access_url(self): - super(PmsReservation, self)._compute_access_url() - for reservation in self: - reservation.access_url = "/my/reservations/%s" % (reservation.id) - - @api.depends("reservation_line_ids") - def _compute_checkin(self): - """ - Allows to calculate the checkin by default or when the create - specifically indicates the lines of the reservation - """ - for record in self: - if record.reservation_line_ids: - checkin_line_date = min(record.reservation_line_ids.mapped("date")) - # check if the checkin was created directly as reservation_line_id: - if checkin_line_date != record.checkin: - record.checkin = checkin_line_date - elif not record.checkin: - # default checkout other folio reservations or today - if len(record.folio_id.reservation_ids) > 1: - record.checkin = record.folio_id.reservation_ids[0].checkin - else: - record.checkin = fields.date.today() - record.check_in_out_dates() - - @api.depends("reservation_line_ids", "checkin") - def _compute_checkout(self): - """ - Allows to calculate the checkout by default or when the create - specifically indicates the lines of the reservation - """ - for record in self: - if record.reservation_line_ids: - checkout_line_date = max( - record.reservation_line_ids.mapped("date") - ) + datetime.timedelta(days=1) - # check if the checkout was created directly as reservation_line_id: - if checkout_line_date != record.checkout: - record.checkout = checkout_line_date - # default checkout if checkin is set - elif record.checkin and not record.checkout: - if len(record.folio_id.reservation_ids) > 1: - record.checkin = record.folio_id.reservation_ids[0].checkout - else: - record.checkout = record.checkin + datetime.timedelta(days=1) - elif not record.checkout: - record.checkout = False - # date checking - record.check_in_out_dates() - - def _compute_precheckin_url(self): - super(PmsReservation, self)._compute_access_url() - for reservation in self: - reservation.access_url = "/my/reservations/precheckin/%s" % (reservation.id) - - @api.depends("pms_property_id", "folio_id") - def _compute_arrival_hour(self): - for record in self: - if not record.arrival_hour and record.pms_property_id: - default_arrival_hour = record.pms_property_id.default_arrival_hour - if ( - record.folio_id - and record.folio_id.reservation_ids - and record.folio_id.reservation_ids[0].arrival_hour - ): - record.arrival_hour = record.folio_id.reservation_ids[ - 0 - ].arrival_hour - else: - record.arrival_hour = default_arrival_hour - elif not record.arrival_hour: - record.arrival_hour = False - - @api.depends("pms_property_id", "folio_id") - def _compute_departure_hour(self): - for record in self: - if not record.departure_hour and record.pms_property_id: - default_departure_hour = record.pms_property_id.default_departure_hour - if ( - record.folio_id - and record.folio_id.reservation_ids - and record.folio_id.reservation_ids[0].departure_hour - ): - record.departure_hour = record.folio_id.reservation_ids[ - 0 - ].departure_hour - else: - record.departure_hour = default_departure_hour - elif not record.departure_hour: - record.departure_hour = False - - @api.depends("agency_id") - def _compute_commission_percent(self): - for reservation in self: - if reservation.agency_id: - reservation.commission_percent = ( - reservation.agency_id.default_commission - ) - else: - reservation.commission_percent = 0 - - @api.depends("commission_percent", "price_total") - def _compute_commission_amount(self): - for reservation in self: - if reservation.commission_percent > 0: - reservation.commission_amount = ( - reservation.price_total * reservation.commission_percent / 100 - ) - else: - reservation.commission_amount = 0 - - # REVIEW: Dont run with set room_type_id -> room_id(compute)-> No set adults¿? - @api.depends("preferred_room_id", "reservation_type", "overnight_room") - def _compute_adults(self): - for reservation in self: - if not reservation.overnight_room: - reservation.adults = 0 - if reservation.preferred_room_id and reservation.reservation_type != "out": - if reservation.adults == 0: - reservation.adults = reservation.preferred_room_id.capacity - elif not reservation.adults or reservation.reservation_type == "out": - reservation.adults = 0 - - @api.depends("reservation_line_ids", "reservation_line_ids.room_id") - def _compute_splitted(self): - # REVIEW: Updating preferred_room_id here avoids cyclical dependency - for reservation in self: - room_ids = reservation.reservation_line_ids.mapped("room_id.id") - if len(room_ids) > 1 and not self._context.get("not_split"): - reservation.splitted = True - reservation.preferred_room_id = False - else: - reservation.splitted = False - if room_ids: - reservation.preferred_room_id = room_ids[0] - - @api.depends( - "sale_line_ids", - "sale_line_ids.invoice_status", - ) - def _compute_invoice_status(self): - """ - Compute the invoice status of a Reservation. Possible statuses: - Base on folio sale line invoice status - """ - for line in self: - states = list(set(line.sale_line_ids.mapped("invoice_status"))) - if len(states) == 1: - line.invoice_status = states[0] - elif len(states) >= 1: - if "to_invoice" in states: - line.invoice_status = "to_invoice" - elif "invoiced" in states: - line.invoice_status = "invoiced" - else: - line.invoice_status = "no" - else: - line.invoice_status = "no" - if line.reservation_type != "normal": - line.invoice_status = "no" - - @api.depends("reservation_line_ids") - def _compute_nights(self): - for res in self: - res.nights = len(res.reservation_line_ids) - - @api.depends("service_ids.price_total", "services_discount") - def _compute_price_services(self): - for record in self: - record.price_services = ( - sum(record.mapped("service_ids.price_total")) - record.services_discount - ) - - @api.depends("price_services", "price_total") - def _compute_price_room_services_set(self): - for record in self: - record.price_room_services_set = record.price_services + record.price_total - - @api.depends( - "reservation_line_ids.discount", - "reservation_line_ids.cancel_discount", - ) - def _compute_discount(self): - for record in self: - discount = 0 - for line in record.reservation_line_ids: - first_discount = line.price * ((line.discount or 0.0) * 0.01) - price = line.price - first_discount - cancel_discount = price * ((line.cancel_discount or 0.0) * 0.01) - discount += first_discount + cancel_discount - - record.discount = discount - - @api.depends("service_ids.discount") - def _compute_services_discount(self): - for record in self: - services_discount = 0 - for service in record.service_ids: - services_discount += service.discount - record.services_discount = services_discount - - @api.depends("reservation_line_ids.price", "discount", "tax_ids") - def _compute_amount_reservation(self): - """ - Compute the amounts of the reservation. - """ - for record in self: - amount_room = sum(record.reservation_line_ids.mapped("price")) - if amount_room > 0: - product = record.room_type_id.product_id - price = amount_room - record.discount - taxes = record.tax_ids.compute_all( - price, record.currency_id, 1, product=product - ) - record.update( - { - "price_tax": sum( - t.get("amount", 0.0) for t in taxes.get("taxes", []) - ), - "price_total": taxes["total_included"], - "price_subtotal": taxes["total_excluded"], - } - ) - else: - record.update( - { - "price_tax": 0, - "price_total": 0, - "price_subtotal": 0, - } - ) - - def _compute_shared_folio(self): - # Has this reservation more charges associates in folio?, - # Yes?, then, this is share folio ;) - for record in self: - if record.folio_id: - record.shared_folio = len(record.folio_id.reservation_ids) > 1 or any( - record.folio_id.service_ids.filtered( - lambda x: x.reservation_id.id != record.id - ) - ) - else: - record.shared_folio = False - - @api.depends( - "partner_id", - "partner_id.name", - "agency_id", - "reservation_type", - "out_service_description", - ) - def _compute_partner_name(self): - for record in self: - if record.reservation_type != "out": - self.env["pms.folio"]._apply_partner_name(record) - else: - record.partner_name = record.out_service_description - - @api.depends("partner_id", "partner_id.email", "agency_id") - def _compute_email(self): - for record in self: - self.env["pms.folio"]._apply_email(record) - - @api.depends("partner_id", "partner_id.mobile", "agency_id") - def _compute_mobile(self): - for record in self: - self.env["pms.folio"]._apply_mobile(record) - - @api.depends( - "partner_name", - "email", - "mobile", - "partner_id", - ) - def _compute_partner_incongruences(self): - fields_mapping = { - "partner_name": "name", - "email": "email", - "mobile": "mobile", - } - for record in self: - incongruous_fields = False - if record.partner_id: - for k, v in fields_mapping.items(): - if record.partner_id[v] and record.partner_id[v] != record[k]: - if not incongruous_fields: - incongruous_fields = v - else: - incongruous_fields += ", " + v - if incongruous_fields: - record.partner_incongruences = ( - incongruous_fields + " field/s don't correspond to saved host" - ) - else: - record.partner_incongruences = False - else: - record.partner_incongruences = False - - def _compute_checkin_partner_count(self): - for record in self: - if record.reservation_type != "out" and record.overnight_room: - record.checkin_partner_count = len(record.checkin_partner_ids) - record.checkin_partner_pending_count = record.adults - len( - record.checkin_partner_ids - ) - else: - record.checkin_partner_count = 0 - record.checkin_partner_pending_count = 0 - - @api.depends("room_type_id") - def _compute_tax_ids(self): - for record in self: - record = record.with_company(record.company_id) - product = self.env["product.product"].browse( - record.room_type_id.product_id.id - ) - record.tax_ids = product.taxes_id.filtered( - lambda t: t.company_id == record.env.company - ) - - @api.depends("reservation_line_ids", "reservation_line_ids.room_id") - def _compute_rooms(self): - self.rooms = False - for reservation in self: - if reservation.splitted: - reservation.rooms = ", ".join( - [r for r in reservation.reservation_line_ids.mapped("room_id.name")] - ) - else: - reservation.rooms = reservation.preferred_room_id.name - - @api.depends("folio_id", "folio_id.reservation_type") - def _compute_reservation_type(self): - for record in self: - if record.folio_id: - record.reservation_type = record.folio_id.reservation_type - else: - record.reservation_type = "normal" - - @api.depends("partner_id") - def _compute_document_number(self): - for record in self: - self.env["pms.folio"]._apply_document_number(record) - - @api.depends("partner_id") - def _compute_document_type(self): - for record in self: - self.env["pms.folio"]._apply_document_type(record) - - @api.depends("partner_id") - def _compute_document_id(self): - for record in self: - self.env["pms.folio"]._apply_document_id(record) - - @api.depends("email", "mobile", "partner_name") - def _compute_possible_existing_customer_ids(self): - for record in self: - if record.partner_name: - possible_customer = self.env[ - "pms.folio" - ]._apply_possible_existing_customer_ids( - record.email, record.mobile, record.partner_id - ) - if possible_customer: - record.possible_existing_customer_ids = possible_customer - else: - record.possible_existing_customer_ids = False - else: - record.possible_existing_customer_ids = False - - @api.depends("checkin", "checkout") - def _compute_is_modified_reservation(self): - for record in self: - if record.state in "draft": - record.is_modified_reservation = False - elif record.state in ("confirm", "onboard") and record.is_mail_send: - record.is_modified_reservation = True - record.is_mail_send = False - else: - record.is_modified_reservation = False - - @api.depends("partner_id") - def _compute_lang(self): - for record in self: - if record.partner_id: - record.lang = record.partner_id.lang - else: - record.lang = self.env["res.lang"].get_installed() - - def _search_allowed_checkin(self, operator, value): - if operator not in ("=",): - raise UserError( - _("Invalid domain operator %s for left of checkin", operator) - ) - - if value not in (True,): - raise UserError( - _("Invalid domain right operand %s for left of checkin", value) - ) - - today = fields.Date.context_today(self) - return [ - ("state", "in", ("draft", "confirm", "arrival_delayed")), - ("checkin", "<=", today), - ("adults", ">", 0), - ] - - def _search_allowed_checkout(self, operator, value): - if operator not in ("=",): - raise UserError( - _("Invalid domain operator %s for left of checkout", operator) - ) - - if value not in (True,): - raise UserError( - _("Invalid domain right operand %s for left of checkout", value) - ) - - today = fields.Date.context_today(self) - return [ - ("state", "in", ("onboard", "departure_delayed")), - ("checkout", ">=", today), - ("adults", ">", 0), - ] - - def _search_allowed_cancel(self, operator, value): - if operator not in ("=",): - raise UserError( - _("Invalid domain operator %s for left of cancel", operator) - ) - - if value not in (True,): - raise UserError( - _("Invalid domain right operand %s for left of cancel", value) - ) - return [ - ("state", "not in", ("cancel", "done", "departure_delayed")), - ] - - def _search_checkin_partner_pending(self, operator, value): - self.ensure_one() - recs = self.search([]).filtered(lambda x: x.checkin_partner_pending_count > 0) - return [("id", "in", [x.id for x in recs])] if recs else [] - - def _get_default_segmentation(self): - folio = False - segmentation_ids = False - if "folio_id" in self._context: - folio = self.env["pms.folio"].search( - [("id", "=", self._context["folio_id"])] - ) - if folio and folio.segmentation_ids: - segmentation_ids = folio.segmentation_ids - return segmentation_ids - - def check_in_out_dates(self): - """ - 1.-When date_order is less then checkin date or - Checkout date should be greater than the checkin date. - 3.-Check the reservation dates are not occuped - """ - for record in self: - if ( - record.checkout - and record.checkout - and record.checkin >= record.checkout - ): - raise UserError( - _( - "Room line Check In Date Should be \ - less than the Check Out Date!" - ) - ) - - @api.constrains("reservation_line_ids") - def check_consecutive_dates(self): - """ - simply convert date objects to integers using the .toordinal() method - of datetime objects. The difference between the maximum and minimum value - of the set of ordinal dates is one more than the length of the set - """ - for record in self: - if record.reservation_line_ids and len(record.reservation_line_ids) > 1: - dates = record.reservation_line_ids.mapped("date") - date_ints = {d.toordinal() for d in dates} - if not (max(date_ints) - min(date_ints) == len(date_ints) - 1): - raise ValidationError(_("Reservation dates should be consecutives")) - - # @api.constrains("checkin_partner_ids", "adults") - # def _max_checkin_partner_ids(self): - # for record in self: - # if len(record.checkin_partner_ids) > record.adults: - # raise models.ValidationError( - # _("The room already is completed (%s)", record.name) - # ) - - @api.constrains("state") - def _check_onboard_reservation(self): - for record in self: - if ( - not record.checkin_partner_ids.filtered(lambda c: c.state == "onboard") - and record.state == "onboard" - and record.reservation_type != "out" - ): - raise ValidationError( - _("No person from reserve %s has arrived", record.name) - ) - - @api.constrains("arrival_hour") - def _check_arrival_hour(self): - for record in self: - if record.arrival_hour: - try: - time.strptime(record.arrival_hour, "%H:%M") - return True - except ValueError: - raise ValidationError( - _("Format Arrival Hour (HH:MM) Error: %s", record.arrival_hour) - ) - - @api.constrains("departure_hour") - def _check_departure_hour(self): - for record in self: - if record.departure_hour: - try: - time.strptime(record.departure_hour, "%H:%M") - return True - except ValueError: - raise ValidationError( - _( - "Format Departure Hour (HH:MM) Error: %s", - record.departure_hour, - ) - ) - - @api.constrains("agency_id") - def _no_agency_as_agency(self): - for record in self: - if record.agency_id and not record.agency_id.is_agency: - raise ValidationError(_("booking agency with wrong configuration: ")) - - @api.constrains("check_adults") - def _check_capacity(self): - for record in self: - self.env["pms.room"]._check_adults( - record, record.service_ids.service_line_ids - ) - - @api.constrains("reservation_type") - def _check_same_reservation_type(self): - for record in self: - if len(record.folio_id.reservation_ids) > 1: - for reservation in record.folio_id.reservation_ids: - if reservation.reservation_type != record.reservation_type: - raise ValidationError( - _( - "The reservation type must be the " - "same for all reservations in folio" - ) - ) - - # Action methods - def open_partner(self): - """ Utility method used to add an "View Customer" button in reservation views """ - self.ensure_one() - partner_form_id = self.env.ref("pms.view_partner_data_form").id - return { - "type": "ir.actions.act_window", - "res_model": "res.partner", - "view_mode": "form", - "views": [(partner_form_id, "form")], - "res_id": self.partner_id.id, - "target": "new", - "flags": {"form": {"action_buttons": True}}, - } - - 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 ("precheckin", "onboard", "done") - ) - if checkins: - return self.env.ref("pms.action_traveller_report").report_action(checkins) - else: - raise ValidationError(_("There are no checkins to print")) - - def open_folio(self): - action = self.env.ref("pms.open_pms_folio1_form_tree_all").sudo().read()[0] - if self.folio_id: - action["views"] = [(self.env.ref("pms.pms_folio_view_form").id, "form")] - action["res_id"] = self.folio_id.id - else: - action = {"type": "ir.actions.act_window_close"} - return action - - def open_reservation_form(self): - action = self.env.ref("pms.open_pms_reservation_form_tree_all").sudo().read()[0] - action["views"] = [(self.env.ref("pms.pms_reservation_view_form").id, "form")] - action["res_id"] = self.id - return action - - def action_pay_folio(self): - self.ensure_one() - return self.folio_id.action_pay() - - def open_reservation_wizard(self): - pms_property = self.pms_property_id - pms_property = pms_property.with_context( - checkin=self.checkin, - checkout=self.checkout, - current_lines=self.reservation_line_ids.ids, - pricelist_id=self.pricelist_id.id, - ) - rooms_available = pms_property.free_room_ids - - # REVIEW: check capacity room - return { - "view_type": "form", - "view_mode": "form", - "name": "Unify the reservation", - "res_model": "pms.reservation.split.join.swap.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": { - "rooms_available": rooms_available.ids, - }, - } - - def action_open_mail_composer(self): - self.ensure_one() - template = False - pms_property = self.pms_property_id - if ( - not self.is_mail_send - and not self.is_modified_reservation - and self.state not in "cancel" - ): - if pms_property.property_confirmed_template: - template = pms_property.property_confirmed_template - elif ( - not self.is_mail_send - and self.is_modified_reservation - and self.state not in "cancel" - ): - if pms_property.property_modified_template: - template = pms_property.property_modified_template - elif not self.is_mail_send and self.state in "cancel": - if pms_property.property_canceled_template: - template = pms_property.property_canceled_template - compose_form = self.env.ref( - "mail.email_compose_message_wizard_form", raise_if_not_found=False - ) - ctx = dict( - model="pms.folio", - default_res_model="pms.folio", - default_res_id=self.folio_id.id, - template_id=template and template.id or False, - composition_mode="comment", - partner_ids=[self.partner_id.id], - force_email=True, - record_id=self.folio_id.id, - ) - return { - "name": _("Send Confirmed Reservation Mail "), - "type": "ir.actions.act_window", - "view_type": "form", - "view_mode": "form", - "res_model": "mail.compose.message", - "views": [(compose_form.id, "form")], - "view_id": compose_form.id, - "target": "new", - "context": ctx, - } - - def open_wizard_several_partners(self): - ctx = dict( - reservation_id=self.id, - possible_existing_customer_ids=self.possible_existing_customer_ids.ids, - ) - return { - "view_type": "form", - "view_mode": "form", - "name": "Several Customers", - "res_model": "pms.several.partners.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": ctx, - } - - @api.model - def name_search(self, name="", args=None, operator="ilike", limit=100): - if args is None: - args = [] - if not (name == "" and operator == "ilike"): - args += [ - "|", - ("name", operator, name), - ("folio_id.name", operator, name), - ("preferred_room_id.name", operator, name), - ] - return super(PmsReservation, self).name_search( - name="", args=args, operator="ilike", limit=limit - ) - - def name_get(self): - result = [] - for res in self: - name = u"{} ({})".format(res.name, res.rooms if res.rooms else "No room") - result.append((res.id, name)) - return result - - @api.model - def create(self, vals): - if vals.get("folio_id"): - folio = self.env["pms.folio"].browse(vals["folio_id"]) - default_vals = {"pms_property_id": folio.pms_property_id.id} - if folio.partner_id: - default_vals["partner_id"] = folio.partner_id.id - elif folio.partner_name: - default_vals["partner_name"] = folio.partner_name - default_vals["mobile"] = folio.mobile - default_vals["email"] = folio.email - else: - raise ValidationError(_("Partner contact name is required")) - vals.update(default_vals) - elif "pms_property_id" in vals and ( - "partner_name" in vals or "partner_id" in vals or "agency_id" in vals - ): - folio_vals = { - "pms_property_id": vals["pms_property_id"], - } - if vals.get("partner_id"): - folio_vals["partner_id"] = vals.get("partner_id") - elif vals.get("agency_id"): - folio_vals["agency_id"] = vals.get("agency_id") - elif vals.get("partner_name"): - folio_vals["partner_name"] = vals.get("partner_name") - folio_vals["mobile"] = vals.get("mobile") - folio_vals["email"] = vals.get("email") - else: - raise ValidationError(_("Partner contact name is required")) - # Create the folio in case of need - # (To allow to create reservations direct) - if vals.get("reservation_type"): - folio_vals["reservation_type"] = vals.get("reservation_type") - folio = self.env["pms.folio"].create(folio_vals) - vals.update( - { - "folio_id": folio.id, - "reservation_type": vals.get("reservation_type"), - } - ) - else: - raise ValidationError(_("The Property are mandatory in the reservation")) - if vals.get("name", _("New")) == _("New") or "name" not in vals: - pms_property_id = ( - self.env.user.get_active_property_ids()[0] - if "pms_property_id" not in vals - else vals["pms_property_id"] - ) - pms_property = self.env["pms.property"].browse(pms_property_id) - vals["name"] = pms_property.reservation_sequence_id._next_do() - - if not vals.get("reservation_type"): - vals["reservation_type"] = ( - folio.reservation_type if folio.reservation_type else "normal" - ) - - record = super(PmsReservation, self).create(vals) - if record.preconfirm: - record.confirm() - return record - - def update_prices(self): - self.ensure_one() - for line in self.reservation_line_ids: - line.with_context(force_recompute=True)._compute_price() - self.show_update_pricelist = False - self.message_post( - body=_( - """Prices have been recomputed according to pricelist %s - and room type %s""", - self.pricelist_id.display_name, - self.room_type_id.name, - ) - ) - - @api.model - def autocheckout(self): - reservations = self.env["pms.reservation"].search( - [ - ("state", "not in", ["done", "cancel"]), - ("checkout", "<", fields.Date.today()), - ] - ) - for res in reservations: - res.action_reservation_checkout() - res_without_checkin = reservations.filtered(lambda r: r.state != "onboard") - for res in res_without_checkin: - msg = _("No checkin was made for this reservation") - res.message_post(subject=_("No Checkins!"), subtype="mt_comment", body=msg) - return True - - @api.model - def update_daily_priority_reservation(self): - reservations = self.env["pms.reservation"].search([("priority", "<", 1000)]) - reservations._compute_priority() - return True - - def overbooking_button(self): - self.ensure_one() - self.overbooking = not self.overbooking - - def confirm(self): - for record in self: - vals = {} - if record.checkin_partner_ids.filtered(lambda c: c.state == "onboard"): - vals.update({"state": "onboard"}) - else: - vals.update({"state": "confirm"}) - record.write(vals) - record.reservation_line_ids.update({"cancel_discount": 0}) - if record.folio_id.state != "confirm": - record.folio_id.action_confirm() - return True - - def action_cancel(self): - for record in self: - # else state = cancel - if not record.allowed_cancel: - raise UserError(_("This reservation cannot be cancelled")) - else: - record.state = "cancel" - record.folio_id._compute_amount() - record.is_mail_send = False - - def action_assign(self): - for record in self: - record.to_assign = False - - @api.depends("state") - def _compute_cancelled_reason(self): - for record in self: - # self.ensure_one() - if record.state == "cancel": - pricelist = record.pricelist_id - if record._context.get("no_penalty", False): - record.cancelled_reason = "intime" - _logger.info("Modified Reservation - No Penalty") - elif pricelist and pricelist.cancelation_rule_id: - tz_property = record.pms_property_id.tz - today = fields.Date.context_today( - record.with_context(tz=tz_property) - ) - days_diff = ( - fields.Date.from_string(record.checkin) - - fields.Date.from_string(today) - ).days - if days_diff < 0: - record.cancelled_reason = "noshow" - elif days_diff < pricelist.cancelation_rule_id.days_intime: - record.cancelled_reason = "late" - else: - record.cancelled_reason = "intime" - else: - record.cancelled_reason = False - - def action_reservation_checkout(self): - for record in self: - if not record.allowed_checkout: - raise UserError(_("This reservation cannot be check out")) - record.state = "done" - if record.checkin_partner_ids: - record.checkin_partner_ids.filtered( - lambda check: check.state == "onboard" - ).action_done() - return True - - def action_checkin_partner_view(self): - self.ensure_one() - tree_id = self.env.ref("pms.pms_checkin_partner_reservation_view_tree").id - return { - "name": _("Register Partners"), - "views": [[tree_id, "tree"]], - "res_model": "pms.checkin.partner", - "type": "ir.actions.act_window", - "context": { - "create": False, - "edit": True, - "popup": True, - }, - "domain": [("reservation_id", "=", self.id), ("state", "=", "draft")], - "search_view_id": [ - self.env.ref("pms.pms_checkin_partner_view_folio_search").id, - "search", - ], - "target": "new", - } - - def action_checkin_partner_onboard_view(self): - self.ensure_one() - kanban_id = self.env.ref("pms.pms_checkin_partner_kanban_view").id - return { - "name": _("Register Checkins"), - "views": [[kanban_id, "kanban"]], - "res_model": "pms.checkin.partner", - "type": "ir.actions.act_window", - "context": { - "create": False, - "edit": True, - "popup": True, - }, - "search_view_id": [ - self.env.ref("pms.pms_checkin_partner_view_folio_search").id, - "search", - ], - "domain": [("reservation_id", "=", self.id)], - "target": "new", - } - - @api.model - def auto_arrival_delayed(self): - # No show when pass 1 day from checkin day - arrival_delayed_reservations = self.env["pms.reservation"].search( - [ - ("state", "in", ("draft", "confirm")), - ("checkin", "<", fields.Date.today()), - ] - ) - for record in arrival_delayed_reservations: - if record.overnight_room: - record.state = "arrival_delayed" - - @api.model - def auto_departure_delayed(self): - # No checkout when pass checkout hour - reservations = self.env["pms.reservation"].search( - [ - ("state", "in", ("onboard",)), - ("checkout", "<=", fields.Datetime.today()), - ] - ) - for reservation in reservations: - if reservation.overnight_room: - if reservation.checkout_datetime <= fields.Datetime.now(): - reservations.state = "departure_delayed" - else: - reservation.state = "done" - - def preview_reservation(self): - self.ensure_one() - return { - "type": "ir.actions.act_url", - "target": "self", - "url": self.get_portal_url(), - } diff --git a/pms/models/pms_reservation_line.py b/pms/models/pms_reservation_line.py deleted file mode 100644 index eb2495402..000000000 --- a/pms/models/pms_reservation_line.py +++ /dev/null @@ -1,483 +0,0 @@ -# Copyright 2017-2018 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import datetime -import logging - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - -_logger = logging.getLogger(__name__) - - -class PmsReservationLine(models.Model): - _name = "pms.reservation.line" - _description = "Reservations by day" - _order = "date" - _check_company_auto = True - - reservation_id = fields.Many2one( - string="Reservation", - help="It is the reservation in a reservation line", - required=True, - copy=False, - comodel_name="pms.reservation", - ondelete="cascade", - check_pms_properties=True, - ) - room_id = fields.Many2one( - string="Room", - help="The room of a reservation. ", - readonly=False, - store=True, - compute="_compute_room_id", - comodel_name="pms.room", - ondelete="restrict", - check_pms_properties=True, - ) - - sale_line_ids = fields.Many2many( - string="Sales Lines", - readonly=True, - copy=False, - comodel_name="folio.sale.line", - relation="reservation_line_sale_line_rel", - column1="reservation_line_id", - column2="sale_line_id", - check_pms_properties=True, - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property with access to the element;" - " if not set, all properties can access", - readonly=True, - store=True, - comodel_name="pms.property", - related="reservation_id.pms_property_id", - check_pms_properties=True, - ) - date = fields.Date( - string="Date", - help="The date of the reservation in reservation line", - ) - state = fields.Selection( - string="State", - help="State of the reservation line.", - related="reservation_id.state", - store=True, - ) - price = fields.Float( - string="Price", - help="The price in a reservation line", - store=True, - readonly=False, - digits=("Product Price"), - compute="_compute_price", - ) - cancel_discount = fields.Float( - string="Cancelation Discount (%)", - help="", - readonly=False, - default=0.0, - store=True, - digits=("Discount"), - compute="_compute_cancel_discount", - ) - avail_id = fields.Many2one( - string="Availability Day", - help="", - store=True, - comodel_name="pms.availability", - ondelete="restrict", - compute="_compute_avail_id", - check_pms_properties=True, - ) - - discount = fields.Float( - string="Discount (%)", - help="", - default=0.0, - digits=("Discount"), - ) - occupies_availability = fields.Boolean( - string="Occupies", - help="This record is taken into account to calculate availability", - store=True, - compute="_compute_occupies_availability", - ) - impacts_quota = fields.Integer( - string="Impacts quota", - help="This line has been taken into account in the avail quota", - readonly=True, - store=True, - compute="_compute_impacts_quota", - ) - overnight_room = fields.Boolean( - related="reservation_id.overnight_room", - store=True, - ) - _sql_constraints = [ - ( - "rule_availability", - "EXCLUDE (room_id WITH =, date WITH =) \ - WHERE (occupies_availability = True)", - "Room Occupied", - ), - ] - - def name_get(self): - result = [] - for res in self: - date = fields.Date.from_string(res.date) - name = u"{}/{}".format(date.day, date.month) - result.append((res.id, name)) - return result - - def _get_display_price(self, product): - if self.reservation_id.pricelist_id.discount_policy == "with_discount": - return product.with_context( - pricelist=self.reservation_id.pricelist_id.id - ).price - product_context = dict( - self.env.context, - partner_id=self.reservation_id.partner_id.id, - date=self.date, - uom=product.uom_id.id, - ) - final_price, rule_id = self.reservation_id.pricelist_id.with_context( - product_context - ).get_product_price_rule(product, 1.0, self.reservation_id.partner_id) - base_price, currency = self.with_context( - product_context - )._get_real_price_currency( - product, rule_id, 1, product.uom_id, self.reservation_id.pricelist_id.id - ) - if currency != self.reservation_id.pricelist_id.currency_id: - base_price = currency._convert( - base_price, - self.reservation_id.pricelist_id.currency_id, - self.reservation_id.company_id or self.env.company, - fields.Date.today(), - ) - # negative discounts (= surcharge) are included in the display price - return max(base_price, final_price) - - @api.depends("reservation_id.room_type_id", "reservation_id.preferred_room_id") - def _compute_room_id(self): - for line in self.filtered("reservation_id.room_type_id").sorted( - key=lambda r: (r.reservation_id, r.date) - ): - reservation = line.reservation_id - if ( - reservation.preferred_room_id - and reservation.preferred_room_id != line.room_id - ) or ( - (reservation.preferred_room_id or reservation.room_type_id) - and not line.room_id - ): - free_room_select = True if reservation.preferred_room_id else False - - # we get the rooms available for the entire stay - # (real_avail if True if the reservation was created with - # specific room selected) - pms_property = line.pms_property_id - pms_property = pms_property.with_context( - checkin=reservation.checkin, - checkout=reservation.checkout, - room_type_id=reservation.room_type_id.id - if not free_room_select - else False, - current_lines=reservation.reservation_line_ids.ids, - pricelist_id=reservation.pricelist_id.id, - real_avail=free_room_select, - ) - rooms_available = pms_property.free_room_ids - - # Check if the room assigment is manual or automatic to set the - # to_assign value on reservation - manual_assigned = False - if ( - free_room_select - and reservation.preferred_room_id.id - not in reservation.reservation_line_ids.room_id.ids - ): - # This case is a preferred_room_id manually assigned - manual_assigned = True - # if there is availability for the entire stay - if rooms_available: - # Avoid that reservation._compute_splitted set the - # reservation like splitted in intermediate calculations - reservation = reservation.with_context(not_split=True) - # if the reservation has a preferred room - if reservation.preferred_room_id: - - # if the preferred room is available - if reservation.preferred_room_id in rooms_available: - line.room_id = reservation.preferred_room_id - reservation.to_assign = ( - False if manual_assigned else reservation.to_assign - ) - - # if the preferred room is NOT available - else: - if self.env.context.get("force_overbooking"): - reservation.overbooking = True - line.room_id = reservation.preferred_room_id - else: - raise ValidationError( - _("%s: No room available in %s <-> %s.") - % ( - reservation.preferred_room_id.name, - reservation.checkin, - reservation.checkout, - ) - ) - - # otherwise we assign the first of those - # available for the entire stay - else: - line.room_id = rooms_available[0] - # check that the reservation cannot be allocated even by dividing it - elif not self.env["pms.property"].splitted_availability( - checkin=reservation.checkin, - checkout=reservation.checkout, - room_type_id=reservation.room_type_id.id, - current_lines=line._origin.reservation_id.reservation_line_ids.ids, - pricelist=reservation.pricelist_id, - pms_property_id=line.pms_property_id.id, - ): - if self.env.context.get("force_overbooking"): - reservation.overbooking = True - line.room_id = reservation.room_type_id.room_ids[0] - else: - raise ValidationError( - _("%s: No room type available") - % (reservation.room_type_id.name) - ) - - # the reservation can be allocated into several rooms - else: - rooms_ranking = dict() - - # we go through the rooms of the type - for room in self.env["pms.room"].search( - [ - ("room_type_id", "=", reservation.room_type_id.id), - ("pms_property_id", "=", reservation.pms_property_id.id), - ] - ): - # we iterate the dates from the date of the line to the checkout - for date_iterator in [ - line.date + datetime.timedelta(days=x) - for x in range(0, (reservation.checkout - line.date).days) - ]: - # if the room is already assigned for - # a date we go to the next room - ids = reservation.reservation_line_ids.ids - if ( - self.env["pms.reservation.line"].search_count( - [ - ("date", "=", date_iterator), - ("room_id", "=", room.id), - ("id", "not in", ids), - ("occupies_availability", "=", True), - ] - ) - > 0 - ): - break - # if the room is not assigned for a date we - # add it to the ranking / update its ranking - else: - rooms_ranking[room.id] = ( - 1 - if room.id not in rooms_ranking - else rooms_ranking[room.id] + 1 - ) - - if len(rooms_ranking) > 0: - # we get the best score in the ranking - best = max(rooms_ranking.values()) - - # we keep the rooms with the best ranking - bests = { - key: value - for (key, value) in rooms_ranking.items() - if value == best - } - - # if there is a tie in the rankings - if len(bests) > 1: - - # we get the line from last night - date_last_night = line.date + datetime.timedelta(days=-1) - line_past_night = self.env["pms.reservation.line"].search( - [ - ("date", "=", date_last_night), - ("reservation_id", "=", reservation.id), - ] - ) - # if there is the night before and if the room - # from the night before is in the ranking - if line_past_night and line_past_night.room_id.id in bests: - line.room_id = line_past_night.room_id.id - - # if the room from the night before is not in the ranking - # or there is no night before - else: - # At this point we set the room with the best ranking, - # no matter what it is - line.room_id = list(bests.keys())[0] - - # if there is no tie in the rankings - else: - # At this point we set the room with the best ranking, - # no matter what it is - line.room_id = list(bests.keys())[0] - - @api.depends("reservation_id.room_type_id", "reservation_id.pricelist_id") - def _compute_impacts_quota(self): - for line in self: - reservation = line.reservation_id - if isinstance(line.id, int): - impacts_quota = False - else: - impacts_quota = line.impacts_quota - line.impacts_quota = self.env["pms.availability.plan"].update_quota( - pricelist_id=reservation.pricelist_id, - room_type_id=reservation.room_type_id, - date=line.date, - impacts_quota_id=impacts_quota, - ) - - @api.depends( - "reservation_id", - "reservation_id.room_type_id", - "reservation_id.reservation_type", - "reservation_id.pms_property_id", - ) - def _compute_price(self): - for line in self: - reservation = line.reservation_id - if ( - not reservation.room_type_id - or not reservation.pricelist_id - or not reservation.pms_property_id - or reservation.reservation_type != "normal" - ): - line.price = 0 - elif not line.price or self._context.get("force_recompute"): - room_type_id = reservation.room_type_id.id - product = self.env["pms.room.type"].browse(room_type_id).product_id - partner = self.env["res.partner"].browse(reservation.partner_id.id) - product = product.with_context( - lang=partner.lang, - partner=partner.id, - quantity=1, - date=reservation.date_order, - consumption_date=line.date, - pricelist=reservation.pricelist_id.id, - uom=product.uom_id.id, - property=reservation.pms_property_id.id, - ) - line.price = self.env["account.tax"]._fix_tax_included_price_company( - line._get_display_price(product), - product.taxes_id, - reservation.tax_ids, - reservation.company_id, - ) - # TODO: Out of service 0 amount - - @api.depends("reservation_id.state", "reservation_id.overbooking") - def _compute_occupies_availability(self): - for line in self: - if line.reservation_id.state == "cancel" or line.reservation_id.overbooking: - line.occupies_availability = False - else: - line.occupies_availability = True - - # TODO: Refact method and allowed cancelled single days - @api.depends("reservation_id.cancelled_reason") - def _compute_cancel_discount(self): - for line in self: - line.cancel_discount = 0 - reservation = line.reservation_id - pricelist = reservation.pricelist_id - if reservation.state == "cancel": - if ( - reservation.cancelled_reason - and pricelist - and pricelist.cancelation_rule_id - ): - checkin = fields.Date.from_string(reservation.checkin) - checkout = fields.Date.from_string(reservation.checkout) - days = abs((checkin - checkout).days) - rule = pricelist.cancelation_rule_id - discount = 0 - if reservation.cancelled_reason == "late": - discount = 100 - rule.penalty_late - if rule.apply_on_late == "first": - days = 1 - elif rule.apply_on_late == "days": - days = rule.days_late - elif reservation.cancelled_reason == "noshow": - discount = 100 - rule.penalty_noshow - if rule.apply_on_noshow == "first": - days = 1 - elif rule.apply_on_noshow == "days": - days = rule.days_late - 1 - elif reservation.cancelled_reason == "intime": - discount = 100 - - dates = [] - for i in range(0, days): - dates.append( - fields.Date.from_string( - fields.Date.from_string(checkin) - + datetime.timedelta(days=i) - ) - ) - reservation.reservation_line_ids.filtered( - lambda r: r.date in dates - ).update({"cancel_discount": discount}) - reservation.reservation_line_ids.filtered( - lambda r: r.date not in dates - ).update({"cancel_discount": 100}) - else: - reservation.reservation_line_ids.update({"cancel_discount": 0}) - else: - reservation.reservation_line_ids.update({"cancel_discount": 0}) - - @api.depends("room_id", "pms_property_id", "date", "occupies_availability") - def _compute_avail_id(self): - for record in self: - if record.room_id.room_type_id and record.date and record.pms_property_id: - avail = self.env["pms.availability"].search( - [ - ("date", "=", record.date), - ("room_type_id", "=", record.room_id.room_type_id.id), - ("pms_property_id", "=", record.pms_property_id.id), - ] - ) - if avail: - record.avail_id = avail.id - else: - record.avail_id = self.env["pms.availability"].create( - { - "date": record.date, - "room_type_id": record.room_id.room_type_id.id, - "pms_property_id": record.pms_property_id.id, - } - ) - else: - record.avail_id = False - - # Constraints and onchanges - @api.constrains("date") - def constrains_duplicated_date(self): - for record in self: - duplicated = record.reservation_id.reservation_line_ids.filtered( - lambda r: r.date == record.date and r.id != record.id - ) - if duplicated: - raise ValidationError(_("Duplicated reservation line date")) diff --git a/pms/models/pms_room.py b/pms/models/pms_room.py deleted file mode 100644 index 0c03d5cc7..000000000 --- a/pms/models/pms_room.py +++ /dev/null @@ -1,185 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# Copyright 2018 Pablo Quesada -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsRoom(models.Model): - """The rooms for lodging can be for sleeping, usually called rooms, - and also for speeches (conference rooms), parking, - relax with cafe con leche, spa... - """ - - _name = "pms.room" - _description = "Property Room" - _order = "sequence, room_type_id, name" - _check_pms_properties_auto = True - - name = fields.Char( - string="Room Name", - help="Room Name", - required=True, - ) - active = fields.Boolean( - string="Active", help="Determines if room is active", default=True - ) - sequence = fields.Integer( - string="Sequence", - help="Field used to change the position of the rooms in tree view." - "Changing the position changes the sequence", - default=0, - ) - pms_property_id = fields.Many2one( - string="Property", - help="Properties with access to the element;" - " if not set, all properties can access", - required=True, - default=lambda self: self.env.user.get_active_property_ids()[0], - comodel_name="pms.property", - ondelete="restrict", - ) - room_type_id = fields.Many2one( - string="Property Room Type", - help="Unique room type for the rooms", - required=True, - comodel_name="pms.room.type", - ondelete="restrict", - check_pms_properties=True, - ) - parent_id = fields.Many2one( - string="Parent Room", - help="Indicates that this room is a child of another room", - comodel_name="pms.room", - ondelete="restrict", - check_pms_properties=True, - ) - child_ids = fields.One2many( - string="Child Rooms", - help="Child rooms of the room", - comodel_name="pms.room", - inverse_name="parent_id", - check_pms_properties=True, - ) - ubication_id = fields.Many2one( - string="Ubication", - help="At which ubication the room is located.", - comodel_name="pms.ubication", - check_pms_properties=True, - ) - capacity = fields.Integer( - string="Capacity", help="The maximum number of people that can occupy a room" - ) - extra_beds_allowed = fields.Integer( - string="Extra Beds Allowed", - help="Number of extra beds allowed in room", - required=True, - default="0", - ) - room_amenity_ids = fields.Many2many( - string="Room Amenities", - help="List of amenities included in room", - comodel_name="pms.amenity", - relation="pms_room_amenity_rel", - column1="room_id", - column2="amenity_id", - check_pms_properties=True, - ) - is_shared_room = fields.Boolean( - string="Is a Shared Room", - help="allows you to reserve units " " smaller than the room itself (eg beds)", - compute="_compute_is_shared_room", - readonly=False, - store=True, - ) - description_sale = fields.Text( - string="Sale Description", - help="A description of the Product that you want to communicate to " - " your customers. This description will be copied to every Sales " - " Order, Delivery Order and Customer Invoice/Credit Note", - translate=True, - ) - - _sql_constraints = [ - ( - "room_property_unique", - "unique(name, pms_property_id)", - "you cannot have more than one room " - "with the same name in the same property", - ) - ] - - @api.depends("child_ids") - def _compute_is_shared_room(self): - for record in self: - if record.child_ids: - record.is_shared_room = True - elif not record.is_shared_room: - record.is_shared_room = False - - def name_get(self): - result = [] - for room in self: - name = room.name - if room.room_type_id: - name += " [%s]" % room.room_type_id.default_code - if room.room_amenity_ids: - for amenity in room.room_amenity_ids: - if amenity.is_add_code_room_name: - name += " %s" % amenity.default_code - result.append((room.id, name)) - return result - - # Constraints and onchanges - @api.constrains("capacity") - def _check_capacity(self): - for record in self: - if record.capacity < 1: - raise ValidationError( - _( - "The capacity of the \ - room must be greater than 0." - ) - ) - - @api.constrains("is_shared_room") - def _check_shared_room(self): - for record in self: - if record.is_shared_room and not record.child_ids: - raise ValidationError( - _( - "The reservation units are required \ - on shared rooms." - ) - ) - - @api.model - def _check_adults(self, reservation, service_line_ids=False): - for line in reservation.reservation_line_ids: - num_extra_beds = 0 - if service_line_ids: - extra_beds = service_line_ids.filtered( - lambda x: x.date == line.date and x.product_id.is_extra_bed is True - ) - num_extra_beds = sum(extra_beds.mapped("day_qty")) if extra_beds else 0 - if line.room_id: - if ( - reservation.adults + reservation.children_occupying - ) > line.room_id.get_capacity(num_extra_beds): - raise ValidationError( - _( - "Persons can't be higher than room capacity (%s)", - reservation.name, - ) - ) - - # Business methods - - def get_capacity(self, extra_bed=0): - for record in self: - if extra_bed > record.extra_beds_allowed: - raise ValidationError( - _("Extra beds can't be greater than allowed beds for this room") - ) - return record.capacity + extra_bed diff --git a/pms/models/pms_room_closure_reason.py b/pms/models/pms_room_closure_reason.py deleted file mode 100644 index a1135c623..000000000 --- a/pms/models/pms_room_closure_reason.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class RoomClosureReason(models.Model): - _name = "room.closure.reason" - _description = "Cause of out of service" - - name = fields.Char( - string="Name", - help="The name that identifies the room closure reason", - required=True, - translate=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="pms_room_closure_reason_pms_property_rel", - column1="room_closure_reason_type_id", - column2="pms_property_id", - ondelete="restrict", - ) - description = fields.Text( - string="Description", - help="Explanation of the reason for closing a room", - translate=True, - ) diff --git a/pms/models/pms_room_type.py b/pms/models/pms_room_type.py deleted file mode 100644 index b97cb1fa1..000000000 --- a/pms/models/pms_room_type.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsRoomType(models.Model): - """Before creating a 'room type', you need to consider the following: - With the term 'room type' is meant a sales type of residential accommodation: for - example, a Double Room, a Economic Room, an Apartment, a Tent, a Caravan... - """ - - _name = "pms.room.type" - _description = "Room Type" - _inherits = {"product.product": "product_id"} - _order = "sequence,default_code,name" - _check_pms_properties_auto = True - - sequence = fields.Integer( - string="Sequence", - help="Field used to change the position of the room types in tree view.", - default=0, - ) - product_id = fields.Many2one( - string="Product Room Type", - help="Product identifier associated with room type", - comodel_name="product.product", - required=True, - delegate=True, - ondelete="cascade", - ) - room_ids = fields.One2many( - string="Rooms", - help="Rooms that belong to room type.", - comodel_name="pms.room", - inverse_name="room_type_id", - check_pms_properties=True, - ) - class_id = fields.Many2one( - string="Property Type Class", - help="Class to which the room type belongs", - comodel_name="pms.room.type.class", - required=True, - check_pms_properties=True, - ) - board_service_room_type_ids = fields.One2many( - string="Board Services", - help="Board Service included in room type", - comodel_name="pms.board.service.room.type", - inverse_name="pms_room_type_id", - check_pms_properties=True, - ) - room_amenity_ids = fields.Many2many( - string="Room Type Amenities", - help="List of amenities included in room type", - comodel_name="pms.amenity", - relation="pms_room_type_amenity_rel", - column1="room_type_id", - column2="amenity_id", - check_pms_properties=True, - ) - default_code = fields.Char( - string="Code", - help="Identification code for a room type", - required=True, - ) - total_rooms_count = fields.Integer( - string="Total Rooms Count", - help="The number of rooms in a room type", - compute="_compute_total_rooms_count", - store=True, - ) - default_max_avail = fields.Integer( - string="Default Max. Availability", - help="Maximum simultaneous availability on own Booking Engine " - "given no availability rules. " - "Use `-1` for using maximum simultaneous availability.", - default=-1, - ) - default_quota = fields.Integer( - string="Default Quota", - help="Quota assigned to the own Booking Engine given no availability rules. " - "Use `-1` for managing no quota.", - default=-1, - ) - overnight_room = fields.Boolean( - related="class_id.overnight", - store=True, - ) - - def name_get(self): - result = [] - for room_type in self: - name = room_type.name - if self._context.get("checkin") and self._context.get("checkout"): - pms_property = self.env["pms.property"].browse( - self._context.get("pms_property_id") - ) - pms_property = pms_property.with_context( - checkin=self._context.get("checkin"), - checkout=self._context.get("checkout"), - room_type_id=room_type.id, - pricelist_id=self._context.get("pricelist_id") or False, - ) - avail = pms_property.availability - name += " (%s)" % avail - result.append((room_type.id, name)) - return result - - @api.depends("room_ids", "room_ids.active") - def _compute_total_rooms_count(self): - for record in self: - record.total_rooms_count = len(record.room_ids) - - @api.model - def get_room_types_by_property(self, pms_property_id, default_code=None): - """ - :param pms_property_id: property ID - :param default_code: room type code (optional) - :return: - recordset of - - all the pms.room.type of the pms_property_id - if default_code not defined - - one or 0 pms.room.type if default_code defined - - ValidationError if more than one default_code found by - the same pms_property_id - """ - domain = [] - if default_code: - domain += ["&", ("default_code", "=", default_code)] - company_id = self.env["pms.property"].browse(pms_property_id).company_id.id - domain += [ - "|", - ("pms_property_ids", "in", pms_property_id), - "|", - "&", - ("pms_property_ids", "=", False), - ("company_id", "=", company_id), - "&", - ("pms_property_ids", "=", False), - ("company_id", "=", False), - ] - records = self.search(domain) - res, res_priority = {}, {} - for rec in records: - res_priority.setdefault(rec.default_code, -1) - priority = (rec.pms_property_ids and 2) or (rec.company_id and 1 or 0) - if priority > res_priority[rec.default_code]: - res.setdefault(rec.default_code, rec.id) - res[rec.default_code], res_priority[rec.default_code] = rec.id, priority - elif priority == res_priority[rec.default_code]: - raise ValidationError( - _( - "Integrity error: There's multiple room types " - "with the same code %s and properties" - ) - % rec.default_code - ) - return self.browse(list(res.values())) - - @api.constrains("default_code", "pms_property_ids", "company_id") - def _check_code_property_company_uniqueness(self): - msg = _("Already exists another room type with the same code and properties") - for rec in self: - if not rec.pms_property_ids: - if self.search( - [ - ("id", "!=", rec.id), - ("default_code", "=", rec.default_code), - ("pms_property_ids", "=", False), - ("company_id", "=", rec.company_id.id), - ] - ): - raise ValidationError(msg) - else: - for pms_property in rec.pms_property_ids: - other = rec.get_room_types_by_property( - pms_property.id, rec.default_code - ) - if other and other != rec: - raise ValidationError(msg) - - # ORM Overrides - # TODO: Review Check product fields default values to room - @api.model - def create(self, vals): - """ Add room types as not purchase services. """ - vals.update( - { - "purchase_ok": False, - "sale_ok": False, - "type": "service", - } - ) - return super().create(vals) - - # def unlink(self): - # for record in self: - # record.product_id.unlink() - # return super().unlink() - - def get_capacity(self): - self.ensure_one() - capacities = self.room_ids.mapped("capacity") - return min(capacities) if any(capacities) else 0 diff --git a/pms/models/pms_room_type_class.py b/pms/models/pms_room_type_class.py deleted file mode 100644 index 6c4a07e65..000000000 --- a/pms/models/pms_room_type_class.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsRoomTypeClass(models.Model): - """Before creating a 'room type_class', you need to consider the following: - With the term 'room type class' is meant a physical class of - residential accommodation: for example, a Room, a Bed, an Apartment, - a Tent, a Caravan... - """ - - _name = "pms.room.type.class" - _description = "Room Type Class" - _order = "sequence, name, default_code" - _check_pms_properties_auto = True - - name = fields.Char( - string="Class Name", - help="Name of the room type class", - required=True, - translate=True, - ) - active = fields.Boolean( - string="Active", - help="If unchecked, it will allow you to hide the room type", - default=True, - ) - sequence = fields.Integer( - string="Sequence", - help="Field used to change the position of the room type classes in tree view.", - default=0, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="pms_room_type_class_property_rel", - column1="room_type_class_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - room_type_ids = fields.One2many( - string="Types", - help="Room Types that belong to this Room Type Class", - comodel_name="pms.room.type", - inverse_name="class_id", - check_pms_properties=True, - ) - default_code = fields.Char( - string="Code", - help="Room type class identification code", - required=True, - ) - overnight = fields.Boolean( - string="Use for overnight stays", - help="Set False if if these types of spaces are not used for overnight stays", - default=True, - ) - - @api.model - def get_unique_by_property_code(self, pms_property_id, default_code=None): - """ - :param pms_property_id: property ID - :param default_code: room type code (optional) - :return: - recordset of - - all the pms.room.type.class of the pms_property_id - if default_code not defined - - one or 0 pms.room.type.class if default_code defined - - ValidationError if more than one default_code found by - the same pms_property_id - """ - # TODO: similiar code as room.type -> unify - domain = [] - if default_code: - domain += ["&", ("default_code", "=", default_code)] - domain += [ - "|", - ("pms_property_ids", "in", pms_property_id), - ("pms_property_ids", "=", False), - ] - records = self.search(domain) - res, res_priority = {}, {} - for rec in records: - res_priority.setdefault(rec.default_code, -1) - priority = rec.pms_property_ids and 1 or 0 - if priority > res_priority[rec.default_code]: - res.setdefault(rec.default_code, rec.id) - res[rec.default_code], res_priority[rec.default_code] = rec.id, priority - elif priority == res_priority[rec.default_code]: - raise ValidationError( - _( - "Integrity error: There's multiple room types " - "with the same code %s and properties" - ) - % rec.default_code - ) - return self.browse(list(res.values())) - - @api.constrains("default_code", "pms_property_ids") - def _check_code_property_uniqueness(self): - # TODO: similiar code as room.type -> unify - msg = _( - "Already exists another room type class with the same code and properties" - ) - for rec in self: - if not rec.pms_property_ids: - if self.search( - [ - ("id", "!=", rec.id), - ("default_code", "=", rec.default_code), - ("pms_property_ids", "=", False), - ] - ): - raise ValidationError(msg) - else: - for pms_property in rec.pms_property_ids: - other = rec.get_unique_by_property_code( - pms_property.id, rec.default_code - ) - if other and other != rec: - raise ValidationError(msg) diff --git a/pms/models/pms_sale_channel.py b/pms/models/pms_sale_channel.py deleted file mode 100644 index 1f60daab1..000000000 --- a/pms/models/pms_sale_channel.py +++ /dev/null @@ -1,40 +0,0 @@ -from odoo import fields, models - - -class PmsSaleChannel(models.Model): - _name = "pms.sale.channel" - _description = "Sales Channel" - _check_pms_properties_auto = True - - name = fields.Text(string="Sale Channel Name", help="The name of the sale channel") - channel_type = fields.Selection( - string="Sale Channel Type", - help="Type of sale channel; it can be 'direct'(if there is" - "no intermediary) or 'indirect'(if there are" - "intermediaries between partner and property", - selection=[("direct", "Direct"), ("indirect", "Indirect")], - ) - is_on_line = fields.Boolean( - string="On Line", help="Indicates if the sale channel is on-line" - ) - product_pricelist_ids = fields.Many2many( - string="Pricelists", - help="Pricelists for a sale channel", - comodel_name="product.pricelist", - relation="pms_sale_channel_product_pricelist_rel", - column1="pms_sale_channel_id", - column2="product_pricelist_id", - check_pms_properties=True, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - ondelete="restrict", - comodel_name="pms.property", - relation="pms_sale_channel_pms_property_rel", - column1="pms_sale_channel_id", - column2="pms_property_id", - check_pms_properties=True, - ) diff --git a/pms/models/pms_service.py b/pms/models/pms_service.py deleted file mode 100644 index d52c73f92..000000000 --- a/pms/models/pms_service.py +++ /dev/null @@ -1,590 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import logging -from datetime import timedelta - -from odoo import _, api, fields, models - -_logger = logging.getLogger(__name__) - - -class PmsService(models.Model): - _name = "pms.service" - _description = "Services and its charges" - _check_pms_properties_auto = True - - name = fields.Char( - string="Service description", - help="Service description", - readonly=False, - store=True, - compute="_compute_name", - ) - product_id = fields.Many2one( - string="Service", - help="Product associated with this service", - required=True, - comodel_name="product.product", - ondelete="restrict", - check_pms_properties=True, - ) - folio_id = fields.Many2one( - string="Folio", - help="Folio in which the service is included", - readonly=False, - store=True, - comodel_name="pms.folio", - compute="_compute_folio_id", - check_pms_properties=True, - ) - sale_line_ids = fields.One2many( - string="Sale Lines", - help="", - copy=False, - comodel_name="folio.sale.line", - inverse_name="service_id", - check_pms_properties=True, - ) - reservation_id = fields.Many2one( - string="Room", - help="Reservation in which the service is included", - default=lambda self: self._default_reservation_id(), - comodel_name="pms.reservation", - ondelete="cascade", - check_pms_properties=True, - ) - service_line_ids = fields.One2many( - string="Service Lines", - help="Subservices included in this service", - readonly=False, - store=True, - comodel_name="pms.service.line", - inverse_name="service_id", - compute="_compute_service_line_ids", - check_pms_properties=True, - ) - company_id = fields.Many2one( - string="Company", - help="Company to which the service belongs", - readonly=True, - store=True, - related="folio_id.company_id", - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property to which the service belongs", - readonly=True, - store=True, - comodel_name="pms.property", - related="folio_id.pms_property_id", - check_pms_properties=True, - ) - tax_ids = fields.Many2many( - string="Taxes", - help="Taxes applied in the service", - readonly=False, - store=True, - comodel_name="account.tax", - domain=["|", ("active", "=", False), ("active", "=", True)], - compute="_compute_tax_ids", - ) - analytic_tag_ids = fields.Many2many( - string="Analytic Tags", - help="", - comodel_name="account.analytic.tag", - ) - currency_id = fields.Many2one( - string="Currency", - help="The currency used in relation to the folio", - readonly=True, - store=True, - related="folio_id.currency_id", - ) - sequence = fields.Integer(string="Sequence", help="", default=10) - state = fields.Selection( - string="State", - help="Service status, it corresponds with folio status", - related="folio_id.state", - ) - per_day = fields.Boolean( - string="Per Day", - help="Indicates if service is sold by days", - related="product_id.per_day", - related_sudo=True, - ) - product_qty = fields.Integer( - string="Quantity", - help="Number of services that were sold", - readonly=False, - store=True, - compute="_compute_product_qty", - ) - is_board_service = fields.Boolean( - string="Is Board Service", - help="Indicates if the service is part of a board service", - ) - # Non-stored related field to allow portal user to - # see the image of the product he has ordered - product_image = fields.Binary( - string="Product Image", - help="Image of the service", - store=False, - related="product_id.image_1024", - related_sudo=True, - ) - invoice_status = fields.Selection( - string="Invoice Status", - help="State in which the service is with respect to invoices." - "It can be 'invoiced', 'to_invoice' or 'no'", - readonly=True, - default="no", - store=True, - compute="_compute_invoice_status", - selection=[ - ("invoiced", "Fully Invoiced"), - ("to_invoice", "To Invoice"), - ("no", "Nothing to Invoice"), - ], - ) - channel_type = fields.Selection( - string="Sales Channel", - help="sales channel through which the service was sold." - "It can be 'door', 'mail', 'phone', 'call' or 'web'", - selection=[ - ("door", "Door"), - ("mail", "Mail"), - ("phone", "Phone"), - ("call", "Call Center"), - ("web", "Web"), - ], - ) - price_subtotal = fields.Monetary( - string="Subtotal", - help="Subtotal price without taxes", - readonly=True, - store=True, - compute="_compute_amount_service", - ) - price_total = fields.Monetary( - string="Total", - help="Total price with taxes", - readonly=True, - store=True, - compute="_compute_amount_service", - ) - price_tax = fields.Float( - string="Taxes Amount", - help="Total of taxes in service", - readonly=True, - store=True, - compute="_compute_amount_service", - ) - - discount = fields.Float( - string="Discount (€)", - help="Discount of total price", - readonly=False, - store=True, - digits=("Discount"), - compute="_compute_discount", - ) - - # Compute and Search methods - @api.depends("product_id") - def _compute_tax_ids(self): - for service in self: - service.tax_ids = service.product_id.taxes_id.filtered( - lambda r: not service.company_id or r.company_id == service.company_id - ) - - @api.depends("service_line_ids", "service_line_ids.day_qty") - def _compute_product_qty(self): - self.product_qty = 0 - for service in self.filtered("service_line_ids"): - qty = sum(service.service_line_ids.mapped("day_qty")) - service.product_qty = qty - - @api.depends("reservation_id", "reservation_id.folio_id") - def _compute_folio_id(self): - for record in self: - if record.reservation_id: - record.folio_id = record.reservation_id.folio_id - elif not record.folio_id: - record.folio_id = False - - @api.depends( - "sale_line_ids", - "sale_line_ids.invoice_status", - ) - def _compute_invoice_status(self): - """ - Compute the invoice status of a Reservation. Possible statuses: - Base on folio sale line invoice status - """ - for line in self: - states = list(set(line.sale_line_ids.mapped("invoice_status"))) - if len(states) == 1: - line.invoice_status = states[0] - elif len(states) >= 1: - if "to_invoice" in states: - line.invoice_status = "to_invoice" - elif "invoiced" in states: - line.invoice_status = "invoiced" - else: - line.invoice_status = "no" - else: - line.invoice_status = "no" - - @api.depends("service_line_ids.price_day_total") - def _compute_amount_service(self): - for service in self: - if service.service_line_ids: - service.update( - { - "price_tax": sum( - service.service_line_ids.mapped("price_day_tax") - ), - "price_total": sum( - service.service_line_ids.mapped("price_day_total") - ), - "price_subtotal": sum( - service.service_line_ids.mapped("price_day_subtotal") - ), - } - ) - else: - service.update( - { - "price_tax": 0, - "price_total": 0, - "price_subtotal": 0, - } - ) - - @api.depends("product_id") - def _compute_name(self): - self.name = False - for service in self.filtered("product_id"): - product = service.product_id.with_context( - lang=service.folio_id.partner_id.lang, - partner=service.folio_id.partner_id.id, - ) - title = False - message = False - warning = {} - if product.sale_line_warn != "no-message": - title = _("Warning for %s") % product.name - message = product.sale_line_warn_msg - warning["title"] = title - warning["message"] = message - result = {"warning": warning} - if product.sale_line_warn == "block": - self.product_id = False - return result - name = product.name_get()[0][1] - if product.description_sale: - name += "\n" + product.description_sale - service.name = name - - @api.depends( - "reservation_id.checkin", - "reservation_id.checkout", - "product_id", - "reservation_id.adults", - ) - def _compute_service_line_ids(self): - for service in self: - if service.product_id: - day_qty = 1 - if service.reservation_id and service.product_id: - reservation = service.reservation_id - # REVIEW: review method dependencies, reservation_line_ids - # instead of checkin/checkout - if not reservation.checkin or not reservation.checkout: - if not service.service_line_ids: - service.service_line_ids = False - continue - product = service.product_id - consumed_on = product.consumed_on - if product.per_day: - lines = [] - day_qty = service._service_day_qty() - days_diff = (reservation.checkout - reservation.checkin).days - for i in range(0, days_diff): - if consumed_on == "after": - i += 1 - idate = reservation.checkin + timedelta(days=i) - old_line = service.service_line_ids.filtered( - lambda r: r.date == idate - ) - price_unit = service._get_price_unit_line(idate) - if old_line and old_line.auto_qty: - lines.append( - ( - 1, - old_line.id, - { - "day_qty": day_qty, - "auto_qty": True, - }, - ) - ) - elif not old_line: - lines.append( - ( - 0, - False, - { - "date": idate, - "day_qty": day_qty, - "auto_qty": True, - "price_unit": price_unit, - }, - ) - ) - move_day = 0 - if consumed_on == "after": - move_day = 1 - for del_service_id in service.service_line_ids.filtered_domain( - [ - "|", - ( - "date", - "<", - reservation.checkin + timedelta(move_day), - ), - ( - "date", - ">=", - reservation.checkout + timedelta(move_day), - ), - ] - ).ids: - lines.append((2, del_service_id)) - # TODO: check intermediate states in check_adults restriction - # when lines are removed - service.service_line_ids = lines - else: - if not service.service_line_ids: - price_unit = service._get_price_unit_line() - service.service_line_ids = [ - ( - 0, - False, - { - "date": fields.Date.today(), - "day_qty": day_qty, - "price_unit": price_unit, - }, - ) - ] - else: - if not service.service_line_ids: - price_unit = service._get_price_unit_line() - service.service_line_ids = [ - ( - 0, - False, - { - "date": fields.Date.today(), - "day_qty": day_qty, - "price_unit": price_unit, - }, - ) - ] - else: - service.service_line_ids = False - - @api.depends("service_line_ids.cancel_discount") - def _compute_discount(self): - for record in self: - discount = 0 - for line in record.service_line_ids: - first_discount = line.price_day_total * ((line.discount or 0.0) * 0.01) - price = line.price_day_total - first_discount - cancel_discount = price * ((line.cancel_discount or 0.0) * 0.01) - discount += first_discount + cancel_discount - record.discount = discount - - def name_get(self): - result = [] - for rec in self: - name = [] - name.append("{name}".format(name=rec.name)) - if rec.reservation_id.name: - name.append("{name}".format(name=rec.reservation_id.name)) - result.append((rec.id, ", ".join(name))) - return result - - @api.model - def _default_reservation_id(self): - if self.env.context.get("reservation_ids"): - ids = [item[1] for item in self.env.context["reservation_ids"]] - return self.env["pms.reservation"].browse([(ids)], limit=1) - elif self.env.context.get("default_reservation_id"): - return self.env.context.get("default_reservation_id") - return False - - # Action methods - def open_service_ids(self): - action = self.env.ref("pms.action_pms_services_form").sudo().read()[0] - action["views"] = [(self.env.ref("pms.pms_service_view_form").id, "form")] - action["res_id"] = self.id - action["target"] = "new" - return action - - # ORM Overrides - @api.model - def name_search(self, name="", args=None, operator="ilike", limit=100): - if args is None: - args = [] - if not (name == "" and operator == "ilike"): - args += [ - "|", - ("reservation_id.name", operator, name), - ("name", operator, name), - ] - return super(PmsService, self).name_search( - name="", args=args, operator="ilike", limit=limit - ) - - def _get_display_price(self, product): - folio = self.folio_id - reservation = self.reservation_id - origin = folio if folio else reservation - if origin.pricelist_id.discount_policy == "with_discount": - return product.price - final_price, rule_id = origin.pricelist_id.with_context( - product._context - ).get_product_price_rule(product, self.product_qty or 1.0, origin.partner_id) - base_price, currency_id = self.with_context( - product._context - )._get_real_price_currency( - product, - rule_id, - self.product_qty, - self.product_id.uom_id, - origin.pricelist_id.id, - ) - if currency_id != origin.pricelist_id.currency_id.id: - base_price = ( - self.env["res.currency"] - .browse(currency_id) - .with_context(product._context) - .compute(base_price, origin.pricelist_id.currency_id) - ) - # negative discounts (= surcharge) are included in the display price - return max(base_price, final_price) - - def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id): - """Retrieve the price before applying the pricelist - :param obj product: object of current product record - :parem float qty: total quantity of product - :param tuple price_and_rule: tuple(price, suitable_rule) - coming from pricelist computation - :param obj uom: unit of measure of current order line - :param integer pricelist_id: pricelist id of sales order""" - PricelistItem = self.env["product.pricelist.item"] - field_name = "lst_price" - currency_id = None - product_currency = product.currency_id - if rule_id: - pricelist_item = PricelistItem.browse(rule_id) - if pricelist_item.pricelist_id.discount_policy == "without_discount": - while ( - pricelist_item.base == "pricelist" - and pricelist_item.base_pricelist_id - and pricelist_item.base_pricelist_id.discount_policy - == "without_discount" - ): - price, rule_id = pricelist_item.base_pricelist_id.with_context( - uom=uom.id - ).get_product_price_rule(product, qty, self.order_id.partner_id) - pricelist_item = PricelistItem.browse(rule_id) - - if pricelist_item.base == "standard_price": - field_name = "standard_price" - product_currency = product.cost_currency_id - elif ( - pricelist_item.base == "pricelist" and pricelist_item.base_pricelist_id - ): - field_name = "price" - product = product.with_context( - pricelist=pricelist_item.base_pricelist_id.id - ) - product_currency = pricelist_item.base_pricelist_id.currency_id - currency_id = pricelist_item.pricelist_id.currency_id - - if not currency_id: - currency_id = product_currency - cur_factor = 1.0 - else: - if currency_id.id == product_currency.id: - cur_factor = 1.0 - else: - cur_factor = currency_id._get_conversion_rate( - product_currency, - currency_id, - self.company_id or self.env.company, - self.folio_id.date_order or fields.Date.today(), - ) - - product_uom = self.env.context.get("uom") or product.uom_id.id - if uom and uom.id != product_uom: - # the unit price is in a different uom - uom_factor = uom._compute_price(1.0, product.uom_id) - else: - uom_factor = 1.0 - - return product[field_name] * uom_factor * cur_factor, currency_id - - # Businness Methods - def _service_day_qty(self): - self.ensure_one() - qty = self.product_qty if len(self.service_line_ids) == 1 else 1 - if not self.reservation_id: - return qty - # TODO: Pass per_person to service line from product default_per_person - # When the user modifies the quantity avoid overwriting - if self.product_id.per_person: - qty = self.reservation_id.adults - return qty - - def _get_price_unit_line(self, date=False): - self.ensure_one() - if self.reservation_id.reservation_type == "normal": - folio = self.folio_id - reservation = self.reservation_id - origin = reservation if reservation else folio - if origin: - partner = origin.partner_id - pricelist = origin.pricelist_id - board_room_type = False - product_context = dict( - self.env.context, - lang=partner.lang, - partner=partner.id, - quantity=self.product_qty, - date=folio.date_order if folio else fields.Date.today(), - pricelist=pricelist.id, - board_service=board_room_type.id if board_room_type else False, - uom=self.product_id.uom_id.id, - fiscal_position=False, - property=self.reservation_id.pms_property_id.id, - ) - if date: - product_context["consumption_date"] = date - if reservation and self.is_board_service: - product_context[ - "board_service" - ] = reservation.board_service_room_id.id - product = self.product_id.with_context(product_context) - return self.env["account.tax"]._fix_tax_included_price_company( - self._get_display_price(product), - product.taxes_id, - self.tax_ids, - origin.company_id, - ) - else: - return 0 diff --git a/pms/models/pms_service_line.py b/pms/models/pms_service_line.py deleted file mode 100644 index 10ece7e8f..000000000 --- a/pms/models/pms_service_line.py +++ /dev/null @@ -1,249 +0,0 @@ -# Copyright 2017-2018 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import datetime - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsServiceLine(models.Model): - _name = "pms.service.line" - _description = "Service by day" - _order = "date" - _rec_name = "service_id" - _check_pms_properties_auto = True - - service_id = fields.Many2one( - string="Service Room", - help="Service identifier", - required=True, - copy=False, - comodel_name="pms.service", - ondelete="cascade", - ) - is_board_service = fields.Boolean( - string="Is Board Service", - help="Indicates if the service line is part of a board service", - store=True, - related="service_id.is_board_service", - ) - product_id = fields.Many2one( - string="Product", - help="Product associated with this service line", - store=True, - related="service_id.product_id", - check_pms_properties=True, - ) - tax_ids = fields.Many2many( - string="Taxes", - help="Taxes applied in the service line", - readonly="True", - comodel_name="account.tax", - related="service_id.tax_ids", - ) - pms_property_id = fields.Many2one( - string="Property", - help="Property to which the service belongs", - readonly=True, - store=True, - comodel_name="pms.property", - related="service_id.pms_property_id", - check_pms_properties=True, - ) - date = fields.Date( - string="Date", - help="Sate on which the product is to be consumed", - ) - day_qty = fields.Integer( - string="Units", - help="Amount to be consumed per day", - ) - price_unit = fields.Float( - string="Unit Price", - help="Price per unit of service", - digits=("Product Price"), - ) - price_day_subtotal = fields.Monetary( - string="Subtotal", - help="Subtotal price without taxes", - readonly=True, - store=True, - compute="_compute_day_amount_service", - ) - price_day_total = fields.Monetary( - string="Total", - help="Total price with taxes", - readonly=True, - store=True, - compute="_compute_day_amount_service", - ) - price_day_tax = fields.Float( - string="Taxes Amount", - help="", - readonly=True, - store=True, - compute="_compute_day_amount_service", - ) - currency_id = fields.Many2one( - string="Currency", - help="The currency used in relation to the service where it's included", - readonly=True, - store=True, - related="service_id.currency_id", - ) - reservation_id = fields.Many2one( - string="Reservation", - help="Room to which the services will be applied", - readonly=True, - store=True, - related="service_id.reservation_id", - check_pms_properties=True, - ) - discount = fields.Float( - string="Discount (%)", - help="Discount in the price of the service.", - readonly=False, - store=True, - default=0.0, - digits=("Discount"), - compute="_compute_discount", - ) - cancel_discount = fields.Float( - string="Cancelation Discount", - help="", - compute="_compute_cancel_discount", - readonly=True, - store=True, - ) - auto_qty = fields.Boolean( - string="Qty automated setted", - help="Show if the day qty was calculated automatically", - compute="_compute_auto_qty", - readonly=False, - store=True, - ) - - @api.depends("day_qty", "discount", "price_unit", "tax_ids") - def _compute_day_amount_service(self): - for line in self: - amount_service = line.price_unit - if amount_service > 0: - currency = line.service_id.currency_id - product = line.product_id - price = amount_service * (1 - (line.discount or 0.0) * 0.01) - # REVIEW: line.day_qty is not the total qty (the total is on service_id) - taxes = line.tax_ids.compute_all( - price, currency, line.day_qty, product=product - ) - line.update( - { - "price_day_tax": sum( - t.get("amount", 0.0) for t in taxes.get("taxes", []) - ), - "price_day_total": taxes["total_included"], - "price_day_subtotal": taxes["total_excluded"], - } - ) - else: - line.update( - { - "price_day_tax": 0, - "price_day_total": 0, - "price_day_subtotal": 0, - } - ) - - @api.depends("service_id.reservation_id", "service_id.reservation_id.discount") - def _compute_discount(self): - """ - On board service the line discount is always - equal to reservation line discount - """ - for record in self: - if record.is_board_service: - consumed_date = ( - record.date - if record.product_id.consumed_on == "before" - else record.date + datetime.timedelta(days=-1) - ) - record.discount = ( - record.service_id.reservation_id.reservation_line_ids.filtered( - lambda l: l.date == consumed_date - ).discount - ) - elif not record.discount: - record.discount = 0 - - # TODO: Refact method and allowed cancelled single days - @api.depends("service_id.reservation_id.reservation_line_ids.cancel_discount") - def _compute_cancel_discount(self): - for line in self: - line.cancel_discount = 0 - reservation = line.reservation_id - if reservation.state == "cancel": - if ( - reservation.cancelled_reason - and reservation.pricelist_id - and reservation.pricelist_id.cancelation_rule_id - and reservation.reservation_line_ids.mapped("cancel_discount") - ): - if line.is_board_service: - consumed_date = ( - line.date - if line.product_id.consumed_on == "before" - else line.date + datetime.timedelta(days=-1) - ) - line.cancel_discount = ( - reservation.reservation_line_ids.filtered( - lambda l: l.date == consumed_date - ).cancel_discount - ) - else: - line.cancel_discount = 100 - else: - line.cancel_discount = 0 - else: - line.cancel_discount = 0 - - @api.depends("day_qty") - def _compute_auto_qty(self): - """ - Set auto_qty = False if the service is no linked to room or - if the day_qty was set manually - (See autogeneration of service lines in - _compute_service_line_ids -pms.service-) - """ - self.auto_qty = False - - # Constraints and onchanges - @api.constrains("day_qty") - def no_free_resources(self): - for record in self: - limit = record.product_id.daily_limit - if limit > 0: - out_qty = sum( - self.env["pms.service.line"] - .search( - [ - ("product_id", "=", record.product_id.id), - ("date", "=", record.date), - ("service_id", "!=", record.service_id.id), - ] - ) - .mapped("day_qty") - ) - if limit < out_qty + record.day_qty: - raise ValidationError( - _("%s limit exceeded for %s") - % (record.service_id.product_id.name, record.date) - ) - - # Business methods - def _cancel_discount(self): - for record in self: - if record.reservation_id: - day = record.reservation_id.reservation_line_ids.filtered( - lambda d: d.date == record.date - ) - record.cancel_discount = day.cancel_discount diff --git a/pms/models/pms_ubication.py b/pms/models/pms_ubication.py deleted file mode 100644 index 5169eefcd..000000000 --- a/pms/models/pms_ubication.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class PmsUbication(models.Model): - _name = "pms.ubication" - _description = "Ubication" - _check_pms_properties_auto = True - - name = fields.Char( - string="Ubication Name", - help="Ubication Name", - required=True, - translate=True, - ) - sequence = fields.Integer( - string="Sequence", - help="Field used to change the position of the ubications in tree view." - "Changing the position changes the sequence", - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="pms_ubication_pms_property_rel", - column1="ubication_type_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - pms_room_ids = fields.One2many( - string="Rooms", - help="Rooms found in this location", - comodel_name="pms.room", - inverse_name="ubication_id", - check_pms_properties=True, - ) - - @api.constrains( - "pms_property_ids", - "pms_room_ids", - ) - def _check_property_integrity(self): - for rec in self: - if rec.pms_property_ids and rec.pms_room_ids: - if rec.pms_room_ids.pms_property_id not in rec.pms_property_ids: - raise ValidationError(_("Property not allowed")) diff --git a/pms/models/product_pricelist.py b/pms/models/product_pricelist.py deleted file mode 100644 index 0feb51de7..000000000 --- a/pms/models/product_pricelist.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright 2017 Alexandre Díaz, Pablo Quesada, Darío Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import logging - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - -_logger = logging.getLogger(__name__) - - -class ProductPricelist(models.Model): - """Before creating a 'daily' pricelist, you need to consider the following: - A pricelist marked as daily is used as a daily rate plan for room types and - therefore is related only with one property. - """ - - _inherit = "product.pricelist" - _check_pms_properties_auto = True - - # Fields declaration - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - comodel_name="pms.property", - relation="product_pricelist_pms_property_rel", - column1="product_pricelist_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - company_id = fields.Many2one( - string="Company", - help="Company to which the pricelist belongs", - check_pms_properties=True, - ) - cancelation_rule_id = fields.Many2one( - string="Cancelation Policy", - help="Cancelation Policy included in the room", - comodel_name="pms.cancelation.rule", - check_pms_properties=True, - ) - pricelist_type = fields.Selection( - string="Pricelist Type", - help="Pricelist types, it can be Daily Plan", - default="daily", - selection=[("daily", "Daily Plan")], - ) - pms_sale_channel_ids = fields.Many2many( - string="Available Channels", - help="Sale channel for which the pricelist is included", - comodel_name="pms.sale.channel", - check_pms_properties=True, - ) - availability_plan_id = fields.Many2one( - string="Availability Plan", - help="Availability Plan for which the pricelist is included", - comodel_name="pms.availability.plan", - ondelete="restrict", - check_pms_properties=True, - ) - item_ids = fields.One2many( - string="Items", - help="Items for which the pricelist is made up", - check_pms_properties=True, - ) - - def _compute_price_rule_get_items( - self, products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids - ): - board_service = True if self._context.get("board_service") else False - if ( - "property" in self._context - and self._context["property"] - and self._context.get("consumption_date") - ): - self.env.cr.execute( - """ - SELECT item.id - FROM product_pricelist_item item - LEFT JOIN product_category categ - ON item.categ_id = categ.id - LEFT JOIN product_pricelist_pms_property_rel cab - ON item.pricelist_id = cab.product_pricelist_id - LEFT JOIN product_pricelist_item_pms_property_rel lin - ON item.id = lin.product_pricelist_item_id - WHERE (lin.pms_property_id = %s OR lin.pms_property_id IS NULL) - AND (cab.pms_property_id = %s OR cab.pms_property_id IS NULL) - AND (item.product_tmpl_id IS NULL - OR item.product_tmpl_id = ANY(%s)) - AND (item.product_id IS NULL OR item.product_id = ANY(%s)) - AND (item.categ_id IS NULL OR item.categ_id = ANY(%s)) - AND (item.pricelist_id = %s) - AND (item.date_start IS NULL OR item.date_start <=%s) - AND (item.date_end IS NULL OR item.date_end >=%s) - AND (item.date_start_consumption IS NULL - OR item.date_start_consumption <=%s) - AND (item.date_end_consumption IS NULL - OR item.date_end_consumption >=%s) - GROUP BY item.id - ORDER BY item.applied_on, - /* REVIEW: priotrity date sale / date consumption */ - item.date_end - item.date_start ASC, - item.date_end_consumption - item.date_start_consumption ASC, - NULLIF((SELECT COUNT(1) - FROM product_pricelist_item_pms_property_rel l - WHERE item.id = l.product_pricelist_item_id) - + (SELECT COUNT(1) - FROM product_pricelist_pms_property_rel c - WHERE item.pricelist_id = c.product_pricelist_id),0) - NULLS LAST, - item.id DESC; - """, - ( - self._context["property"], - self._context["property"], - prod_tmpl_ids, - prod_ids, - categ_ids, - self.id, - date, - date, - self._context["consumption_date"], - self._context["consumption_date"], - ), - ) - item_ids = [x[0] for x in self.env.cr.fetchall()] - items = self.env["product.pricelist.item"].browse(item_ids) - if board_service: - items = items.filtered( - lambda x: x.board_service_room_type_id.id - == self._context.get("board_service") - ) - else: - items = items.filtered(lambda x: not x.board_service_room_type_id.id) - else: - items = super(ProductPricelist, self)._compute_price_rule_get_items( - products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids - ) - return items - - @api.constrains("pricelist_type", "item_ids", "pms_property_ids") - def _check_pricelist_type(self): - for record in self: - if record.item_ids: - for item in record.item_ids: - if record.pricelist_type == "daily" and ( - item.compute_price != "fixed" - or len(item.pms_property_ids) != 1 - or not item.date_end_consumption - or not item.date_start_consumption - or item.date_end_consumption != item.date_start_consumption - ): - raise ValidationError( - _( - "Daily Plan must have fixed price, " - "only one property and its items must be daily" - ) - ) - - # Action methods - # Constraints and onchanges - # @api.constrains("pricelist_type", "pms_property_ids") - # def _check_pricelist_type_property_ids(self): - # for record in self: - # if record.pricelist_type == "daily" and len(record.pms_property_ids) != 1: - # raise ValidationError( - # _( - # "A daily pricelist is used as a daily Rate Plan " - # "for room types and therefore must be related with " - # "one and only one property." - # ) - # ) - - # if record.pricelist_type == "daily" and len(record.pms_property_ids) == 1: - # pms_property_id = ( - # self.env["pms.property"].search( - # [("default_pricelist_id", "=", record.id)] - # ) - # or None - # ) - # if pms_property_id and pms_property_id != record.pms_property_ids: - # raise ValidationError( - # _("Relationship mismatch.") - # + " " - # + _( - # "This pricelist is used as default in a " - # "different property." - # ) - # ) - - def open_massive_changes_wizard(self): - - if self.ensure_one(): - return { - "view_type": "form", - "view_mode": "form", - "name": "Massive changes on Pricelist: " + self.name, - "res_model": "pms.massive.changes.wizard", - "target": "new", - "type": "ir.actions.act_window", - "context": { - "pricelist_id": self.id, - }, - } diff --git a/pms/models/product_pricelist_item.py b/pms/models/product_pricelist_item.py deleted file mode 100644 index d6507ae46..000000000 --- a/pms/models/product_pricelist_item.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2017 Alexandre Díaz, Pablo Quesada, Darío Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models - - -class ProductPricelistItem(models.Model): - _inherit = "product.pricelist.item" - _check_pms_properties_auto = True - - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - comodel_name="pms.property", - relation="product_pricelist_item_pms_property_rel", - column1="product_pricelist_item_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - date_start_consumption = fields.Date( - string="Start Date Consumption", - help="Start date to apply daily pricelist items", - ) - date_end_consumption = fields.Date( - string="End Date Consumption", - help="End date to apply daily pricelist items", - ) - board_service_room_type_id = fields.Many2one( - string="Board Service", - help="Specify a Board services on Room Types.", - comodel_name="pms.board.service.room.type", - check_pms_properties=True, - ) - pricelist_id = fields.Many2one( - string="Pricelist", - help="Pricelist in which this item is included", - check_pms_properties=True, - ) - product_id = fields.Many2one( - string="Product", - help="Product associated with the item", - check_pms_properties=True, - ) - product_tmpl_id = fields.Many2one( - string="Product Template", - help="Product template associated with the item", - check_pms_properties=True, - ) - allowed_board_service_product_ids = fields.Many2many( - string="Allowed board service products", - comodel_name="product.product", - store=True, - readonly=False, - compute="_compute_allowed_board_service_product_ids", - ) - - allowed_board_service_room_type_ids = fields.Many2many( - string="Allowed board service room types", - comodel_name="pms.board.service.room.type", - store=True, - readonly=False, - compute="_compute_allowed_board_service_room_type_ids", - ) - - @api.depends("board_service_room_type_id") - def _compute_allowed_board_service_product_ids(self): - for record in self: - domain = [] - if record.board_service_room_type_id: - domain.append( - ( - "id", - "in", - record.board_service_room_type_id.board_service_line_ids.mapped( - "product_id" - ).ids, - ) - ) - allowed_board_service_product_ids = self.env["product.product"].search( - domain - ) - record.allowed_board_service_product_ids = allowed_board_service_product_ids - - @api.depends("product_id") - def _compute_allowed_board_service_room_type_ids(self): - for record in self: - allowed_board_service_room_type_ids = [] - all_board_service_room_type_ids = self.env[ - "pms.board.service.room.type" - ].search([]) - if record.product_id: - for board_service_room_type_id in all_board_service_room_type_ids: - if ( - record.product_id - in board_service_room_type_id.board_service_line_ids.mapped( - "product_id" - ) - ): - allowed_board_service_room_type_ids.append( - board_service_room_type_id.id - ) - else: - allowed_board_service_room_type_ids = ( - all_board_service_room_type_ids.ids - ) - domain = [] - if allowed_board_service_room_type_ids: - domain.append(("id", "in", allowed_board_service_room_type_ids)) - record.allowed_board_service_room_type_ids = ( - self.env["pms.board.service.room.type"].search(domain) - if domain - else False - ) diff --git a/pms/models/product_product.py b/pms/models/product_product.py deleted file mode 100644 index bafb7fbcf..000000000 --- a/pms/models/product_product.py +++ /dev/null @@ -1,64 +0,0 @@ -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class ProductProduct(models.Model): - _inherit = "product.product" - - board_price = fields.Float( - string="Board Service Price", - help="Get price on board service", - digits="Product Price", - compute="_compute_board_price", - ) - - room_type_id = fields.Many2one( - string="Room Type", - comodel_name="pms.room.type", - compute="_compute_room_type_id", - ) - - @api.depends_context("consumption_date") - def _compute_product_price(self): - super(ProductProduct, self)._compute_product_price() - - def _compute_board_price(self): - for record in self: - if self._context.get("board_service"): - record.board_price = ( - self.env["pms.board.service.room.type.line"] - .search( - [ - ( - "pms_board_service_room_type_id", - "=", - self._context.get("board_service"), - ), - ("product_id", "=", record.id), - ] - ) - .amount - ) - else: - record.board_price = False - - def _compute_room_type_id(self): - for rec in self: - room_type = self.env["pms.room.type"].search( - [ - ("product_id", "=", rec.id), - ] - ) - if room_type: - if len(room_type) > 1: - raise ValidationError( - _("More than one room found for the same product") - ) - rec.room_type_id = room_type - - def price_compute(self, price_type, uom=False, currency=False, company=None): - if self._context.get("board_service"): - price_type = "board_price" - return super(ProductProduct, self).price_compute( - price_type, uom, currency, company - ) diff --git a/pms/models/product_template.py b/pms/models/product_template.py deleted file mode 100644 index b52733fa1..000000000 --- a/pms/models/product_template.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class ProductTemplate(models.Model): - _inherit = "product.template" - - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - comodel_name="pms.property", - relation="product_template_pms_property_rel", - column1="product_tmpl_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - company_id = fields.Many2one( - check_pms_properties=True, - ) - per_day = fields.Boolean( - string="Unit increment per day", - help="Indicates that the product is sold by days", - ) - per_person = fields.Boolean( - string="Unit increment per person", - help="Indicates that the product is sold per person", - ) - consumed_on = fields.Selection( - string="Consumed", - help="Indicates when the product is consumed", - selection=[("before", "Before night"), ("after", "After night")], - default="before", - ) - daily_limit = fields.Integer( - string="Daily limit", help="Indicates how much products can consumed in one day" - ) - is_extra_bed = fields.Boolean( - string="Is extra bed", - help="Indicates if that product is a extra bed, add +1 capacity in the room", - default=False, - ) - is_crib = fields.Boolean( - string="Is a baby crib", - help="Indicates if that product is a crib", - default=False, - ) diff --git a/pms/models/res_company.py b/pms/models/res_company.py deleted file mode 100644 index 341d20f80..000000000 --- a/pms/models/res_company.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class ResCompany(models.Model): - _inherit = "res.company" - - pms_property_ids = fields.One2many( - string="Properties", - help="Properties with access to the element", - 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", - ) diff --git a/pms/models/res_partner.py b/pms/models/res_partner.py deleted file mode 100644 index ced9d231e..000000000 --- a/pms/models/res_partner.py +++ /dev/null @@ -1,403 +0,0 @@ -# Copyright 2017 Alexandre Díaz -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -import logging - -from odoo import _, api, fields, models - -_logger = logging.getLogger(__name__) - - -class ResPartner(models.Model): - _inherit = "res.partner" - - reservations_count = fields.Integer( - string="Number of Reservations", - help="Number of reservations of the partner", - compute="_compute_reservations_count", - ) - folios_count = fields.Integer( - string="Number of Folios", - help="Number of folios of the partner", - compute="_compute_folios_count", - ) - is_agency = fields.Boolean( - string="Is Agency", help="Indicates if the partner is an agency" - ) - sale_channel_id = fields.Many2one( - string="Sale Channel", - help="The sale channel of the partner", - comodel_name="pms.sale.channel", - domain=[("channel_type", "=", "indirect")], - ondelete="restrict", - ) - default_commission = fields.Integer(string="Commission", help="Default commission") - apply_pricelist = fields.Boolean( - string="Apply Pricelist", - help="Indicates if agency pricelist is applied to his reservations", - ) - invoice_to_agency = fields.Boolean( - string="Invoice Agency", - help="Indicates if agency invoices partner", - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="Properties with access to the element;" - " if not set, all properties can access", - required=False, - comodel_name="pms.property", - relation="res_partner_pms_property_rel", - column1="res_partner_id", - column2="pms_property_id", - ondelete="restrict", - check_pms_properties=True, - ) - company_id = fields.Many2one( - 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", - ) - pms_reservation_ids = fields.One2many( - string="Reservations", - help="Associated reservation", - comodel_name="pms.reservation", - inverse_name="partner_id", - ) - pms_folio_ids = fields.One2many( - string="Folios", - help="Associated Folios", - comodel_name="pms.folio", - 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", - ) - # TODO: Use new partner contact "other or "private" with - # personal contact address complete?? - # to avoid user country_id on companies contacts. - # view to checkin partner state_id field - state_id = fields.Many2one( - readonly=False, - store=True, - compute="_compute_state_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", - ) - comment = fields.Text( - tracking=True, - ) - reservation_possible_customer_id = fields.Many2one( - string="Possible Customer In Reservation", comodel_name="pms.reservation" - ) - folio_possible_customer_id = fields.Many2one( - string="Possible Customer In Folio", comodel_name="pms.folio" - ) - checkin_partner_possible_customer_id = fields.Many2one( - string="Possible Customer In Checkin Partner", - comodel_name="pms.checkin.partner", - ) - - @api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.gender") - def _compute_gender(self): - if hasattr(super(), "_compute_gender"): - super()._compute_gender() - for record in self: - if not record.gender and record.pms_checkin_partner_ids: - gender = list( - filter(None, 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_birthdate_date() - for record in self: - if not record.birthdate_date and record.pms_checkin_partner_ids: - birthdate = list( - filter( - None, - 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_nationality_id() - for record in self: - if not record.nationality_id and record.pms_checkin_partner_ids: - nationality_id = list( - filter( - None, - 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.state_id") - def _compute_state_id(self): - if hasattr(super(), "_compute_state_id"): - super()._compute_state_id() - for record in self: - if not record.state_id and record.pms_checkin_partner_ids: - state_id = list( - filter( - None, - set(record.pms_checkin_partner_ids.mapped("state_id")), - ) - ) - if len(state_id) == 1: - record.state_id = state_id[0] - else: - record.state_id = False - elif not record.state_id: - record.state_id = False - - @api.depends( - "pms_checkin_partner_ids", - "pms_checkin_partner_ids.email", - "pms_reservation_ids", - "pms_reservation_ids.email", - "pms_folio_ids", - "pms_folio_ids.email", - ) - def _compute_email(self): - if hasattr(super(), "_compute_email"): - super()._compute_email() - for record in self: - if not record.email and ( - record.pms_checkin_partner_ids - or record.pms_reservation_ids - or record.pms_folio_ids - ): - email = list( - filter( - None, - set( - record.pms_checkin_partner_ids.mapped("email") - + record.pms_reservation_ids.mapped("email") - + record.pms_folio_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", - "pms_reservation_ids", - "pms_reservation_ids.mobile", - "pms_folio_ids", - "pms_folio_ids.mobile", - ) - def _compute_mobile(self): - if hasattr(super(), "_compute_mobile"): - super()._compute_mobile() - for record in self: - if not record.mobile and ( - record.pms_checkin_partner_ids - or record.pms_reservation_ids - or record.pms_folio_ids - ): - mobile = list( - filter( - None, - set( - record.pms_checkin_partner_ids.mapped("mobile") - + record.pms_reservation_ids.mapped("mobile") - + record.pms_folio_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_firstname() - for record in self: - if not record.firstname and record.pms_checkin_partner_ids: - firstname = list( - filter( - None, 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_lastname() - for record in self: - if not record.lastname and record.pms_checkin_partner_ids: - lastname = list( - filter(None, 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_lastname2() - for record in self: - if not record.lastname2 and record.pms_checkin_partner_ids: - lastname2 = list( - filter( - None, 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"] - for record in self: - record.reservations_count = pms_reservation_obj.search_count( - [ - ( - "partner_id.id", - "child_of", - record.id if isinstance(record.id, int) else False, - ) - ] - ) - - def _compute_folios_count(self): - pms_folio_obj = self.env["pms.folio"] - for record in self: - record.folios_count = pms_folio_obj.search_count( - [ - ( - "partner_id.id", - "=", - record.id if isinstance(record.id, int) else False, - ) - ] - ) - - @api.constrains("is_agency", "sale_channel_id") - def _check_is_agency(self): - for record in self: - if record.is_agency and not record.sale_channel_id: - raise models.ValidationError(_("Sale Channel must be entered")) - if record.is_agency and record.sale_channel_id.channel_type != "indirect": - raise models.ValidationError( - _("Sale Channel for an agency must be indirect") - ) - if not record.is_agency and record.sale_channel_id: - record.sale_channel_id = None - - # REVIEW: problems with odoo demo data - # @api.constrains("mobile", "email") - # def _check_duplicated(self): - # for record in self: - # partner, field = record._search_duplicated() - # if partner: - # raise models.ValidationError( - # _( - # "Partner %s found with same %s (%s)", - # partner.name, - # partner._fields[field].string, - # getattr(record, field), - # ) - # ) - - def _search_duplicated(self): - self.ensure_one() - partner = False - for field in self._get_key_fields(): - if getattr(self, field): - partner = self.search( - [(field, "=", getattr(self, field)), ("id", "!=", self.id)] - ) - if partner: - field = field - return partner, field - - @api.model - def _get_key_fields(self): - key_fields = super(ResPartner, self)._get_key_fields() - key_fields.extend(["document_number"]) - return key_fields diff --git a/pms/models/res_partner_id_number.py b/pms/models/res_partner_id_number.py deleted file mode 100644 index 9f43b045e..000000000 --- a/pms/models/res_partner_id_number.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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 -# 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_valid_from() - 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")) diff --git a/pms/models/res_users.py b/pms/models/res_users.py deleted file mode 100644 index a7becc480..000000000 --- a/pms/models/res_users.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2019 Pablo Quesada -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError -from odoo.http import request - - -class ResUsers(models.Model): - _inherit = "res.users" - - pms_property_id = fields.Many2one( - string="Default Property", - help="The property that is selected within " "those allowed for the user", - comodel_name="pms.property", - domain="[('id','in',pms_property_ids)]", - context={"user_preference": True}, - ) - pms_property_ids = fields.Many2many( - string="Properties", - help="The properties allowed for this user", - comodel_name="pms.property", - relation="pms_property_users_rel", - column1="user_id", - column2="pms_property_id", - domain="[('company_id','in',company_ids)]", - ) - - @api.model - def get_active_property_ids(self): - # TODO: Require performance test and security (dont allow any property id) - # checks (Review lazy_property decorator?) - user_property_ids = self.env.user.pms_property_ids.ids - if request and request.httprequest.cookies.get("pms_pids"): - active_property_ids = list( - map(int, request.httprequest.cookies.get("pms_pids", "").split(",")) - ) - active_property_ids = [ - pid for pid in active_property_ids if pid in user_property_ids - ] - return self.env["pms.property"].browse(active_property_ids).ids - return user_property_ids - - @api.constrains("pms_property_id", "pms_property_ids") - def _check_property_in_allowed_properties(self): - if any(user.pms_property_id not in user.pms_property_ids for user in self): - raise ValidationError( - _("The chosen property is not in the allowed properties for this user") - ) - - @api.constrains("pms_property_ids", "company_id") - def _check_company_in_property_ids(self): - for record in self: - for pms_property in record.pms_property_ids: - if pms_property.company_id not in record.company_ids: - raise ValidationError( - _("Some properties do not belong to the allowed companies") - ) diff --git a/pms/readme/CONFIGURE.rst b/pms/readme/CONFIGURE.rst deleted file mode 100644 index 940574e83..000000000 --- a/pms/readme/CONFIGURE.rst +++ /dev/null @@ -1,3 +0,0 @@ -You will find the hotel settings in PMS Management > Configuration > Properties > Your Property. - -This module required additional configuration for company, accounting, invoicing and user privileges. diff --git a/pms/readme/CONTRIBUTORS.rst b/pms/readme/CONTRIBUTORS.rst deleted file mode 100644 index 91f25d79a..000000000 --- a/pms/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,10 +0,0 @@ -* Alexandre Díaz -* Pablo Quesada -* Jose Luis Algara -* `Commit [Sun] `: - - * Dario Lodeiros - * Eric Antones - * Sara Lago - * Brais Abeijon - * Miguel Padin diff --git a/pms/readme/DESCRIPTION.rst b/pms/readme/DESCRIPTION.rst deleted file mode 100644 index 9001d9117..000000000 --- a/pms/readme/DESCRIPTION.rst +++ /dev/null @@ -1,5 +0,0 @@ -This module is an all-in-one property management system (PMS) focused on medium-sized properties -for managing every aspect of your property's daily operations. - -You can manage properties with multi-property and multi-company support, including your rooms inventory, -reservations, check-in, daily reports, board services, rate and availability plans among other property functionalities. diff --git a/pms/readme/INSTALL.rst b/pms/readme/INSTALL.rst deleted file mode 100644 index 1661ad5e7..000000000 --- a/pms/readme/INSTALL.rst +++ /dev/null @@ -1,2 +0,0 @@ -This module depends on modules ``base``, ``mail``, ``sale`` and ``multi_pms_properties``. -Ensure yourself to have all them in your addons list. diff --git a/pms/readme/USAGE.rst b/pms/readme/USAGE.rst deleted file mode 100644 index e6a897c6a..000000000 --- a/pms/readme/USAGE.rst +++ /dev/null @@ -1 +0,0 @@ -To use this module, please, read the complete user guide at ``_. diff --git a/pms/report/pms_folio.xml b/pms/report/pms_folio.xml deleted file mode 100644 index a626c3493..000000000 --- a/pms/report/pms_folio.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Report Folio - pms.folio - qweb-pdf - pms.report_folio - pms.report_folio - (object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name) - - - diff --git a/pms/report/pms_folio_templates.xml b/pms/report/pms_folio_templates.xml deleted file mode 100644 index fa23f7152..000000000 --- a/pms/report/pms_folio_templates.xml +++ /dev/null @@ -1,311 +0,0 @@ - - - - - - - - diff --git a/pms/report/traveller_report_action.xml b/pms/report/traveller_report_action.xml deleted file mode 100644 index f04c2bbdf..000000000 --- a/pms/report/traveller_report_action.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Traveller Report - pms.checkin.partner - qweb-pdf - pms.traveller_report - pms.traveller_report - - (object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name) - - - diff --git a/pms/security/ir.model.access.csv b/pms/security/ir.model.access.csv deleted file mode 100644 index 0cf1b3a73..000000000 --- a/pms/security/ir.model.access.csv +++ /dev/null @@ -1,66 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -user_access_pms_ubication,user_access_pms_ubication,model_pms_ubication,pms.group_pms_user,1,0,0,0 -user_access_pms_amenity,user_access_pms_amenity,model_pms_amenity,pms.group_pms_user,1,0,0,0 -user_access_pms_amenity_type,user_access_pms_amenity_type,model_pms_amenity_type,pms.group_pms_user,1,0,0,0 -user_access_pms_service,user_access_pms_service,model_pms_service,pms.group_pms_user,1,1,1,1 -user_access_pms_reservation_line,user_access_pms_reservation_line,model_pms_reservation_line,pms.group_pms_user,1,1,1,1 -user_access_room_closure_reason,user_access_room_closure_reason,model_room_closure_reason,pms.group_pms_user,1,0,0,0 -user_access_pms_service_line,user_access_pms_service_line,model_pms_service_line,pms.group_pms_user,1,1,1,1 -user_access_pms_board_service,user_access_pms_board_service,model_pms_board_service,pms.group_pms_user,1,0,0,0 -user_access_pms_checkin_partner,user_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_user,1,1,1,1 -user_access_pms_room_type_class,user_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_user,1,0,0,0 -user_access_pms_room,user_access_pms_room,model_pms_room,pms.group_pms_user,1,0,0,0 -user_access_pms_availability_plan_rule,user_access_pms_availability_plan_rule,model_pms_availability_plan_rule,pms.group_pms_user,1,0,0,0 -user_access_pms_availability,user_access_pms_availability,model_pms_availability,pms.group_pms_user,1,1,1,0 -user_access_pms_reservation,user_access_pms_reservation,model_pms_reservation,pms.group_pms_user,1,1,1,1 -user_access_pms_folio,user_access_pms_folio,model_pms_folio,pms.group_pms_user,1,1,1,1 -user_access_pms_room_type,user_access_pms_room_type,model_pms_room_type,pms.group_pms_user,1,0,0,0 -user_access_pms_board_service_room_type,user_access_pms_board_service_room_type,model_pms_board_service_room_type,pms.group_pms_user,1,0,0,0 -user_access_pms_board_service_room_type_line,user_access_pms_board_service_room_type_line,model_pms_board_service_room_type_line,pms.group_pms_user,1,0,0,0 -user_access_pms_board_service_line,user_access_pms_board_service_line,model_pms_board_service_line,pms.group_pms_user,1,0,0,0 -user_access_account_partial_reconcile,user_access_account_partial_reconcile,account.model_account_partial_reconcile,pms.group_pms_user,1,1,1,1 -user_access_pms_cancelation_rule,user_access_pms_cancelation_rule,model_pms_cancelation_rule,pms.group_pms_user,1,0,0,0 -user_access_account_full_reconcile,user_access_account_full_reconcile,account.model_account_full_reconcile,pms.group_pms_user,1,1,1,1 -user_access_property,user_access_property,model_pms_property,pms.group_pms_user,1,0,0,0 -user_access_availability,user_access_availability,model_pms_availability_plan,pms.group_pms_user,1,0,0,0 -user_access_pms_sale_channel,user_access_pms_sale_channel,model_pms_sale_channel,pms.group_pms_user,1,0,0,0 -manager_access_pms_ubication,manager_access_pms_ubication,model_pms_ubication,pms.group_pms_manager,1,1,1,1 -manager_access_pms_amenity,manager_access_pms_amenity,model_pms_amenity,pms.group_pms_manager,1,1,1,1 -manager_access_pms_amenity_type,manager_access_pms_amenity_type,model_pms_amenity_type,pms.group_pms_manager,1,1,1,1 -manager_access_pms_service,manager_access_pms_service,model_pms_service,pms.group_pms_manager,1,1,1,1 -manager_access_pms_reservation_line,manager_access_pms_reservation_line,model_pms_reservation_line,pms.group_pms_manager,1,1,1,1 -manager_access_room_closure_reason,manager_access_room_closure_reason,model_room_closure_reason,pms.group_pms_manager,1,1,1,1 -manager_access_pms_service_line,manager_access_pms_service_line,model_pms_service_line,pms.group_pms_manager,1,1,1,1 -manager_access_pms_board_service,manager_access_pms_board_service,model_pms_board_service,pms.group_pms_manager,1,1,1,1 -manager_access_pms_checkin_partner,manager_access_pms_checkin_partner,model_pms_checkin_partner,pms.group_pms_manager,1,1,1,1 -manager_access_pms_room_type_class,manager_access_pms_room_type_class,model_pms_room_type_class,pms.group_pms_manager,1,1,1,1 -manager_access_pms_room,manager_access_pms_room,model_pms_room,pms.group_pms_manager,1,1,1,1 -manager_access_pms_availability_plan_rule,manager_access_pms_availability_plan_rule,model_pms_availability_plan_rule,pms.group_pms_manager,1,1,1,1 -manager_access_pms_reservation,manager_access_pms_reservation,model_pms_reservation,pms.group_pms_manager,1,1,1,1 -manager_access_pms_availability,manager_access_pms_availability,model_pms_availability,pms.group_pms_manager,1,1,1,0 -manager_access_pms_folio,manager_access_pms_folio,model_pms_folio,pms.group_pms_manager,1,1,1,1 -manager_access_pms_room_type,manager_access_pms_room_type,model_pms_room_type,pms.group_pms_manager,1,1,1,1 -manager_access_pms_board_service_room_type,manager_access_pms_board_service_room_type,model_pms_board_service_room_type,pms.group_pms_manager,1,1,1,1 -manager_access_pms_board_service_room_type_line,manager_access_pms_board_service_room_type_line,model_pms_board_service_room_type_line,pms.group_pms_manager,1,1,1,1 -manager_access_pms_board_service_line,manager_access_pms_board_service_line,model_pms_board_service_line,pms.group_pms_manager,1,1,1,1 -manager_access_property,manager_access_property,model_pms_property,pms.group_pms_manager,1,1,1,1 -manager_access_pms_cancelation_rule,manager_access_pms_cancelation_rule,model_pms_cancelation_rule,pms.group_pms_manager,1,1,1,1 -manager_access_availability,manager_access_availability,model_pms_availability_plan,pms.group_pms_manager,1,1,1,1 -manager_access_pms_sale_channel,manager_access_pms_sale_channel,model_pms_sale_channel,pms.group_pms_manager,1,1,1,1 -user_access_pms_reservation_split_join_swap_wizard,user_access_pms_reservation_split_join_swap_wizard,model_pms_reservation_split_join_swap_wizard,pms.group_pms_user,1,1,1,1 -user_access_pms_wizard_reservation_lines_split,user_access_pms_wizard_reservation_lines_split,model_pms_wizard_reservation_lines_split,pms.group_pms_user,1,1,1,1 -user_access_pms_massive_changes_wizard,user_access_pms_massive_changes_wizard,model_pms_massive_changes_wizard,pms.group_pms_user,1,1,1,1 -user_access_pms_advanced_filters_wizard,user_access_pms_advanced_filters_wizard,model_pms_advanced_filters_wizard,pms.group_pms_user,1,1,1,1 -user_access_pms_booking_engine,user_access_pms_booking_engine,model_pms_booking_engine,pms.group_pms_user,1,1,1,1 -user_access_pms_folio_availability_wizard,user_access_pms_folio_availability_wizard,model_pms_folio_availability_wizard,pms.group_pms_user,1,1,1,1 -user_access_pms_num_rooms_selection,user_access_pms_num_rooms_selection,model_pms_num_rooms_selection,pms.group_pms_user,1,1,1,1 -user_access_pms_folio_sale_line,user_access_pms_folio_sale_line,model_folio_sale_line,pms.group_pms_user,1,0,0,0 -user_access_folio_make_invoice_advance,user_access_folio_make_invoice_advance,model_folio_advance_payment_inv,pms.group_pms_user,1,1,1,1 -user_access_wizard_payment_folio,user_access_wizard_payment_folio,model_wizard_payment_folio,pms.group_pms_user,1,1,1,1 -user_access_wizard_folio_changes,user_access_wizard_folio_changes,model_wizard_folio_changes,pms.group_pms_user,1,1,1,1 -user_access_pms_folio_portal,user_access_pms_folio_portal,model_pms_folio,base.group_portal,1,0,0,0 -user_access_pms_reservation_portal,user_access_pms_reservation_portal,model_pms_reservation,base.group_portal,1,0,0,0 -user_access_pms_automated_mails,user_access_pms_automated_mails,model_pms_automated_mails,pms.group_pms_user,1,1,1,1 -access_pms_several_partners_wizard,access_pms_several_partners_wizard,model_pms_several_partners_wizard,base.group_user,1,1,1,1 -user_access_res_partner_portal,user_access_res_partner_portal,model_res_partner,base.group_portal,1,1,1,1 -user_access_pms_precheckin_portal,user_access_pms_precheckin_portal,model_pms_checkin_partner,base.group_portal,1,1,1,1 diff --git a/pms/security/pms_security.xml b/pms/security/pms_security.xml deleted file mode 100644 index 7ab889e8c..000000000 --- a/pms/security/pms_security.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Property Management / User - - - - Property Management/ Manager - - - - - Property Management / CallCenter - - - - - - PMS Folio Company Rule - - - - ['|',('company_id','=',False),('company_id', 'in', company_ids)] - - - - PMS Reservation Company Rule - - - - ['|',('company_id','=',False),('company_id', 'in', company_ids)] - - - - - PMS Folio Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Reservation Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Amenity Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Amenity Type Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Board Service Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Board Service Line Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Board Service Room Type Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Cancelation Rule Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Ubication Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Reservation Line Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Clousure Reason Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Room Type Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Room Type Availability Plan Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Room Type Availability Rule Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Service Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Service Line Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Product Pricelist Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Room Type Class Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Users Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - PMS Account Move Property Rule - - - - ['|',('pms_property_id','=',False),('pms_property_id', 'in', - user.get_active_property_ids())] - - - - PMS Account Journal Property Rule - - - - ['|',('pms_property_ids','=',False),('pms_property_ids', 'in', - user.get_active_property_ids())] - - - - Portal Personal Folios - - [] - - - - - Portal Personal Reservation - - [] - - - - - Portal Personal Pre-checkin - - [] - - - - - Res Partner Rule - - [] - - - - - Portal Checkin Partner Rule - - [] - - - - - diff --git a/pms/static/description/agency_logo.png b/pms/static/description/agency_logo.png deleted file mode 100644 index bffa2c63a..000000000 Binary files a/pms/static/description/agency_logo.png and /dev/null differ diff --git a/pms/static/description/agency_logo1.png b/pms/static/description/agency_logo1.png deleted file mode 100644 index d20ba13b3..000000000 Binary files a/pms/static/description/agency_logo1.png and /dev/null differ diff --git a/pms/static/description/avatar.png b/pms/static/description/avatar.png deleted file mode 100644 index dff716c28..000000000 Binary files a/pms/static/description/avatar.png and /dev/null differ diff --git a/pms/static/description/icon.png b/pms/static/description/icon.png deleted file mode 100644 index a81dd64c3..000000000 Binary files a/pms/static/description/icon.png and /dev/null differ diff --git a/pms/static/description/index.html b/pms/static/description/index.html deleted file mode 100644 index f2429e666..000000000 --- a/pms/static/description/index.html +++ /dev/null @@ -1,455 +0,0 @@ - - - - - - -PMS (Property Management System) - - - -
-

PMS (Property Management System)

- - -

Alpha License: AGPL-3 OCA/pms Translate me on Weblate Try me on Runbot

-

This module is an all-in-one property management system (PMS) focused on medium-sized properties -for managing every aspect of your property’s daily operations.

-

You can manage properties with multi-property and multi-company support, including your rooms inventory, -reservations, check-in, daily reports, board services, rate and availability plans among other property functionalities.

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

Installation

-

This module depends on modules base, mail, sale and multi_pms_properties. -Ensure yourself to have all them in your addons list.

-
-
-

Configuration

-

You will find the hotel settings in PMS Management > Configuration > Properties > Your Property.

-

This module required additional configuration for company, accounting, invoicing and user privileges.

-
-
-

Usage

-

To use this module, please, read the complete user guide at roomdoo.com.

-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Commit [Sun]
  • -
-
-
-

Contributors

-
    -
  • Alexandre Díaz
  • -
  • Pablo Quesada
  • -
  • Jose Luis Algara
  • -
  • Commit [Sun] <https://www.commitsun.com>:
      -
    • Dario Lodeiros
    • -
    • Eric Antones
    • -
    • Sara Lago
    • -
    • Brais Abeijon
    • -
    • Miguel Padin
    • -
    -
  • -
-
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

This module is part of the OCA/pms project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- - diff --git a/pms/static/src/js/inherited_abstract_web_client.js b/pms/static/src/js/inherited_abstract_web_client.js deleted file mode 100644 index 249700140..000000000 --- a/pms/static/src/js/inherited_abstract_web_client.js +++ /dev/null @@ -1,39 +0,0 @@ -odoo.define("pms.AbstractWebClient", function (require) { - "use strict"; - - var AbstractWebClient = require("web.AbstractWebClient"); - var session = require("web.session"); - var utils = require("web.utils"); - - return AbstractWebClient.include({ - start: function () { - var state = $.bbq.getState(); - var current_pms_property_id = - session.user_pms_properties.current_pms_property[0]; - if (!state.pms_pids) { - state.pms_pids = utils.get_cookie("pms_pids") - ? utils.get_cookie("pms_pids") - : String(current_pms_property_id); - } - var statePmsPropertyIDS = _.map(state.pms_pids.split(","), function ( - pms_pid - ) { - return parseInt(pms_pid, 10); - }); - var userPmsPropertyIDS = _.map( - session.user_pms_properties.allowed_pms_properties, - function (pms_property) { - return pms_property[0]; - } - ); - // Check that the user has access to all the companies - if (!_.isEmpty(_.difference(statePmsPropertyIDS, userPmsPropertyIDS))) { - state.pms_pids = String(current_pms_property_id); - statePmsPropertyIDS = [current_pms_property_id]; - } - session.user_context.allowed_pms_property_ids = statePmsPropertyIDS; - - return this._super.apply(this, arguments); - }, - }); -}); diff --git a/pms/static/src/js/pms_list_controller.js b/pms/static/src/js/pms_list_controller.js deleted file mode 100644 index 74db95065..000000000 --- a/pms/static/src/js/pms_list_controller.js +++ /dev/null @@ -1,41 +0,0 @@ -odoo.define("booking.engine.tree", function (require) { - "use strict"; - var ListController = require("web.ListController"); - var ListView = require("web.ListView"); - var viewRegistry = require("web.view_registry"); - - function renderBookingEngineButton() { - if (this.$buttons) { - var self = this; - this.$buttons.on("click", ".o_button_booking_engine", function () { - self.do_action({ - name: "Booking Engine", - type: "ir.actions.act_window", - res_model: "pms.booking.engine", - target: "new", - views: [[false, "form"]], - context: {is_modal: true}, - }); - }); - } - } - - var BookingEngineRequestListController = ListController.extend({ - start: function () { - return this._super.apply(this, arguments); - }, - buttons_template: "BookingEngineRequestListView.buttons", - renderButtons: function () { - this._super.apply(this, arguments); - renderBookingEngineButton.apply(this, arguments); - }, - }); - - var BookingEngineRequestListView = ListView.extend({ - config: _.extend({}, ListView.prototype.config, { - Controller: BookingEngineRequestListController, - }), - }); - - viewRegistry.add("pms_booking_engine_request_tree", BookingEngineRequestListView); -}); diff --git a/pms/static/src/js/send_invitation_data.js b/pms/static/src/js/send_invitation_data.js deleted file mode 100644 index b5eb4e964..000000000 --- a/pms/static/src/js/send_invitation_data.js +++ /dev/null @@ -1,68 +0,0 @@ -odoo.define("pms.SendInvitationData", function (require) { - "use strict"; - - require("web.dom_ready"); - var publicWidget = require("web.public.widget"); - - publicWidget.registry.SendInvitationData = publicWidget.Widget.extend({ - selector: ".o_send_invitation_js", - events: { - click: "_onReminderToggleClick", - }, - - _onReminderToggleClick: function (ev) { - ev.preventDefault(); - var checkinPartnerId = $(ev.currentTarget) - .parent() - .parent() - .parent() - .find("input[name=checkin_partner_id]") - .val(); - var firstname = $(ev.currentTarget) - .parent() - .parent() - .find("input[name=invitation_firstname]") - .val(); - var email = $(ev.currentTarget) - .parent() - .parent() - .find("input[name=invitation_email]") - .val(); - var error_firstname = $(ev.currentTarget) - .parent() - .parent() - .find("span:first"); - var error_email = $(ev.currentTarget) - .parent() - .parent() - .find("input[name=invitation_email]") - .siblings("span"); - console.log(error_firstname); - console.log(error_email); - if (firstname === "" || email === "") { - if (firstname === "") { - error_firstname.removeClass("d-none"); - } else { - error_firstname.addClass("d-none"); - } - if (email === "") { - error_email.removeClass("d-none"); - } else { - error_email.addClass("d-none"); - } - } else { - error_firstname.addClass("d-none"); - error_email.addClass("d-none"); - this._rpc({ - route: "/my/precheckin/send_invitation", - params: { - checkin_partner_id: checkinPartnerId, - firstname: firstname, - email: email, - }, - }); - } - }, - }); - return publicWidget.registry.SendInvitationData; -}); diff --git a/pms/static/src/js/session.js b/pms/static/src/js/session.js deleted file mode 100644 index 8bc2d57de..000000000 --- a/pms/static/src/js/session.js +++ /dev/null @@ -1,26 +0,0 @@ -odoo.define("pms.session", function (require) { - "use strict"; - - var Session = require("web.Session"); - var utils = require("web.utils"); - - Session.include({ - // TODO: require test and debug - setPmsProperties: function (pms_main_property_id, pms_property_ids) { - var hash = $.bbq.getState(); - hash.pms_pids = pms_property_ids - .sort(function (a, b) { - if (a === pms_main_property_id) { - return -1; - } else if (b === pms_main_property_id) { - return 1; - } - return a - b; - }) - .join(","); - utils.set_cookie("pms_pids", hash.pms_pids || String(pms_main_property_id)); - $.bbq.pushState({pms_pids: hash.pms_pids}, 0); - location.reload(); - }, - }); -}); diff --git a/pms/static/src/js/widgets/switch_property_menu.js b/pms/static/src/js/widgets/switch_property_menu.js deleted file mode 100644 index 0404f19fc..000000000 --- a/pms/static/src/js/widgets/switch_property_menu.js +++ /dev/null @@ -1,163 +0,0 @@ -odoo.define("web.SwitchPmsMenu", function (require) { - "use strict"; - - /** - * When Odoo is configured in multi-property mode, users should obviously be able - * to switch their interface from one property to the other. This is the purpose - * of this widget, by displaying a dropdown menu in the systray. - */ - - var config = require("web.config"); - var session = require("web.session"); - var SystrayMenu = require("web.SystrayMenu"); - var Widget = require("web.Widget"); - - var SwitchPmsMenu = Widget.extend({ - template: "SwitchPmsMenu", - events: { - "click .dropdown-item[data-menu] div.pms_log_into": - "_onSwitchPmsPropertyClick", - "keydown .dropdown-item[data-menu] div.pms_log_into": - "_onSwitchPmsPropertyClick", - "click .dropdown-item[data-menu] div.pms_toggle_property": - "_onTogglePmsPropertyClick", - "keydown .dropdown-item[data-menu] div.pms_toggle_property": - "_onTogglePmsPropertyClick", - }, - /** - * @override - */ - init: function () { - this._super.apply(this, arguments); - this.isMobile = config.device.isMobile; - this._onSwitchPmsPropertyClick = _.debounce( - this._onSwitchPmsPropertyClick, - 1500, - true - ); - }, - - /** - * @override - */ - willStart: function () { - var self = this; - this.allowed_pms_property_ids = String( - session.user_context.allowed_pms_property_ids - ) - .split(",") - .map(function (id) { - return parseInt(id, 10); - }); - this.user_pms_properties = - session.user_pms_properties.allowed_pms_properties; - this.current_pms_property = this.allowed_pms_property_ids[0]; - this.current_pms_property_name = _.find( - session.user_pms_properties.allowed_pms_properties, - function (pms_property) { - return pms_property[0] === self.current_pms_property; - } - )[1]; - return this._super.apply(this, arguments); - }, - - // -------------------------------------------------------------------------- - // Handlers - // -------------------------------------------------------------------------- - - /** - * @private - * @param {MouseEvent|KeyEvent} ev - */ - _onSwitchPmsPropertyClick: function (ev) { - if ( - ev.type === "keydown" && - ev.which !== $.ui.keyCode.ENTER && - ev.which !== $.ui.keyCode.SPACE - ) { - return; - } - ev.preventDefault(); - ev.stopPropagation(); - var dropdownItem = $(ev.currentTarget).parent(); - var dropdownMenu = dropdownItem.parent(); - var pms_propertyID = dropdownItem.data("pms_property-id"); - var allowed_pms_property_ids = this.allowed_pms_property_ids; - if (dropdownItem.find(".fa-square-o").length) { - // 1 enabled pms_property: Stay in single pms proeprty mode - if (this.allowed_pms_property_ids.length === 1) { - if (this.isMobile) { - dropdownMenu = dropdownMenu.parent(); - } - dropdownMenu - .find(".fa-check-square") - .removeClass("fa-check-square") - .addClass("fa-square-o"); - dropdownItem - .find(".fa-square-o") - .removeClass("fa-square-o") - .addClass("fa-check-square"); - allowed_pms_property_ids = [pms_propertyID]; - } else { - // Multi pms proeprty mode - allowed_pms_property_ids.push(pms_propertyID); - dropdownItem - .find(".fa-square-o") - .removeClass("fa-square-o") - .addClass("fa-check-square"); - } - } - $(ev.currentTarget).attr("aria-pressed", "true"); - session.setPmsProperties(pms_propertyID, allowed_pms_property_ids); - }, - - // -------------------------------------------------------------------------- - // Handlers - // -------------------------------------------------------------------------- - - /** - * @private - * @param {MouseEvent|KeyEvent} ev - */ - _onTogglePmsPropertyClick: function (ev) { - if ( - ev.type === "keydown" && - ev.which !== $.ui.keyCode.ENTER && - ev.which !== $.ui.keyCode.SPACE - ) { - return; - } - ev.preventDefault(); - ev.stopPropagation(); - var dropdownItem = $(ev.currentTarget).parent(); - var pms_propertyID = dropdownItem.data("pms_property-id"); - var allowed_pms_property_ids = this.allowed_pms_property_ids; - var current_pms_property_id = allowed_pms_property_ids[0]; - if (dropdownItem.find(".fa-square-o").length) { - allowed_pms_property_ids.push(pms_propertyID); - dropdownItem - .find(".fa-square-o") - .removeClass("fa-square-o") - .addClass("fa-check-square"); - $(ev.currentTarget).attr("aria-checked", "true"); - } else { - allowed_pms_property_ids.splice( - allowed_pms_property_ids.indexOf(pms_propertyID), - 1 - ); - dropdownItem - .find(".fa-check-square") - .addClass("fa-square-o") - .removeClass("fa-check-square"); - $(ev.currentTarget).attr("aria-checked", "false"); - } - session.setPmsProperties(current_pms_property_id, allowed_pms_property_ids); - }, - }); - - if (session.display_switch_pms_property_menu) { - SystrayMenu.Items.push(SwitchPmsMenu); - } - - return SwitchPmsMenu; -}); diff --git a/pms/static/src/xml/pms_base_templates.xml b/pms/static/src/xml/pms_base_templates.xml deleted file mode 100644 index b054fb56c..000000000 --- a/pms/static/src/xml/pms_base_templates.xml +++ /dev/null @@ -1,76 +0,0 @@ - diff --git a/pms/static/src/xml/reservation_group_button_views.xml b/pms/static/src/xml/reservation_group_button_views.xml deleted file mode 100644 index 05e713adb..000000000 --- a/pms/static/src/xml/reservation_group_button_views.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/pms/templates/pms_email_template.xml b/pms/templates/pms_email_template.xml deleted file mode 100644 index d21955c07..000000000 --- a/pms/templates/pms_email_template.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - Property: Reservation Confirmed - - ${('%s <%s>' % (object.pms_property_id.partner_id.name, object.pms_property_id.partner_id.email) or '')|safe} - ${(object.email or '')|safe} - ${(object.partner_id.id or '')} - ${object.partner_id.lang} - - Your reservation ${object.name} has been confirmed by the property staff - - - qweb - - - - diff --git a/pms/tests/__init__.py b/pms/tests/__init__.py deleted file mode 100644 index 43e0a2cbe..000000000 --- a/pms/tests/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2017 Solucións Aloxa S.L. -# Alexandre Díaz -# -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################################## -from . import test_pms_reservation -from . import test_pms_pricelist -from . import test_pms_checkin_partner -from . import test_pms_sale_channel -from . import test_pms_folio -from . import test_pms_availability_plan_rules -from . import test_pms_room_type -from . import test_pms_room_type_class -from . import test_pms_board_service -from . import test_pms_wizard_massive_changes -from . import test_pms_booking_engine -from . import test_pms_res_users -from . import test_pms_room -from . import test_pms_folio_invoice -from . import test_pms_folio_sale_line -from . import test_pms_wizard_split_join_swap_reservation -from . import test_product_template -from . import test_pms_multiproperty -from . import test_shared_room -from . import test_automated_mails diff --git a/pms/tests/common.py b/pms/tests/common.py deleted file mode 100644 index e79743bb5..000000000 --- a/pms/tests/common.py +++ /dev/null @@ -1,29 +0,0 @@ -from odoo.tests import common - - -class TestPms(common.SavepointCase): - def setUp(self): - super().setUp() - self.pricelist1 = self.env["product.pricelist"].create( - { - "name": "Pricelist 1", - } - ) - self.company1 = self.env["res.company"].create( - { - "name": "Company 1", - } - ) - self.pms_property1 = self.env["pms.property"].create( - { - "name": "Property 1", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.room_type_class1 = self.env["pms.room.type.class"].create( - { - "name": "Room Type Class 1", - "default_code": "RTC1", - } - ) diff --git a/pms/tests/test_automated_mails.py b/pms/tests/test_automated_mails.py deleted file mode 100644 index 8f60d2abd..000000000 --- a/pms/tests/test_automated_mails.py +++ /dev/null @@ -1,618 +0,0 @@ -from odoo.exceptions import UserError - -from .common import TestPms - - -class TestPmsAutomatedMails(TestPms): - def setUp(self): - super().setUp() - self.template = self.env["mail.template"].search( - [("name", "=", "Confirmed Reservation")] - ) - - def test_create_automated_action(self): - """ - Checks that an automated_action is created correctly when an - automated_mail is created. - --------------------- - An automated_mail is created and then it is verified that - the automated_action was created. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "creation", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertTrue( - auto_mail.automated_actions_id, "Automated action should be created " - ) - - def test_no_action_creation_before(self): - """ - Check that an automated mail cannot be created with action='creation' - and moment='before'. - ----------------------- - An automated mail is created with action = 'creation' and moment = 'before'. - Then it is verified that a UserError was thrown because an automated_mail with - these parameters cannot be created. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "creation", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT & ASSERT - with self.assertRaises( - UserError, - msg="It should not be allowed to create the automated mail " - "with action 'creation' and moment 'before' values", - ): - self.env["pms.automated.mails"].create(automated_mail_vals) - - def test_trigger_moment_in_act_creation(self): - """ - Check that when creating an automated mail with parameters - action = 'creation' and moment = 'in_act' the trigger of the - automated_action created is 'on_create'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "creation", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_create", - "The trigger of the automated action must be 'on_create'", - ) - - def test_trigger_moment_after_in_creation_action(self): - """ - Check that when creating an automated mail with parameters - action = 'creation' and moment = 'after' the trigger of the - automated_action created is 'on_time'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "creation", - "moment": "after", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 1, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_time", - "The trigger of the automated action must be 'on_time'", - ) - - def test_trigger_moment_in_act_in_write_action(self): - """ - Check that when creating an automated mail with parameters - action = 'write' and moment = 'in_act' the trigger of the - automated_action created is 'on_write'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "write", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_write", - "The trigger of the automated action must be 'on_write'", - ) - - def test_trigger_moment_after_in_write_action(self): - """ - Check that when creating an automated mail with parameters - action = 'write' and moment = 'after' the trigger of the - automated_action created is 'on_time'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "write", - "moment": "after", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 1, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_time", - "The trigger of the automated action must be 'on_time'", - ) - - def test_time_moment_before_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'before' the trg_date_range - of the automated_action created is equal to - (automated_mail.time * -1)'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 60, - "time_type": "minutes", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - -60, - "The trg_date_range of the automated action must be '-60'", - ) - - def test_time_moment_in_act_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'in_act' the trg_date_range - of the automated_action created is equal to 0 - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - 0, - "The trg_date_range of the automated action must be '0'", - ) - - def test_trigger_moment_before_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'before' the trigger of the - automated_action created is 'on_time'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 24, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_time", - "The trigger of the automated action must be 'on_time'", - ) - - def test_trigger_moment_in_act_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'in_act' the trigger of the - automated_action created is 'on_write'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_write", - "The trigger of the automated action must be 'on_write'", - ) - - def test_time_moment_before_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'before' the trg_date_range - of the automated_action created is equal to - (automated_mail.time * -1)'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 60, - "time_type": "minutes", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - -60, - "The trg_date_range of the automated action must be '-60'", - ) - - def test_time_moment_in_act_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'in_act' the trg_date_range - of the automated_action created is equal to 0. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - 0, - "The trg_date_range of the automated action must be '0'", - ) - - def test_trigger_moment_before_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'before' the trigger of the - automated_action created is 'on_time'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 24, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_time", - "The trigger of the automated action must be 'on_time'", - ) - - def test_trigger_moment_in_act_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'in_act' the trigger of the - automated_action created is 'on_write'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_write", - "The trigger of the automated action must be 'on_write'", - ) - - def test_trigger_moment_in_act_in_payment_action(self): - """ - Check that when creating an automated mail with parameters - action = 'payment' and moment = 'in_act' the trigger of the - automated_action created is 'on_create'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "payment", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_create", - "The trigger of the automated action must be 'on_create'", - ) - - def test_trigger_moment_before_in_payment_action(self): - """ - Check that when creating an automated mail with parameters - action = 'payment' and moment = 'before' the trigger of the - automated_action created is 'on_time'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "payment", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 24, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_time", - "The trigger of the automated action must be 'on_time'", - ) - - def test_time_moment_before_in_payment_action(self): - """ - Check that when creating an automated mail with parameters - action = 'payment' and moment = 'before' the trg_date_range - field of the automated_action is (automated_mail.time * -1). - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "payment", - "moment": "before", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "time": 24, - "time_type": "hour", - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - -24, - "The trg_date_range of the automated action must be '-24'", - ) - - def test_trigger_moment_in_act_in_invoice_action(self): - """ - Check that when creating an automated mail with parameters - action = 'invoice' and moment = 'in_act' the trigger field - of the automated_action created is 'on_create'. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "invoice", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trigger, - "on_create", - "The trigger of the automated action must be 'on_create'", - ) - - def test_time_moment_in_act_in_invoice_action(self): - """ - Check that when creating an automated mail with parameters - action = 'invoice' and moment = 'in_act' the trg_date_range - field of the automated_action is 0. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "invoice", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.trg_date_range, - 0, - "The trg_date_range of the automated action must be '0'", - ) - - def test_filter_pre_domain_moment_in_act_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'in_act' the filter_pre_domain - field of the automated_action is [('state', '=', 'confirm')]. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.filter_pre_domain, - "[('state', '=', 'confirm')]", - "The filter_pre_domain of the automated action " - "must be '[('state', '=', 'confirm')]'", - ) - - def test_filter_domain_moment_in_act_in_checkin(self): - """ - Check that when creating an automated mail with parameters - action = 'checkin' and moment = 'in_act' the filter_domain - field of the automated_action is - [('state', '=', 'onboard'), ('pms_property_id', '=', [value of property_id.id])]]. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkin", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - pms_property_id_str = str(auto_mail.pms_property_ids.ids) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.filter_domain, - "[('state', '=', 'onboard'), ('pms_property_id', 'in', " - + pms_property_id_str - + ")]", - "The filter_domain of the automated action must be " - "'[('state', '=', 'onboard'), " - "('pms_property_id', '=', [value of property_id.id])]'", - ) - - def test_filter_pre_domain_moment_in_act_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'in_act' the filter_pre_domain - field of the automated_action is [('state', '=', 'onboard')]. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.filter_pre_domain, - "[('state', '=', 'onboard')]", - "The filter_pre_domain of the automated action must " - "be '[('state', '=', 'onboard')]'", - ) - - def test_filter_domain_moment_in_act_in_checkout(self): - """ - Check that when creating an automated mail with parameters - action = 'checkout' and moment = 'in_act' the filter_domain - field of the automated_action is - [('state', '=', 'out'), ('pms_property_id', '=', [value of property_id.id])]]. - """ - # ARRANGE - automated_mail_vals = { - "name": "Auto Mail 1", - "template_id": self.template.id, - "action": "checkout", - "moment": "in_act", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - - # ACT - auto_mail = self.env["pms.automated.mails"].create(automated_mail_vals) - pms_property_id_str = str(auto_mail.pms_property_ids.ids) - - # ASSERT - self.assertEqual( - auto_mail.automated_actions_id.filter_domain, - "[('state', '=', 'out'), ('pms_property_id', 'in', " - + pms_property_id_str - + ")]", - "The filter_pre_domain of the automated action must " - "be '[('state', '=', 'out'), ('pms_property_id', '=', [value of property_id.id])]", - ) diff --git a/pms/tests/test_pms_availability_plan_rules.py b/pms/tests/test_pms_availability_plan_rules.py deleted file mode 100644 index f3668bf70..000000000 --- a/pms/tests/test_pms_availability_plan_rules.py +++ /dev/null @@ -1,656 +0,0 @@ -import datetime - -from odoo import fields -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsRoomTypeAvailabilityRules(TestPms): - def setUp(self): - super().setUp() - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 1", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - - # pms.availability.plan - self.test_room_type_availability1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist2.id])], - } - ) - # pms.property - self.pms_property3 = self.env["pms.property"].create( - { - "name": "MY PMS TEST", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist2.id, - } - ) - - # pms.room.type - self.test_room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property3.id], - "name": "Single Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - # pms.room.type - self.test_room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [ - (4, self.pms_property3.id), - ], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - # pms.room - self.test_room1_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property3.id, - "name": "Double 201 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - # pms.room - self.test_room2_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property3.id, - "name": "Double 202 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - self.test_room1_single = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property3.id, - "name": "Single 101 test", - "room_type_id": self.test_room_type_single.id, - "capacity": 1, - } - ) - # pms.room - self.test_room2_single = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property3.id, - "name": "Single 102 test", - "room_type_id": self.test_room_type_single.id, - "capacity": 1, - } - ) - # partner - self.partner1 = self.env["res.partner"].create({"name": "Charles"}) - - def test_availability_rooms_all(self): - """ - Check the availability of rooms in a property with an availability plan without - availability rules. - --------------------- - The checkin and checkout dates on which the availability will be checked are saved - in a variable and in another all the rooms of the property are also saved. Then the - free_room_ids compute field is called which should return the number of available rooms - of the property and they are saved in another variable with which it is verified that - all the rooms have been returned because there are no availability rules for that plan. - """ - - # ARRANGE - checkin = fields.date.today() - checkout = (fields.datetime.today() + datetime.timedelta(days=4)).date() - test_rooms_double_rooms = self.env["pms.room"].search( - [("pms_property_id", "=", self.pms_property3.id)] - ) - # ACT - pms_property = self.pms_property3.with_context( - checkin=checkin, - checkout=checkout, - ) - result = pms_property.free_room_ids - - # ASSERT - obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) - self.assertTrue( - obtained, - "Availability should contain the test rooms" - "because there's no availability rules for them.", - ) - - def test_plan_avail_update_to_one(self): - """ - Check that the plan avail on a room is updated when the real avail is changed - -------------------------------------------------------------- - Room type with 2 rooms, new reservation with this room type, the plan avail - must to be updated to 1. You must know that the pricelist2 is linked - with the plan test_room_type_availability1 - """ - # ARRANGE - checkin = fields.date.today() - checkout = (fields.datetime.today() + datetime.timedelta(days=4)).date() - room_type = self.test_room_type_double - - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": fields.datetime.today(), - "pms_property_id": self.pms_property3.id, - } - ) - # ACT - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": checkin, - "checkout": checkout, - "partner_id": self.partner1.id, - "room_type_id": room_type.id, - } - ) - result = self.test_room_type_availability_rule1.plan_avail - - # ASSERT - self.assertEqual( - result, - 1, - "There should be only one room in the result of the availability plan" - "because the real avail is 1 and the availability plan" - "is updated.", - ) - - def test_plan_avail_update_to_zero(self): - """ - Check that the plan avail on a room is updated when the real avail is changed - with real avail 0 - -------------------------------------------------------------- - Room type with 2 rooms, two new reservations with this room type, the plan avail - must to be updated to 0. You must know that the pricelist2 is linked - with the plan test_room_type_availability1 - """ - # ARRANGE - checkin = fields.date.today() - checkout = (fields.datetime.today() + datetime.timedelta(days=4)).date() - room_type = self.test_room_type_double - - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": fields.datetime.today(), - "pms_property_id": self.pms_property3.id, - } - ) - # ACT - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": checkin, - "checkout": checkout, - "partner_id": self.partner1.id, - "room_type_id": room_type.id, - } - ) - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": checkin, - "checkout": checkout, - "partner_id": self.partner1.id, - "room_type_id": room_type.id, - } - ) - result = self.test_room_type_availability_rule1.plan_avail - - # ASSERT - self.assertEqual( - result, - 0, - "There should be zero in the result of the availability plan" - "because the real avail is 0 and the availability plan" - "is updated.", - ) - - def test_availability_rooms_all_lines(self): - """ - Check the availability of rooms in a property with an availability plan without - availability rules and passing it the reservation lines of a reservation for that - property. - ----------------- - The checkin and checkout dates on which the availability will be checked are saved - in a variable and in another all the rooms of the property are also saved. Then create - a reservation for this property and the free_room_ids compute field is called with the - parameters checkin, checkout and the reservation lines of the reservation as a curent - lines, this method should return the number of available rooms of the property. Then the - result is saved in another variable with which it is verified that all the rooms have - been returned because there are no availability rules for that plan. - """ - - # ARRANGE - checkin = fields.date.today() - checkout = (fields.datetime.today() + datetime.timedelta(days=4)).date() - test_rooms_double_rooms = self.env["pms.room"].search( - [("pms_property_id", "=", self.pms_property3.id)] - ) - test_reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": checkin, - "checkout": checkout, - "partner_id": self.partner1.id, - } - ) - - # ACT - # REVIEW: reservation without room and wihout room type? - pms_property = self.pms_property3.with_context( - checkin=checkin, - checkout=checkout, - current_lines=test_reservation.reservation_line_ids.ids, - ) - result = pms_property.free_room_ids - - # ASSERT - obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) - self.assertTrue( - obtained, - "Availability should contain the test rooms" - "because there's no availability rules for them.", - ) - - def test_availability_rooms_room_type(self): - """ - Check the availability of a room type for a property. - ---------------- - Double rooms of a property are saved in a variable. The free_room_ids compute field - is called giving as parameters checkin, checkout and the type of room (in this - case double). Then with the all () function we check that all rooms of this type - were returned. - """ - - # ARRANGE - test_rooms_double_rooms = self.env["pms.room"].search( - [ - ("pms_property_id", "=", self.pms_property3.id), - ("room_type_id", "=", self.test_room_type_double.id), - ] - ) - # ACT - pms_property = self.pms_property3.with_context( - checkin=fields.date.today(), - checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(), - room_type_id=self.test_room_type_double.id, - ) - result = pms_property.free_room_ids - - # ASSERT - obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) - self.assertTrue( - obtained, - "Availability should contain the test rooms" - "because there's no availability rules for them.", - ) - - def test_availability_closed_no_room_type(self): - """ - Check that rooms of a type with an availability rule with closed = True are - not available on the dates marked in the date field of the availability rule. - -------------------- - Create an availability rule for double rooms with the field closed = true - and the date from today until tomorrow. Then the availability is saved in a - variable through the free_room_ids computed field, passing it the pricelist that - it contains the availability plan where the rule is included, and the checkin - and checkout dates are between the date of the rule. Then it is verified that - the double rooms are not available. - """ - # ARRANGE - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": (fields.datetime.today() + datetime.timedelta(days=2)).date(), - "closed": True, # <- (1/2) - "pms_property_id": self.pms_property3.id, - } - ) - # ACT - pms_property = self.pms_property3.with_context( - checkin=fields.date.today(), - checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(), - # room_type_id=False, # <- (2/2) - pricelist_id=self.pricelist2.id, - ) - result = pms_property.free_room_ids - - # ASSERT - self.assertNotIn( - self.test_room_type_double, - result.mapped("room_type_id"), - "Availability should not contain rooms of a type " - "which its availability rules applies", - ) - - def test_availability_rules(self): - """ - Check through subtests that the availability rules are applied - for a specific room type. - ---------------- - Test cases: - 1. closed_arrival = True - 2. closed_departure = True - 3. min_stay = 5 - 4. max_stay = 2 - 5. min_stay_arrival = 5 - 6. max_stay_arrival = 3 - 7. quota = 0 - 8. max_avail = 0 - For each test case, it is verified through the free_room_ids compute field, - that double rooms are not available since the rules are applied to this - room type. - """ - - # ARRANGE - - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": fields.date.today(), - "pms_property_id": self.pms_property3.id, - } - ) - - checkin = fields.date.today() - checkout = (fields.datetime.today() + datetime.timedelta(days=4)).date() - - test_cases = [ - { - "closed": False, - "closed_arrival": True, - "closed_departure": False, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": True, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": -1, - "date": checkout, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 5, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 0, - "max_stay": 2, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 5, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 3, - "quota": -1, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": 0, - "max_avail": -1, - "date": checkin, - }, - { - "closed": False, - "closed_arrival": False, - "closed_departure": False, - "min_stay": 0, - "max_stay": 0, - "min_stay_arrival": 0, - "max_stay_arrival": 0, - "quota": -1, - "max_avail": 0, - "date": checkin, - }, - ] - - for test_case in test_cases: - with self.subTest(k=test_case): - - # ACT - self.test_room_type_availability_rule1.write(test_case) - - pms_property = self.pms_property3.with_context( - checkin=checkin, - checkout=checkout, - room_type_id=self.test_room_type_double.id, - pricelist_id=self.pricelist2.id, - ) - result = pms_property.free_room_ids - - # ASSERT - self.assertNotIn( - self.test_room_type_double, - result.mapped("room_type_id"), - "Availability should not contain rooms of a type " - "which its availability rules applies", - ) - - def test_rule_on_create_reservation(self): - """ - Check that a reservation is not created when an availability rule prevents it . - ------------------- - Create an availability rule for double rooms with the - field closed = True and the date from today until tomorrow. Then try to create - a reservation for that type of room with a checkin date today and a checkout - date within 4 days. This should throw a ValidationError since the rule does - not allow creating reservations for those dates. - """ - - # ARRANGE - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": (fields.datetime.today() + datetime.timedelta(days=2)).date(), - "closed": True, - "pms_property_id": self.pms_property3.id, - } - ) - checkin = datetime.datetime.now() - checkout = datetime.datetime.now() + datetime.timedelta(days=4) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Availability rules should be applied that would" - " prevent the creation of the reservation.", - ): - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": checkin, - "checkout": checkout, - "adults": 2, - "room_type_id": self.test_room_type_double.id, - "pricelist_id": self.pricelist2.id, - "partner_id": self.partner1.id, - } - ) - - def test_rule_update_quota_on_create_reservation(self): - """ - Check that the availability rule with quota = 1 for a room - type does not allow you to create more reservations than 1 - for that room type. - """ - - # ARRANGE - - self.test_room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": datetime.date.today(), - "quota": 1, - "pms_property_id": self.pms_property3.id, - } - ) - self.pricelist2.pms_property_ids = [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - (4, self.pms_property3.id), - ] - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": datetime.date.today(), - "checkout": datetime.date.today() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.test_room_type_double.id, - "pricelist_id": self.pricelist2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - with self.assertRaises( - ValidationError, - msg="The quota shouldnt be enough to create a new reservation", - ): - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": datetime.date.today(), - "checkout": datetime.date.today() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.test_room_type_double.id, - "pricelist_id": self.pricelist2.id, - "partner_id": self.partner1.id, - } - ) - - def test_rule_update_quota_on_update_reservation(self): - """ - Checks that an availability rule is maintained if its pricelist is modified. - --------------------- - Quota rule is restored after creating a reservation with pricelist linked - to an availability rule that applies and then modify the pricelist of the - reservation and no rules applies - """ - # ARRANGE - test_quota = 2 - test_pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 2", - } - ) - self.pricelist2.pms_property_ids = [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - (4, self.pms_property3.id), - ] - rule = self.env["pms.availability.plan.rule"].create( - { - "availability_plan_id": self.test_room_type_availability1.id, - "room_type_id": self.test_room_type_double.id, - "date": datetime.date.today(), - "quota": test_quota, - "pms_property_id": self.pms_property3.id, - } - ) - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property3.id, - "checkin": datetime.date.today(), - "checkout": datetime.date.today() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.test_room_type_double.id, - "pricelist_id": self.pricelist2.id, - "partner_id": self.partner1.id, - } - ) - - # ACT - reservation.pricelist_id = test_pricelist2.id - reservation.flush() - self.assertEqual( - test_quota, - rule.quota, - "The quota should be restored after changing the reservation's pricelist", - ) diff --git a/pms/tests/test_pms_board_service.py b/pms/tests/test_pms_board_service.py deleted file mode 100644 index 800301c84..000000000 --- a/pms/tests/test_pms_board_service.py +++ /dev/null @@ -1,410 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestBoardService(TestPms): - def setUp(self): - super().setUp() - self.company2 = self.env["res.company"].create( - { - "name": "Company 2", - } - ) - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Property 3", - "company_id": self.company2.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - def test_create_bs_one_company_inconsistent_code(self): - """ - Creation of board service with the same code as an existing one - belonging to the same property should fail. - - PRE: - board service bs1 exists - - board_service1 has code c1 - - board_service1 has pms_property1 - - pms_property1 has company company1 - ACT: - create a new board_service2 - - board_service2 has code c1 - - board_service2 has pms_property1 - - pms_property1 has company company1 - POST: - Integrity error: the room type already exists - - board_service2 not created - """ - # ARRANGE - # board_service1 - self.env["pms.board.service"].create( - { - "name": "Board service bs1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The board service has been created and it shouldn't" - ): - # board_service2 - self.env["pms.board.service"].create( - { - "name": "Board service bs2", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - - def test_create_bs_several_companies_inconsistent_code(self): - """ - Creation of board service with properties and one of its - properties has the same code on its board services should fail. - - PRE: - board service bs1 exists - - board_service1 has code c1 - - board_service1 has property pms_property1 - - pms_property1 has company company1 - ACT: - create a new board_service2 - - board_service2 has code c1 - - board_service2 has property pms_property1, pms_property2, - pms_property3 - - pms_property1, pms_property2 has company company1 - - pms_property3 has company company2 - POST: - Integrity error: the board service already exists - - board_service2 not created - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - # board_service1 - self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The board service has been created and it shouldn't" - ): - # board_service2 - self.env["pms.board.service"].create( - { - "name": "Board service bs2", - "default_code": "c1", - "pms_property_ids": [ - ( - 6, - 0, - [ - self.pms_property1.id, - self.pms_property2.id, - self.pms_property3.id, - ], - ) - ], - } - ) - - def test_search_bs_code_same_company_several_properties(self): - """ - Checks the search for a board service by code when the board service - belongs to properties of the same company - - PRE: - board service bs1 exists - - board_service1 has code c1 - - board_service1 has 2 properties pms_property1 and pms_property2 - - pms_property_1 and pms_property2 have the same company company1 - ACT: - search board service with code c1 and pms_property1 - - pms_property1 has company company1 - POST: - only board_service1 board service found - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property2.id]) - ], - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual( - board_services.id, - board_service1.id, - "Expected board service not found", - ) - - def test_search_bs_code_several_companies_several_properties_not_found(self): - """ - Checks the search for a board service by code when the board service - belongs to properties with different companies - - PRE: - board service bs1 exists - - board_service1 has code c1 - - board_service1 has 2 properties pms_property1 and pms_property3 - - pms_property1 and pms_property3 have different companies - - pms_property1 have company company1 and pms_property3 have company2 - ACT: - search board service with code c1 and property pms_property1 - - pms_property1 has company company1 - POST: - only board_service1 room type found - """ - # ARRANGE - bs1 = self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual(board_services.id, bs1.id, "Expected board service not found") - - def test_search_bs_code_no_result(self): - """ - Search for a specific board service code and its property. - The board service exists but not in the property given. - - PRE: - board_service1 exists - - board_service1 has code c1 - - board_service1 with 2 properties pms_property1 and pms_property2 - - pms_property1 and pms_property2 have same company company1 - ACT: - search board service with code c1 and property pms_property3 - - pms_property3 have company company2 - POST: - no room type found - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - # board_service1 - self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property2.id]) - ], - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property3.id, "c1" - ) - # ASSERT - self.assertFalse( - board_services, "Board service found but it should not have found any" - ) - - def test_search_bs_code_present_all_companies_and_properties(self): - """ - Search for a specific board service and its property. - The board service exists without property, then - the search foundS the result. - - PRE: - board_service1 exists - - board_service1 has code c1 - - board_service1 properties are null - ACT: - search board service with code c1 and property pms_property1 - - pms_property1 have company company1 - POST: - only board_service1 board service found - """ - # ARRANGE - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": False, - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual( - board_services.id, - board_service1.id, - "Expected board service not found", - ) - - def test_search_bs_code_several_companies_several_properties(self): - """ - Search for a specific board service and its property. - There is one board service without properties and - another one with the same code that belongs to 2 properties - (from different companies) - The search founds only the board service that match the - property given. - - PRE: - board_service1 exists - - board_service1 has code c1 - - board_service1 has 2 properties pms_property1 and pms_property3 - - pms_property1 and pms_property2 have the same company company1 - - board service board_service2 exists - - board_service2 has code c1 - - board_service2 has no properties - ACT: - search board service with code c1 and property pms_property1 - - pms_property1 have company company1 - POST: - only board_service1 board service found - """ - # ARRANGE - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - } - ) - # board_service2 - self.env["pms.board.service"].create( - { - "name": "Board service bs2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual( - board_services.id, - board_service1.id, - "Expected board service not found", - ) - - def test_search_bs_code_same_companies_several_properties(self): - """ - Search for a specific board service and its property. - There is one board service without properties and - another one with the same code that belongs to 2 properties - (same company). - The search founds only the board service that match the - property given. - - PRE: - board_service1 exists - - board_service1 has code c1 - - board_service1 has property pms_property1 - - pms_property1 have the company company1 - - board service board_service2 exists - - board_service2 has code c1 - - board_service2 has no properties - ACT: - search board service with code c1 and pms_property2 - - pms_property2 have company company1 - POST: - only board_service2 board service found - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - board_service2 = self.env["pms.board.service"].create( - { - "name": "Board service bs2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property2.id, "c1" - ) - # ASSERT - self.assertEqual( - board_services.id, - board_service2.id, - "Expected board service not found", - ) - - def test_search_bs_code_no_properties(self): - """ - Search for a specific board service and its property. - There is one board service without properties and - another one with the same code that belongs to one property. - The search founds only the board service that match the - property given that it's not the same as the 2nd one. - - PRE: - board_service1 exists - - board_service1 has code c1 - - board_service1 has property pms_property1 - - pms_property1 have the company company1 - - board service board_service2 exists - - board_service2 has code c1 - - board_service2 has no properties - ACT: - search board service with code c1 and property pms_property3 - - pms_property3 have company company2 - POST: - only board_service2 board service found - """ - # ARRANGE - # board_service1 - self.env["pms.board.service"].create( - { - "name": "Board service bs1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - board_service2 = self.env["pms.board.service"].create( - { - "name": "Board service bs2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - # ACT - board_services = self.env["pms.board.service"].get_unique_by_property_code( - self.pms_property3.id, "c1" - ) - # ASSERT - self.assertEqual( - board_services.id, - board_service2.id, - "Expected board service not found", - ) diff --git a/pms/tests/test_pms_booking_engine.py b/pms/tests/test_pms_booking_engine.py deleted file mode 100644 index e3be0f92f..000000000 --- a/pms/tests/test_pms_booking_engine.py +++ /dev/null @@ -1,964 +0,0 @@ -import datetime - -from freezegun import freeze_time - -from odoo import fields - -from .common import TestPms - - -class TestPmsBookingEngine(TestPms): - def setUp(self): - super().setUp() - # CREATION OF ROOM TYPE (WITH ROOM TYPE CLASS) - self.test_room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "list_price": 40.0, - } - ) - - # pms.room - self.test_room1_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 201 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - # pms.room - self.test_room2_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 202 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - # pms.room - self.test_room3_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 203 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - # pms.room - self.test_room4_double = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 204 test", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - # res.partner - self.partner_id = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "654667733", - "email": "miguel@example.com", - } - ) - - def test_price_wizard_correct(self): - # TEST CASE - """ - Check by subtests if the total_price field is applied correctly - with and without discount. - ------------ - Create two test cases: one with the discount at 0 and with the - expected total price, which is the difference in days between - checkin and checkout, multiplied by the room price and multiplied - by the number of rooms, and another with the discount at 0.5 and with - total price the same as the first. Then the wizard is created and it - is verified that the wizard's total_price_folio is the same as the - expected price. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - days = (checkout - checkin).days - num_double_rooms = 4 - discounts = [ - { - "discount": 0, - "expected_price": days - * self.test_room_type_double.list_price - * num_double_rooms, - }, - { - "discount": 0.5, - "expected_price": ( - days * self.test_room_type_double.list_price * num_double_rooms - ) - * 0.5, - }, - ] - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - } - ) - - # force pricelist load - - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - - # set value for room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", num_double_rooms), - ] - ) - - lines_availability_test[0].num_rooms_selected = value - for discount in discounts: - with self.subTest(k=discount): - # ACT - booking_engine.discount = discount["discount"] - - # ASSERT - self.assertEqual( - booking_engine.total_price_folio, - discount["expected_price"], - "The total price calculation is wrong", - ) - - def test_price_wizard_correct_pricelist_applied(self): - """ - Check that the total_price field is applied correctly in - the wizard(pricelist applied). - ------------------ - Create a pricelist item for pricelist1 and a wizard is also - created with pricelist1. Then it is verified that the value - of the total price of the wizard corresponds to the value of - the price of the pricelist item. - """ - - # ARRANGE - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - days = (checkout - checkin).days - - # num. rooms of type double to book - num_double_rooms = 4 - - # price for today - price_today = 38.0 - - # expected price - expected_price_total = days * price_today * num_double_rooms - - # set pricelist item for current day - product_tmpl = self.test_room_type_double.product_id.product_tmpl_id - self.env["product.pricelist.item"].create( - { - "pricelist_id": self.pricelist1.id, - "date_start_consumption": checkin, - "date_end_consumption": checkin, - "compute_price": "fixed", - "applied_on": "1_product", - "product_tmpl_id": product_tmpl.id, - "fixed_price": price_today, - "min_quantity": 0, - "pms_property_ids": product_tmpl.pms_property_ids.ids, - } - ) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - - # set value for room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", num_double_rooms), - ] - ) - - # ACT - lines_availability_test[0].num_rooms_selected = value - - # ASSERT - self.assertEqual( - booking_engine.total_price_folio, - expected_price_total, - "The total price calculation is wrong", - ) - - # REVIEW: This test is set to check min qty, but the workflow price, actually, - # always is set to 1 qty and the min_qty cant be applied. - # We could set qty to number of rooms?? - - # def test_price_wizard_correct_pricelist_applied_min_qty_applied(self): - # # TEST CASE - # # Set values for the wizard and the total price is correct - # # (pricelist applied) - - # # ARRANGE - # # common scenario - # self.create_common_scenario() - - # # checkin & checkout - # checkin = fields.date.today() - # checkout = fields.date.today() + datetime.timedelta(days=1) - # days = (checkout - checkin).days - - # # set pricelist item for current day - # product_tmpl_id = self.test_room_type_double.product_id.product_tmpl_id.id - # pricelist_item = self.env["product.pricelist.item"].create( - # { - # "pricelist_id": self.test_pricelist.id, - # "date_start_consumption": checkin, - # "date_end_consumption": checkin, - # "compute_price": "fixed", - # "applied_on": "1_product", - # "product_tmpl_id": product_tmpl_id, - # "fixed_price": 38.0, - # "min_quantity": 4, - # } - # ) - - # # create folio wizard with partner id => pricelist & start-end dates - # booking_engine = self.env["pms.booking.engine"].create( - # { - # "start_date": checkin, - # "end_date": checkout, - # "partner_id": self.partner_id.id, - # "pricelist_id": self.test_pricelist.id, - # } - # ) - - # # availability items belonging to test property - # lines_availability_test = self.env["pms.folio.availability.wizard"].search( - # [ - # ("room_type_id.pms_property_ids", "in", self.test_property.id), - # ] - # ) - - # test_cases = [ - # { - # "num_rooms": 3, - # "expected_price": 3 * self.test_room_type_double.list_price * days, - # }, - # {"num_rooms": 4, "expected_price": 4 * pricelist_item.fixed_price * days}, - # ] - # import wdb; wdb.set_trace() - # for tc in test_cases: - # with self.subTest(k=tc): - # # ARRANGE - # # set value for room type double - # value = self.env["pms.num.rooms.selection"].search( - # [ - # ("room_type_id", "=", self.test_room_type_double.id), - # ("value", "=", tc["num_rooms"]), - # ] - # ) - # # ACT - # lines_availability_test[0].num_rooms_selected = value - - # # ASSERT - # self.assertEqual( - # booking_engine.total_price_folio, - # tc["expected_price"], - # "The total price calculation is wrong", - # ) - - def test_check_create_folio(self): - """ - Test that a folio is created correctly from the booking engine wizard. - ------------ - The wizard is created with a partner_id, a pricelist, and start and end - dates for property1. The availability items are searched for that property - and in the first one a double room is set. The create_folio() method of the - wizard is launched. The folios of the partner_id entered in the wizard are - searched and it is verified that the folio exists. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - # set one room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - - # ACT - booking_engine.create_folio() - - # ASSERT - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - self.assertTrue(folio, "Folio not created.") - - def test_check_create_reservations(self): - """ - Check that reservations are created correctly from the booking engine wizard. - ------------ - The wizard is created with a partner_id, a pricelist, and start and end - dates for property1. The availability items are searched for that property - and in the first one, two double rooms are set, which create two reservations - too. The create_folio() method of the wizard is launched. The folios of the - partner_id entered in the wizard are searched and it is verified that the two - reservations of the folio was created. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - # set one room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 2), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 2 - - # ACT - booking_engine.create_folio() - - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - # ASSERT - self.assertEqual(len(folio.reservation_ids), 2, "Reservations not created.") - - def test_values_folio_created(self): - """ - Check that the partner_id and pricelist_id values of the folio correspond - to the partner_id and pricelist_id of the booking engine wizard that created - the folio. - ----------- - The wizard is created with a partner_id, a pricelist, and start and end - dates for property1. The availability items are searched for that property - and in the first one a double room are set. The create_folio() method of the - wizard is launched. Then it is checked that the partner_id and the pricelist_id - of the created folio are the same as the partner_id and the pricelist_id of the - booking engine wizard. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - # set one room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 1 - - # ACT - booking_engine.create_folio() - vals = { - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - } - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - # ASSERT - for key in vals: - with self.subTest(k=key): - self.assertEqual( - folio[key].id, - vals[key], - "The value of " + key + " is not correctly established", - ) - - def test_values_reservation_created(self): - """ - Check with subtests that the values of the fields of a reservation created through - a booking engine wizard are correct. - -------------- - The wizard is created with a partner_id, a pricelist, and start and end - dates for property1. The availability items are searched for that property - and in the first one a double room are set. The create_folio() method of the - wizard is launched. A vals dictionary is created with folio_id, checkin and - checkout, room_type_id, partner_id, pricelist_id, and pms_property_id. Then - the keys of this dictionary are crossed and it is verified that the values - correspond with the values of the reservation created from the wizard . - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - # set one room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 1 - - # ACT - booking_engine.create_folio() - - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - vals = { - "folio_id": folio.id, - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.test_room_type_double.id, - "partner_id": self.partner_id.id, - "pricelist_id": folio.pricelist_id.id, - "pms_property_id": self.pms_property1.id, - } - - # ASSERT - for reservation in folio.reservation_ids: - for key in vals: - with self.subTest(k=key): - self.assertEqual( - reservation[key].id - if key - in [ - "folio_id", - "partner_id", - "pricelist_id", - "pms_property_id", - "room_type_id", - ] - else reservation[key], - vals[key], - "The value of " + key + " is not correctly established", - ) - - def test_reservation_line_discounts(self): - """ - Check that a discount applied to a reservation from a booking engine wizard - is applied correctly in the reservation line. - ----------------- - The wizard is created with a partner_id, a pricelist, a discount of 0.5 and - start and end dates for property1. The availability items are searched for - that property and in the first one a double room are set. The create_folio() - method of the wizard is launched.Then it is verified that the discount of the - reservation line is equal to the discount applied in the wizard. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - discount = 0.5 - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "discount": discount, - "pms_property_id": self.pms_property1.id, - } - ) - # availability items belonging to test property - lines_availability_test = self.env["pms.folio.availability.wizard"].search( - [ - ("room_type_id.pms_property_ids", "in", self.pms_property1.id), - ] - ) - # set one room type double - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 1 - - # ACT - booking_engine.create_folio() - - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - # ASSERT - for line in folio.reservation_ids.reservation_line_ids: - with self.subTest(k=line): - self.assertEqual( - line.discount, - discount * 100, - "The discount is not correctly established", - ) - - def test_check_quota_avail(self): - """ - Check that the availability for a room type in the booking engine - wizard is correct by creating an availability_plan_rule with quota. - ----------------- - An availability_plan_rule with quota = 1 is created for the double - room type. A booking engine wizard is created with the checkin same - date as the availability_plan_rule and with pricelist1, which also has - the availability_plan set that contains the availability_plan_rule - created before. Then the availability is searched for the type of - double room which must be 1 because the availavility_plan_rule quota - for that room is 1. - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - self.availability_plan1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - self.env["pms.availability.plan.rule"].create( - { - "quota": 1, - "room_type_id": self.test_room_type_double.id, - "availability_plan_id": self.availability_plan1.id, - "date": fields.date.today(), - "pms_property_id": self.pms_property1.id, - } - ) - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - room_type_plan_avail = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_double.id - ).num_rooms_available - - # ASSERT - - self.assertEqual(room_type_plan_avail, 1, "Quota not applied in Wizard Folio") - - def test_check_min_stay_avail(self): - """ - Check that the availability for a room type in the booking engine - wizard is correct by creating an availability_plan_rule with min_stay. - ----------------- - An availability_plan_rule with min_stay = 3 is created for the double - room type. A booking engine wizard is created with start_date = today - and end_date = tomorrow. Then the availability is searched for the type of - double room which must be 0 because the availability_plan_rule establishes - that the min_stay is 3 days and the difference of days in the booking engine - wizard is 1 . - """ - - # ARRANGE - - # checkin & checkout - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - # AVAILABILITY PLAN CREATION - self.availability_plan1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - self.env["pms.availability.plan.rule"].create( - { - "min_stay": 3, - "room_type_id": self.test_room_type_double.id, - "availability_plan_id": self.availability_plan1.id, - "date": fields.date.today(), - "pms_property_id": self.pms_property1.id, - } - ) - - # create folio wizard with partner id => pricelist & start-end dates - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - room_type_plan_avail = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_double.id - ).num_rooms_available - - # ASSERT - - self.assertEqual(room_type_plan_avail, 0, "Quota not applied in Wizard Folio") - - @freeze_time("2015-05-05") - def _test_price_total_with_board_service(self): - """ - In booking engine when in availability results choose a room or several - and also choose a board service, the total price is calculated from price of the room, - number of nights, board service included price and number of guests - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - self.product_test1 = self.env["product.product"].create( - { - "name": "Test Product 1", - "per_day": True, - "consumed_on": "after", - } - ) - self.board_service_test = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - } - ) - self.env["pms.board.service.line"].create( - { - "pms_board_service_id": self.board_service_test.id, - "product_id": self.product_test1.id, - "amount": 8, - } - ) - self.board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.test_room_type_double.id, - "pms_board_service_id": self.board_service_test.id, - } - ) - # self.board_service_room_type.flush() - # ACT - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - lines_availability_test = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_double.id - ) - - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 1 - lines_availability_test[ - 0 - ].board_service_room_id = self.board_service_room_type.id - - self.test_room_type_double.list_price = 25 - - room_price = self.test_room_type_double.list_price - days = (checkout - checkin).days - board_service_price = self.board_service_test.amount - room_capacity = self.test_room_type_double.get_capacity() - expected_price = room_price * days + ( - board_service_price * room_capacity * days - ) - - # ASSERT - self.assertEqual( - lines_availability_test[0].price_per_room, - expected_price, - "The total price calculation is wrong", - ) - - @freeze_time("2014-05-05") - def test_board_service_discount(self): - """ - In booking engine when a discount is indicated it must be - applied correctly on both reservation lines and board services, - whether consumed after or before night - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - self.product_test1 = self.env["product.product"].create( - { - "name": "Test Product 1", - "per_day": True, - "consumed_on": "after", - } - ) - self.board_service_test = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - } - ) - self.env["pms.board.service.line"].create( - { - "pms_board_service_id": self.board_service_test.id, - "product_id": self.product_test1.id, - "amount": 8, - } - ) - self.board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.test_room_type_double.id, - "pms_board_service_id": self.board_service_test.id, - } - ) - discount = 15 - - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id.id, - "pricelist_id": self.pricelist1.id, - "discount": discount, - "pms_property_id": self.pms_property1.id, - } - ) - - lines_availability_test = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_double.id - ) - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test[0].num_rooms_selected = value - lines_availability_test[0].value_num_rooms_selected = 1 - lines_availability_test[ - 0 - ].board_service_room_id = self.board_service_room_type.id - - # ACT - booking_engine.create_folio() - - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id.id)]) - - # ASSERT - for line in folio.service_ids.service_line_ids: - if line.is_board_service: - self.assertEqual( - line.discount, - discount * 100, - "The discount is not correctly established", - ) - - def test_check_folio_when_change_selection(self): - """ - Check, when creating a folio from booking engine, - if a room type is chosen and then deleted that selection - isn`t registered on the folio and is properly unselected - """ - # ARRANGE - # CREATION OF ROOM TYPE (WITH ROOM TYPE CLASS) - self.partner_id2 = self.env["res.partner"].create( - { - "name": "Brais", - "mobile": "654665553", - "email": "braistest@example.com", - } - ) - self.test_room_type_triple = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Triple Test", - "default_code": "TRP_Test", - "class_id": self.room_type_class1.id, - "list_price": 60.0, - } - ) - - # pms.room - self.test_room1_triple = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Triple 301 test", - "room_type_id": self.test_room_type_triple.id, - "capacity": 3, - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=1) - - booking_engine = self.env["pms.booking.engine"].create( - { - "start_date": checkin, - "end_date": checkout, - "partner_id": self.partner_id2.id, - "pricelist_id": self.pricelist1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - lines_availability_test_double = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_double.id - ) - value = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_double.id), - ("value", "=", 1), - ] - ) - lines_availability_test_double[0].num_rooms_selected = value - lines_availability_test_double[0].value_num_rooms_selected = 1 - - lines_availability_test_double[0].value_num_rooms_selected = 0 - - lines_availability_test_triple = booking_engine.availability_results.filtered( - lambda r: r.room_type_id.id == self.test_room_type_triple.id - ) - value_triple = self.env["pms.num.rooms.selection"].search( - [ - ("room_type_id", "=", self.test_room_type_triple.id), - ("value", "=", 1), - ] - ) - lines_availability_test_triple[0].num_rooms_selected = value_triple - lines_availability_test_triple[0].value_num_rooms_selected = 1 - - # ACT - booking_engine.create_folio() - - folio = self.env["pms.folio"].search([("partner_id", "=", self.partner_id2.id)]) - # ASSERT - self.assertEqual( - len(folio.reservation_ids), - 1, - "Reservations of folio are incorrect", - ) diff --git a/pms/tests/test_pms_checkin_partner.py b/pms/tests/test_pms_checkin_partner.py deleted file mode 100644 index 29cd15214..000000000 --- a/pms/tests/test_pms_checkin_partner.py +++ /dev/null @@ -1,1477 +0,0 @@ -import datetime -import logging - -from freezegun import freeze_time - -from odoo import fields -from odoo.exceptions import ValidationError - -from .common import TestPms - -_logger = logging.getLogger(__name__) - - -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", - "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": 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": self.pms_property1.id, - } - self.reservation_1 = self.env["pms.reservation"].create(reservation_vals) - self.checkin1 = self.env["pms.checkin.partner"].create( - { - "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 - checkins_count = len(self.reservation_1.checkin_partner_ids) - # ASSERT - self.assertEqual( - checkins_count, - 3, - "the automatic partner checkin was not created successful", - ) - - @freeze_time("2012-01-14") - def test_auto_unlink_checkins(self): - # ACTION - host2 = self.env["res.partner"].create( - { - "name": "Carlos", - "mobile": "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": "85564627G", - "valid_from": datetime.date.today(), - "partner_id": host2.id, - } - ) - self.reservation_1.checkin_partner_ids = [ - ( - 0, - False, - { - "partner_id": host2.id, - }, - ) - ] - - checkins_count = len(self.reservation_1.checkin_partner_ids) - - # ASSERT - self.assertEqual( - checkins_count, - 3, - "the automatic partner checkin was not updated successful", - ) - - def test_onboard_checkin(self): - """ - Check that the reservation cannot be onboard because - checkin_partner data are incomplete and not have onboard status - """ - - # ACT & ASSERT - 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): - """ - Check that reservation state is onboard as the checkin day is - today and checkin_partners data are complete - """ - # ACT - self.checkin1.action_on_board() - - # ASSERT - self.assertEqual( - self.reservation_1.state, - "onboard", - "the reservation checkin was not successful", - ) - - @freeze_time("2012-01-14") - def test_premature_checkin(self): - """ - Check that cannot change checkin_partner state to onboard if - it's not yet checkin day - """ - - # ARRANGE - self.reservation_1.write( - { - "checkin": datetime.date.today() + datetime.timedelta(days=1), - } - ) - # ACT & ASSERT - with self.assertRaises(ValidationError, msg="Cannot do checkin onboard"): - self.checkin1.action_on_board() - - @freeze_time("2012-01-14") - def test_late_checkin_on_checkout_day(self): - """ - Check that allowed register checkin arrival the next day - even if it is the same day of checkout - """ - - # ARRANGE - self.reservation_1.write( - { - "checkin": datetime.date.today() + datetime.timedelta(days=-1), - "checkout": datetime.date.today(), - } - ) - - # ACT - self.checkin1.action_on_board() - - # ASSERT - self.assertEqual( - self.checkin1.arrival, - fields.datetime.now(), - """The system did not allow to check in the next - day because it was the same day of checkout""", - ) - - @freeze_time("2012-01-13") - def test_late_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.reservation_1.write( - { - "checkin": datetime.date.today(), - } - ) - - # ACT - self.checkin1.action_on_board() - - # ASSERT - self.assertEqual( - self.checkin1.arrival, - fields.datetime.now(), - "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 - host2 = self.env["res.partner"].create( - { - "name": "Carlos", - "mobile": "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": "95876871Z", - "valid_from": datetime.date.today(), - "partner_id": host2.id, - } - ) - host3 = self.env["res.partner"].create( - { - "name": "Enmanuel", - "mobile": "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": "58261664L", - "valid_from": datetime.date.today(), - "partner_id": host3.id, - } - ) - host4 = self.env["res.partner"].create( - { - "name": "Enrique", - "mobile": "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": "61645604S", - "valid_from": datetime.date.today(), - "partner_id": host4.id, - } - ) - self.env["pms.checkin.partner"].create( - { - "partner_id": host2.id, - "reservation_id": self.reservation_1.id, - } - ) - self.env["pms.checkin.partner"].create( - { - "partner_id": host3.id, - "reservation_id": self.reservation_1.id, - } - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Reservation cannot have more checkin_partner than adults who have", - ): - self.reservation_1.write( - { - "checkin_partner_ids": [ - ( - 0, - 0, - { - "partner_id": host4.id, - }, - ) - ] - } - ) - - @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", - "mobile": "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": "63073204M", - "valid_from": datetime.date.today(), - "partner_id": self.host2.id, - } - ) - self.host3 = self.env["res.partner"].create( - { - "name": "Enmanuel", - "mobile": "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": "70699468K", - "valid_from": datetime.date.today(), - "partner_id": self.host3.id, - } - ) - - self.checkin2 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host2.id, - "reservation_id": self.reservation_1.id, - } - ) - self.checkin3 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host3.id, - "reservation_id": self.reservation_1.id, - } - ) - - # ACT - self.checkin1.action_on_board() - self.checkin2.action_on_board() - - # ASSERT - self.assertEqual( - self.reservation_1.count_pending_arrival, - 1, - "Fail the count pending arrival on reservation", - ) - self.assertEqual( - self.reservation_1.checkins_ratio, - int(2 * 100 / 3), - "Fail the checkins ratio on reservation", - ) - - 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.host2 = self.env["res.partner"].create( - { - "name": "Carlos", - "mobile": "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": "12650631X", - "valid_from": datetime.date.today(), - "partner_id": self.host2.id, - } - ) - # ACT - - self.checkin2 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host2.id, - "reservation_id": self.reservation_1.id, - } - ) - pending_checkin_data = self.reservation_1.pending_checkin_data - ratio_checkin_data = self.reservation_1.ratio_checkin_data - # ASSERT - self.assertEqual( - pending_checkin_data, - 1, - "Fail the count pending checkin data on reservation", - ) - self.assertEqual( - ratio_checkin_data, - int(2 * 100 / 3), - "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.host2 = self.env["res.partner"].create( - { - "name": "Carlos", - "mobile": "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": "61369791H", - "valid_from": datetime.date.today(), - "partner_id": self.host2.id, - } - ) - self.host3 = self.env["res.partner"].create( - { - "name": "Enmanuel", - "mobile": "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": "53563260D", - "valid_from": datetime.date.today(), - "partner_id": self.host3.id, - } - ) - self.host4 = self.env["res.partner"].create( - { - "name": "Enrique", - "mobile": "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": "63742138F", - "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-19 10:00:00") - freezer.start() - PmsReservation.auto_arrival_delayed() - - arrival_delayed_reservations = folio_1.reservation_ids.filtered( - lambda r: r.state == "arrival_delayed" - ) - - # ASSERT - self.assertEqual( - len(arrival_delayed_reservations), - 3, - "Reservations not set like No Show", - ) - 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.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() - - # ACTION - freezer = freeze_time("2012-01-17 12:00:00") - freezer.start() - PmsReservation.auto_departure_delayed() - - freezer.stop() - # ASSERT - self.assertEqual( - self.reservation_1.state, - "departure_delayed", - "Reservations not set like Departure delayed", - ) - - # REVIEW: Redesing constrains mobile&mail control - # @freeze_time("2010-12-10") - # def test_not_valid_emails(self): - # # TEST CASES - # # Check that the email format is incorrect - - # # ARRANGE - # reservation = self.env["pms.reservation"].create( - # { - # "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.pms_property1.id, - # } - # ) - # test_cases = [ - # "myemail", - # "myemail@", - # "myemail@", - # "myemail@.com", - # ".myemail", - # ".myemail@", - # ".myemail@.com" ".myemail@.com." "123myemail@aaa.com", - # ] - # for mail in test_cases: - # with self.subTest(i=mail): - # with self.assertRaises( - # ValidationError, msg="Email format is correct and shouldn't" - # ): - # reservation.write( - # { - # "checkin_partner_ids": [ - # ( - # 0, - # False, - # { - # "name": "Carlos", - # "email": mail, - # }, - # ) - # ] - # } - # ) - - # @freeze_time("2014-12-10") - # def test_valid_emails(self): - # # TEST CASES - # # Check that the email format is correct - - # # ARRANGE - # reservation = self.env["pms.reservation"].create( - # { - # "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.pms_property1.id, - # } - # ) - # test_cases = [ - # "hello@commitsun.com", - # "hi.welcome@commitsun.com", - # "hi.welcome@dev.commitsun.com", - # "hi.welcome@dev-commitsun.com", - # "john.doe@xxx.yyy.zzz", - # ] - # for mail in test_cases: - # with self.subTest(i=mail): - # guest = self.env["pms.checkin.partner"].create( - # { - # "name": "Carlos", - # "email": mail, - # "reservation_id": reservation.id, - # } - # ) - # self.assertEqual( - # mail, - # guest.email, - # ) - # guest.unlink() - - # @freeze_time("2016-12-10") - # def test_not_valid_phone(self): - # # TEST CASES - # # Check that the phone format is incorrect - - # # ARRANGE - # reservation = self.env["pms.reservation"].create( - # { - # "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.pms_property1.id, - # } - # ) - # test_cases = [ - # "phone", - # "123456789123", - # "123.456.789", - # "123", - # "123123", - # ] - # for phone in test_cases: - # with self.subTest(i=phone): - # with self.assertRaises( - # ValidationError, msg="Phone format is correct and shouldn't" - # ): - # self.env["pms.checkin.partner"].create( - # { - # "name": "Carlos", - # "mobile": phone, - # "reservation_id": reservation.id, - # } - # ) - - # @freeze_time("2018-12-10") - # def test_valid_phones(self): - # # TEST CASES - # # Check that the phone format is correct - - # # ARRANGE - # reservation = self.env["pms.reservation"].create( - # { - # "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.pms_property1.id, - # } - # ) - # test_cases = [ - # "981 981 981", - # "981981981", - # "981 98 98 98", - # ] - # for mobile in test_cases: - # with self.subTest(i=mobile): - # guest = self.env["pms.checkin.partner"].create( - # { - # "name": "Carlos", - # "mobile": mobile, - # "reservation_id": reservation.id, - # } - # ) - # self.assertEqual( - # 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, - } - ) - - checkin.flush() - - # 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.checkin1.flush() - 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", - "mobile": "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", - ) - - def test_is_possible_customer_by_email(self): - """ - It is checked that the field possible_existing_customer_ids - exists in a checkin partner with an email from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A checkin partner - is created by adding the same email as the res.partner. Then it is - checked that some possible_existing_customer_ids exists. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Courtney Campbell", - "email": "courtney@example.com", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type1.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "email": partner.email, - } - ) - # ACT - checkin = self.env["pms.checkin.partner"].create( - { - "name": partner.name, - "email": partner.email, - "reservation_id": reservation.id, - } - ) - # ASSERT - self.assertTrue( - checkin.possible_existing_customer_ids, - "No customer found with this email", - ) - - def test_is_possible_customer_by_mobile(self): - """ - It is checked that the field possible_existing_customer_ids - exists in a checkin partner with a mobile from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A checkin partner - is created by adding the same mobile as the res.partner. Then it is - checked that some possible_existing_customer_ids exists. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Ledicia Sandoval", - "mobile": "615369231", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type1.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - } - ) - # ACT - checkin = self.env["pms.checkin.partner"].create( - { - "name": partner.name, - "mobile": partner.mobile, - "reservation_id": reservation.id, - } - ) - # ASSERT - self.assertTrue( - checkin.possible_existing_customer_ids, - "No customer found with this mobile", - ) - - def test_add_possible_customer(self): - """ - Check that a partner was correctly added to the checkin partner - after launching the add_partner() method of the several partners wizard - --------------- - A res.partner is created with name, email and mobile. A checkin partner is - created with the email field equal to that of the res.partner created before. - The wizard is created with the checkin partner id and the partner added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is checked that the partner was correctly added to the - checkin partner. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type1.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - } - ) - checkin = self.env["pms.checkin.partner"].create( - { - "name": partner.name, - "email": partner.email, - "reservation_id": reservation.id, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "checkin_partner_id": checkin.id, - "possible_existing_customer_ids": [(6, 0, [partner.id])], - } - ) - # ACT - several_partners_wizard.add_partner() - # ASSERT - self.assertEqual( - checkin.partner_id.id, - partner.id, - "The partner was not added to the checkin partner ", - ) - - def test_not_add_several_possibles_customers(self): - """ - Check that multiple partners cannot be added to a checkin partner - from the several partners wizard. - --------------- - Two res.partner are created with name, email and mobile. A checkin partner is - created with the email field equal to that of the partner1 created before. - The wizard is created with the checkin partner id and the two partners added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is verified that a Validation_Error was raised. - """ - # ARRANGE - partner1 = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - partner2 = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type1.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner1.name, - } - ) - - checkin = self.env["pms.checkin.partner"].create( - { - "name": partner1.name, - "email": partner1.email, - "reservation_id": reservation.id, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "checkin_partner_id": checkin.id, - "possible_existing_customer_ids": [(6, 0, [partner1.id, partner2.id])], - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="Two partners cannot be added to the checkin partner", - ): - several_partners_wizard.add_partner() - - def test_not_add_any_possibles_customers(self): - """ - Check that the possible_existing_customer_ids field of the several - partners wizard can be left empty and then launch the add_partner() - method of this wizard to add a partner in checkin_partner. - --------------- - A checkin_partner is created. The wizard is created without the - possible_existing_customer_ids field. The add_partner method of - the wizard is launched and it is verified that a Validation_Error - was raised. - """ - - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type1.id, - "pms_property_id": self.pms_property1.id, - "partner_name": "Rosa Costa", - } - ) - checkin = self.env["pms.checkin.partner"].create( - {"name": "Rosa Costa", "reservation_id": reservation.id} - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "checkin_partner_id": checkin.id, - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="A partner can be added to the checkin partner", - ): - several_partners_wizard.add_partner() - - def test_calculate_dni_expedition_date_from_validity_date_age_lt_30(self): - """ - Check that the calculate_doc_type_expedition_date_from_validity_date() - method calculates correctly the expedition_date of an id category DNI - when the age is less than 30. - ------------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id DNI, birthdate calculated so that the age - is = 20 years old and document_date = today + 1 year. The expected - expedition date has to be doc_date - 5 years - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "D")]).id - ) - doc_date = fields.date.today() + datetime.timedelta(days=366) - doc_date_str = str(doc_date) - - # age=20 years old - birthdate = fields.date.today() - datetime.timedelta(days=7305) - birthdate_str = str(birthdate) - - # expected_expedition_date = doc_date - 5 years - expected_exp_date = doc_date - datetime.timedelta(days=1826.25) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - expected_exp_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_calculate_dni_expedition_date_from_validity_date_age_gt_30(self): - """ - Check that the calculate_doc_type_expedition_date_from_validity_date() - method calculates correctly the expedition_date of an id category DNI - when the age is greater than 30. - ------------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id DNI, birthdate calculated so that the age - is = 40 years old and document_date = today + 1 year. The expected - expedition date has to be doc_date - 10 years - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "D")]).id - ) - doc_date = fields.date.today() + datetime.timedelta(days=366) - doc_date_str = str(doc_date) - - # age=40 years old - birthdate = fields.date.today() - datetime.timedelta(days=14610) - birthdate_str = str(birthdate) - - # expected_expedition_date = doc_date - 10 years - expected_exp_date = doc_date - datetime.timedelta(days=3652.5) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - expected_exp_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_calculate_passport_expedition_date_from_validity_date_age_lt_30(self): - """ - Check that the calculate_doc_type_expedition_date_from_validity_date() - method calculates correctly the expedition_date of an id category Passport - when the age is less than 30. - ------------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id Passport, birthdate calculated so that the age - is = 20 years old and document_date = today + 1 year. The expected - expedition date has to be doc_date - 5 years - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "P")]).id - ) - doc_date = fields.date.today() + datetime.timedelta(days=366) - doc_date_str = str(doc_date) - - # age=20 years old - birthdate = fields.date.today() - datetime.timedelta(days=7305) - birthdate_str = str(birthdate) - - # expected_expedition_date = doc_date - 5 years - expected_exp_date = doc_date - datetime.timedelta(days=1826.25) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - expected_exp_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_calculate_passport_expedition_date_from_validity_date_age_gt_30(self): - """ - Check that the calculate_doc_type_expedition_date_from_validity_date() - method calculates correctly the expedition_date of an id category Passport - when the age is greater than 30. - ------------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id Passport, birthdate calculated so that the age - is = 40 years old and document_date = today + 1 year. The expected - expedition date has to be doc_date - 10 years - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "P")]).id - ) - doc_date = fields.date.today() + datetime.timedelta(days=366) - doc_date_str = str(doc_date) - - # age=40 years old - birthdate = fields.date.today() - datetime.timedelta(days=14610) - birthdate_str = str(birthdate) - - # expected_expedition_date = doc_date - 10 years - expected_exp_date = doc_date - datetime.timedelta(days=3652.5) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - expected_exp_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_calculate_drive_license_expedition_date_from_validity_date_age_lt_70(self): - """ - Check that the calculate_doc_type_expedition_date_from_validity_date() - method calculates correctly the expedition_date of an id category Driving - License when the age is lesser than 70. - ------------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id DNI, birthdate calculated so that the age - is = 40 years old and document_date = today + 1 year. The expected - expedition date has to be doc_date - 10 years - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "C")]).id - ) - doc_date = fields.date.today() + datetime.timedelta(days=366) - doc_date_str = str(doc_date) - - # age=40 years old - birthdate = fields.date.today() - datetime.timedelta(days=14610) - birthdate_str = str(birthdate) - - # expected_expedition_date = doc_date - 10 years - expected_exp_date = doc_date - datetime.timedelta(days=3652.5) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - expected_exp_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_calculate_expedition_date(self): - """ - Check that if the value of the doc_date is less than today, - the method calculate_doc_type_expedition_date_from_validity_date - returns the value of the doc_date as expedition_date. - ----------- - We launch the method calculate_doc_type_expedition_date_from_validity_date - with the parameters doc_type_id DNI, birthdate calculated so that the age - is = 20 years old and document_date = today - 1 year. The expected - expedition date has to be the value of doc_date. - """ - doc_type_id = ( - self.env["res.partner.id_category"].search([("code", "=", "D")]).id - ) - doc_date = fields.date.today() - datetime.timedelta(days=366) - doc_date_str = str(doc_date) - birthdate = fields.date.today() - datetime.timedelta(days=7305) - birthdate_str = str(birthdate) - expedition_date = ( - self.checkin1.calculate_doc_type_expedition_date_from_validity_date( - doc_type_id, doc_date_str, birthdate_str - ) - ) - date_expedition_date = datetime.date( - year=expedition_date.year, - month=expedition_date.month, - day=expedition_date.day, - ) - self.assertEqual( - date_expedition_date, - doc_date, - "Expedition date doesn't correspond with expected expedition date", - ) - - def test_save_checkin_from_portal(self): - """ - Check by subtesting that a checkin partner is saved correctly - with the _save_data_from_portal() method. - --------- - A reservation is created with an adult, and it will create a checkin partner. - A dictionary is created with the values to be saved and with the key 'id' - equal to the id of the checkin_partner created when the reservation was - created. We launch the _save_data_from_portal() method, passing the created - dictionary as a parameter. Then it is verified that the value of each key - in the dictionary corresponds to the fields of the saved checkin_partner. - """ - self.reservation = self.env["pms.reservation"].create( - { - "checkin": datetime.date.today() + datetime.timedelta(days=10), - "checkout": datetime.date.today() + datetime.timedelta(days=13), - "room_type_id": self.room_type1.id, - "partner_id": self.host1.id, - "adults": 1, - "pms_property_id": self.pms_property1.id, - } - ) - checkin_partner_id = self.reservation.checkin_partner_ids[0] - checkin_partner_vals = { - "id": checkin_partner_id.id, - "firstname": "Serafín", - "lastname": "Rivas", - "lastname2": "Gonzalez", - "document_type": self.id_category, - "document_number": "18038946T", - "document_expedition_date": "2015-10-07", - "birthdate_date": "1983-10-05", - "mobile": "60595595", - "email": "serafin@example.com", - "gender": "male", - "nationality_id": "1", - "state": "1", - } - checkin_partner_id._save_data_from_portal(checkin_partner_vals) - nationality_id = self.env["res.country"].browse( - checkin_partner_vals["nationality_id"] - ) - checkin_partner_vals.update( - { - "birthdate_date": datetime.date(1983, 10, 5), - "document_expedition_date": datetime.date(2015, 10, 7), - "nationality_id": nationality_id, - } - ) - for key in checkin_partner_vals: - with self.subTest(k=key): - self.assertEqual( - self.reservation.checkin_partner_ids[0][key], - checkin_partner_vals[key], - "The value of " + key + " is not correctly established", - ) diff --git a/pms/tests/test_pms_folio.py b/pms/tests/test_pms_folio.py deleted file mode 100644 index cb772a1b5..000000000 --- a/pms/tests/test_pms_folio.py +++ /dev/null @@ -1,963 +0,0 @@ -import datetime - -from freezegun import freeze_time - -from odoo import fields -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsFolio(TestPms): - - # SetUp and Common Scenarios methods - - def setUp(self): - """ - - common + room_type_double with 2 rooms (double1 and double2) in pms_property1 - """ - super().setUp() - - # create room type - self.room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - # create room - self.double1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 101", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - - # create room - self.double2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 102", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - # make current journals payable - journals = self.env["account.journal"].search( - [ - ("type", "in", ["bank", "cash"]), - ] - ) - journals.allowed_pms_payments = True - - def create_sale_channel_scenario(self): - """ - Method to simplified scenario on sale channel tests: - - create a sale_channel1 like indirect - - create a agency1 like sale_channel1 agency - """ - PmsPartner = self.env["res.partner"] - PmsSaleChannel = self.env["pms.sale.channel"] - - self.sale_channel1 = PmsSaleChannel.create( - {"name": "saleChannel1", "channel_type": "indirect"} - ) - self.agency1 = PmsPartner.create( - { - "name": "partner1", - "is_agency": True, - "invoice_to_agency": True, - "default_commission": 15, - "sale_channel_id": self.sale_channel1.id, - } - ) - - def create_configuration_accounting_scenario(self): - """ - Method to simplified scenario to payments and accounting: - # REVIEW: - - Use new property with odoo demo data company to avoid account configuration - - Emule SetUp with new property: - - create demo_room_type_double - - Create 2 rooms room_type_double - """ - self.pms_property_demo = self.env["pms.property"].create( - { - "name": "Property Based on Comapany Demo", - "company_id": self.env.ref("base.main_company").id, - "default_pricelist_id": self.env.ref("product.list0").id, - } - ) - # create room type - self.demo_room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property_demo.id], - "name": "Double Test", - "default_code": "Demo_DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - # create rooms - self.double1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property_demo.id, - "name": "Double 101", - "room_type_id": self.demo_room_type_double.id, - "capacity": 2, - } - ) - self.double2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property_demo.id, - "name": "Double 102", - "room_type_id": self.demo_room_type_double.id, - "capacity": 2, - } - ) - - # TestCases: Sale Channels - - def test_default_agency_commission(self): - """ - Check the total commission of a folio with agency based on the - reservation night price and the preconfigured commission in the agency. - ------- - Agency with 15% default commision, folio with one reservation - and 3 nights at 20$ by night (60$ total) - """ - # ARRANGE - self.create_sale_channel_scenario() - commission = (20 + 20 + 20) * 0.15 - - # ACT - folio1 = self.env["pms.folio"].create( - { - "agency_id": self.agency1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - self.env["pms.reservation"].create( - { - "folio_id": folio1.id, - "room_type_id": self.room_type_double.id, - "reservation_line_ids": [ - ( - 0, - False, - { - "date": fields.date.today(), - "price": 20, - }, - ), - ( - 0, - False, - { - "date": fields.date.today() + datetime.timedelta(days=1), - "price": 20, - }, - ), - ( - 0, - False, - { - "date": fields.date.today() + datetime.timedelta(days=2), - "price": 20, - }, - ), - ], - } - ) - # ASSERT - self.assertEqual( - commission, folio1.commission, "The folio compute commission is wrong" - ) - - def test_reservation_agency_without_partner(self): - """ - Check that a reservation / folio created with an agency - and without a partner will automatically take the partner. - ------- - Create the folio1 and the reservation1, only set agency_id, - and the partner_id should be the agency itself. - """ - # ARRANGE - self.create_sale_channel_scenario() - - # ACT - folio1 = self.env["pms.folio"].create( - { - "agency_id": self.agency1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - reservation1 = self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "folio_id": folio1.id, - } - ) - - # ASSERT - self.assertEqual( - reservation1.agency_id, folio1.partner_id, "Agency has to be the partner" - ) - - # TestCases: Priority - - def test_compute_folio_priority(self): - """ - Check the priority of a folio based on its reservations - #TODO: Commented test waiting to redefine the priority calculation - """ - # reservation1 = self.env["pms.reservation"].create( - # { - # "checkin": fields.date.today(), - # "checkout": fields.date.today() + datetime.timedelta(days=1), - # "room_type_id": self.room_type_double.id, - # "partner_id": self.env.ref("base.res_partner_12").id, - # "pms_property_id": self.property.id, - # } - # ) - # reservation1.allowed_checkin = False - - # self.env["pms.reservation"].create( - # { - # "folio_id": reservation1.folio_id.id, - # "checkin": fields.date.today(), - # "checkout": fields.date.today() + datetime.timedelta(days=1), - # "room_type_id": self.room_type_double.id, - # "partner_id": self.env.ref("base.res_partner_12").id, - # "pms_property_id": self.property.id, - # } - # ) - - # self.assertEqual( - # reservation1.priority, - # reservation1.folio_id.max_reservation_priority, - # "The max. reservation priority on the whole folio is incorrect", - # ) - - # TestCases: Payments - @freeze_time("2000-02-02") - def test_full_pay_folio(self): - """ - After making the payment of a folio for the entire amount, - check that there is nothing pending. - ----- - We create a reservation (autocalculates the amounts) and - then make the payment using the do_payment method of the folio, - directly indicating the pending amount on the folio of the newly - created reservation - """ - # ARRANGE - self.create_configuration_accounting_scenario() - reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property_demo.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "partner_id": self.env.ref("base.res_partner_12").id, - "room_type_id": self.demo_room_type_double.id, - } - ) - - # ACTION - self.env["pms.folio"].do_payment( - journal=self.env["account.journal"].browse( - reservation1.folio_id.pms_property_id._get_payment_methods().ids[0] - ), - receivable_account=self.env["account.journal"] - .browse(reservation1.folio_id.pms_property_id._get_payment_methods().ids[0]) - .suspense_account_id, - user=self.env.user, - amount=reservation1.folio_id.pending_amount, - folio=reservation1.folio_id, - partner=reservation1.partner_id, - date=fields.date.today(), - ) - - # ASSERT - self.assertFalse( - reservation1.folio_id.pending_amount, - "The pending amount of a folio paid in full has not been zero", - ) - - @freeze_time("2000-02-02") - def test_partial_pay_folio(self): - """ - After making the payment of a folio for the partial amount, - We check that the pending amount is the one that corresponds to it. - ----- - We create a reservation (autocalculates the amounts) and - then make the payment using the do_payment method of the folio, - directly indicating the pending amount on the folio MINUS 1$ - of the newly created reservation - """ - # ARRANGE - self.create_configuration_accounting_scenario() - left_to_pay = 1 - reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property_demo.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "partner_id": self.env.ref("base.res_partner_12").id, - "room_type_id": self.demo_room_type_double.id, - } - ) - - # ACTION - self.env["pms.folio"].do_payment( - journal=self.env["account.journal"].browse( - reservation1.folio_id.pms_property_id._get_payment_methods().ids[0] - ), - receivable_account=self.env["account.journal"] - .browse(reservation1.folio_id.pms_property_id._get_payment_methods().ids[0]) - .suspense_account_id, - user=self.env.user, - amount=reservation1.folio_id.pending_amount - left_to_pay, - folio=reservation1.folio_id, - partner=reservation1.partner_id, - date=fields.date.today(), - ) - - # ASSERT - self.assertEqual( - reservation1.folio_id.pending_amount, - left_to_pay, - "The pending amount on a partially paid folio it \ - does not correspond to the amount that it should", - ) - - def test_reservation_type_folio(self): - """ - Check that the reservation_type of a folio with - a reservation with the default reservation_type is equal - to 'normal'. - --------------- - A folio is created. A reservation is created to which the - value of the folio_id is the id of the previously created - folio. Then it is verified that the value of the reservation_type - field of the folio is 'normal'. - """ - # ARRANGE AND ACT - self.partner1 = self.env["res.partner"].create({"name": "Ana"}) - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "folio_id": folio1.id, - } - ) - - # ASSERT - self.assertEqual( - folio1.reservation_type, - "normal", - "The default reservation type of the folio should be 'normal'", - ) - - def test_invoice_status_staff_reservation(self): - """ - Check that the value of the invoice_status field is 'no' - on a page with reservation_type equal to 'staff'. - ------------ - A reservation is created with the reservation_type field - equal to 'staff'. Then it is verified that the value of - the invoice_status field of the folio created with the - reservation is equal to 'no'. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.partner1 = self.env["res.partner"].create({"name": "Pedro"}) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "staff", - } - ) - # ASSERT - self.assertEqual( - reservation.folio_id.invoice_status, - "no", - "The invoice status of the folio in a staff reservation should be 'no' ", - ) - - def test_invoice_status_out_reservation(self): - """ - Check that the value of the invoice_status field is 'no' - on a page with reservation_type equal to 'out'. - ------------ - A reservation is created with the reservation_type field - equal to 'out'. Then it is verified that the value of - the invoice_status field of the folio created with the - reservation is equal to 'no'. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.partner1 = self.env["res.partner"].create({"name": "Pedro"}) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "out", - } - ) - # ASSERT - self.assertEqual( - reservation.folio_id.invoice_status, - "no", - "The invoice status of the folio in a out reservation should be 'no' ", - ) - - def test_amount_total_staff_reservation(self): - """ - Check that the amount_total field of the folio whose - reservation has the reservation_type field as staff - is not calculated. - ------------------------- - A folio is created. A reservation is created to which the - value of the folio_id is the id of the previously created - folio and the field reservation_type equal to 'staff'. Then - it is verified that the value of the amount_total field of - the folio is 0. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.partner1 = self.env["res.partner"].create({"name": "Pedro"}) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": checkin, - "checkout": checkout, - "folio_id": folio1.id, - "reservation_type": "staff", - } - ) - # ASSERT - self.assertEqual( - folio1.amount_total, - 0.0, - "The amount total of the folio in a staff reservation should be 0", - ) - - def test_amount_total_out_reservation(self): - """ - Check that the amount_total field of the folio whose - reservation has the reservation_type field as out - is not calculated. - ------------------------- - A folio is created. A reservation is created to which the - value of the folio_id is the id of the previously created - folio and the field reservation_type equal to 'out'. Then - it is verified that the value of the amount_total field of - the folio is 0. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.partner1 = self.env["res.partner"].create({"name": "Pedro"}) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": checkin, - "checkout": checkout, - "folio_id": folio1.id, - "reservation_type": "out", - } - ) - # ASSERT - self.assertEqual( - folio1.amount_total, - 0.0, - "The amount total of the folio in a out of service reservation should be 0", - ) - - def test_reservation_type_incongruence(self): - """ - Check that a reservation cannot be created - with the reservation_type field different from the - reservation_type of its folio. - ------------- - A folio is created. A reservation is created to which the - value of the folio_id is the id of the previously created - folio and the field reservation_type by default('normal'). - Then it is tried to create another reservation with its - reservation_type equal to 'staff'. But it should throw an - error because the value of the reservation_type of the - folio is equal to 'normal'. - """ - self.partner1 = self.env["res.partner"].create({"name": "Ana"}) - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "folio_id": folio1.id, - } - ) - with self.assertRaises( - ValidationError, - msg="You cannot create reservations with different reservation_type for a folio", - ): - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "folio_id": folio1.id, - "reservation_type": "staff", - } - ) - - def test_create_partner_in_folio(self): - """ - Check that a res_partner is created from a folio. - ------------ - A folio is created by adding the document_type and - document_number fields, with these two fields a res.partner - should be created, which is what is checked after creating - the folio. - """ - # ARRANGE - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": "Savannah Byles", - "document_type": self.id_category.id, - "document_number": "32861114W", - } - ) - # ASSERT - self.assertTrue(folio1.partner_id.id, "The partner has not been created") - - def test_auto_complete_partner_mobile(self): - """ - It is checked that the mobile field of the folio - is correctly added to it when the document_number and - document_type fields of a res.partner that exists in - the DB are put in the folio. - -------------------- - A res.partner is created with the name, mobile and email fields. - The document_id is added to the res.partner. The folio is - created and the category_id of the document_id associated with - the res.partner is added as document_type and as document_number - the name of the document_id associated with the res.partner as well. - Then it is checked that the mobile of the res.partner and that of - the folio are the same. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Enrique", - "mobile": "654667733", - "email": "enrique@example.com", - } - ) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - self.document_id = self.env["res.partner.id_number"].create( - { - "category_id": self.id_category.id, - "name": "61645604S", - "partner_id": partner.id, - } - ) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "document_type": self.document_id.category_id.id, - "document_number": self.document_id.name, - } - ) - # ASSERT - self.assertEqual( - folio1.mobile, - partner.mobile, - "The partner mobile has not autocomplete in folio", - ) - - def test_auto_complete_partner_email(self): - """ - It is checked that the email field of the folio - is correctly added to it when the document_number and - document_type fields of a res.partner that exists in - the DB are put in the folio. - -------------------- - A res.partner is created with the name, mobile and email fields. - The document_id is added to the res.partner. The folio is - created and the category_id of the document_id associated with - the res.partner is added as document_type and as document_number - the name of the document_id associated with the res.partner as well. - Then it is checked that the email of the res.partner and that of - the folio are the same. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - self.document_id = self.env["res.partner.id_number"].create( - { - "category_id": self.id_category.id, - "name": "74247377L", - "partner_id": partner.id, - } - ) - - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "document_type": self.document_id.category_id.id, - "document_number": self.document_id.name, - } - ) - # ASSERT - self.assertEqual( - folio1.email, - partner.email, - "The partner mobile has not autocomplete in folio", - ) - - def test_is_possible_customer_by_email(self): - """ - It is checked that the field is_possible_existing_customer_id - exists in a folio with an email from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A folio - is created by adding the same email as the res.partner. Then it is - checked that the field is_possible_existing_customer_id is equal to True. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Courtney Campbell", - "email": "courtney@example.com", - } - ) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "email": partner.email, - } - ) - # ASSERT - self.assertTrue( - folio1.possible_existing_customer_ids, "No customer found with this email" - ) - - def test_is_possible_customer_by_mobile(self): - """ - It is checked that the field is_possible_existing_customer_id - exists in a folio with a mobile from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A folio - is created by adding the same mobile as the res.partner. Then it is - checked that the field is_possible_existing_customer_id is equal to True. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Ledicia Sandoval", - "mobile": "615369231", - } - ) - # ACT - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "mobile": partner.mobile, - } - ) - # ASSERT - self.assertTrue( - folio1.possible_existing_customer_ids, - "No customer found with this mobile", - ) - - def test_add_possible_customer(self): - """ - Check that a partner was correctly added to the folio - after launching the add_partner() method of the several partners wizard - --------------- - A res.partner is created with name, email and mobile. A folio is created. - The wizard is created with the folio id and the partner added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is checked that the partner was correctly added to the - folio. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "email": partner.email, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "folio_id": folio1.id, - "possible_existing_customer_ids": [(6, 0, [partner.id])], - } - ) - # ACT - several_partners_wizard.add_partner() - # ASSERT - self.assertEqual( - folio1.partner_id.id, - partner.id, - "The partner was not added to the folio ", - ) - - def test_not_add_several_possibles_customers(self): - """ - Check that multiple partners cannot be added to a folio - from the several partners wizard. - --------------- - Two res.partner are created with name, email and mobile. A folio is created. - The wizard is created with the folio id and the two partners added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is verified that a Validation_Error was raised. - """ - # ARRANGE - partner1 = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - partner2 = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner1.name, - "email": partner1.email, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "folio_id": folio1.id, - "possible_existing_customer_ids": [(6, 0, [partner1.id, partner2.id])], - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="Two partners cannot be added to the folio", - ): - several_partners_wizard.add_partner() - - def test_not_add_any_possibles_customers(self): - """ - Check that the possible_existing_customer_ids field of the several - partners wizard can be left empty and then launch the add_partner() - method of this wizard to add a partner in folio. - --------------- - A folio is created. The wizard is created without the - possible_existing_customer_ids field. The add_partner method of - the wizard is launched and it is verified that a Validation_Error - was raised. - """ - - # ARRANGE - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": "Rosa Costa", - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "folio_id": folio1.id, - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="A partner can be added to the folio", - ): - several_partners_wizard.add_partner() - - def test_add_partner_invoice_contact(self): - """ - Check that when adding a customer at check-in, reservation or folio, - it is added as a possible billing address - --------------- - Three res.partner are created with name, email and mobile. A folio is created. - We add the partners to the folio, reservation, and checkin, and check that the - three partners are on partner_invoice in folio. - """ - # ARRANGE - partner1 = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - partner2 = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - partner3 = self.env["res.partner"].create( - { - "name": "Sofia", - "mobile": "688667733", - "email": "sofia@example.com", - } - ) - - # FIRST ACTION - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": partner1.name, - "email": partner1.email, - } - ) - reservation1 = self.env["pms.reservation"].create( - { - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "folio_id": folio1.id, - } - ) - - # FIRST ASSERT - self.assertEqual( - len(folio1.partner_invoice_ids), - 0, - "A partner was added as a billing contact for no reason", - ) - - # SECOND ACTION - folio1.partner_id = partner1.id - - # SECOND ASSERT - self.assertEqual( - folio1.partner_invoice_ids.ids, - [partner1.id], - "A folio partner was not added as a billing contact", - ) - - # SECOND ACTION - reservation1.partner_id = partner2.id - - # SECOND ASSERT - self.assertIn( - partner2.id, - folio1.partner_invoice_ids.ids, - "A reservation partner was not added as a billing contact", - ) - - # THIRD ACTION - reservation1.checkin_partner_ids[0].partner_id = partner3.id - - # THIRD ASSERT - self.assertIn( - partner3.id, - folio1.partner_invoice_ids.ids, - "A checkin partner was not added as a billing contact", - ) diff --git a/pms/tests/test_pms_folio_invoice.py b/pms/tests/test_pms_folio_invoice.py deleted file mode 100644 index c64412a17..000000000 --- a/pms/tests/test_pms_folio_invoice.py +++ /dev/null @@ -1,601 +0,0 @@ -import datetime - -from .common import TestPms - - -class TestPmsFolioInvoice(TestPms): - def setUp(self): - super().setUp() - # create a room type availability - self.room_type_availability = self.env["pms.availability.plan"].create( - {"name": "Availability plan for TEST"} - ) - # create a property - self.property = self.env["pms.property"].create( - { - "name": "MY PMS TEST", - "company_id": self.env.ref("base.main_company").id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - # create room type - self.room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.property.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - - # create rooms - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.property.id, - "name": "Double 101", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.property.id, - "name": "Double 102", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - - self.room3 = self.env["pms.room"].create( - { - "pms_property_id": self.property.id, - "name": "Double 103", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - - # res.partner - self.partner_id = self.env["res.partner"].create( - { - "name": "Miguel", - } - ) - - def test_invoice_full_folio(self): - """ - Check that when launching the create_invoices() method for a full folio, - the invoice_status field is set to "invoiced". - ---------------- - A reservation is created. The create_invoices() method of the folio of - that reservation is launched. It is verified that the invoice_status field - of the folio is equal to "invoiced". - """ - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - state_expected = "invoiced" - # ACT - r1.folio_id._create_invoices() - # ASSERT - self.assertEqual( - state_expected, - r1.folio_id.invoice_status, - "The status after a full invoice folio isn't correct", - ) - - def test_invoice_partial_folio_by_steps(self): - """ - Check that when launching the create_invoices() method for a partial folio, - the invoice_status field is set to "invoiced". - ---------------- - A reservation is created. The create_invoices() method of the folio of - that reservation is launched with the first sale line. It is verified - that the invoice_status field of the folio is equal to "invoiced". - """ - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - dict_lines = dict() - - dict_lines[ - r1.folio_id.sale_line_ids.filtered(lambda l: not l.display_type)[0].id - ] = 3 - r1.folio_id._create_invoices(lines_to_invoice=dict_lines) - - self.assertEqual( - "invoiced", - r1.folio_id.invoice_status, - "The status after an invoicing is not correct", - ) - - def test_invoice_partial_folio_diferent_partners(self): - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - dict_lines = dict() - # qty to 1 to 1st folio sale line - dict_lines[ - r1.folio_id.sale_line_ids.filtered(lambda l: not l.display_type)[0].id - ] = 1 - r1.folio_id._create_invoices( - lines_to_invoice=dict_lines, - partner_invoice_id=self.env.ref("base.res_partner_1"), - ) - - # test does not work without invalidating cache - self.env["account.move"].invalidate_cache() - - self.assertNotEqual( - "invoiced", - r1.folio_id.invoice_status, - "The status after a partial invoicing is not correct", - ) - - # qty to 2 to 1st folio sale line - dict_lines[ - r1.folio_id.sale_line_ids.filtered(lambda l: not l.display_type)[0].id - ] = 2 - r1.folio_id._create_invoices( - lines_to_invoice=dict_lines, - partner_invoice_id=self.env.ref("base.res_partner_12"), - ) - self.assertNotEqual( - r1.folio_id.move_ids.mapped("partner_id")[0], - r1.folio_id.move_ids.mapped("partner_id")[1], - "The status after an invoicing is not correct", - ) - - def test_invoice_partial_folio_wrong_qtys(self): - """ - Check that an invoice of a folio with wrong amounts cannot be created. - ------------ - A reservation is created. Then the create_invoices method of the folio - is launched with the lines to be invoiced with wrong amounts and through - subtest it is verified that the invoices cannot be created. - """ - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - tcs = [-1, 0, 3] - - for tc in tcs: - with self.subTest(k=tc): - with self.assertRaises(ValueError): - # ARRANGE - dict_lines = dict() - dict_lines[ - r1.folio_id.sale_line_ids.filtered( - lambda l: not l.display_type - )[0].id - ] = tc - r1.folio_id._create_invoices(lines_to_invoice=dict_lines) - # test does not work without invalidating cache - self.env["account.move"].invalidate_cache() - - def test_amount_invoice_folio(self): - """ - Test create and invoice from the Folio, and check amount of the reservation. - ------------- - A reservation is created. The create_invoices() method is launched and it is - verified that the total amount of the reservation folio is equal to the total - of the created invoice. - """ - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - - total_amount_expected = r1.folio_id.amount_total - r1.folio_id._create_invoices() - self.assertEqual( - r1.folio_id.move_ids.amount_total, - total_amount_expected, - "Total amount of the invoice and total amount of folio don't match", - ) - - def test_qty_to_invoice_folio(self): - """ - Test create and invoice from the Folio, and check qty to invoice. - ---------------------- - A reservation is created.Then it is verified that the total quantity - to be invoice from the sale lines of the reservation folio corresponds - to expected. - """ - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - qty_to_invoice_expected = sum( - r1.folio_id.sale_line_ids.mapped("qty_to_invoice") - ) - self.assertEqual( - qty_to_invoice_expected, - 3.0, - "The quantity to be invoice on the folio does not correspond", - ) - - def test_qty_invoiced_folio(self): - """ - Test create and invoice from the Folio, and check qty invoiced. - --------------- - A reservation is created.The create_invoices() method is launched and it is - verified that the total quantity invoiced of the reservation folio is equal - to the total quantity of the created invoice. - """ - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - } - ) - r1.folio_id._create_invoices() - qty_invoiced_expected = sum(r1.folio_id.sale_line_ids.mapped("qty_invoiced")) - self.assertEqual( - qty_invoiced_expected, - 3.0, - "The quantity invoiced on the folio does not correspond", - ) - - def test_price_invoice_by_services_folio(self): - """ - Test create and invoice from the Folio, and check amount in a - specific segment of services. - """ - - self.product1 = self.env["product.product"].create( - {"name": "Test Product 1", "per_day": True, "list_price": 10} - ) - - self.service1 = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product1.id, - } - ) - - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "service_ids": [(6, 0, [self.service1.id])], - } - ) - dict_lines = dict() - dict_lines[ - self.reservation1.folio_id.sale_line_ids.filtered("service_id")[0].id - ] = 1 - self.reservation1.folio_id._create_invoices(lines_to_invoice=dict_lines) - self.assertEqual( - self.reservation1.folio_id.sale_line_ids.filtered("service_id")[ - 0 - ].price_total, - self.reservation1.folio_id.move_ids.amount_total, - "The service price don't match between folio and invoice", - ) - - def test_qty_invoiced_by_services_folio(self): - """ - Test create and invoice from the Folio, and check qty invoiced - in a specific segment of services - """ - - self.product1 = self.env["product.product"].create( - {"name": "Test Product 1", "per_day": True, "list_price": 10} - ) - - self.service1 = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product1.id, - } - ) - - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "service_ids": [(6, 0, [self.service1.id])], - } - ) - dict_lines = dict() - service_lines = self.reservation1.folio_id.sale_line_ids.filtered("service_id") - for line in service_lines: - dict_lines[line.id] = 1 - self.reservation1.folio_id._create_invoices(lines_to_invoice=dict_lines) - expected_qty_invoiced = sum( - self.reservation1.folio_id.move_ids.invoice_line_ids.mapped("quantity") - ) - self.assertEqual( - expected_qty_invoiced, - sum(self.reservation1.folio_id.sale_line_ids.mapped("qty_invoiced")), - "The quantity of invoiced services don't match between folio and invoice", - ) - - def test_qty_to_invoice_by_services_folio(self): - """ - Test create an invoice from the Folio, and check qty to invoice - in a specific segment of services - """ - - self.product1 = self.env["product.product"].create( - {"name": "Test Product 1", "per_day": True, "list_price": 10} - ) - - self.service1 = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product1.id, - } - ) - - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "service_ids": [(6, 0, [self.service1.id])], - } - ) - expected_qty_to_invoice = sum( - self.reservation1.folio_id.sale_line_ids.filtered("service_id").mapped( - "qty_to_invoice" - ) - ) - self.assertEqual( - expected_qty_to_invoice, - 3.0, - "The quantity of services to be invoice is wrong", - ) - - def test_price_invoice_board_service(self): - """ - Test create and invoice from the Folio, and check the related - amounts with board service linked - """ - self.product1 = self.env["product.product"].create( - { - "name": "Test Product 1", - } - ) - - self.board_service1 = self.env["pms.board.service"].create( - { - "name": "Test Board Service 1", - "default_code": "CB1", - } - ) - self.board_service_line1 = self.env["pms.board.service.line"].create( - { - "product_id": self.product1.id, - "pms_board_service_id": self.board_service1.id, - "amount": 10, - } - ) - - self.board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type_double.id, - "pms_board_service_id": self.board_service1.id, - } - ) - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - dict_lines = dict() - dict_lines[ - self.reservation1.folio_id.sale_line_ids.filtered("service_id")[0].id - ] = 1 - self.reservation1.folio_id._create_invoices(lines_to_invoice=dict_lines) - self.assertEqual( - self.reservation1.folio_id.sale_line_ids.filtered("service_id")[ - 0 - ].price_total, - self.reservation1.folio_id.move_ids.amount_total, - "The board service price don't match between folio and invoice", - ) - - def test_qty_invoiced_board_service(self): - """ - Test create and invoice from the Folio, and check qty invoiced - with board service linked. - """ - self.product1 = self.env["product.product"].create( - { - "name": "Test Product 1", - } - ) - - self.board_service1 = self.env["pms.board.service"].create( - { - "name": "Test Board Service 1", - "default_code": "CB1", - } - ) - self.board_service_line1 = self.env["pms.board.service.line"].create( - { - "product_id": self.product1.id, - "pms_board_service_id": self.board_service1.id, - "amount": 10, - } - ) - - self.board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type_double.id, - "pms_board_service_id": self.board_service1.id, - } - ) - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - dict_lines = dict() - service_lines = self.reservation1.folio_id.sale_line_ids.filtered("service_id") - for line in service_lines: - dict_lines[line.id] = 1 - self.reservation1.folio_id._create_invoices(lines_to_invoice=dict_lines) - expected_qty_invoiced = sum( - self.reservation1.folio_id.move_ids.invoice_line_ids.mapped("quantity") - ) - self.assertEqual( - expected_qty_invoiced, - sum(self.reservation1.folio_id.sale_line_ids.mapped("qty_invoiced")), - "The quantity of invoiced board services don't match between folio and invoice", - ) - - def test_qty_to_invoice_board_service(self): - """ - Test create and invoice from the Folio, and check qty to invoice - with board service linked - """ - self.product1 = self.env["product.product"].create( - { - "name": "Test Product 1", - } - ) - - self.board_service1 = self.env["pms.board.service"].create( - { - "name": "Test Board Service 1", - "default_code": "CB1", - } - ) - self.board_service_line1 = self.env["pms.board.service.line"].create( - { - "product_id": self.product1.id, - "pms_board_service_id": self.board_service1.id, - "amount": 10, - } - ) - - self.board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type_double.id, - "pms_board_service_id": self.board_service1.id, - } - ) - self.reservation1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.property.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner_id.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - dict_lines = dict() - service_lines = self.reservation1.folio_id.sale_line_ids.filtered("service_id") - for line in service_lines: - dict_lines[line.id] = 1 - self.reservation1.folio_id._create_invoices(lines_to_invoice=dict_lines) - expected_qty_to_invoice = sum( - self.reservation1.folio_id.sale_line_ids.filtered("service_id").mapped( - "qty_to_invoice" - ) - ) - self.assertEqual( - expected_qty_to_invoice, - 0, - "The quantity of board services to be invoice is wrong", - ) - - def _test_invoice_line_group_by_room_type_sections(self): - """Test create and invoice from the Folio, and check qty invoice/to invoice, - and the grouped invoice lines by room type, by one - line by unit prices/qty with nights""" - - def _test_autoinvoice_folio(self): - """ Test create and invoice the cron by partner preconfig automation """ - - def _test_downpayment(self): - """Test invoice qith a way of downpaument and check dowpayment's - folio line is created and also check a total amount of invoice is - equal to a respective folio's total amount""" - - def _test_invoice_with_discount(self): - """Test create with a discount and check discount applied - on both Folio lines and an inovoice lines""" - - def _test_reinvoice(self): - """Test the compute reinvoice folio take into account - nights and services qty invoiced""" diff --git a/pms/tests/test_pms_folio_prices.py b/pms/tests/test_pms_folio_prices.py deleted file mode 100644 index 101c58b68..000000000 --- a/pms/tests/test_pms_folio_prices.py +++ /dev/null @@ -1,10 +0,0 @@ -from odoo.tests.common import SavepointCase - - -class TestPmsFolioPrice(SavepointCase): - def setUp(self): - super(TestPmsFolioPrice, self).setUp() - - def test_price_folio(self): - """Test create reservation and services, and check price - tax and discounts""" diff --git a/pms/tests/test_pms_folio_sale_line.py b/pms/tests/test_pms_folio_sale_line.py deleted file mode 100644 index ca0e3c951..000000000 --- a/pms/tests/test_pms_folio_sale_line.py +++ /dev/null @@ -1,1253 +0,0 @@ -import datetime - -from odoo import fields - -from .common import TestPms - - -class TestPmsFolioSaleLine(TestPms): - def setUp(self): - """ - - common + room_type_avalability_plan - """ - super().setUp() - - # create room type - self.room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - # create room - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 101", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 102", - "room_type_id": self.room_type_double.id, - "capacity": 2, - } - ) - - self.product_test1 = self.env["product.product"].create( - { - "name": "Test Product 1", - "per_day": True, - } - ) - self.product_test2 = self.env["product.product"].create( - { - "name": "Test Product 1", - "per_day": True, - "consumed_on": "after", - } - ) - self.board_service_test = self.board_service = self.env[ - "pms.board.service" - ].create( - { - "name": "Test Board Service", - "default_code": "TPS", - } - ) - self.env["pms.board.service.line"].create( - { - "pms_board_service_id": self.board_service_test.id, - "product_id": self.product_test1.id, - "amount": 8, - } - ) - self.board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type_double.id, - "pms_board_service_id": self.board_service_test.id, - } - ) - self.extra_service = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product_test2.id, - } - ) - - # RESERVATION LINES - def test_comp_fsl_rooms_all_same_group(self): - """ - check the grouping of the reservation lines on the sale line folio - when the price, discount match- - ------------ - reservation with 3 nights with the same price, - should generate just 1 reservation sale line - """ - # ARRANGE - expected_sale_lines = 1 - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "reservation_line_ids": [ - ( - 0, - False, - { - "date": fields.date.today(), - "price": 20, - "discount": 10, - }, - ), - ( - 0, - False, - { - "date": fields.date.today() + datetime.timedelta(days=1), - "price": 20, - "discount": 10, - }, - ), - ( - 0, - False, - { - "date": fields.date.today() + datetime.timedelta(days=2), - "price": 20, - "discount": 10, - }, - ), - ], - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ASSERT - self.assertEqual( - expected_sale_lines, - len(r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)), - "Folio should contain {} sale lines".format(expected_sale_lines), - ) - - def test_comp_fsl_rooms_different_prices(self): - """ - Check that a reservation with two nights and different prices per - night generates two sale lines. - ------------ - Create a reservation with a double room as a room type and 2 nights, - which has a price of 25.0 per night. Then the price of one of the reservation - lines is changed to 50.0. As there are two different prices per - night in the reservation the sale lines of the folio should be 2 . - """ - - # ARRANGE - expected_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ACT - r_test.reservation_line_ids[0].price = 50.0 - - # ASSERT - self.assertEqual( - expected_sale_lines, - len(r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)), - "Folio should contain {} reservation sale lines".format( - expected_sale_lines - ), - ) - - def test_comp_fsl_rooms_different_discount(self): - """ - Check that a reservation with two nights and different discount per - night generates two sale lines. - ------------ - Create a reservation with a double room as a room type and 2 nights, which has - a default discount of 0 per night. Then the discount of one of the reservation - lines is changed to 50.0. As there are two different discounts per night in the - reservation the sale lines of the folio should be 2. - """ - - # ARRANGE - expected_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ACT - r_test.reservation_line_ids[0].discount = 50.0 - - # ASSERT - self.assertEqual( - expected_sale_lines, - len(r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)), - "Folio should contain {} reservation sale lines".format( - expected_sale_lines - ), - ) - - def test_comp_fsl_rooms_different_cancel_discount(self): - """ - Check that a reservation with two nights and different cancel - discount per night generates two sale lines. - ------------ - Create a reservation with a double room as a room type and 2 nights, - which has a default cancel discount of 0 per night. Then the cancel discount - of one of the reservation lines is changed to 50.0. As there are two - different cancel discount per night in the reservation the sale lines of - the folio should be 2. As one of the reservation lines has a 100% cancel - discount, the sale line should be 1 . - """ - - # ARRANGE - expected_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ACT - r_test.reservation_line_ids[0].cancel_discount = 50.0 - - # ASSERT - self.assertEqual( - expected_sale_lines, - len(r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)), - "Folio should contain {} reservation sale lines".format( - expected_sale_lines - ), - ) - - def test_comp_fsl_rooms_one_full_cancel_discount(self): - """ - Check that a reservation with a 100% cancel discount on one night - does not generate different sale lines. - ---------------- - Create a reservation with a double room as a room type, which has - a default cancel discount of 0 per night. Then the cancel discount - of one of the reservation lines is changed to 100.0. - """ - # ARRANGE - expected_sale_lines = 1 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ACT - r_test.reservation_line_ids[0].cancel_discount = 100.0 - r_test.flush() - - # ASSERT - self.assertEqual( - expected_sale_lines, - len(r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)), - "Folio should contain {} reservation sale lines".format( - expected_sale_lines - ), - ) - - def test_comp_fsl_rooms_increase_stay(self): - """ - Check when adding a night to a reservation after creating it and this night - has the same price, cancel and cancel discount values, the sales line that - were created with the reservation are maintained. - --------- - Create a reservation of 2 nights for a double room. The value of the sale lines - of that reservation is stored in a variable. Then one more night is added to the - reservation and it is verified that the sale lines are the same as the value of - the previously saved variable. - """ - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.flush() - previous_folio_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=4) - r_test.flush() - - # ASSERT - self.assertEqual( - previous_folio_sale_line, - r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)[0], - "Previous records of reservation sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_rooms_decrease_stay(self): - """ - Check when a night is removed from a reservation after creating - it, the sales lines that were created with the reservation are kept. - --------- - Create a reservation of 2 nights for a double room. The value of the sale lines - of that reservation is stored in a variable. Then it is removed one night at - reservation and it is verified that the reservation sale lines are equal to the value of - the previously saved variable. - """ - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.flush() - previous_folio_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=2) - r_test.flush() - - # ASSERT - self.assertEqual( - previous_folio_sale_line, - r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)[0], - "Previous records of reservation sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_rooms_same_stay(self): - """ - Check that when changing the price of all the reservation lines in a - reservation, which before the change had the same price, discount - and cancel discount values, the same sale lines that existed before - the change are kept. - ------------------ - Create a reservation of 2 nights for a double room with a price of 25.0. - The value of the sale lines of that reservation is stored in a variable. - Then the value of the price of all the reservation lines is changed to 50.0 - and it is verified that the reservation sale lines are equal to the value - of the previously saved variable. - """ - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.flush() - previous_folio_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type - )[0] - - # ACT - r_test.reservation_line_ids.price = 50 - r_test.flush() - - # ASSERT - self.assertEqual( - previous_folio_sale_line, - r_test.folio_id.sale_line_ids.filtered(lambda x: not x.display_type)[0], - "Previous records of reservation sales lines should not be " - "deleted if it is not necessary", - ) - - # BOARD SERVICES - def test_comp_fsl_board_services_all_same_group(self): - - """ - Check that the board services of reservation with the same price, discount - and cancel discount values, should only generate one sale line. - ---------------- - Create a reservation of 2 nights, for a double room with a board service - room per night. Then it is verified that the length of the sale lines of the - board services in the reservation is equal to 1. - """ - # ARRANGE - expected_board_service_sale_lines = 1 - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - # ASSERT - self.assertEqual( - expected_board_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.reservation_id and x.service_id and x.is_board_service - ) - ), - "Folio should contain {} board service sale lines".format( - expected_board_service_sale_lines - ), - ) - - def test_comp_fsl_board_services_different_prices(self): - """ - Check that the board services of reservation with different prices - should generate several sale lines. - ---------------- - Create a reservation of 2 nights, for a double room with a board service - room per night. Then change the price of the first board service line to - 1.0 and it is verified that the length of the sale lines of the board services - in the reservation is equal to 2 because there are 2 different board service - prices in the reservation. - """ - # ARRANGE - expected_board_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - r_test.service_ids[0].service_line_ids[0].price_unit = 1.0 - - # ASSERT - self.assertEqual( - expected_board_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - ) - ), - "Folio should contain {} board service sale lines".format( - expected_board_service_sale_lines - ), - ) - - def test_comp_fsl_board_services_different_discount(self): - """ - Check that the board services of reservation with different discounts - should generate several sale lines. - ---------------- - Create a reservation of 2 nights, for a double room with a board service - room per night. Then change the discount of the first board service line - to 1.0 and it is verified that the length of the sale lines of the board services - in the reservation is equal to 2 because there are 2 different board service - discounts in the reservation. - """ - # ARRANGE - expected_board_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - # ACT - r_test.service_ids[0].service_line_ids[0].discount = 1.0 - - # ASSERT - self.assertEqual( - expected_board_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - ) - ), - "Folio should contain {} board service sale lines".format( - expected_board_service_sale_lines - ), - ) - - def test_comp_fsl_board_services_different_cancel_discount(self): - """ - Check that the board services of reservation with different cancel - discounts should generate several sale lines. - ---------------- - Create a reservation of 2 nights, for a double room with a board service - room per night. Then change the cancel discount of the first board service line - to 1.0 and it is verified that the length of the sale lines of the board services - in the reservation is equal to 2 because there are 2 different board service - cancel discounts in the reservation. - """ - - # ARRANGE - expected_board_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - # ACT - r_test.service_ids[0].service_line_ids[0].cancel_discount = 1.0 - - # ASSERT - self.assertEqual( - expected_board_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - ) - ), - "Folio should contain {} board service sale lines".format( - expected_board_service_sale_lines - ), - ) - - def test_comp_fsl_board_services_one_full_cancel_discount(self): - """ - Check that the board services of reservation with 100% cancel - discount should generate only 1 sale line. - ---------------- - Create a reservation of 2 nights, for a double room with a board service - room per night. Then change the cancel discount of the first board service line - to 100.0 and it is verified that the length of the sale lines of the board services - in the reservation is equal to 1. - """ - - # ARRANGE - expected_board_service_sale_lines = 1 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - # ACT - r_test.service_ids[0].service_line_ids[0].cancel_discount = 100.0 - - # ASSERT - self.assertEqual( - expected_board_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - ) - ), - "Folio should contain {} board service sale lines".format( - expected_board_service_sale_lines - ), - ) - - def test_comp_fsl_board_services_increase_stay(self): - """ - Check when adding a night to a reservation with board services room, - after creating it and this board service has the same price, cancel - and cancel discount values, the sale lines that were created with the - reservation are kept. - --------- - Create a reservation of 2 nights for a double room with a board service. - The value of the sale lines of that board services is stored in a variable. - Then one more night is added to the reservation and it is verified that - the sale lines are the same as the value of the previously saved variable. - """ - - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - previous_folio_board_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=4) - - # ASSERT - self.assertEqual( - previous_folio_board_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0], - "Previous records of board service sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_board_services_decrease_stay(self): - """ - Check when removing a night to a reservation with board services room, - after creating it and this board service has the same price, cancel - and cancel discount values, the sale lines that were created with the - reservation are kept. - --------- - Create a reservation of 2 nights for a double room with a board service. - The value of the sale lines of that board services is stored in a variable. - Then one night is removed to the reservation and it is verified that - the sale lines are the same as the value of the previously saved variable. - """ - - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - previous_folio_board_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=2) - - # ASSERT - self.assertEqual( - previous_folio_board_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0], - "Previous records of board service sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_board_services_same_stay(self): - """ - Check that when changing the price of all board services in a - reservation, which before the change had the same price, discount - and cancel discount values, the same sale lines that existed before - the change are kept. - ------------------ - Create a reservation of 2 nights for a double room with a board service - price of 8.0. The value of the sale lines of the board services is stored - in a variable. Then the value of the price of all the reservation board services - is changed to 50 and it is verified that the reservation sale lines are equal to - the value of the previously saved variable. - """ - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - "board_service_room_id": self.board_service_room_type.id, - } - ) - - previous_folio_board_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0] - - # ACT - r_test.service_ids.filtered( - lambda x: x.is_board_service - ).service_line_ids.price_unit = 50 - - # ASSERT - self.assertEqual( - previous_folio_board_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.display_type and x.is_board_service - )[0], - "Previous records of board service sales lines should not be " - "deleted if it is not necessary", - ) - - # RESERVATION EXTRA DAILY SERVICES - def test_comp_fsl_res_extra_services_all_same_group(self): - """ - Check that when adding a service that is not a board service to a - reservation with the same price, cancel and cancel discount, the - number of sales lines is kept. - ------------------ - Create a 2 night reservation. Then a service is added with - is_board_service = False and it is verified that the length of - the sale lines of the reservation is 1. - """ - # ARRANGE - expected_extra_service_sale_lines = 1 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - # ACT - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_extra_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} reservation service sale lines".format( - expected_extra_service_sale_lines - ), - ) - - def test_comp_fsl_res_extra_services_different_prices(self): - """ - Check that a reservation of several nights and with different - prices per day on services should generate several sale lines. - ----------------- - Create a reservation for 2 nights. Then add a service to this - reservation and the price of the first service line is changed - to 44.5. It is verified that the length of the reservation's sale - lines is equal to 2, because there are two different prices per day - for service lines. - """ - - # ARRANGE - expected_extra_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - - # ACT - r_test.service_ids.service_line_ids[0].price_unit = 44.5 - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_extra_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} reservation service sale lines".format( - expected_extra_service_sale_lines - ), - ) - - def test_comp_fsl_res_extra_services_different_discount(self): - """ - Check that a reservation of several nights and with different - discount per day on services should generate several sale lines. - ----------------- - Create a reservation for 2 nights. Then add a service to this - reservation and the discount of the first service line is changed - to 44.5. It is verified that the length of the reservation's sale - lines is equal to 2, because there are two different discounts per day - for service lines. - """ - - # ARRANGE - expected_extra_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - - # ACT - r_test.service_ids.service_line_ids[0].discount = 44.5 - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_extra_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} reservation service sale lines".format( - expected_extra_service_sale_lines - ), - ) - - def test_comp_fsl_res_extra_services_different_cancel_discount(self): - """ - Check that a reservation of several nights and with different - cancel discount per day on services should generate several sale - lines. - ----------------- - Create a reservation for 2 nights. Then add a service to this - reservation and the cancel discount of the first service line is changed - to 44.5. It is verified that the length of the reservation's sale - lines is equal to 2, because there are two different cancel discounts per - day for service lines. - """ - - # ARRANGE - expected_extra_service_sale_lines = 2 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - - # ACT - r_test.service_ids.service_line_ids[0].cancel_discount = 44.5 - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_extra_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} reservation service sale lines".format( - expected_extra_service_sale_lines - ), - ) - - def test_comp_fsl_res_extra_services_one_full_cancel_discount(self): - """ - Check that a reservation of several nights and with a 100% cancel - discount for a service should generate only 1 sale line. - ----------------- - Create a reservation for 2 nights. Then add a service to this - reservation and the cancel discount of the first service line is changed - to 100%. It is verified that the length of the reservation sale - lines is equal to 1. - """ - - # ARRANGE - expected_extra_service_sale_lines = 1 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - - # ACT - r_test.service_ids.service_line_ids[0].cancel_discount = 100 - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_extra_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} reservation service sale lines".format( - expected_extra_service_sale_lines - ), - ) - - def test_comp_fsl_res_extra_services_increase_stay(self): - """ - Check when adding a night to a reservation after creating it and this services - has the same price, cancel and cancel discount values, the sales line that - were created with the reservation are maintained. - --------- - Create a reservation of 2 nights for a double room and add a service to this - reservation. The value of the sale lines of that reservation services is stored - in a variable. Then one more night is added to the reservation and it is verified - that the reservation service sale lines are the same as the value of the previously - saved variable. - """ - - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - previous_folio_extra_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=4) - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - previous_folio_extra_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ), - "Previous records of reservation service sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_res_extra_services_decrease_stay(self): - """ - Check when removing a night to a reservation after creating it and this services - has the same price, cancel and cancel discount values, the sales line that - were created with the reservation are maintained. - --------- - Create a reservation of 2 nights for a double room and add a service to this - reservation. The value of the sale lines of the services is stored - in a variable. Then one night is removed to the reservation and it is verified - that the reservation service sale lines are the same as the value of the previously - saved variable. - """ - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - previous_folio_extra_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - )[0] - - # ACT - r_test.checkout = datetime.datetime.now() + datetime.timedelta(days=2) - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - previous_folio_extra_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ), - "Previous records of reservation service sales lines should not be " - "deleted if it is not necessary", - ) - - def test_comp_fsl_res_extra_services_same_stay(self): - # TEST CASE - # Price is changed for all reservation services of a 2-night reservation. - # But price, discount & cancel discount after the change is the same - # for all nights. - # Should keep the same reservation service sales line record. - """ - Check that when changing the price of all services in a - reservation, which before the change had the same price, discount - and cancel discount values, the same sale lines that existed before - the change are kept. - ------------------ - Create a reservation of 2 nights for a double room and add a service to this - reservation. The value of the sale lines of the services is stored - in a variable. Then the value of the price of all the reservation services - is changed to 50 and it is verified that the reservation service sale lines - are equal to the value of the previously saved variable. - """ - - # ARRANGE - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - r_test.service_ids = [(4, self.extra_service.id)] - r_test.service_ids.service_line_ids.flush() - previous_folio_extra_service_sale_line = r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - )[0] - - # ACT - r_test.service_ids.filtered( - lambda x: x.id == self.extra_service.id - ).service_line_ids.price_unit = 50 - r_test.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - previous_folio_extra_service_sale_line, - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ), - "Previous records of reservation service sales lines should not be " - "deleted if it is not necessary", - ) - - # FOLIO EXTRA SERVICES - def test_comp_fsl_fol_extra_services_one(self): - # TEST CASE - # Folio with extra services - # should generate 1 folio service sale line - """ - Check that when adding a service that is not a board service to a - folio with the same price, cancel and cancel discount, the number - of sales lines is kept. - ------------------ - Create a 2 night reservation. Then a service is added with - is_board_service = False and it is verified that the length of - the sale lines of the folio is 1. - """ - # ARRANGE - expected_folio_service_sale_lines = 1 - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - # ACT - r_test.folio_id.service_ids = [(4, self.extra_service.id)] - r_test.folio_id.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_folio_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: x.service_id == self.extra_service - ) - ), - "Folio should contain {} folio service sale lines".format( - expected_folio_service_sale_lines - ), - ) - - def test_comp_fsl_fol_extra_services_two(self): - """ - Check that when adding several services to a folio, - several sale lines should be generated on the folio. - ----------------- - Create a 2 night reservation. Two services are added - to the reservation and it is verified that the length - of the folio sale lines is equal to 2. - """ - - # ARRANGE - expected_folio_service_sale_lines = 2 - product_test2 = self.env["product.product"].create( - { - "name": "Test Product 1", - } - ) - - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.env.ref("base.res_partner_12").id, - } - ) - - extra_service2 = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": product_test2.id, - } - ) - - # ACT - r_test.folio_id.service_ids = [(4, self.extra_service.id)] - r_test.folio_id.service_ids = [(4, extra_service2.id)] - r_test.folio_id.service_ids.service_line_ids.flush() - - # ASSERT - self.assertEqual( - expected_folio_service_sale_lines, - len( - r_test.folio_id.sale_line_ids.filtered( - lambda x: not x.reservation_id and not x.display_type - ) - ), - "Folio should contain {} folio service sale lines".format( - expected_folio_service_sale_lines - ), - ) - - def test_no_sale_lines_staff_reservation(self): - """ - Check that the sale_line_ids of a folio whose reservation - is of type 'staff' are not created. - ----- - A reservation is created with the reservation_type field - with value 'staff'. Then it is verified that the - sale_line_ids of the folio created with the creation of - the reservation are equal to False. - """ - # ARRANGE - self.partner1 = self.env["res.partner"].create({"name": "Alberto"}) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "staff", - } - ) - # ASSERT - self.assertFalse( - reservation.folio_id.sale_line_ids, - "Folio sale lines should not be generated for a staff type reservation ", - ) - - def test_no_sale_lines_out_reservation(self): - """ - Check that the sale_line_ids of a folio whose reservation - is of type 'out' are not created. - ----- - A reservation is created with the reservation_type field - with value 'out'. Then it is verified that the - sale_line_ids of the folio created with the creation of - the reservation are equal to False. - """ - # ARRANGE - self.partner1 = self.env["res.partner"].create({"name": "Alberto"}) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "out", - } - ) - # ASSERT - self.assertFalse( - reservation.folio_id.sale_line_ids, - "Folio sale lines should not be generated for a out of service type reservation ", - ) diff --git a/pms/tests/test_pms_invoice_refund.py b/pms/tests/test_pms_invoice_refund.py deleted file mode 100644 index 21edab794..000000000 --- a/pms/tests/test_pms_invoice_refund.py +++ /dev/null @@ -1,10 +0,0 @@ -from freezegun import freeze_time - -from odoo.tests.common import SavepointCase - -freeze_time("2000-02-02") - - -class TestPmsInvoiceRefund(SavepointCase): - def setUp(self): - super(TestPmsInvoiceRefund, self).setUp() diff --git a/pms/tests/test_pms_multiproperty.py b/pms/tests/test_pms_multiproperty.py deleted file mode 100644 index e040491a6..000000000 --- a/pms/tests/test_pms_multiproperty.py +++ /dev/null @@ -1,1038 +0,0 @@ -import datetime - -from odoo import fields -from odoo.exceptions import UserError - -from .common import TestPms - - -class TestPmsMultiproperty(TestPms): - def setUp(self): - super().setUp() - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Pms_property_test2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Pms_property_test3", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - def test_availability_closed_no_room_type_check_property(self): - """ - Check that availability rules are applied to the correct properties. - ---------- - Check that for that date test_property1 doesnt have rooms available - (of that type:room_type1), - instead, property2 has room_type1 available - """ - # ARRANGE - self.pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 1", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - self.availability_plan1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist2.id])], - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - "name": "Special Room Test", - "default_code": "SP_Test", - "class_id": self.room_type_class1.id, - } - ) - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 201 test", - "room_type_id": self.room_type1.id, - "capacity": 2, - } - ) - # pms.room - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property2.id, - "name": "Double 202 test", - "room_type_id": self.room_type1.id, - "capacity": 2, - } - ) - self.room_type_availability_rule1 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.availability_plan1.id, - "room_type_id": self.room_type1.id, - "date": (fields.datetime.today() + datetime.timedelta(days=2)).date(), - "closed": True, - "pms_property_id": self.pms_property1.id, - } - ) - self.room_type_availability_rule2 = self.env[ - "pms.availability.plan.rule" - ].create( - { - "availability_plan_id": self.availability_plan1.id, - "room_type_id": self.room_type1.id, - "date": (fields.datetime.today() + datetime.timedelta(days=2)).date(), - "pms_property_id": self.pms_property2.id, - } - ) - - properties = [ - {"property": self.pms_property1.id, "value": False}, - {"property": self.pms_property2.id, "value": True}, - ] - - for p in properties: - with self.subTest(k=p): - # ACT - pms_property = self.env["pms.property"].browse(p["property"]) - pms_property = pms_property.with_context( - checkin=fields.date.today(), - checkout=( - fields.datetime.today() + datetime.timedelta(days=2) - ).date(), - room_type_id=self.room_type1.id, - pricelist_id=self.pricelist2.id, - ) - rooms_avail = pms_property.free_room_ids - - # ASSERT - self.assertEqual( - len(rooms_avail) > 0, p["value"], "Availability is not correct" - ) - - # AMENITY - def test_amenity_property_not_allowed(self): - """ - Creation of a Amenity with Properties incompatible with it Amenity Type - - +-----------------------------------+-----------------------------------+ - | Amenity Type (TestAmenityType1) | Amenity (TestAmenity1) | - +-----------------------------------+-----------------------------------+ - | Property1 - Property2 | Property1 - Property2 - Property3 | - +-----------------------------------+-----------------------------------+ - """ - # ARRANGE - AmenityType = self.env["pms.amenity.type"] - Amenity = self.env["pms.amenity"] - amenity_type1 = AmenityType.create( - { - "name": "TestAmenityType1", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - # ACT & ASSERT - with self.assertRaises(UserError), self.cr.savepoint(): - Amenity.create( - { - "name": "TestAmenity1", - "pms_amenity_type_id": amenity_type1.id, - "pms_property_ids": [ - ( - 6, - 0, - [ - self.pms_property1.id, - self.pms_property2.id, - self.pms_property3.id, - ], - ) - ], - } - ) - - # AVAILABILITY PLAN RULES - def test_check_property_availability_room_type(self): - """ - Check integrity between availability properties and room_type properties. - Test cases when creating a availability_rule: - Allowed properties: - Room Type(room_type1) --> pms_property1, pms_property_4 - Availability Plan(availability_example) --> pms_property1, pms_property2 - - Both cases throw an exception: - # 1:Rule for property2, - # it is allowed in availability_plan but not in room_type - # 2:Rule for property4, - # it is allowed in room_type, but not in availability_plan - """ - # ARRANGE - self.pms_property4 = self.env["pms.property"].create( - { - "name": "Property 3", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 1", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - # create new room_type - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property4.id), - ], - "name": "Special Room Test", - "default_code": "SP_Test", - "class_id": self.room_type_class1.id, - } - ) - # ACT - self.availability_plan1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist2.id])], - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - self.availability_rule1 = self.env["pms.availability.plan.rule"].create( - { - "availability_plan_id": self.availability_plan1.id, - "room_type_id": self.room_type1.id, - "date": (fields.datetime.today() + datetime.timedelta(days=2)).date(), - "closed": True, - "pms_property_id": self.pms_property1.id, - } - ) - - test_cases = [ - { - "pms_property_id": self.pms_property2.id, - }, - { - "pms_property_id": self.pms_property4.id, - }, - ] - # ASSERT - for test_case in test_cases: - with self.subTest(k=test_case): - with self.assertRaises(UserError): - self.availability_rule1.pms_property_id = test_case[ - "pms_property_id" - ] - - # BOARD SERVICE LINE - def test_pms_bsl_product_property_integrity(self): - """ - Creation of a board service line without property, of a product - only available for a specific property. - """ - # ARRANGE - product1 = self.env["product.product"].create( - {"name": "Product", "pms_property_ids": [self.pms_property1.id]} - ) - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service", - "default_code": "CB", - } - ) - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Board service line shouldnt be created." - ): - self.env["pms.board.service.line"].create( - { - "product_id": product1.id, - "pms_board_service_id": board_service1.id, - } - ) - - def test_pms_bsl_board_service_property_integrity(self): - """ - Creation of a board service line without property, of board service - only available for a specific property. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "Property 1", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - product1 = self.env["product.product"].create( - {"name": "Product", "pms_property_ids": [self.pms_property1.id]} - ) - - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service", - "default_code": "CB", - "pms_property_ids": [pms_property2.id], - } - ) - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Board service line shouldnt be created." - ): - self.env["pms.board.service.line"].create( - { - "product_id": product1.id, - "pms_board_service_id": board_service1.id, - } - ) - - def test_pms_bsl_board_service_line_prop_integrity(self): - """ - Creation of a board service line with a specific property, - of board service without property. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "Property 1", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - product1 = self.env["product.product"].create( - {"name": "Product", "pms_property_ids": [self.pms_property1.id]} - ) - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service", - "default_code": "CB", - } - ) - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Board service line shouldnt be created." - ): - self.env["pms.board.service.line"].create( - { - "product_id": product1.id, - "pms_board_service_id": board_service1.id, - "pms_property_ids": [pms_property2.id], - } - ) - - # BOARD SERVICE ROOM TYPE - def test_create_rt_props_gt_bs_props(self): - """ - Create board service for a room type and the room type - have MORE properties than the board service. - Record of board_service_room_type should contain the - board service properties. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, pms_property2.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service_test = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - "pms_property_ids": [self.pms_property1.id], - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_double.id, - "pms_board_service_id": board_service_test.id, - } - ) - # ASSERT - self.assertEqual( - new_bsrt.pms_property_ids.ids, - board_service_test.pms_property_ids.ids, - "Record of board_service_room_type should contain the" - " board service properties.", - ) - - def test_create_rt_props_lt_bs_props(self): - """ - Create board service for a room type and the room type - have LESS properties than the board service. - Record of board_service_room_type should contain the - room types properties. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service1 = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - "pms_property_ids": [self.pms_property1.id, pms_property2.id], - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type1.id, - "pms_board_service_id": board_service1.id, - } - ) - # ASSERT - self.assertEqual( - new_bsrt.pms_property_ids.ids, - room_type1.pms_property_ids.ids, - "Record of board_service_room_type should contain the" - " room types properties.", - ) - - def test_create_rt_props_eq_bs_props(self): - """ - Create board service for a room type and the room type - have THE SAME properties than the board service. - Record of board_service_room_type should contain the - room types properties that matchs with the board - service properties - """ - # ARRANGE - room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service1 = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - "pms_property_ids": [self.pms_property1.id], - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type1.id, - "pms_board_service_id": board_service1.id, - } - ) - # ASSERT - self.assertTrue( - new_bsrt.pms_property_ids.ids == room_type1.pms_property_ids.ids - and new_bsrt.pms_property_ids.ids == board_service1.pms_property_ids.ids, - "Record of board_service_room_type should contain the room " - "types properties and matchs with the board service properties", - ) - - def test_create_rt_no_props_and_bs_props(self): - """ - Create board service for a room type and the room type - hasn't properties but the board services. - Record of board_service_room_type should contain the - board service properties. - """ - # ARRANGE - room_type1 = self.env["pms.room.type"].create( - { - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service1 = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - "pms_property_ids": [self.pms_property1.id], - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type1.id, - "pms_board_service_id": board_service1.id, - } - ) - # ASSERT - self.assertEqual( - new_bsrt.pms_property_ids.ids, - board_service1.pms_property_ids.ids, - "Record of board_service_room_type should contain the" - " board service properties.", - ) - - def test_create_rt_props_and_bs_no_props(self): - """ - Create board service for a room type and the board service - hasn't properties but the room type. - Record of board_service_room_type should contain the - room type properties. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, pms_property2.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service1 = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type1.id, - "pms_board_service_id": board_service1.id, - } - ) - # ASSERT - self.assertEqual( - new_bsrt.pms_property_ids.ids, - room_type1.pms_property_ids.ids, - "Record of board_service_room_type should contain the" - " room type properties.", - ) - - def test_create_rt_no_props_and_bs_no_props(self): - """ - Create board service for a room type and the board service - has no properties and neither does the room type - Record of board_service_room_type shouldnt contain properties. - """ - # ARRANGE - - room_type1 = self.env["pms.room.type"].create( - { - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - "price": 25, - } - ) - board_service1 = self.board_service = self.env["pms.board.service"].create( - { - "name": "Test Board Service", - "default_code": "TPS", - } - ) - # ACT - new_bsrt = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type1.id, - "pms_board_service_id": board_service1.id, - } - ) - # ASSERT - self.assertFalse( - new_bsrt.pms_property_ids.ids, - "Record of board_service_room_type shouldnt contain properties.", - ) - - def test_pms_bsrtl_product_property_integrity(self): - """ - Creation of a board service room type line without property, of a product - only available for a specific property. - """ - # ARRANGE - - product1 = self.env["product.product"].create( - {"name": "Product", "pms_property_ids": self.pms_property1} - ) - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service", - "default_code": "CB", - } - ) - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "Type1", - "class_id": self.room_type_class1.id, - } - ) - board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_board_service_id": board_service1.id, - "pms_room_type_id": room_type1.id, - } - ) - - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Board service room type line shouldnt be created." - ): - self.env["pms.board.service.room.type.line"].create( - { - "pms_board_service_room_type_id": board_service_room_type1.id, - "product_id": product1.id, - } - ) - - def test_pms_bsrtl_board_service_line_prop_integrity(self): - """ - Creation of a board service room type line with a specific property, - of board service without property. - """ - # ARRANGE - product1 = self.env["product.product"].create( - {"name": "Product", "pms_property_ids": [self.pms_property1.id]} - ) - board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service", - "default_code": "CB", - } - ) - - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "Type1", - "class_id": self.room_type_class1.id, - } - ) - board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_board_service_id": board_service1.id, - "pms_room_type_id": room_type1.id, - } - ) - - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Board service line shouldnt be created." - ): - self.env["pms.board.service.room.type.line"].create( - { - "product_id": product1.id, - "pms_property_ids": [self.pms_property2.id], - "pms_board_service_room_type_id": board_service_room_type1.id, - } - ) - - # PMS.FOLIO - def test_folio_closure_reason_consistency_properties(self): - """ - Check the multiproperty consistency between - clousure reasons and folios - ------- - create multiproperty scenario (3 properties in total) and - a new clousure reason in pms_property1 and pms_property2, then, create - a new folio in property3 and try to set the clousure_reason - waiting a error property consistency. - """ - # ARRANGE - cl_reason = self.env["room.closure.reason"].create( - { - "name": "closure_reason_test", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - - # ACTION & ASSERT - with self.assertRaises( - UserError, - msg="Folio created with clousure_reason_id with properties inconsistence", - ): - self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property3.id, - "closure_reason_id": cl_reason.id, - } - ) - - # PRICELIST - def test_inconsistency_property_pricelist_item(self): - """ - Check a pricelist item and its pricelist are inconsistent with the property. - Create a pricelist item that belongs to a property and check if - a pricelist that belongs to a diferent one, cannot be created. - """ - # ARRANGE - # ACT & ASSERT - self.pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 1", - "pms_property_ids": [ - (4, self.pms_property1.id), - (4, self.pms_property2.id), - ], - } - ) - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SIN", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - with self.assertRaises(UserError): - self.item1 = self.env["product.pricelist.item"].create( - { - "name": "item_1", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "date_start": datetime.datetime.today(), - "date_end": datetime.datetime.today() + datetime.timedelta(days=1), - "fixed_price": 40.0, - "pricelist_id": self.pricelist2.id, - "pms_property_ids": [self.pms_property3.id], - } - ) - - def test_inconsistency_cancelation_rule_property(self): - """ - Check a cancelation rule and its pricelist are inconsistent with the property. - Create a cancelation rule that belongs to a two properties and check if - a pricelist that belongs to a diferent properties, cannot be created. - """ - # ARRANGE - - Pricelist = self.env["product.pricelist"] - # ACT - self.cancelation_rule1 = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "pms_property_ids": [self.pms_property1.id, self.pms_property3.id], - } - ) - # ASSERT - with self.assertRaises(UserError): - Pricelist.create( - { - "name": "Pricelist Test", - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "cancelation_rule_id": self.cancelation_rule1.id, - } - ) - - def test_inconsistency_availability_plan_property(self): - """ - Check a availability plan and its pricelist are inconsistent with the property. - Create a availability plan that belongs to a two properties and check if - a pricelist that belongs to a diferent properties, cannot be created. - """ - self.availability_plan1 = self.env["pms.availability.plan"].create( - {"name": "Availability Plan", "pms_property_ids": [self.pms_property1.id]} - ) - with self.assertRaises(UserError): - self.env["product.pricelist"].create( - { - "name": "Pricelist", - "pms_property_ids": [self.pms_property2.id], - "availability_plan_id": self.availability_plan1.id, - } - ) - - def test_multiproperty_checks(self): - """ - # TEST CASE - Multiproperty checks in reservation - +---------------+------+------+------+----+----+ - | reservation | property1 | - +---------------+------+------+------+----+----+ - | room | property2 | - | room_type | property2, property3 | - | board_service | property2, property3 | - | pricelist | property2, property3 | - +---------------+------+------+------+----+----+ - """ - # ARRANGE - self.board_service1 = self.env["pms.board.service"].create( - { - "name": "Board Service Test", - "default_code": "CB", - } - ) - host1 = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "654667733", - "email": "miguel@example.com", - } - ) - self.reservation1 = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "pms_property_id": self.pms_property1.id, - "partner_id": host1.id, - } - ) - - room_type_test = self.env["pms.room.type"].create( - { - "pms_property_ids": [ - (4, self.pms_property3.id), - (4, self.pms_property2.id), - ], - "name": "Single", - "default_code": "SIN", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - - room = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property2.id, - "room_type_id": room_type_test.id, - } - ) - - pricelist2 = self.env["product.pricelist"].create( - { - "name": "pricelist_test", - "pms_property_ids": [ - (4, self.pms_property2.id), - (4, self.pms_property3.id), - ], - } - ) - - board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_board_service_id": self.board_service1.id, - "pms_room_type_id": room_type_test.id, - "pms_property_ids": [self.pms_property2.id, self.pms_property3.id], - } - ) - test_cases = [ - {"preferred_room_id": room.id}, - {"room_type_id": room_type_test.id}, - {"pricelist_id": pricelist2.id}, - {"board_service_room_id": board_service_room_type1.id}, - ] - - for test_case in test_cases: - with self.subTest(k=test_case): - with self.assertRaises(UserError): - self.reservation1.write(test_case) - - # ROOM - def test_inconsistency_room_ubication_property(self): - """ - Room property and its ubication properties are inconsistent. - A Room with property that is not included in available properties - for its ubication cannot be created. - """ - # ARRANGE - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SI", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - ubication1 = self.env["pms.ubication"].create( - { - "name": "UbicationTest", - "pms_property_ids": [ - (4, self.pms_property1.id), - ], - } - ) - # ACT & ASSERT - with self.assertRaises( - UserError, - msg="The room should not be created if its property is not included " - "in the available properties for its ubication.", - ): - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property2.id, - "room_type_id": self.room_type1.id, - "ubication_id": ubication1.id, - } - ) - - def test_consistency_room_ubication_property(self): - """ - Room property and its ubication properties are consistent. - A Room with property included in available properties - for its ubication can be created. - """ - # ARRANGE - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SI", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - ubication1 = self.env["pms.ubication"].create( - { - "name": "UbicationTest", - "pms_property_ids": [ - (4, self.pms_property1.id), - ], - } - ) - # ACT - new_room1 = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - "ubication_id": ubication1.id, - } - ) - # ASSERT - self.assertIn( - new_room1.pms_property_id, - ubication1.pms_property_ids, - "The room should be created if its property belongs to the availabe" - "properties for its ubication.", - ) - - def test_inconsistency_room_type_property(self): - """ - Room property and its room type properties are inconsistent. - A Room with property that is not included in available properties - for its room type cannot be created. - """ - # ARRANGE - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Property_3", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SI", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - # ACT & ARRANGE - with self.assertRaises( - UserError, - msg="The room should not be created if its property is not included " - "in the available properties for its room type.", - ): - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property3.id, - "room_type_id": self.room_type1.id, - } - ) - - def test_consistency_room_type_property(self): - """ - Room property and its room type properties are inconsistent. - A Room with property included in available properties - for its room type can be created. - """ - # ARRANGE - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SI", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - # ACT - room1 = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - } - ) - # ASSERT - self.assertIn( - room1.pms_property_id, - self.room_type1.pms_property_ids, - "The room should be created if its property is included " - "in the available properties for its room type.", - ) diff --git a/pms/tests/test_pms_payment.py b/pms/tests/test_pms_payment.py deleted file mode 100644 index 5f3f0d7e6..000000000 --- a/pms/tests/test_pms_payment.py +++ /dev/null @@ -1,38 +0,0 @@ -from freezegun import freeze_time - -from odoo.tests.common import SavepointCase - -freeze_time("2000-02-02") - - -class TestPmsPayment(SavepointCase): - def setUp(self): - super(TestPmsPayment, self).setUp() - - # TODO: Test allowed manual payment - # create a journal with allowed_pms_payments = True and - # check that the _get_payment_methods property method return it - - # TODO: Test not allowed manual payment - # create a journal without allowed_pms_payments = True and - # check that the _get_payment_methods property method dont return it - - # TODO: Test default account payment create - # create a bank journal, a reservation, pay the reservation - # with do_payment method without pay_type parameter - # and check that account payment was created - - # TODO: Test default statement line create - # create a cash journal, a reservation, pay the reservation - # with do_payment method without pay_type parameter - # and check that statement line was created - - # TODO: Test set pay_type cash, statement line create - # create a bank journal, a reservation, pay the reservation - # with do_payment method with 'cash' pay_type parameter - # and check that statement line was created - - # TODO: Test set pay_type bank, account payment create - # create a cash journal, a reservation, pay the reservation - # with do_payment method with 'bank' pay_type parameter - # and check that account payment was created diff --git a/pms/tests/test_pms_pricelist.py b/pms/tests/test_pms_pricelist.py deleted file mode 100644 index 9a034ccf4..000000000 --- a/pms/tests/test_pms_pricelist.py +++ /dev/null @@ -1,1240 +0,0 @@ -import datetime - -from freezegun import freeze_time - -from odoo import fields -from odoo.exceptions import ValidationError -from odoo.tests import tagged - -from .common import TestPms - - -@tagged("standard", "nice") -class TestPmsPricelist(TestPms): - def setUp(self): - super().setUp() - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property_2", - "company_id": self.env.ref("base.main_company").id, - "default_pricelist_id": self.env.ref("product.list0").id, - } - ) - - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Property_3", - "company_id": self.env.ref("base.main_company").id, - "default_pricelist_id": self.env.ref("product.list0").id, - } - ) - - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SIN", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - - # pms.room - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Single 101", - "room_type_id": self.room_type1.id, - "capacity": 2, - } - ) - - self.pricelist2 = self.env["product.pricelist"].create( - { - "name": "pricelist_2", - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - } - ) - # product.product 1 - self.product1 = self.env["product.product"].create({"name": "Test Breakfast"}) - - # pms.board.service - self.board_service1 = self.env["pms.board.service"].create( - { - "name": "Test Only Breakfast", - "default_code": "CB1", - } - ) - # pms.board.service.line - self.board_service_line1 = self.env["pms.board.service.line"].create( - { - "product_id": self.product1.id, - "pms_board_service_id": self.board_service1.id, - } - ) - - # pms.board.service.room.type - self.board_service_room_type1 = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type1.id, - "pms_board_service_id": self.board_service1.id, - } - ) - - self.partner1 = self.env["res.partner"].create({"name": "Carles"}) - - @freeze_time("2000-01-01") - def test_board_service_pricelist_item_apply_sale_dates(self): - """ - Pricelist item is created to apply on board services at SALE date. - The reservation created take into account the board service - pricelist item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() - date_to = fields.date.today() - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "board_service_room_type_id": self.board_service_room_type1.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - # ASSERT - self.assertEqual( - reservation_created.service_ids.price_subtotal, - expected_price, - "The reservation created should take into account the board service" - " pricelist item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_board_service_pricelist_item_not_apply_sale_dates(self): - """ - Pricelist item is created to apply on board services at SALE date. - The reservation created DONT take into account the board service pricelist - item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "board_service_room_type_id": self.board_service_room_type1.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.service_ids.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the board service pricelist" - " item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_board_service_pricelist_item_apply_consumption_dates(self): - """ - Pricelist item is created to apply on board services - at CONSUMPTION date. - The reservation created take into account the board service - pricelist item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start_consumption": date_from, - "date_end_consumption": date_to, - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "board_service_room_type_id": self.board_service_room_type1.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - # ASSERT - self.assertEqual( - reservation_created.service_ids.price_subtotal, - expected_price, - "The reservation created should take into account the board service" - " pricelist item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_board_service_pricelist_item_not_apply_consumption_dates(self): - """ - Pricelist item is created to apply on board services - at CONSUMPTION date. - The reservation created DONT take into account the board service - pricelist item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=2) - date_to = fields.date.today() + datetime.timedelta(days=2) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "board_service_room_type_id": self.board_service_room_type1.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "board_service_room_id": self.board_service_room_type1.id, - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.service_ids.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the board service" - " pricelist item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_room_type_pricelist_item_apply_sale_dates(self): - """ - Pricelist item is created to apply on room types - at SALE date. - The reservation created take into account the room type - pricelist item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() - date_to = fields.date.today() - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - } - ) - # ASSERT - self.assertEqual( - reservation_created.price_subtotal, - expected_price, - "The reservation created should take into account the room type" - " pricelist item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_room_type_pricelist_item_not_apply_sale_dates(self): - """ - Pricelist item is created to apply on room types - at SALE date. - The reservation created DONT take into account the room type - pricelist item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the room type" - " pricelist item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_room_type_pricelist_item_apply_consumption_dates(self): - """ - Pricelist item is created to apply on room types - at CONSUMPTION date. - The reservation created take into account the room type - pricelist item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start_consumption": date_from, - "date_end_consumption": date_to, - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - } - ) - # ASSERT - self.assertEqual( - reservation_created.price_subtotal, - expected_price, - "The reservation created should take into account the room type" - " pricelist item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_room_type_pricelist_item_not_apply_consumption_dates(self): - """ - Pricelist item is created to apply on room types - at CONSUMPTION date. - The reservation created DONT take into account the room type - pricelist item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=2) - date_to = fields.date.today() + datetime.timedelta(days=2) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the room type" - " pricelist item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_service_pricelist_item_apply_sale_dates(self): - """ - Pricelist item is created to apply on services at SALE date. - The reservation created take into account the service - pricelist item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() - date_to = fields.date.today() - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "service_ids": [(0, 0, {"product_id": self.product1.id})], - } - ) - # ASSERT - self.assertEqual( - reservation_created.service_ids.price_subtotal, - expected_price, - "The reservation created should take into account the service" - " pricelist item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_service_pricelist_item_not_apply_sale_dates(self): - """ - Pricelist item is created to apply on services at SALE date. - The reservation created DONT take into account the service pricelist - item created previously according to the SALE date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "service_ids": [(0, 0, {"product_id": self.product1.id})], - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.service_ids.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the service pricelist" - " item created previously according to the SALE date.", - ) - - @freeze_time("2000-01-01") - def test_service_pricelist_item_apply_consumption_dates(self): - """ - Pricelist item is created to apply on services at CONSUMPTION date. - The reservation created take into account the service - pricelist item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=1) - date_to = fields.date.today() + datetime.timedelta(days=1) - expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start_consumption": date_from, - "date_end_consumption": date_to, - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "fixed_price": expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "service_ids": [(0, 0, {"product_id": self.product1.id})], - } - ) - # ASSERT - self.assertEqual( - reservation_created.service_ids.price_subtotal, - expected_price, - "The reservation created should take into account the service" - " pricelist item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_service_pricelist_item_not_apply_consumption_dates(self): - """ - Pricelist item is created to apply on services at CONSUMPTION date. - The reservation created DONT take into account the service pricelist - item created previously according to the CONSUMPTION date. - """ - # ARRANGE - date_from = fields.date.today() + datetime.timedelta(days=2) - date_to = fields.date.today() + datetime.timedelta(days=2) - not_expected_price = 1000.0 - vals = { - "pricelist_id": self.pricelist2.id, - "date_start": datetime.datetime.combine( - date_from, datetime.datetime.min.time() - ), - "date_end": datetime.datetime.combine( - date_to, datetime.datetime.max.time() - ), - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.product1.id, - "fixed_price": not_expected_price, - "pms_property_ids": [self.pms_property1.id], - } - self.env["product.pricelist.item"].create(vals) - # ACT - reservation_created = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist2.id, - "service_ids": [(0, 0, {"product_id": self.product1.id})], - } - ) - # ASSERT - self.assertNotEqual( - reservation_created.service_ids.price_subtotal, - not_expected_price, - "The reservation created shouldnt take into account the service pricelist " - "item created previously according to the CONSUMPTION date.", - ) - - @freeze_time("2000-01-01") - def test_inconsistencies_pricelist_daily(self): - """ - Test cases to verify that a daily pricelist cannot be created because: - (Test case1): item has two properties and a items daily pricelist only - can has a one property. - (Test case2): item has all properties(pms_property_ids = False indicates - all properties)and a items daily pricelist only can has a one property. - (Test case3): item compute_price is 'percentage' and only can be 'fixed' - for items daily pricelist. - (Test case4): item compute_price is 'percentage' and has two properties - but compute_price can only be fixed and can only have one - property for items daily pricelist. - (Test case5): item compute_price is 'percentage' and has all properties - (pms_property_ids = False indicates all properties)but - compute_pricecan only be fixed and can only have one property for - items daily pricelist. - (Test case6): The difference of days between date_start_consumption and - date_end_consumption is three and the items of a daily pricelist - can only be one. - """ - test_cases = [ - { - "compute_price": "fixed", - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=1), - }, - { - "compute_price": "fixed", - "pms_property_ids": False, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=1), - }, - { - "compute_price": "percentage", - "pms_property_ids": [self.pms_property1.id], - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=1), - }, - { - "compute_price": "percentage", - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=1), - }, - { - "compute_price": "percentage", - "pms_property_ids": False, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=1), - }, - { - "compute_price": "fixed", - "pms_property_ids": [self.pms_property1.id], - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.today() - + datetime.timedelta(days=3), - }, - ] - - for tc in test_cases: - with self.subTest(k=tc): - with self.assertRaises( - ValidationError, - msg="Item only can has one property, the compute price only can" - "be fixed and the difference between date_start_consumption" - "and date_end_consumption only can be 1", - ): - self.room_type1.pms_property_ids = tc["pms_property_ids"] - item = self.env["product.pricelist.item"].create( - { - "pms_property_ids": tc["pms_property_ids"], - "compute_price": tc["compute_price"], - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "date_start_consumption": tc["date_start_consumption"], - "date_end_consumption": tc["date_end_consumption"], - } - ) - self.pricelist_test = self.env["product.pricelist"].create( - { - "name": "Pricelist test", - "pricelist_type": "daily", - "pms_property_ids": tc["pms_property_ids"], - "item_ids": [item.id], - } - ) - - @freeze_time("2020-01-01") - def test_consistency_pricelist_daily(self): - """ - Test to verify that a daily pricelist is created. - Create a pricelist item with a property, the value of compute_price is - fixed and date_start_consumption date_end_consumption has the same value - """ - self.room_type1.pms_property_ids = (self.pms_property1.id,) - item = self.env["product.pricelist.item"].create( - { - "pms_property_ids": [self.pms_property1.id], - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": self.room_type1.product_id.id, - "date_start_consumption": datetime.date.today(), - "date_end_consumption": datetime.date.today(), - } - ) - self.pricelist_test = self.env["product.pricelist"].create( - { - "name": "Pricelist test", - "pricelist_type": "daily", - "pms_property_ids": [self.pms_property1.id], - "item_ids": [item.id], - } - ) - self.assertTrue(self.pricelist_test, "Pricelist not created.") - - @freeze_time("2000-01-01") - def test_simple_price_without_items(self): - """ - Test case for no items applied in a reservation. - """ - - # ARRANGE - self.room_type = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "S", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - - self.room = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Single 1", - "room_type_id": self.room_type.id, - } - ) - reservation = self.env["pms.reservation"].create( - { - "checkin": datetime.datetime.today(), - "checkout": datetime.datetime.today() + datetime.timedelta(days=3), - "preferred_room_id": self.room.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - # ACT - n_days = (reservation.checkout - reservation.checkin).days - expected_price = self.room.room_type_id.list_price * n_days - - # ASSERT - self.assertEqual( - expected_price, reservation.price_subtotal, "The price is not as expected" - ) - - @freeze_time("2022-01-01") - def test_items_sort(self): - """ - Test cases to verify the order for each field considered individually - Test cases to prioritize fields over other fields: - 1. applied_on - 2. date - 3. date consumption - 4. num. properties - 5. id - - tie - - no [date_start|date_end|date_start_consumption|date_end_consumption] - """ - # ARRANGE - self.product_category = self.env["product.category"].create( - {"name": "Category1"} - ) - self.product_template = self.env["product.template"].create( - {"name": "Template1"} - ) - self.room_type = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SGL", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - - self.room = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "101", - "room_type_id": self.room_type.id, - } - ) - properties = self.room_type.product_id.pms_property_ids.ids - test_cases = [ - { - "name": "sorting applied_on", - "expected_price": 50 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "2_product_category", - "categ_id": self.product_category.id, - "fixed_price": 60.0, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "1_product", - "product_id": self.room_type.product_id.id, - "product_tmpl_id": self.product_template.id, - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "sorting SALE date min range", - "expected_price": 50.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=2), - "fixed_price": 60.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=1), - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=3), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "sorting CONSUMPTION date min range", - "expected_price": 40.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=6), - "fixed_price": 60.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=10), - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "sorting num. properties", - "expected_price": 50.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "fixed_price": 60.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "pms_property_ids": [self.pms_property1.id], - "fixed_price": 50.0, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "pms_property_ids": [ - self.pms_property1.id, - self.pms_property2.id, - ], - "fixed_price": 40.0, - }, - ], - }, - { - "name": "sorting by item id", - "expected_price": 40.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "fixed_price": 60.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "prioritize applied_on over SALE date", - "expected_price": 60.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=2), - "fixed_price": 60.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "product_id": self.room_type.product_id.id, - "product_tmpl_id": self.product_template.id, - "applied_on": "1_product", - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=1), - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "prioritize SALE date over CONSUMPTION date", - "expected_price": 120.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=10), - "fixed_price": 120.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "fixed_price": 50.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "prioritize CONSUMPTION date over min. num. properties", - "expected_price": 50.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "fixed_price": 120.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "pms_property_ids": [ - self.pms_property1.id, - self.pms_property2.id, - ], - "fixed_price": 50.0, - }, - ], - }, - { - "name": "prioritize min. num. properties over item id", - "expected_price": 50.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "fixed_price": 120.0, - "pms_property_ids": properties, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "pms_property_ids": [ - self.pms_property1.id, - self.pms_property2.id, - ], - "fixed_price": 50.0, - }, - ], - }, - { - "name": "tie => order by item id", - "expected_price": 50.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=3), - "pms_property_ids": [ - self.pms_property1.id, - self.pms_property2.id, - ], - "fixed_price": 120.0, - }, - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now() - + datetime.timedelta(days=3), - "date_start": datetime.datetime.now(), - "date_end": datetime.datetime.now() - + datetime.timedelta(days=3), - "pms_property_ids": [ - self.pms_property1.id, - self.pms_property2.id, - ], - "fixed_price": 50.0, - }, - ], - }, - { - "name": "no SALE DATE START", - "expected_price": 40.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_end": datetime.datetime.now() - + datetime.timedelta(days=1), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "no SALE DATE END", - "expected_price": 40.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start": datetime.datetime.now(), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "no consumption DATE START", - "expected_price": 40.0 + self.room_type.list_price * 2, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_end_consumption": datetime.datetime.now(), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "no consumption DATE END", - "expected_price": 40.0 * 3, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - { - "name": "only applied consumption in one night", - "expected_price": 40.0 + self.room_type.list_price * 2, - "items": [ - { - "pricelist_id": self.pricelist1.id, - "applied_on": "0_product_variant", - "product_id": self.room_type.product_id.id, - "date_start_consumption": datetime.datetime.now(), - "date_end_consumption": datetime.datetime.now(), - "fixed_price": 40.0, - "pms_property_ids": properties, - }, - ], - }, - ] - - for tc in test_cases: - with self.subTest(k=tc): - - # ARRANGE - items = [] - for item in tc["items"]: - item = self.env["product.pricelist.item"].create(item) - items.append(item.id) - - # ACT - reservation = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() - + datetime.timedelta(days=3), - "preferred_room_id": self.room.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - } - ) - reservation_price = reservation.price_subtotal - self.env["pms.reservation"].browse(reservation.id).unlink() - self.env["product.pricelist.item"].browse(items).unlink() - - # ASSERT - self.assertEqual(tc["expected_price"], reservation_price, tc["name"]) diff --git a/pms/tests/test_pms_pricelist_settings.py b/pms/tests/test_pms_pricelist_settings.py deleted file mode 100644 index 7b04ebc96..000000000 --- a/pms/tests/test_pms_pricelist_settings.py +++ /dev/null @@ -1,55 +0,0 @@ -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsPricelistSettings(TestPms): - def test_advanced_pricelist_exists(self): - """ - Check if value of Pricelist parameter in sales settings is Advanced Price Rules. - Find the value of Pricelist parameter - with the key product.product_pricelist_setting and check if is equal to "advanced". - """ - # ARRANGE - key = "product.product_pricelist_setting" - value = "advanced" - - # ACT - found_value = self.env["ir.config_parameter"].sudo().get_param(key) - - # ASSERT - self.assertEqual( - found_value, value, "Parameter of Pricelist in setting is not 'advanced'" - ) - - def test_product_pricelist_setting_not_modified(self): - """ - Check that Pricelist parameter 'advanced' cannot be modified. - Set the value of product.product_pricelist_setting to 'basic' - but is not possible because this only can be 'advanced'. - """ - # ARRANGE - key = "product.product_pricelist_setting" - value = "basic" - - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The Pricelist parameter 'advanced' was modified." - ): - self.env["ir.config_parameter"].set_param(key, value) - - def test_product_pricelist_setting_not_unlink(self): - """ - Check that Pricelist parameter 'advanced' cannot be unlink. - Try to unlink the parameter product_pricelist with value 'advanced' - but this should be impossible. - """ - # ARRANGE - key = "product.product_pricelist_setting" - value = "advanced" - - # ACT & ASSERT - with self.assertRaises(ValidationError), self.cr.savepoint(): - self.env["ir.config_parameter"].search( - [("key", "=", key), ("value", "=", value)] - ).unlink() diff --git a/pms/tests/test_pms_res_users.py b/pms/tests/test_pms_res_users.py deleted file mode 100644 index bf0514909..000000000 --- a/pms/tests/test_pms_res_users.py +++ /dev/null @@ -1,164 +0,0 @@ -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsResUser(TestPms): - def setUp(self): - super().setUp() - # create a company and properties - self.company_A = self.env["res.company"].create( - { - "name": "Pms_Company1", - } - ) - self.company_B = self.env["res.company"].create( - { - "name": "Pms_Company2", - } - ) - self.property_A1 = self.env["pms.property"].create( - { - "name": "Pms_property", - "company_id": self.company_A.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.pricelist1.id, - } - ) - self.property_B1 = self.env["pms.property"].create( - { - "name": "Pms_propertyB1", - "company_id": self.company_B.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - def test_property_not_in_allowed_properties(self): - """ - 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 - Users = self.env["res.users"] - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Some property is not included in the allowed properties", - ): - 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)], - "pms_property_id": self.property_B1.id, - } - ) - - 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 - Users = self.env["res.users"] - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="Some property doesn't belong to the allowed companies" - ): - 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_B1.id), - ], - "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", - ) diff --git a/pms/tests/test_pms_reservation.py b/pms/tests/test_pms_reservation.py deleted file mode 100644 index 939df2aae..000000000 --- a/pms/tests/test_pms_reservation.py +++ /dev/null @@ -1,3621 +0,0 @@ -import datetime - -from freezegun import freeze_time - -from odoo import fields -from odoo.exceptions import UserError, ValidationError - -from .common import TestPms - - -class TestPmsReservations(TestPms): - def setUp(self): - super().setUp() - # create a room type availability - self.room_type_availability = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - - # create room type - self.room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - - self.room_type_triple = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Triple Test", - "default_code": "TRP_Test", - "class_id": self.room_type_class1.id, - } - ) - - # create rooms - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 101", - "room_type_id": self.room_type_double.id, - "capacity": 2, - "extra_beds_allowed": 1, - } - ) - - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 102", - "room_type_id": self.room_type_double.id, - "capacity": 2, - "extra_beds_allowed": 1, - } - ) - - self.room3 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 103", - "room_type_id": self.room_type_double.id, - "capacity": 2, - "extra_beds_allowed": 1, - } - ) - - self.room4 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Triple 104", - "room_type_id": self.room_type_triple.id, - "capacity": 3, - "extra_beds_allowed": 1, - } - ) - self.partner1 = self.env["res.partner"].create( - { - "firstname": "Jaime", - "lastname": "García", - "email": "jaime@example.com", - "birthdate_date": "1983-03-01", - "gender": "male", - } - ) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - - def test_reservation_dates_not_consecutive(self): - """ - Check the constrain if not consecutive dates - ---------------- - Create correct reservation set 3 reservation lines consecutives (nights) - """ - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - three_days_later = fields.date.today() + datetime.timedelta(days=3) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Error, it has been allowed to create a reservation with non-consecutive days", - ): - self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "reservation_line_ids": [ - (0, False, {"date": today}), - (0, False, {"date": tomorrow}), - (0, False, {"date": three_days_later}), - ], - } - ) - - def test_reservation_dates_compute_checkin_out(self): - """ - Check the reservation creation with specific reservation lines - anc compute checkin checkout - ---------------- - Create reservation with correct reservation lines and check - the checkin and checkout fields. Take into account that the - checkout of the reservation must be the day after the last night - (view checkout assertEqual) - """ - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - two_days_later = fields.date.today() + datetime.timedelta(days=2) - - # ACT - reservation = self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "reservation_line_ids": [ - (0, False, {"date": today}), - (0, False, {"date": tomorrow}), - (0, False, {"date": two_days_later}), - ], - } - ) - - # ASSERT - self.assertEqual( - reservation.checkin, - today, - "The calculated checkin of the reservation does \ - not correspond to the first day indicated in the dates", - ) - self.assertEqual( - reservation.checkout, - two_days_later + datetime.timedelta(days=1), - "The calculated checkout of the reservation does \ - not correspond to the last day indicated in the dates", - ) - - def test_create_reservation_start_date(self): - """ - Check that the reservation checkin and the first reservation date are equal. - ---------------- - Create a reservation and check if the first reservation line date are the same - date that the checkin date. - """ - # reservation should start on checkin day - - # ARRANGE - today = fields.date.today() - checkin = today + datetime.timedelta(days=8) - checkout = checkin + datetime.timedelta(days=11) - reservation_vals = { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - - # ACT - reservation = self.env["pms.reservation"].create(reservation_vals) - - self.assertEqual( - reservation.reservation_line_ids[0].date, - checkin, - "Reservation lines don't start in the correct date", - ) - - def test_create_reservation_end_date(self): - """ - Check that the reservation checkout and the last reservation date are equal. - ---------------- - Create a reservation and check if the last reservation line date are the same - date that the checkout date. - """ - # ARRANGE - today = fields.date.today() - checkin = today + datetime.timedelta(days=8) - checkout = checkin + datetime.timedelta(days=11) - reservation_vals = { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - - # ACT - reservation = self.env["pms.reservation"].create(reservation_vals) - - self.assertEqual( - reservation.reservation_line_ids[-1].date, - checkout - datetime.timedelta(1), - "Reservation lines don't end in the correct date", - ) - - def test_split_reservation01(self): - """ - # TEST CASE - The reservation shouldn't be splitted - preferred_room_id with availability provided - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | test | test | test | | | | - | Double 102 | | | | | | | - | Double 103 | | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - - # ASSERT - self.assertTrue( - all( - elem.room_id.id == r_test.reservation_line_ids[0].room_id.id - for elem in r_test.reservation_line_ids - ), - "The entire reservation should be allocated in the preferred room", - ) - - def test_split_reservation02(self): - """ - # TEST CASE - The reservation shouldn't be splitted - room_type_id with availability provided - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | test | test | test | | | | - | Double 102 | | | | | | | - | Double 103 | | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - - # ASSERT - self.assertFalse(r_test.splitted, "The reservation shouldn't be splitted") - - def test_split_reservation03(self): - """ - # TEST CASE - The reservation should be splitted in 2 rooms - (there is only one better option on day 02 and a draw the next day. - The night before should be prioritized) - +------------+------+------+------+------+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+------+----+----+ - | Double 101 | test | r3 | | | | | - | Double 102 | r1 | test | test | test | | | - | Double 103 | r2 | r4 | | | | | - +------------+------+------+------+------+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r1.reservation_line_ids[0].room_id = self.room2.id - r1.flush() - - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r2.reservation_line_ids[0].room_id = self.room3.id - r2.flush() - - r3 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r3.reservation_line_ids[0].room_id = self.room1.id - r3.flush() - - r4 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r4.reservation_line_ids[0].room_id = self.room3.id - r4.flush() - expected_num_changes = 2 - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=4), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - # ASSERT - self.assertEqual( - expected_num_changes, - len(r_test.reservation_line_ids.mapped("room_id")), - "The reservation shouldn't have more than 2 changes", - ) - - def test_split_reservation04(self): - """ - # TEST CASE - The reservation should be splitted in 3 rooms - (there are 2 best options on day 03 and room of last night is not available) - +------------+------+------+------+------+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+------+----+----+ - | Double 101 | test | r3 | test | test | | | - | Double 102 | r1 | test | r5 | | | | - | Double 103 | r2 | r4 | | | | | - +------------+------+------+------+------+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r1.reservation_line_ids[0].room_id = self.room2.id - r1.flush() - - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r2.reservation_line_ids[0].room_id = self.room3.id - r2.flush() - - r3 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r3.reservation_line_ids[0].room_id = self.room1.id - r3.flush() - - r4 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r4.reservation_line_ids[0].room_id = self.room3.id - r4.flush() - - r5 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=2), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r5.reservation_line_ids[0].room_id = self.room2.id - r5.flush() - - # ACT - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=4), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - - rooms = 0 - last_room = None - for line in r_test.reservation_line_ids: - if line.room_id != last_room: - last_room = line.room_id - rooms += 1 - - # ASSERT - self.assertEqual( - 3, rooms, "The reservation shouldn't be splitted in more than 3 roomss" - ) - - def test_split_reservation05(self): - """ - # TEST CASE - The preferred room_id is not available - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 |r1/tst| | | | | | - | Double 102 | | | | | | | - | Double 103 | | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r1.reservation_line_ids[0].room_id = self.room1 - r1.flush() - - # ACT & ASSERT - with self.assertRaises(ValidationError): - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - - def test_split_reservation06(self): - """ - # TEST CASE - There's no availability in the preferred_room_id provided - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 |r1/tst| tst | | | | - | Double 102 | | | | | | | - | Double 103 | | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r1.reservation_line_ids[0].room_id = self.room1 - r1.reservation_line_ids[1].room_id = self.room1 - r1.flush() - - # ACT & ASSERT - with self.assertRaises(ValidationError): - r_test = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r_test.flush() - - def test_split_reservation07(self): - """ - # TEST CASE - There's no availability - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - | Double 103 | r3 | r3 | r3 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r1.reservation_line_ids[0].room_id = self.room1 - r1.reservation_line_ids[1].room_id = self.room1 - r1.reservation_line_ids[2].room_id = self.room1 - r1.flush() - - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r2.reservation_line_ids[0].room_id = self.room2 - r2.reservation_line_ids[1].room_id = self.room2 - r2.reservation_line_ids[2].room_id = self.room2 - r2.flush() - - r3 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r3.reservation_line_ids[0].room_id = self.room3 - r3.reservation_line_ids[1].room_id = self.room3 - r3.reservation_line_ids[2].room_id = self.room3 - r3.flush() - - # ACT & ASSERT - with self.assertRaises(ValidationError): - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - } - ) - - def test_manage_children_raise(self): - # TEST CASE - """ - Check if the error occurs when trying to put more people than the capacity of the room. - -------------- - Create a reservation with a double room whose capacity is two and try to create - it with two adults and a child occupying the room. - """ - # NO ARRANGE - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="The number of people is greater than the capacity of the room", - ): - reservation = self.env["pms.reservation"].create( - { - "adults": 2, - "children_occupying": 1, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - reservation.flush() - - def test_to_assign_priority_reservation(self): - """ - To assign reservation must have priority = 1 - ------ - Create a reservation with only room_type (to_assign = True), - regardless of the rest of the fields the priority must be 1 - - NOTE: - WORK FLOW PRIORITY COMPUTE - Check reservation priority - -------- - 1 - TO ASSIGN, ARRIVAL DELAYED, DEPARTURE DELAYED (= 1) - 2 - CANCELLED with pending amount (= 2) - 3 - DONE with pending amount (= 3) - 4 - ONBOARD with pending amount (= days for checkout) - 5 - CONFIRM/DRAFT with arrival in less than 3 days (= 2 * days for checkin) - 6 - ONBOARD all paid (= 3 * days for checkout) - 7 - DONE with days from checkout < 1 (= 6) - 8 - CONFIRM/DRAFT with arrival between 3 and 20 days (= 3 * days for checkin) - 9 - CONFIRM/DRAFT with arrival in more than 20 days (= 4 * days for checkin) - 10 - DONE with days from checkout < 15 (= 5 * days from checkout) - 11 - DONE with days from checkout between 15 and 90 included (= 10 * days from checkout) - 12 - DONE with days from checkout > 90 (= 100 * days from checkout) - """ - # ARRANGE - expected_priority = 1 - - # ACT - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=30), - "checkout": fields.date.today() + datetime.timedelta(days=31), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a reservation to be assigned \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_arrival_delayed_priority_reservation(self): - """ - Arrival delayed reservation must have priority = 1 - ------ - Create a reservation with checkin date yesterday, and without checkin action, - regardless of the rest of the fields the priority must be 1 - """ - # ARRANGE - expected_priority = 1 - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-1), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # ACT - res.auto_arrival_delayed() - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a arrival delayed reservation \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_departure_delayed_priority_reservation(self): - """ - To departure delayed reservation must have priority = 1 - ------ - Create a reservation and make the work flow to onboard state, - using jump dates, we make the reservation should have left yesterday, - regardless of the rest of the fields the priority must be 1 - """ - # ARRANGE - expected_priority = 1 - freezer = freeze_time("1981-10-08") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - freezer.stop() - - # ACT - res.auto_departure_delayed() - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a departure delayed reservation \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_cancel_pending_amount_priority_reservation(self): - """ - Cancelled with pending payments reservation must have priority = 2 - ------ - create a reservation and cancel it ensuring that there are - pending payments in it, the priority must be 2 - """ - # ARRANGE - expected_priority = 2 - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=55), - "checkout": fields.date.today() + datetime.timedelta(days=56), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # ACT - res.action_cancel() - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a cancelled reservation with pending amount \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_done_with_pending_amountpriority_reservation(self): - """ - Done with pending amount reservation must have priority = 3 - ------ - Create a reservation and make the work flow to onboard - done state, - using jump dates, we make the checkout reservation with pending amount, - regardless of the rest of the fields the priority must be 3 - """ - # ARRANGE - expected_priority = 3 - freezer = freeze_time("1981-10-08") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - - freezer.stop() - freezer = freeze_time("1981-10-09") - freezer.start() - - res.action_reservation_checkout() - - # ACT - res.auto_departure_delayed() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a done reservation with pending amount\ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_onboard_with_pending_amount_priority_reservation(self): - """ - Onboard with pending amount reservation must have priority = days for checkout - ------ - Create a reservation with 3 nights and make the work flow to onboard, - using jump dates, we set today in 2 nights before checkout, - regardless of the rest of the fields the priority must be 2 - """ - # ARRANGE - expected_priority = 3 - freezer = freeze_time("1981-10-08") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - - # ACT - checkin1.action_on_board() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a onboard with payment amount reservation \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_confirm_arriva_lt_3_days_priority_reservation(self): - """ - Confirm reservation with arrival in less than 3 days, priority = 2 * days for checkout - ------ - Create a reservation with checkin date on 2 days - regardless of the rest of the fields the priority must be 2 * 2 = 4 - """ - # ARRANGE - expected_priority = 4 - - # ACT - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=2), - "checkout": fields.date.today() + datetime.timedelta(days=5), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a confirm with less than 3 days for arrival \ - reservation should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_onboard_all_pay_priority_reservation(self): - """ - Onboard with all pay reservation must have priority = 3 * days for checkout - ------ - Create a reservation with 3 nights and make the work flow to onboard, - using jump dates, we set today in 2 nights before checkout, - regardless of the rest of the fields the priority must be 3 * 3 = 9 - """ - # ARRANGE - expected_priority = 9 - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - - # ACT - checkin1.action_on_board() - # REVIEW: set to 0 the price to avoid make the payment - # (config account company issues in test) - res.reservation_line_ids.write({"price": 0}) - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of onboard all pay reservation \ - should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_done_yesterday_all_paid_amountpriority_reservation(self): - """ - Checkout yesterday without pending amount reservation must have priority = 6 - ------ - Create a reservation and make the work flow to onboard - done state, - using jump dates, we make the checkout reservation without pending amount, - and set today 1 day after, - regardless of the rest of the fields the priority must be 6 - """ - # ARRANGE - expected_priority = 6 - freezer = freeze_time("1981-10-08") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - - freezer.stop() - freezer = freeze_time("1981-10-09") - freezer.start() - - res.action_reservation_checkout() - # REVIEW: set to 0 the price to avoid make the payment - # (config account company issues in test) - res.reservation_line_ids.write({"price": 0}) - - # ACT - freezer.stop() - freezer = freeze_time("1981-10-10") - freezer.start() - - res.update_daily_priority_reservation() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a done reservation without pending amount\ - and checkout yesterday should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_confirm_arriva_bt_3_and_20_days_priority_reservation(self): - """ - Confirm reservation with arrival between 3 and 20 days, priority = 3 * days for checkout - ------ - Create a reservation with checkin date on 15 days - regardless of the rest of the fields the priority must be 3 * 15 = 45 - """ - # ARRANGE - expected_priority = 45 - - # ACT - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=15), - "checkout": fields.date.today() + datetime.timedelta(days=20), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a confirm with between 3 and 20 days for arrival \ - reservation should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_confirm_arrival_more_than_20_days_priority_reservation(self): - """ - Confirm reservation with arrival more than 20 days, priority = 4 * days for checkout - ------ - Create a reservation with checkin date on 21 days - regardless of the rest of the fields the priority must be 4 * 21 = 84 - """ - # ARRANGE - expected_priority = 84 - - # ACT - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=21), - "checkout": fields.date.today() + datetime.timedelta(days=25), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - computed_priority = res.priority - - # ASSERT - error_msm = ( - ( - "The priority of a confirm with more than 20 days for arrival \ - reservation should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_done_checkout_lt_15_days_before_all_paid_priority_reservation(self): - """ - Checkout less than 15 days before without pending amount reservation - must have priority = 5 * days from checkout - ------ - Create a reservation and make the work flow to onboard - done state, - using jump dates, we make the checkout reservation without pending amount, - and set today 6 day after, - regardless of the rest of the fields the priority must be 6 * 5 = 30 - """ - # ARRANGE - expected_priority = 30 - freezer = freeze_time("1981-10-09") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - - freezer.stop() - freezer = freeze_time("1981-10-10") - freezer.start() - - res.action_reservation_checkout() - # REVIEW: set to 0 the price to avoid make the payment - # (config account company issues in test) - res.reservation_line_ids.write({"price": 0}) - - # ACT - freezer.stop() - freezer = freeze_time("1981-10-16") - freezer.start() - - res.update_daily_priority_reservation() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a done reservation without pending amount\ - and checkout less than 15 days before should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_done_checkout_bt_30_and_90_days_before_all_paid_priority_reservation(self): - """ - Checkout between 30 and 90 days before without pending amount reservation - must have priority = 10 * days from checkout - ------ - Create a reservation and make the work flow to onboard - done state, - using jump dates, we make the checkout reservation without pending amount, - and set today 45 day after, - regardless of the rest of the fields the priority must be 10 * 45 = 450 - """ - # ARRANGE - expected_priority = 450 - freezer = freeze_time("1981-10-09") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - - freezer.stop() - freezer = freeze_time("1981-10-10") - freezer.start() - - res.action_reservation_checkout() - # REVIEW: set to 0 the price to avoid make the payment - # (config account company issues in test) - res.reservation_line_ids.write({"price": 0}) - - # ACT - freezer.stop() - freezer = freeze_time("1981-11-24") - freezer.start() - - res.update_daily_priority_reservation() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a done reservation without pending amount\ - and checkout between 30 and 90 days before should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - @freeze_time("1981-11-10") - def test_done_checkout_mt_90_days_before_all_paid_priority_reservation(self): - """ - Checkout more than 90 days before without pending amount reservation - must have priority = 100 * days from checkout - ------ - Create a reservation and make the work flow to onboard - done state, - using jump dates, we make the checkout reservation without pending amount, - and set today 91 day after, - regardless of the rest of the fields the priority must be 100 * 91 = 9100 - """ - # ARRANGE - expected_priority = 9100 - freezer = freeze_time("1981-10-09") - freezer.start() - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - host1 = self.env["res.partner"].create( - { - "firstname": "Pepe", - "lastname": "Paz", - "email": "pepe@example.com", - "birthdate_date": "1995-12-10", - "gender": "male", - } - ) - checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": host1.id, - "reservation_id": res.id, - "document_type": self.id_category.id, - "document_number": "77156490T", - "document_expedition_date": fields.date.today() - + datetime.timedelta(days=665), - } - ) - checkin1.action_on_board() - - freezer.stop() - freezer = freeze_time("1981-10-10") - freezer.start() - - res.action_reservation_checkout() - # REVIEW: set to 0 the price to avoid make the payment - # (config account company issues in test) - res.reservation_line_ids.write({"price": 0}) - - # ACT - freezer.stop() - freezer = freeze_time("1982-01-09") - freezer.start() - - res.update_daily_priority_reservation() - computed_priority = res.priority - freezer.stop() - - # ASSERT - error_msm = ( - ( - "The priority of a done reservation without pending amount\ - and checkout more than 90 days before should be %d and this is %d" - ) - % (expected_priority, computed_priority) - ) - - self.assertEqual( - computed_priority, - expected_priority, - error_msm, - ) - - def test_reservation_action_assign(self): - """ - Checks the correct operation of the assign method - --------------- - Create a new reservation with only room_type(autoassign -> to_assign = True), - and the we call to action_assign method to confirm the assignation - """ - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # ACT - res.action_assign() - # ASSERT - self.assertFalse(res.to_assign, "The reservation should be marked as assigned") - - def test_reservation_auto_assign_on_create(self): - """ - When creating a reservation with a specific room, - it is not necessary to mark it as to be assigned - --------------- - Create a new reservation with specific preferred_room_id, - "to_assign" should be set to false automatically - """ - # ARRANGE - - # ACT - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertFalse( - res.to_assign, "Reservation with preferred_room_id set to to_assign = True" - ) - - def test_reservation_auto_assign_after_create(self): - """ - When assigning a room manually to a reservation marked "to be assigned", - this field should be automatically unchecked - --------------- - Create a new reservation without preferred_room_id (only room_type), - "to_assign" is True, then set preferred_room_id and "to_assign" should - be set to false automatically - """ - # ARRANGE - # set the priority of the rooms to control the room chosen by auto assign - self.room1.sequence = 1 - self.room2.sequence = 2 - - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # ACT - # res shoul be room1 in preferred_room_id (minor sequence) - res.preferred_room_id = self.room2.id - - # ASSERT - self.assertFalse( - res.to_assign, - "The reservation should be marked as assigned automatically \ - when assigning the specific room", - ) - - def test_reservation_to_assign_on_create(self): - """ - Check the reservation action assign. - Create a reservation and change the reservation to 'to_assign' = False - through action_assign() method - """ - # ARRANGE - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # ACT - res.action_assign() - # ASSERT - self.assertFalse(res.to_assign, "The reservation should be marked as assigned") - - def test_reservation_action_cancel(self): - """ - Check if the reservation has been cancelled correctly. - ------------- - Create a reservation and change his state to cancelled - through the action_cancel() method. - """ - # ARRANGE - res = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # ACT - res.action_cancel() - # ASSERT - self.assertEqual(res.state, "cancel", "The reservation should be cancelled") - - @freeze_time("1981-11-01") - def test_reservation_action_checkout(self): - # TEST CASE - """ - Check that when the date of a reservation passes, it goes to the 'done' status. - ------------- - Create a host, a reservation and a check-in partner. Assign the partner and the - reservation to the check-in partner and after one day of the reservation it - must be in the 'done' status - """ - # ARRANGE - host = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "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( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": host.id, - "pms_property_id": self.pms_property1.id, - } - ) - r1.flush() - checkin = self.env["pms.checkin.partner"].create( - { - "partner_id": host.id, - "reservation_id": r1.id, - } - ) - checkin.action_on_board() - checkin.flush() - - # ACT - with freeze_time("1981-11-02"): - r1._cache.clear() - r1.action_reservation_checkout() - - # ASSERT - self.assertEqual( - r1.state, "done", "The reservation status should be done after checkout." - ) - - def _test_check_date_order(self): - """ - Check that the date order of a reservation is correct. - --------------- - Create a reservation with today's date and then check that the date order is also today - """ - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "partner_id": self.partner1.id, - "room_type_id": self.room_type_double.id, - } - ) - - date_order = reservation.date_order - date_order_expected = datetime.datetime( - date_order.year, - date_order.month, - date_order.day, - date_order.hour, - date_order.minute, - date_order.second, - ) - - reservation.flush() - self.assertEqual( - date_order, - date_order_expected, - "Date Order isn't correct", - ) - - def test_check_checkin_datetime(self): - """ - Check that the checkin datetime of a reservation is correct. - ------------------ - Create a reservation and then check if the checkin datetime - it is correct - """ - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=300), - "checkout": fields.date.today() + datetime.timedelta(days=305), - "partner_id": self.partner1.id, - "room_type_id": self.room_type_double.id, - } - ) - r = reservation.checkin - checkin_expected = datetime.datetime(r.year, r.month, r.day, 14, 00) - checkin_expected = self.pms_property1.date_property_timezone(checkin_expected) - - self.assertEqual( - str(reservation.checkin_datetime), - str(checkin_expected), - "Date Order isn't correct", - ) - - def test_check_allowed_room_ids(self): - """ - Check available rooms after creating a reservation. - ----------- - Create an availability rule, create a reservation, - and then check that the allowed_room_ids field filtered by room - type of the reservation and the room_type_id.room_ids field of the - availability rule match. - """ - availability_rule = self.env["pms.availability.plan.rule"].create( - { - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type_double.id, - "availability_plan_id": self.room_type_availability.id, - "date": fields.date.today() + datetime.timedelta(days=153), - } - ) - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=150), - "checkout": fields.date.today() + datetime.timedelta(days=152), - "partner_id": self.partner1.id, - "room_type_id": self.room_type_double.id, - "pricelist_id": self.pricelist1.id, - } - ) - self.assertEqual( - reservation.allowed_room_ids.filtered( - lambda r: r.room_type_id.id == availability_rule.room_type_id.id - ).ids, - availability_rule.room_type_id.room_ids.ids, - "Rooms allowed don't match", - ) - - def test_partner_is_agency(self): - """ - Check that a reservation created with an agency and without a partner - assigns that agency as a partner. - ------------- - Create an agency and then create a reservation to which that agency - assigns but does not associate any partner. - Then check that the partner of that reservation is the same as the agency - """ - sale_channel1 = self.env["pms.sale.channel"].create( - {"name": "Test Indirect", "channel_type": "indirect"} - ) - agency = self.env["res.partner"].create( - { - "name": "partner1", - "is_agency": True, - "sale_channel_id": sale_channel1.id, - "invoice_to_agency": True, - } - ) - - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=150), - "checkout": fields.date.today() + datetime.timedelta(days=152), - "agency_id": agency.id, - "room_type_id": self.room_type_double.id, - } - ) - - reservation.flush() - - self.assertEqual( - reservation.partner_id.id, - agency.id, - "Partner_id doesn't match with agency_id", - ) - - def test_agency_pricelist(self): - """ - Check that a pricelist of a reservation created with an - agency and without a partner and the pricelist of that - agency are the same. - ------------- - Create an agency with field apply_pricelist is True and - then create a reservation to which that agency - assigns but does not associate any partner. - Then check that the pricelist of that reservation is the same as the agency - """ - sale_channel1 = self.env["pms.sale.channel"].create( - { - "name": "Test Indirect", - "channel_type": "indirect", - "product_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - agency = self.env["res.partner"].create( - { - "name": "partner1", - "is_agency": True, - "sale_channel_id": sale_channel1.id, - "apply_pricelist": True, - } - ) - - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=150), - "checkout": fields.date.today() + datetime.timedelta(days=152), - "agency_id": agency.id, - "room_type_id": self.room_type_double.id, - } - ) - self.assertEqual( - reservation.pricelist_id.id, - reservation.agency_id.property_product_pricelist.id, - "Rervation pricelist doesn't match with Agency pricelist", - ) - - def test_compute_access_url(self): - """ - Check that the access_url field of the reservation is created with a correct value. - ------------- - Create a reservation and then check that the access_url field has the value - my/reservation/(reservation.id) - """ - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=150), - "checkout": fields.date.today() + datetime.timedelta(days=152), - "partner_id": self.partner1.id, - "room_type_id": self.room_type_double.id, - } - ) - - url = "/my/reservations/%s" % reservation.id - self.assertEqual(reservation.access_url, url, "Reservation url isn't correct") - - def test_compute_ready_for_checkin(self): - """ - Check that the ready_for_checkin field is True when the reservation - checkin day is today. - --------------- - Create two hosts, create a reservation with a checkin date today, - and associate two checkin partners with that reservation and with - each of the hosts. - Then check that the ready_for_checkin field of the reservation is True - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "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( - { - "name": "Brais", - "mobile": "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( - { - "checkin": "2012-01-14", - "checkout": "2012-01-17", - "partner_id": self.host1.id, - "allowed_checkin": True, - "pms_property_id": self.pms_property1.id, - "adults": 3, - "room_type_id": self.room_type_triple.id, - } - ) - self.checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host1.id, - "reservation_id": self.reservation.id, - } - ) - self.checkin2 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host2.id, - "reservation_id": self.reservation.id, - } - ) - - self.reservation.checkin_partner_ids = [ - (6, 0, [self.checkin1.id, self.checkin2.id]) - ] - self.assertTrue( - self.reservation.ready_for_checkin, - "Reservation should is ready for checkin", - ) - - def test_check_checkout_less_checkin(self): - """ - Check that a reservation cannot be created with the - checkin date greater than the checkout date - --------------- - Create a reservation with the checkin date 3 days - after the checkout date, this should throw an error. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - with self.assertRaises(UserError): - self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=3), - "checkout": fields.date.today(), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - "room_type_id": self.room_type_double.id, - } - ) - - def test_check_more_adults_than_beds(self): - """ - Check that a reservation cannot be created when the field - adults is greater than the capacity of the room. - ------------- - Try to create a reservation with a double room and the - field 'adults'=4, this should throw a mistake because the - room capacity is lesser than the number of adults. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - with self.assertRaises(ValidationError): - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - "preferred_room_id": self.room1.id, - "adults": 4, - } - ) - reservation.flush() - - def test_check_format_arrival_hour(self): - """ - Check that the format of the arrival_hour field is correct(HH:mm) - ------------- - Create a reservation with the wrong arrival hour date - format (HH:mm:ss), this should throw an error. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - with self.assertRaises(ValidationError): - self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - "arrival_hour": "14:00:00", - } - ) - - def test_check_format_departure_hour(self): - """ - Check that the format of the departure_hour field is correct(HH:mm) - ------------- - Create a reservation with the wrong departure hour date - format (HH:mm:ss), this should throw an error. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - with self.assertRaises(ValidationError): - self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - "departure_hour": "14:00:00", - } - ) - - def test_check_property_integrity_room(self): - """ - Check that a reservation cannot be created with a room - of a different property. - ------------ - Try to create a reservation for property2 with a - preferred_room that belongs to property1, this - should throw an error . - """ - self.property2 = self.env["pms.property"].create( - { - "name": "MY PMS TEST", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - self.room_type_double.pms_property_ids = [ - (6, 0, [self.pms_property1.id, self.property2.id]) - ] - with self.assertRaises(ValidationError): - self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "pms_property_id": self.property2.id, - "partner_id": self.host1.id, - "room_type_id": self.room_type_double.id, - "preferred_room_id": self.room1.id, - } - ) - - def test_shared_folio_true(self): - """ - Check that the shared_folio field of a reservation whose - folio has other reservations is True. - --------- - Create a reservation and then create another reservation with - its folio_id = folio_id of the previous reservation. This - should set shared_folio to True - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - self.reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=60), - "checkout": fields.date.today() + datetime.timedelta(days=65), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - } - ) - self.reservation2 = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=60), - "checkout": fields.date.today() + datetime.timedelta(days=64), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - "folio_id": self.reservation.folio_id.id, - } - ) - self.assertTrue( - self.reservation.shared_folio, - "Folio.reservations > 1, so reservation.shared_folio must be True", - ) - - def test_shared_folio_false(self): - """ - Check that the shared_folio field for a reservation whose folio has no - other reservations is False. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - self.reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=60), - "checkout": fields.date.today() + datetime.timedelta(days=65), - "pms_property_id": self.pms_property1.id, - "partner_id": self.host1.id, - } - ) - self.assertFalse( - self.reservation.shared_folio, - "Folio.reservations = 1, so reservation.shared_folio must be False", - ) - - def test_reservation_action_cancel_fail(self): - """ - Check that a reservation cannot be in the cancel state if - the cancellation is not allowed. - --------- - Create a reservation, put its state = "canceled" and then try to - pass its state to cancel using the action_cancel () method. This - should throw an error because a reservation with state cancel cannot - be canceled again. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type_double.id, - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - reservation.state = "cancel" - - with self.assertRaises(UserError): - reservation.action_cancel() - - def test_cancelation_reason_noshow(self): - """ - Check that if a reservation has already passed and there is no check-in, - the reason for cancellation must be 'no-show' - ------ - Create a cancellation rule that is assigned to a pricelist. Then create - a reservation with a past date and the action_cancel method is launched. - The canceled_reason field is verified to be is equal to "no_show" - """ - Pricelist = self.env["product.pricelist"] - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "pms_property_ids": [self.pms_property1.id], - "penalty_noshow": 50, - } - ) - - self.pricelist = Pricelist.create( - { - "name": "Pricelist Test", - "pms_property_ids": [self.pms_property1.id], - "cancelation_rule_id": self.cancelation_rule.id, - } - ) - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-5), - "checkout": fields.date.today() + datetime.timedelta(days=-3), - "room_type_id": self.room_type_double.id, - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist.id, - } - ) - - reservation.action_cancel() - reservation.flush() - self.assertEqual( - reservation.cancelled_reason, - "noshow", - "If reservation has already passed and no checkin," - "cancelled_reason must be 'noshow'", - ) - - def test_cancelation_reason_intime(self): - """ - Check that if a reservation is canceled on time according - to the cancellation rules the canceled_reason field must be "intime" - ------ - Create a cancellation rule assigned to a price list with - the field days_intime = 3. Then create a reservation with - a checkin date within 5 days and launch the action_cancel method. - canceled_reason field must be "intime" - """ - Pricelist = self.env["product.pricelist"] - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "pms_property_ids": [self.pms_property1.id], - "days_intime": 3, - } - ) - - self.pricelist = Pricelist.create( - { - "name": "Pricelist Test", - "pms_property_ids": [self.pms_property1.id], - "cancelation_rule_id": self.cancelation_rule.id, - } - ) - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=5), - "checkout": fields.date.today() + datetime.timedelta(days=8), - "room_type_id": self.room_type_double.id, - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist.id, - } - ) - - reservation.action_cancel() - reservation.flush() - - self.assertEqual( - reservation.cancelled_reason, "intime", "Cancelled reason must be 'intime'" - ) - - def test_cancelation_reason_late(self): - """ - Check that if a reservation is canceled outside the cancellation - period, the canceled_reason field of the reservation must be "late" . - --------- - Create a cancellation rule with the field days_intime = 3. - A reservation is created with a checkin date for tomorrow and the - action_cancel() method is launched. As the reservation was canceled - after the deadline, the canceled_reason field must be late - """ - Pricelist = self.env["product.pricelist"] - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "pms_property_ids": [self.pms_property1.id], - "days_intime": 3, - } - ) - - self.pricelist = Pricelist.create( - { - "name": "Pricelist Test", - "pms_property_ids": [self.pms_property1.id], - "cancelation_rule_id": self.cancelation_rule.id, - } - ) - self.host1 = self.env["res.partner"].create( - { - "name": "Host1", - } - ) - - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=1), - "checkout": fields.date.today() + datetime.timedelta(days=4), - "room_type_id": self.room_type_double.id, - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist.id, - } - ) - reservation.action_cancel() - reservation.flush() - self.assertEqual(reservation.cancelled_reason, "late", "-----------") - - def test_compute_checkin_partner_count(self): - """ - Check that the number of guests of a reservation is equal - to the checkin_partner_count field of that same reservation. - ------------- - Create 2 checkin partners. Create a reservation with those - two checkin partners. The checkin_partner_count field must - be equal to the number of checkin partners in the reservation. - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "654667733", - "email": "miguel@example.com", - } - ) - self.host2 = self.env["res.partner"].create( - { - "name": "Brais", - "mobile": "654437733", - "email": "brais@example.com", - } - ) - self.reservation = self.env["pms.reservation"].create( - { - "checkin": "2013-01-14", - "checkout": "2013-01-17", - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - "adults": 3, - "room_type_id": self.room_type_triple.id, - } - ) - self.checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host1.id, - "reservation_id": self.reservation.id, - } - ) - self.checkin2 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host2.id, - "reservation_id": self.reservation.id, - } - ) - - self.reservation.checkin_partner_ids = [ - (6, 0, [self.checkin1.id, self.checkin2.id]) - ] - - self.assertEqual( - self.reservation.checkin_partner_count, - len(self.reservation.checkin_partner_ids), - "Checkin_partner_count must be match with number of checkin_partner_ids", - ) - - def test_compute_checkin_partner_pending_count(self): - """ - Check that the checkin_partner_count field gives - the expected result. - -------------- - Create a reservation with 3 adults and associate 2 - checkin partners with that reservation. The - checkin_partner_pending_count field must be the - same as the difference between the adults in the - reservation and the number of checkin_partner_ids in - the reservation - """ - self.host1 = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "654667733", - "email": "miguel@example.com", - } - ) - self.host2 = self.env["res.partner"].create( - { - "name": "Brais", - "mobile": "654437733", - "email": "brais@example.com", - } - ) - self.reservation = self.env["pms.reservation"].create( - { - "checkin": "2014-01-14", - "checkout": "2014-01-17", - "partner_id": self.host1.id, - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type_triple.id, - "adults": 3, - } - ) - self.checkin1 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host1.id, - "reservation_id": self.reservation.id, - } - ) - self.checkin2 = self.env["pms.checkin.partner"].create( - { - "partner_id": self.host2.id, - "reservation_id": self.reservation.id, - } - ) - - self.reservation.checkin_partner_ids = [ - (6, 0, [self.checkin1.id, self.checkin2.id]) - ] - - count_expected = self.reservation.adults - len( - self.reservation.checkin_partner_ids - ) - self.assertEqual( - self.reservation.checkin_partner_pending_count, - count_expected, - "Checkin_partner_pending_count isn't correct", - ) - - def test_reservation_action_checkout_fail(self): - """ - Check that a reservation cannot be checkout because - the checkout is not allowed. - --------------- - Create a reservation and try to launch the action_reservation_checkout - method, but this should throw an error, because for the - checkout to be allowed, the reservation must be in "onboard" - or "departure_delayed" state - """ - host = self.env["res.partner"].create( - { - "name": "Miguel", - "mobile": "654667733", - "email": "miguel@example.com", - } - ) - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "partner_id": host.id, - "allowed_checkout": True, - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type_double.id, - } - ) - - with self.assertRaises(UserError): - reservation.action_reservation_checkout() - - def test_partner_name_folio(self): - """ - Check that a reservation without a partner_name - is associated with the partner_name of its folio - ---------- - Create a folio with a partner_name. Then create a - reservation with folio_id = folio.id and without - partner_name. The partner name of the reservation - and the folio must be the same - """ - - # ARRANGE - self.folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_name": "Solón", - } - ) - - self.reservation = self.env["pms.reservation"].create( - { - "checkin": "2014-01-14", - "checkout": "2014-01-17", - "pms_property_id": self.pms_property1.id, - "folio_id": self.folio1.id, - "room_type_id": self.room_type_double.id, - } - ) - # ACT AND ASSERT - self.assertEqual( - self.folio1.partner_name, - self.reservation.partner_name, - "The folio partner name and the reservation partner name doesn't correspond", - ) - - def test_partner_is_agency_not_invoice_to_agency(self): - """ - Check that a reservation without partner_name but with - an agency whose field invoice_to_agency = False will - be set as partner_name "Reservation_from (agency name)" - ------------- - Create an agency with invoice_to_agency = False - and then create a reservation to which that agency - assigns but does not associate any partner. - Then check that the partner_name of that reservation is "Reservation from (agency name)" - """ - sale_channel1 = self.env["pms.sale.channel"].create( - {"name": "Test Indirect", "channel_type": "indirect"} - ) - agency = self.env["res.partner"].create( - { - "name": "partner1", - "is_agency": True, - "sale_channel_id": sale_channel1.id, - } - ) - - reservation = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": fields.date.today() + datetime.timedelta(days=150), - "checkout": fields.date.today() + datetime.timedelta(days=152), - "agency_id": agency.id, - "room_type_id": self.room_type_double.id, - } - ) - - reservation.flush() - - self.assertEqual( - reservation.partner_name, - "Reservation from " + agency.name, - "Partner name doesn't match with to the expected", - ) - - @freeze_time("2010-11-10") - def test_cancel_discount_board_service(self): - """ - When a reservation is cancelled, service discount in case of board_services - must be equal to the discounts of each reservation_line. - - """ - - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "after", - } - ) - self.board_service = self.env["pms.service"].create( - { - "is_board_service": True, - "product_id": self.product.id, - } - ) - - self.room_type_double.list_price = 25 - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-3), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "service_ids": [self.board_service.id], - } - ) - # ACTION - reservation.action_cancel() - reservation.flush() - - # ASSERT - self.assertEqual( - set(reservation.reservation_line_ids.mapped("cancel_discount")), - set(reservation.service_ids.service_line_ids.mapped("cancel_discount")), - "Cancel discount of reservation service lines must be the same " - "that reservation board services", - ) - - @freeze_time("2011-10-10") - def test_cancel_discount_reservation_line(self): - """ - When a reservation is cancelled, cancellation discount is given - by the cancellation rule associated with the reservation pricelist. - Each reservation_line calculates depending on the cancellation - reason which is the correspondig discount. In this case the - cancellation reason is'noshow' and the rule specifies that 50% must - be reducted every day, that is, on each of reseravtion_lines - """ - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.room_type_double.list_price = 50 - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-3), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - } - ) - - # ACTION - reservation.action_cancel() - reservation.flush() - - # ASSERT - self.assertEqual( - set(reservation.reservation_line_ids.mapped("cancel_discount")), - {self.cancelation_rule.penalty_noshow}, - "Cancel discount of reservation_lines must be equal than cancellation rule penalty", - ) - - @freeze_time("2011-11-11") - def test_cancel_discount_service(self): - """ - When a reservation is cancelled, service discount in - services that are not board_services ALWAYS have to be 100%, - refardless of the cancellation rule associated with the pricelist - """ - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "after", - "is_extra_bed": True, - } - ) - self.service = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product.id, - } - ) - - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-3), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "service_ids": [self.service.id], - } - ) - - expected_cancel_discount = 100 - - # ACTION - reservation.action_cancel() - reservation.flush() - - # ASSERT - self.assertEqual( - {expected_cancel_discount}, - set(reservation.service_ids.service_line_ids.mapped("cancel_discount")), - "Cancel discount of services must be 100%", - ) - - @freeze_time("2011-06-06") - def test_discount_in_service(self): - """ - Discount in pms.service is calculated from the - discounts that each if its service lines has, - in this case when reservation is cancelled a - 50% cancellation discount is applied and - there aren't other different discounts - """ - - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "after", - } - ) - self.board_service = self.env["pms.service"].create( - { - "is_board_service": True, - "product_id": self.product.id, - } - ) - - self.room_type_double.list_price = 25 - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today() + datetime.timedelta(days=-3), - "checkout": fields.date.today() + datetime.timedelta(days=3), - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "service_ids": [self.board_service.id], - } - ) - - # ACTION - reservation.action_cancel() - reservation.flush() - - expected_discount = sum( - sl.price_day_total * sl.cancel_discount / 100 - for sl in self.board_service.service_line_ids - ) - # ASSERT - self.assertEqual( - expected_discount, - self.board_service.discount, - "Service discount must be the sum of its services_lines discount", - ) - - @freeze_time("2011-11-11") - def test_services_discount_in_reservation(self): - """ - Services discount in reservation is equal to the sum of the discounts of all - its services, whether they are board_services or not - """ - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.product1 = self.env["product.product"].create( - { - "name": "Product test1", - "per_day": True, - "consumed_on": "after", - "is_extra_bed": True, - } - ) - self.service = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product1.id, - } - ) - self.service.flush() - self.product2 = self.env["product.product"].create( - { - "name": "Product test 2", - "per_person": True, - "consumed_on": "after", - } - ) - self.board_service = self.env["pms.service"].create( - { - "is_board_service": True, - "product_id": self.product2.id, - } - ) - - self.room_type_double.list_price = 25 - checkin = fields.date.today() + datetime.timedelta(days=-3) - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "service_ids": [self.service.id, self.board_service.id], - } - ) - - # ACTION - reservation.action_cancel() - reservation.flush() - - expected_discount = sum(s.discount for s in reservation.service_ids) - - # ASSERT - self.assertEqual( - expected_discount, - reservation.services_discount, - "Services discount isn't the expected", - ) - - @freeze_time("2011-12-12") - def test_price_services_in_reservation(self): - """ - Service price total in a reservation corresponds to the sum of prices - of all its services less the total discount of that services - """ - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.product1 = self.env["product.product"].create( - { - "name": "Product test1", - "per_day": True, - "consumed_on": "after", - "is_extra_bed": True, - } - ) - self.service = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": self.product1.id, - } - ) - self.service.flush() - self.product2 = self.env["product.product"].create( - { - "name": "Product test 2", - "per_person": True, - "consumed_on": "after", - } - ) - self.board_service = self.env["pms.service"].create( - { - "is_board_service": True, - "product_id": self.product2.id, - } - ) - - self.room_type_double.list_price = 25 - checkin = fields.date.today() + datetime.timedelta(days=-3) - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "service_ids": [self.service.id, self.board_service.id], - } - ) - - # ACTION - reservation.action_cancel() - reservation.flush() - expected_price = ( - self.service.price_total - + self.board_service.price_total * reservation.adults - ) - reservation.services_discount - - # ASSERT - self.assertEqual( - expected_price, - reservation.price_services, - "Services price isn't the expected", - ) - - @freeze_time("2011-08-08") - def test_room_discount_in_reservation(self): - """ - Discount in pms.reservation is calculated from the - discounts that each if its reservation lines has, - in this case when reservation is cancelled a 50% - cancellation discount is applied and - there aren't other different discounts - """ - # ARRANGE - self.cancelation_rule = self.env["pms.cancelation.rule"].create( - { - "name": "Cancelation Rule Test", - "penalty_noshow": 50, - "apply_on_noshow": "all", - } - ) - - self.pricelist1.cancelation_rule_id = self.cancelation_rule.id - - self.room_type_double.list_price = 30 - checkin = fields.date.today() + datetime.timedelta(days=-3) - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - } - ) - - # ACTION - reservation.action_cancel() - reservation.flush() - - expected_discount = sum( - rl.price * rl.cancel_discount / 100 - for rl in reservation.reservation_line_ids - ) - - # ASSERT - self.assertEqual( - expected_discount, - reservation.discount, - "Room discount isn't the expected", - ) - - def test_default_normal_reservation_type(self): - """ - Check that the default reservation type is "normal". - ----------- - A reservation is created without defining the reservation_type - field and it is checked that it is 'normal' - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.partner1 = self.env["res.partner"].create({"name": "Ana"}) - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - } - ) - # ACT - self.room_type_double.write({"list_price": 30}) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "folio_id": folio1.id, - } - ) - # ASSERT - self.assertEqual( - reservation.reservation_type, - "normal", - "The default reservation type should be 'normal'", - ) - - def test_price_normal_reservation(self): - """ - Check the price of a normal type reservation. - ----------- - A reservation is created for a room with price 30. - Then it is verified that the total price of the - reservation is equal to the price of the room multiplied - by the number of days of the reservation. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - self.room_type_double.write({"list_price": 30}) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - } - ) - diff_days = (checkout - checkin).days - expected_price = self.room_type_double.list_price * diff_days - # ASSERT - self.assertEqual( - reservation.price_total, - expected_price, - "The expected price of the reservation is not correct", - ) - - def test_price_staff_reservation(self): - """ - Check that the price of a staff type reservation - is not calculated. - ------------- - A reservation is created with the reservation_type field as 'staff'. - Then it is verified that the price of the reservation is equal to 0. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - self.room_type_double.write({"list_price": 30}) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "staff", - } - ) - # ASSERT - self.assertEqual( - reservation.price_total, - 0.0, - "The expected price of the reservation is not correct", - ) - - def test_price_out_of_service_reservation(self): - """ - Check that the price of a out type reservation - is not calculated. - ------------- - A reservation is created with the reservation_type field as 'out'. - Then it is verified that the price of the reservation is equal to 0. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - self.room_type_double.write({"list_price": 30}) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "pricelist_id": self.pricelist1.id, - "reservation_type": "out", - } - ) - # ASSERT - self.assertEqual( - reservation.price_total, - 0.0, - "The expected price of the reservation is not correct", - ) - - def test_no_pricelist_staff_reservation(self): - """ - Check that in a staff type reservation the pricelist is False. - ------------- - A reservation is created with the reservation_type field as 'staff'. - Then it is verified that the pricelist of the reservation is False. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "reservation_type": "staff", - } - ) - - self.assertFalse( - reservation.pricelist_id, - "The pricelist of a staff reservation should be False", - ) - - def test_no_pricelist_out_reservation(self): - """ - Check that in a out type reservation the pricelist is False. - ------------- - A reservation is created with the reservation_type field as 'out'. - Then it is verified that the pricelist of the reservation is False. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - self.room_type_double.write({"list_price": 30}) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - "reservation_type": "out", - } - ) - - self.assertFalse( - reservation.pricelist_id, - "The pricelist of a out of service reservation should be False", - ) - - def test_reservation_type_by_folio(self): - """ - Check that the reservation type field in a reservation is the - same as the reservation type on the folio that contains - that reservation. - -------------------------- - A folio is created with the field reservation_type as 'staff'. - A reservation is created to which the - value of the folio_id is the id of the previously created - folio. Then it is verified that the value of the reservation_type - field of the reservation is the same that reservation_type in the folio: - 'staff'. - """ - # ARRANGE AND ACT - self.partner1 = self.env["res.partner"].create({"name": "Ana"}) - folio1 = self.env["pms.folio"].create( - { - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner1.id, - "reservation_type": "staff", - } - ) - - reservation1 = self.env["pms.reservation"].create( - { - "room_type_id": self.room_type_double.id, - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "folio_id": folio1.id, - } - ) - - # ASSERT - self.assertEqual( - reservation1.reservation_type, - "staff", - "The reservation type of the folio should be 'staff'", - ) - - def test_no_partner_id_out_reservation(self): - """ - Check that a reservation of type out of service does not - have a partner_id. - ------------------ - A reservation is created without a partner_id and with the - value of the field reservation_type as '' out. Then it is - checked that the partner_id field of the reservation is False - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "reservation_type": "out", - "partner_name": "Install furniture", - } - ) - - self.assertFalse( - reservation.partner_id, - "The partner of an out of service reservation should be False", - ) - - def test_create_partner_in_reservation(self): - """ - Check that a res_partner is created from a reservation. - ------------ - A reservation is created by adding the document_type and - document_number fields, with these two fields a res.partner - should be created, which is what is checked after creating - the reservation. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": "Elis", - "email": "elis@mail.com", - "mobile": "61568547", - "document_type": self.id_category.id, - "document_number": "31640132K", - } - ) - # ASSERT - self.assertTrue(reservation.partner_id, "The partner has not been created") - - def test_auto_complete_partner_mobile(self): - """ - It is checked that the mobile field of the reservation - is correctly added to it when the document_number and - document_type fields of a res.partner that exists in - the DB are put in the reservation. - -------------------- - A res.partner is created with the name, mobile and email fields. - The document_id is added to the res.partner. The reservation is - created and the category_id of the document_id associated with - the res.partner is added as document_type and as document_number - the name of the document_id associated with the res.partner as well. - Then it is verified that the mobile of the res.partner and that of - the reservation are the same. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Enrique", - "mobile": "654667733", - "email": "enrique@example.com", - } - ) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - self.document_id = self.env["res.partner.id_number"].create( - { - "category_id": self.id_category.id, - "name": "61645604S", - "partner_id": partner.id, - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "document_type": self.document_id.category_id.id, - "document_number": self.document_id.name, - } - ) - # ASSERT - self.assertEqual( - reservation.mobile, - partner.mobile, - "The partner mobile has not autocomplete in reservation", - ) - - def test_auto_complete_partner_email(self): - """ - It is checked that the email field of the reservation - is correctly added to it when the document_number and - document_type fields of a res.partner that exists in - the DB are put in the reservation. - -------------------- - A res.partner is created with the name, mobile and email fields. - The document_id is added to the res.partner. The reservation is - created and the category_id of the document_id associated with - the res.partner is added as document_type and as document_number - the name of the document_id associated with the res.partner as well. - Then it is verified that the email of the res.partner and that of - the reservation are the same. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - self.id_category = self.env["res.partner.id_category"].create( - {"name": "DNI", "code": "D"} - ) - self.document_id = self.env["res.partner.id_number"].create( - { - "category_id": self.id_category.id, - "name": "74247377L", - "partner_id": partner.id, - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "document_type": self.document_id.category_id.id, - "document_number": self.document_id.name, - } - ) - # ASSERT - self.assertEqual( - reservation.email, - partner.email, - "The partner mobile has not autocomplete in reservation", - ) - - def test_is_possible_customer_by_email(self): - """ - It is checked that the field possible_existing_customer_ids - exists in a reservation with an email from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A reservation - is created by adding the same email as the res.partner. Then it is - checked that some possible_existing_customer_ids exists. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Courtney Campbell", - "email": "courtney@example.com", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "email": partner.email, - } - ) - # ASSERT - self.assertTrue( - reservation.possible_existing_customer_ids, - "No customer found with this email", - ) - - def test_is_possible_customer_by_mobile(self): - """ - It is checked that the field possible_existing_customer_ids - exists in a reservation with a mobile from a res.partner saved - in the DB. - ---------------- - A res.partner is created with the name and email fields. A reservation - is created by adding the same mobile as the res.partner. Then it is - checked that some possible_existing_customer_ids exists. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Ledicia Sandoval", - "mobile": "615369231", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "mobile": partner.mobile, - } - ) - # ASSERT - self.assertTrue( - reservation.possible_existing_customer_ids, - "No customer found with this mobile", - ) - - def test_add_possible_customer(self): - """ - Check that a partner was correctly added to the reservation - after launching the add_partner() method of the several partners wizard - --------------- - A res.partner is created with name, email and mobile. A reservation is - created with the email field equal to that of the res.partner created before. - The wizard is created with the reservation id and the partner added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is checked that the partner was correctly added to the - reservation. - """ - # ARRANGE - partner = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner.name, - "email": partner.email, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "reservation_id": reservation.id, - "possible_existing_customer_ids": [(6, 0, [partner.id])], - } - ) - - several_partners_wizard.add_partner() - # ASSERT - self.assertEqual( - reservation.partner_id.id, - partner.id, - "The partner was not added to the reservation ", - ) - - def test_is_modified_reservation(self): - """ - Checked that the is_modified_reservation field is correctly set - to True when the checkin or checkout fields are modified in a - reservation. - ---------------------- - A reservation is created. The checkin and checkout fields of - the reservation are modified. The state of the boolean - is_mail_send is changed to True so that the compute of - the is_modified_reservation field is activated correctly - and it is verified that the state of this field is True. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=2) - reservation_vals = { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - - reservation = self.env["pms.reservation"].create(reservation_vals) - - # ACT - writed_checkin = fields.date.today() + datetime.timedelta(days=4) - writed_checkout = fields.date.today() + datetime.timedelta(days=6) - reservation.is_mail_send = True - reservation.update( - { - "checkin": writed_checkin, - "checkout": writed_checkout, - } - ) - - # ASSERT - self.assertTrue( - reservation.is_modified_reservation, - "is_modified_reservation field should be True ", - ) - - def test_is_not_modified_reservation(self): - """ - Checked that the is_modified_reservation field is correctly set - to False when the reservation is modified but not the checkin - or checkout fields. - ---------------------- - A reservation is created. The adults, arrival_hour and departure_hours - fields of the reservation are modified.The it is verified that the state - of this field is False. - """ - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=2) - reservation_vals = { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "partner_id": self.partner1.id, - "pms_property_id": self.pms_property1.id, - } - - reservation = self.env["pms.reservation"].create(reservation_vals) - reservation.update( - {"adults": 1, "arrival_hour": "18:00", "departure_hour": "08:00"} - ) - - # ASSERT - self.assertFalse( - reservation.is_modified_reservation, - "is_modified_reservation field should be False ", - ) - - def test_not_add_several_possibles_customers(self): - """ - Check that multiple partners cannot be added to a reservation - from the several partners wizard. - --------------- - Two res.partner are created with name, email and mobile. A reservation is - created with the email field equal to that of the partner1 created before. - The wizard is created with the reservation id and the two partners added to the - possible_existing_customer_ids field. The add_partner method of the wizard - is launched and it is verified that a Validation_Error was raised. - """ - # ARRANGE - partner1 = self.env["res.partner"].create( - { - "name": "Serafín Rivas", - "email": "serafin@example.com", - "mobile": "60595595", - } - ) - partner2 = self.env["res.partner"].create( - { - "name": "Simon", - "mobile": "654667733", - "email": "simon@example.com", - } - ) - - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": partner1.name, - "email": partner1.email, - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "reservation_id": reservation.id, - "possible_existing_customer_ids": [(6, 0, [partner1.id, partner2.id])], - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="Two partners cannot be added to the reservation", - ): - several_partners_wizard.add_partner() - - def test_not_add_any_possibles_customers(self): - """ - Check that the possible_existing_customer_ids field of the several - partners wizard can be left empty and then launch the add_partner() - method of this wizard to add a partner in reservation. - --------------- - A reservation is created. The wizard is created without the - possible_existing_customer_ids field. The add_partner method of - the wizard is launched and it is verified that a Validation_Error - was raised. - """ - - # ARRANGE - checkin = fields.date.today() - checkout = fields.date.today() + datetime.timedelta(days=3) - reservation = self.env["pms.reservation"].create( - { - "checkin": checkin, - "checkout": checkout, - "room_type_id": self.room_type_double.id, - "pms_property_id": self.pms_property1.id, - "partner_name": "Rosa Costa", - } - ) - - several_partners_wizard = self.env["pms.several.partners.wizard"].create( - { - "reservation_id": reservation.id, - } - ) - - # ACT AND ASSERT - with self.assertRaises( - ValidationError, - msg="A partner must be added to the reservation", - ): - several_partners_wizard.add_partner() diff --git a/pms/tests/test_pms_room.py b/pms/tests/test_pms_room.py deleted file mode 100644 index 6d0fd4369..000000000 --- a/pms/tests/test_pms_room.py +++ /dev/null @@ -1,220 +0,0 @@ -from psycopg2 import IntegrityError - -from odoo.tools import mute_logger - -from .common import TestPms - - -class TestPmsRoom(TestPms): - def setUp(self): - super().setUp() - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property_2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - self.room_type1 = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id, self.pms_property2.id], - "name": "Single", - "default_code": "SIN", - "class_id": self.room_type_class1.id, - "list_price": 30, - } - ) - - @mute_logger("odoo.sql_db") - def test_room_name_uniqueness_by_property(self): - """ - Check that there are no two rooms with the same name in the same property - PRE: - room1 'Room 101' exists - - room1 has pms_property1 - ACT: - create a new room2 - - room2 has name 'Room 101' - - room2 has pms_property1 - POST: - Integrity error: already exists another room - with the same name on the same property - - room2 not created - """ - # ARRANGE - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - } - ) - # ACT & ASSERT - with self.assertRaises( - IntegrityError, - msg="The room should not be created if its name is equal " - "to another room that belongs to the same property.", - ): - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - } - ) - - def test_room_name_duplicated_different_property(self): - """ - Check that two rooms with the same name can exist in multiple properties - PRE: - room1 'Room 101' exists - - room1 has pms_property1 - ACT: - create a new room2 - - room2 has name 'Room 101' - - room2 has pms_property2 - POST: - room2 created - """ - # ARRANGE - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - } - ) - # ACT & ASSERT - try: - self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property2.id, - "room_type_id": self.room_type1.id, - } - ) - except IntegrityError: - self.fail( - "The room should be created even if its name is equal " - "to another room, but that room not belongs to the same property." - ) - - def test_display_name_room(self): - """ - Check that the display_name field of a room is as expected. - ------------ - A room is created and then it is checked that the display name - field of this is composed of: - room.name [room_type.default_code] - """ - self.room1 = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - } - ) - expected_display_name = "%s [%s]" % ( - self.room1.name, - self.room_type1.default_code, - ) - self.assertEqual( - self.room1.display_name, - expected_display_name, - "The display name of the room is not as expected", - ) - - def test_display_name_room_with_amenity(self): - """ - Check that the display_name field of a room with one amenity - is as expected. - ------------ - A amenity is created with default code and with is_add_code_room_name - field as True. A room is created in which the amenity created before - is added in the room_amenity_ids field and then it is verified that - the display name field of this is composed of: - room.name [room_type.default_code] amenity.default_code - """ - self.amenity_type1 = self.env["pms.amenity.type"].create( - { - "name": "Amenity Type 1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - self.amenity1 = self.env["pms.amenity"].create( - { - "name": "Amenity 1", - "pms_amenity_type_id": self.amenity_type1.id, - "default_code": "A1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "is_add_code_room_name": True, - } - ) - self.room1 = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - "room_amenity_ids": [(6, 0, [self.amenity1.id])], - } - ) - expected_display_name = "%s [%s] %s" % ( - self.room1.name, - self.room_type1.default_code, - self.amenity1.default_code, - ) - self.assertEqual( - self.room1.display_name, - expected_display_name, - "The display name of the room is not as expected", - ) - - def test_display_name_room_with_several_amenities(self): - """ - Check that the display_name field of a room with several amenities - is as expected. - ------------ - Two amenities are created with diferent default code and with is_add_code_room_name - field as True. A room is created in which the amenities created before are added in - the room_amenity_ids field and then it is verified that the display name field of this - is composed of: - room.name [room_type.default_code] amenity1.default_code amenity2.default_code - """ - self.amenity_type1 = self.env["pms.amenity.type"].create( - { - "name": "Amenity Type 1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - self.amenity1 = self.env["pms.amenity"].create( - { - "name": "Amenity 1", - "pms_amenity_type_id": self.amenity_type1.id, - "default_code": "A1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "is_add_code_room_name": True, - } - ) - self.amenity2 = self.env["pms.amenity"].create( - { - "name": "Amenity 2", - "pms_amenity_type_id": self.amenity_type1.id, - "default_code": "B1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "is_add_code_room_name": True, - } - ) - self.room1 = self.env["pms.room"].create( - { - "name": "Room 101", - "pms_property_id": self.pms_property1.id, - "room_type_id": self.room_type1.id, - "room_amenity_ids": [(6, 0, [self.amenity1.id, self.amenity2.id])], - } - ) - expected_display_name = "%s [%s] %s %s" % ( - self.room1.name, - self.room_type1.default_code, - self.amenity1.default_code, - self.amenity2.default_code, - ) - self.assertEqual( - self.room1.display_name, - expected_display_name, - "The display name of the room is not as expected", - ) diff --git a/pms/tests/test_pms_room_type.py b/pms/tests/test_pms_room_type.py deleted file mode 100644 index 3ae81a86e..000000000 --- a/pms/tests/test_pms_room_type.py +++ /dev/null @@ -1,885 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.exceptions import UserError, ValidationError - -from .common import TestPms - - -class TestRoomType(TestPms): - def setUp(self): - super().setUp() - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - self.company2 = self.env["res.company"].create( - { - "name": "Company 2", - } - ) - - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Property 3", - "company_id": self.company2.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - def test_create_room_type_consistency_company(self): - """ - Create a room type with a company (1) consistent with the company property (1). - Creation should be successful. - - PRE: - room_type1 does not exists - ACT: - create a new room_type1 room - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 has company company1 - - room_type1 has company company1 - POST: - room_type1 created - """ - # ARRANGE & ACT - new_room_type = self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - # ASSERT - self.assertTrue(new_room_type.id, "Room type not created when it should") - - def test_create_room_type_inconsistency_company(self): - """ - Create a room type with inconsistency between company (1) - and company property (1). - The creation should fail. - - PRE: - room_type1 does not exists - ACT: - create a new room_type1 room - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 has company1 - - room_type1 has company2 - POST: - Integrity error, pms_property1 has company1 and room type company2 - - room_type1 not created - """ - # ARRANGE & ACT & ASSERT - with self.assertRaises( - UserError, msg="The room type has been created and it shouldn't" - ): - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": self.company2.id, - "class_id": self.room_type_class1.id, - } - ) - - def test_create_room_type_inconsistency_companies(self): - """ - Create a room type with inconsistency between company (1) - and company properties (several). - The creation should fail. - - PRE: - room_type1 does not exists - ACT: - create a new room_type1 room - - room_type1 has code c1 - - room_type1 has property pms_property1 and pms_property3 - - pms_property1 has company company1 - - pms_property3 has company2 - - room_type1 has company2 - POST: - Integrity error, pms_property1 has company1 and room type company2 - - room_type1 not created - """ - # ARRANGE & ACT & ASSERT - with self.assertRaises( - UserError, msg="The room type has been created and it shouldn't" - ): - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - "company_id": self.company2.id, - "class_id": self.room_type_class1.id, - } - ) - - def test_create_room_type_consistency_companies(self): - """ - Create a room type with consistency between companies (all) - and company properties (2). - Creation should be successful. - - PRE: - room_type1 does not exists - ACT: - create a new room_type1 - - room_type1 has code c1 - - room_type1 has property pms_property1 and pms_property3 - - pms_property1 has company company1 - - pms_property3 has company2 - - room_type1 has no company - POST: - room_type1 created - """ - # ARRANGE & ACT - new_room_type = self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # ASSERT - self.assertTrue(new_room_type.id, "Room type not created when it should") - - # external integrity - def test_create_room_type_inconsistency_all_companies(self): - """ - Create a room type for 1 company and 1 property. - Try to create a room type for all the companies. - The creation should fail. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 has company company1 - - room_type1 has no company - ACT: - create a new room_type2 room - - room_type2 has code c1 - - room_type2 has property pms_property1 - - pms_property1 has company company1 - - room_type2 has no company - POST: - Integrity error: the room type already exists - - room_type2 not created - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The room type has been created and it shouldn't" - ): - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - def test_create_room_type_inconsistency_code_company(self): - """ - Create a room type for all the companies and for one property. - Try to create a room type with same code and same property but - for all companies. - The creation should fail. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 has company company1 - - room_type1 has no company - ACT: - create a new room_type2 room - - room_type2 has code c1 - - room_type2 has property pms_property1 - - pms_property1 has company company1 - - room_type2 has company company1 - POST: - Integrity error: the room type already exists - - room_type2 not created - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The room type has been created and it shouldn't" - ): - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - - def test_create_room_type_inconsistency_code_companies(self): - """ - Create a room type for 1 property and 1 company. - Try to create a room type with same code and 3 propertys - belonging to 2 different companies. - The creation should fail. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 has company company1 - - room_type1 has company company1 - ACT: - create a new room_type2 room - - room_type2 has code c1 - - room_type2 has property pms_property1, pms_property2, pms_property3 - - pms_property1, pms_property2 has company company1 - - pms_property3 has company2 - - room_type2 has no company - POST: - Integrity error: the room type already exists - - room_type not created - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The room type has been created and it shouldn't" - ): - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": [ - ( - 6, - 0, - [ - self.pms_property1.id, - self.pms_property2.id, - self.pms_property3.id, - ], - ) - ], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - def test_get_room_type_by_property_first(self): - """ - Room type exists for all the companies and 2 properties. - Search for property of existing room type. - The method should return the existing room type. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 with 2 properties pms_property1 and pms_property2 - - pms_property1 and pms_property2 have the same company company1 - - room_type1 has no company - ACT: - search room type with code c1 and pms_property1 - - pms_property1 has company company1 - POST: - only room_type1 room type found - """ - # ARRANGE - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual(room_types.id, room_type1.id, "Expected room type not found") - - def test_get_room_type_by_property_second(self): - """ - Room type exists for all the companies and 2 properties. - Search for 2nd property of existing room type. - The method should return existing room type. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 with 2 properties pms_property1 and pms_property2 - - pms_property1 and pms_property2 have same company company1 - - room_type1 has no company - ACT: - search room type with code c1 and property pms_property3 - - pms_property3 have company2 - POST: - no room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property2.id]) - ], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertFalse(room_types, "Room type found but it should have not found any") - - def test_get_room_type_by_property_existing_all_same_company(self): - """ - Room type exists for 1 company and for all properties. - Search for one specific property belonging to same company - as the existing room type. - The method should return existing room type. - - PRE: - room type r1 exists - - room_type1 has code c1 - - room_type1 properties are null - - room_type1 company is company1 - ACT: - search room type with code c1 and pms_property1 - - pms_property1 have company company1 - POST: - only rroom_type1 room type found - """ - # ARRANGE - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": False, - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property1.id, "c1" - ) - # ASSERT - self.assertEqual(room_types.id, room_type1.id, "Expected room type not found") - - def test_get_room_type_by_property_existing_all_diff_company(self): - """ - Room type exists for 1 company and all the properties. - Search for property different than existing room type. - The method shouldn't return results. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 properties are null - - room_type1 company is company1 - ACT: - search room type with code c1 and pms_property3 - - pms_property3 have company2 - POST: - no room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type r1", - "default_code": "c1", - "pms_property_ids": False, - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertFalse(room_types, "Room type found but it should have not found any") - - # tests with more than one room type - def test_get_room_type_by_property_existing_several_match_prop(self): - """ - Room type 1 exists for all companies and 2 properties. - Room type 2 exists for all companies and properties. - Search for same property as one of the 1st room type created. - The method should return the 1st room type created. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 with 2 properties pms_property1 and pms_property2 - - pms_property1 and pms_property2 have the same company company1 - - room_type1 has no company - - room type room_type2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has no company - ACT: - search room type with code c1 and property pms_property1 - - pms_property1 have company company1 - POST: - only room_type1 room type found - """ - # ARRANGE - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property1.id, "c1" - ) - - # ASSERT - self.assertEqual(room_types.id, room_type1.id, "Expected room type not found") - - def test_get_room_type_by_property_diff_company(self): - """ - Room type 1 exists for all companies and one property. - Room type 2 exists for all companies and properties. - Search for property different than the 1st room type created - and belonging to different company. - The method should return the 2nd room type created. - - PRE: - room type r1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 have the company company1 - - room_type1 has no company - - room type room_type2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has no company - ACT: - search room type with code c1 and property pms_property2 - - pms_property2 have company company1 - POST: - only room_type1 room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - room_type2 = self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property2.id, "c1" - ) - - # ASSERT - self.assertEqual(room_types.id, room_type2.id, "Expected room type not found") - - def test_get_room_type_by_property_same_company(self): - """ - Room type 1 exists for all companies and one property. - Room type 2 exists for all companies and properties. - Search for property different than the 1st room type created - and belonging to same company. - The method should return the 2nd room type created. - - PRE: - room type room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 have the company company1 - - room_type1 has no company - - room type room_type2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has no company - ACT: - search room type with code c1 and pms_property3 - - pms_property3 have company2 - POST: - only room_type2 room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - room_type2 = self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertEqual(room_types.id, room_type2.id, "Expected room type not found") - - def test_get_room_type_by_property_same_company_prop_not_found(self): - """ - Room type 1 exists for all companies and one property. - Room type 2 exists for one company and for all properties. - Search for property different than the - 1st room type created but belonging to same company. - The method shouldn't return results. - - PRE: - room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 have the company company1 - - room_type1 has no company - - room_type2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has company company1 - ACT: - search room type with code c1 and pms_property3 - - pms_property3 have company2 - POST: - no room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertFalse(room_types, "Room type found but it should have not found any") - - def test_get_room_type_by_property_same_company_prop(self): - """ - Room type 1 exists for all companies and for one property. - Room type 2 exists for one company and for all properties. - Search for property belonging to the same company as - 2nd room type created. - The method should return 2nd existing room type. - - PRE: - room_type1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 have the company company1 - - room_type1 has no company - - room_type2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has company2 - ACT: - search room type with code c1 and pms_property3 - - pms_property3 have company2 - POST: - room_type2 room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - room_type2 = self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": self.company2.id, - "class_id": self.room_type_class1.id, - } - ) - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertEqual(room_types.id, room_type2.id, "Expected room type not found") - - def test_get_room_type_by_property_diff_company_prop(self): - """ - Room type 1 exists for all companies and for one property. - Room type 2 exists for one company and for all properties. - Room type 3 exists for all companies and for all properties. - Search for property belonging to a different company than - the 2nd room type created. - The method should return 3rd room type. - - PRE: - room type r1 exists - - room_type1 has code c1 - - room_type1 has property pms_property1 - - pms_property1 have the company company1 - - room_type1 has no company - - room type r2 exists - - room_type2 has code c1 - - room_type2 has no properties - - room_type2 has company company1 - - room type room_type3 exists - - room_type3 has code c1 - - room_type3 has no properties - - room_type3 has no company - ACT: - search room type with code c1 and pms_property3 - - pms_property3 have company2 - POST: - room_type3 room type found - """ - # ARRANGE - # room_type1 - self.env["pms.room.type"].create( - { - "name": "Room type 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - # room_type2 - self.env["pms.room.type"].create( - { - "name": "Room type 2", - "default_code": "c1", - "pms_property_ids": False, - "company_id": self.company1.id, - "class_id": self.room_type_class1.id, - } - ) - room_type3 = self.env["pms.room.type"].create( - { - "name": "Room type 3", - "default_code": "c1", - "pms_property_ids": False, - "company_id": False, - "class_id": self.room_type_class1.id, - } - ) - - # ACT - room_types = self.env["pms.room.type"].get_room_types_by_property( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertEqual(room_types.id, room_type3.id, "Expected room type not found") - - def test_rooom_type_creation_inconsistency_class(self): - """ - Create a rooom type class belonging to one property. - Create a room type belonging to another property. - Room type creation should fail. - """ - # ARRANGE - room_type_class = self.env["pms.room.type.class"].create( - { - "name": "Room Type Class", - "default_code": "ROOM", - "pms_property_ids": [ - (4, self.pms_property2.id), - ], - }, - ) - # ACT & ASSERT - with self.assertRaises( - UserError, msg="Room Type has been created and it shouldn't" - ): - room_type1 = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "c1", - "class_id": room_type_class.id, - "pms_property_ids": [ - (4, self.pms_property2.id), - ], - } - ) - room_type1.pms_property_ids = [(4, self.pms_property1.id)] - - def test_rooom_type_creation_consistency_class(self): - """ - Create a rooom type class belonging to one property. - Create a room type belonging to same property. - Room type creation should be successful. - """ - # ARRANGE - room_type_class = self.env["pms.room.type.class"].create( - { - "name": "Room Type Class", - "default_code": "ROOM", - "pms_property_ids": [ - (4, self.pms_property2.id), - ], - }, - ) - # ACT - new_room_type = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "c1", - "class_id": room_type_class.id, - "pms_property_ids": [ - (4, self.pms_property2.id), - ], - } - ) - # ASSERT - self.assertTrue(new_room_type.id, "Room type creation should be successful.") - - def test_check_board_service_property_integrity(self): - # ARRANGE - room_type = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "Type1", - "pms_property_ids": self.pms_property1, - "class_id": self.room_type_class1.id, - } - ) - board_service = self.env["pms.board.service"].create( - { - "name": "Board service 1", - "default_code": "c1", - "pms_property_ids": self.pms_property1, - } - ) - # ACT & ASSERT - with self.assertRaises(UserError, msg="Board service created and shouldn't."): - self.env["pms.board.service.room.type"].create( - { - "pms_board_service_id": board_service.id, - "pms_room_type_id": room_type.id, - "pms_property_ids": self.pms_property2, - } - ) - - def test_check_amenities_property_integrity(self): - self.amenity1 = self.env["pms.amenity"].create( - {"name": "Amenity", "pms_property_ids": self.pms_property1} - ) - # ACT & ASSERT - with self.assertRaises( - UserError, - msg="Shouldn't create room type with amenities belonging to other properties", - ): - self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "Type1", - "class_id": self.room_type_class1.id, - "pms_property_ids": [self.pms_property2.id], - "room_amenity_ids": [self.amenity1.id], - } - ) - - def test_rooom_type_creation_consistency_amenity(self): - """ - Create an amenity belonging to one property. - Create a room type belonging to same property. - Room type creation should be successful. - """ - # ARRANGE - self.amenity1 = self.env["pms.amenity"].create( - {"name": "Amenity", "pms_property_ids": self.pms_property1} - ) - # ACT - new_room_type = self.env["pms.room.type"].create( - { - "name": "Room Type", - "default_code": "Type1", - "class_id": self.room_type_class1.id, - "pms_property_ids": [self.pms_property1.id], - "room_amenity_ids": [self.amenity1.id], - } - ) - # ASSERT - self.assertTrue(new_room_type.id, "Room type creation should be successful.") diff --git a/pms/tests/test_pms_room_type_class.py b/pms/tests/test_pms_room_type_class.py deleted file mode 100644 index a064e785c..000000000 --- a/pms/tests/test_pms_room_type_class.py +++ /dev/null @@ -1,382 +0,0 @@ -# Copyright 2021 Eric Antones -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestRoomTypeClass(TestPms): - def setUp(self): - super().setUp() - self.company2 = self.env["res.company"].create( - { - "name": "Company 2", - } - ) - self.pms_property3 = self.env["pms.property"].create( - { - "name": "Property 3", - "company_id": self.company2.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - - # external integrity - def test_external_case_01(self): - """ - Check that a room type class cannot be created with an existing default_code - in the same property. - ---------- - A room type class is created with the default_code = 'c1' in property pms_property1. - Then try to create another room type class in the same property with the same code, - but this should throw a ValidationError. - """ - # ARRANGE - # room_type_class1 - self.env["pms.room.type.class"].create( - { - "name": "Room type class cl1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The room type class has been created and it shouldn't" - ): - # room_type_class2 - self.env["pms.room.type.class"].create( - { - "name": "Room type class cl2", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - - def test_external_case_02(self): - """ - Check that a room type class cannot be created with an existing default_code - in the same property. - ---------- - A room type class is created with the default_code = 'c1' in property pms_property1. - Then try to create another room type class with the same code in 3 properties and one - of them is the same property in which the other room type class was - created(pms_property1), but this should throw a ValidationError. - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - # room_type_class1 - self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="The room type class has been created and it shouldn't" - ): - # room_type_class2 - self.env["pms.room.type.class"].create( - { - "name": "Room type class cl2", - "default_code": "c1", - "pms_property_ids": [ - ( - 6, - 0, - [ - self.pms_property1.id, - self.pms_property2.id, - self.pms_property3.id, - ], - ) - ], - } - ) - - def test_single_case_01(self): - """ - Check that the room type class was created correctly and that - it is in the property in which it was searched through its default code. - ----------- - Create a room type class with default code as 'c1' for properties 1 and 3 - (different companies), save the value returned by the get_unique_by_property_code() - method, passing property1 and default_code 'c1' as parameters. It is checked - that the id of the room type class created and the id of the record returned by the - method match. - """ - # ARRANGE - room_type_class1 = self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, - room_type_class1.id, - "Expected room type class not found", - ) - - def test_single_case_02(self): - """ - Check that the room type class was created correctly and that - it is in the property in which it was searched through its default code. - ----------- - Create a room type class with default code as 'c1' for properties 1 and 3 - (same company), save the value returned by the get_unique_by_property_code() - method, passing property1 and default_code 'c1' as parameters. It is checked - that the id of the room type class created and the id of the record returned by the - method match. - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - cl1 = self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property2.id]) - ], - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, cl1.id, "Expected room type class not found" - ) - - def test_single_case_03(self): - """ - Check that a room type class created for a property is not - found in another property with a different company. - ----------- - A room type class is created with default_code 'c1' for properties - 1 and 2. It is searched through get_unique_by_property_code() - passing it as parameters 'c1' and property 3 (from a different - company than 1 and 2). It is verified that that room type class - does not exist in that property. - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - # room_type_class1 - self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property2.id]) - ], - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertFalse( - room_type_classes, "Room type class found but it should not have found any" - ) - - def test_single_case_04(self): - """ - Check that a room type class with properties = False - (all properties) is found by searching for it in one - of the properties. - -------------- - A room type is created with default code = 'c1' and with - pms_property_ids = False. The room_type_class with - code 'c1' in property 1 is searched through the - get_unique_by_property_code() method and it is verified - that the returned value is correct. - """ - # ARRANGE - room_type_class1 = self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": False, - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, - room_type_class1.id, - "Expected room type class not found", - ) - - # tests with more than one room type class - def test_multiple_case_01(self): - """ - Check that a room type class can be created with the same - code as another when one of them has pms_property_ids = False - ------------ - A room type class is created with code 'c1' for properties 1 and 3. - Another room type class is created with code 'c1' and the properties - set to False. The room_type with code 'c1' in property 1 is - searched through the get_unique_by_property_code() method and it is - verified that the returned value is correct. - """ - # ARRANGE - room_type_class1 = self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [ - (6, 0, [self.pms_property1.id, self.pms_property3.id]) - ], - } - ) - # room_type_class2 - self.env["pms.room.type.class"].create( - { - "name": "Room type class cl2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property1.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, - room_type_class1.id, - "Expected room type class not found", - ) - - def test_multiple_case_02(self): - """ - Check that a room type class can be created with the same - code as another when one of them has pms_property_ids = False - ---------- - A room type class is created with code 'c1' for property 1(company1). - Another room type class is created with code 'c1' and the - properties set to False. Then the room_type with code 'c1' - in property 2(company1) is searched through the - get_unique_by_property_code() method and the result is checked. - """ - # ARRANGE - self.pms_property2 = self.env["pms.property"].create( - { - "name": "Property 2", - "company_id": self.company1.id, - "default_pricelist_id": self.pricelist1.id, - } - ) - # room_type_class1 - self.env["pms.room.type.class"].create( - { - "name": "Room type class 1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - room_type_class2 = self.env["pms.room.type.class"].create( - { - "name": "Room type class cl2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property2.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, - room_type_class2.id, - "Expected room type class not found", - ) - - def test_multiple_case_03(self): - """ - Check that a room type class can be created with the same - code as another when one of them has pms_property_ids = False - ---------- - A room type class is created with code 'c1' for property 1(company1). - Another room type class is created with code 'c1' and the - properties set to False. Then the room_type with code 'c1' - in property 3(company2) is searched through the - get_unique_by_property_code() method and the result is checked. - """ - # ARRANGE - # room_type_class1 - self.env["pms.room.type.class"].create( - { - "name": "Room type class cl1", - "default_code": "c1", - "pms_property_ids": [(6, 0, [self.pms_property1.id])], - } - ) - room_type_class2 = self.env["pms.room.type.class"].create( - { - "name": "Room type class cl2", - "default_code": "c1", - "pms_property_ids": False, - } - ) - - # ACT - room_type_classes = self.env["pms.room.type.class"].get_unique_by_property_code( - self.pms_property3.id, "c1" - ) - - # ASSERT - self.assertEqual( - room_type_classes.id, - room_type_class2.id, - "Expected room type class not found", - ) diff --git a/pms/tests/test_pms_sale_channel.py b/pms/tests/test_pms_sale_channel.py deleted file mode 100644 index 70702b53a..000000000 --- a/pms/tests/test_pms_sale_channel.py +++ /dev/null @@ -1,178 +0,0 @@ -import datetime - -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsSaleChannel(TestPms): - def test_reservation_with_invalid_agency(self): - """ - Reservation with an invalid agency cannot be created. - Create a partner that is not an agency and create - a reservation with that partner as an agency. - """ - # ARRANGE - PmsReservation = self.env["pms.reservation"] - not_agency = self.env["res.partner"].create( - {"name": "partner1", "is_agency": False} - ) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="Reservation with an invalid agency cannot be created." - ): - PmsReservation.create( - { - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "agency_id": not_agency.id, - "pms_property_id": self.pms_property1.id, - } - ) - - def test_reservation_with_valid_agency(self): - """ - Reservation with a valid agency must be created. - Create a partner that is an agency and create - a reservation with that partner as an agency can be created. - """ - # ARRANGE - PmsReservation = self.env["pms.reservation"] - PmsSaleChannel = self.env["pms.sale.channel"] - sale_channel1 = PmsSaleChannel.create( - {"name": "Test Indirect", "channel_type": "indirect"} - ) - # ACT - agency1 = self.env["res.partner"].create( - { - "name": "partner1", - "is_agency": True, - "sale_channel_id": sale_channel1.id, - } - ) - reservation1 = PmsReservation.create( - { - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "agency_id": agency1.id, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertEqual( - reservation1.agency_id.is_agency, - True, - "Reservation with a valid agency should be created.", - ) - - def test_reservation_with_partner_direct(self): - """ - Reservation create with partner (no agency) and sale channel - 'direct' must be set reservation sale channel to 'direct'. - A reservation with partner and sale channel as 'direct' - should be created. - """ - # ARRANGE - PmsReservation = self.env["pms.reservation"] - PmsSaleChannel = self.env["pms.sale.channel"] - # ACT - sale_channel1 = PmsSaleChannel.create({"channel_type": "direct"}) - partner1 = self.env["res.partner"].create({"name": "partner1"}) - reservation1 = PmsReservation.create( - { - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "channel_type_id": sale_channel1.id, - "partner_id": partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # ASSERT - self.assertEqual( - reservation1.channel_type_id.channel_type, - "direct", - "A reservation with partner and sale channel as 'direct'" - "should be created a 'direct' reservation.", - ) - - def test_reservation_with_partner_indirect(self): - """ - Reservation create with partner (no agency) and sale channel - 'indirect' must be set reservation sale channel to 'direct'. - A reservation with partner and sale channel as 'direct' - should be created. - """ - # ARRANGE - PmsReservation = self.env["pms.reservation"] - PmsSaleChannel = self.env["pms.sale.channel"] - # ACT - sale_channel1 = PmsSaleChannel.create({"channel_type": "indirect"}) - partner1 = self.env["res.partner"].create({"name": "partner1"}) - reservation1 = PmsReservation.create( - { - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "channel_type_id": sale_channel1.id, - "partner_id": partner1.id, - "pms_property_id": self.pms_property1.id, - } - ) - # ASSERT - self.assertEqual( - reservation1.channel_type_id.channel_type, - "indirect", - "A reservation with partner and sale channel as 'direct'" - "should be created a 'indirect' reservation.", - ) - - def test_create_agency_with_sale_channel_indirect(self): - """ - Agency should be created as partner setted as 'agency' - and its sale channel as 'indirect'. - """ - # ARRANGE - PmsSaleChannel = self.env["pms.sale.channel"] - saleChannel1 = PmsSaleChannel.create({"channel_type": "indirect"}) - # ACT - agency1 = self.env["res.partner"].create( - {"name": "example", "is_agency": True, "sale_channel_id": saleChannel1.id} - ) - # ASSERT - self.assertEqual( - agency1.sale_channel_id.channel_type, - "indirect", - "An agency should be an indirect channel.", - ) - - def test_create_agency_with_sale_channel_direct(self): - """ - Agency shouldnt be created as partner setted as 'agency' - and its sale channel as 'direct'. - """ - # ARRANGE - PmsSaleChannel = self.env["pms.sale.channel"] - saleChannel1 = PmsSaleChannel.create({"channel_type": "direct"}) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="An agency should be an indirect channel." - ): - self.env["res.partner"].create( - { - "name": "example", - "is_agency": True, - "sale_channel_id": saleChannel1.id, - } - ) - - def test_create_agency_without_sale_channel(self): - """ - Agency creation should fails if there's no sale channel. - """ - # ARRANGE & ACT & ASSERT - with self.assertRaises( - ValidationError, msg="Agency should not be created without sale channel." - ): - self.env["res.partner"].create( - {"name": "example", "is_agency": True, "sale_channel_id": None} - ) diff --git a/pms/tests/test_pms_simple_invoice.py b/pms/tests/test_pms_simple_invoice.py deleted file mode 100644 index 7d00b251b..000000000 --- a/pms/tests/test_pms_simple_invoice.py +++ /dev/null @@ -1,10 +0,0 @@ -from freezegun import freeze_time - -from odoo.tests.common import SavepointCase - -freeze_time("2000-02-02") - - -class TestPmsInvoiceSimpleInvoice(SavepointCase): - def setUp(self): - super(TestPmsInvoiceSimpleInvoice, self).setUp() diff --git a/pms/tests/test_pms_wizard_massive_changes.py b/pms/tests/test_pms_wizard_massive_changes.py deleted file mode 100644 index 8c8a13b03..000000000 --- a/pms/tests/test_pms_wizard_massive_changes.py +++ /dev/null @@ -1,1238 +0,0 @@ -import datetime - -from freezegun import freeze_time - -from odoo import fields - -from .common import TestPms - - -class TestPmsWizardMassiveChanges(TestPms): - def setUp(self): - super().setUp() - self.availability_plan1 = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - - # MASSIVE CHANGE WIZARD TESTS ON AVAILABILITY RULES - - def test_num_availability_rules_create(self): - """ - Rules should be created consistently for 1,2,3,4 days - subtests: {1 day -> 1 rule, n days -> n rules} - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - for days in [0, 1, 2, 3]: - with self.subTest(k=days): - num_exp_rules_to_create = days + 1 - # ACT - self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "start_date": fields.date.today(), - "end_date": fields.date.today() + datetime.timedelta(days=days), - "room_type_ids": [(6, 0, [room_type_double.id])], - "pms_property_ids": [self.pms_property1.id], - } - ).apply_massive_changes() - # ASSERT - self.assertEqual( - len(self.availability_plan1.rule_ids), - num_exp_rules_to_create, - "the number of rules created should contains all the " - "days between start and finish (both included)", - ) - - def test_num_availability_rules_create_no_room_type(self): - """ - Rules should be created consistently for all rooms & days. - (days * num rooom types) - Create rules for 4 days and for all room types. - """ - # ARRANGE - date_from = fields.date.today() - date_to = fields.date.today() + datetime.timedelta(days=3) - - num_room_types = self.env["pms.room.type"].search_count( - [ - "|", - ("pms_property_ids", "=", False), - ("pms_property_ids", "in", self.pms_property1.id), - ] - ) - num_exp_rules_to_create = ((date_to - date_from).days + 1) * num_room_types - - # ACT - self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "start_date": date_from, - "end_date": date_to, - "pms_property_ids": [self.pms_property1.id], - } - ).apply_massive_changes() - - # ASSERT - self.assertEqual( - len(self.availability_plan1.rule_ids), - num_exp_rules_to_create, - "the number of rules created by the wizard should consider all " - "room types", - ) - - def test_value_availability_rules_create(self): - """ - The value of the rules created is setted properly. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - vals = { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "start_date": date_from, - "end_date": date_to, - "room_type_ids": [(6, 0, [room_type_double.id])], - "quota": 50, - "max_avail": 5, - "min_stay": 10, - "min_stay_arrival": 10, - "max_stay": 10, - "max_stay_arrival": 10, - "closed": True, - "closed_arrival": True, - "closed_departure": True, - "pms_property_ids": [self.pms_property1.id], - } - # ACT - self.env["pms.massive.changes.wizard"].create(vals).apply_massive_changes() - # ASSERT - del vals["massive_changes_on"] - del vals["availability_plan_ids"] - del vals["start_date"] - del vals["end_date"] - del vals["room_type_ids"] - del vals["pms_property_ids"] - for key in vals: - with self.subTest(k=key): - self.assertEqual( - self.availability_plan1.rule_ids[0][key], - vals[key], - "The value of " + key + " is not correctly established", - ) - - @freeze_time("1980-12-01") - def test_day_of_week_availability_rules_create(self): - """ - Rules for each day of week should be created. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - test_case_week_days = [ - [1, 0, 0, 0, 0, 0, 0], - [0, 1, 0, 0, 0, 0, 0], - [0, 0, 1, 0, 0, 0, 0], - [0, 0, 0, 1, 0, 0, 0], - [0, 0, 0, 0, 1, 0, 0], - [0, 0, 0, 0, 0, 1, 0], - [0, 0, 0, 0, 0, 0, 1], - ] - date_from = fields.date.today() - date_to = fields.date.today() + datetime.timedelta(days=6) - - wizard = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "room_type_ids": [(6, 0, [room_type_double.id])], - "start_date": date_from, - "end_date": date_to, - "pms_property_ids": [self.pms_property1.id], - } - ) - - for index, test_case in enumerate(test_case_week_days): - with self.subTest(k=test_case): - # ARRANGE - wizard.write( - { - "apply_on_monday": test_case[0], - "apply_on_tuesday": test_case[1], - "apply_on_wednesday": test_case[2], - "apply_on_thursday": test_case[3], - "apply_on_friday": test_case[4], - "apply_on_saturday": test_case[5], - "apply_on_sunday": test_case[6], - } - ) - # ACT - wizard.apply_massive_changes() - availability_rules = self.availability_plan1.rule_ids.sorted( - key=lambda s: s.date - ) - # ASSERT - self.assertTrue( - availability_rules[index].date.timetuple()[6] == index - and test_case[index], - "Rule not created on correct day of week.", - ) - - def test_no_overwrite_values_not_setted(self): - """ - A rule value shouldnt overwrite with the default values - another rules for the same day and room type. - Create a rule with quota and another rule for the same date with max - avail. Should not overwrite quota. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - date = fields.date.today() - initial_quota = 20 - self.env["pms.availability.plan.rule"].create( - { - "availability_plan_id": self.availability_plan1.id, - "room_type_id": room_type_double.id, - "date": date, - "quota": initial_quota, - "pms_property_id": self.pms_property1.id, - } - ) - vals_wizard = { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "start_date": date, - "end_date": date, - "room_type_ids": [(6, 0, [room_type_double.id])], - "apply_max_avail": True, - "max_avail": 2, - "pms_property_ids": [self.pms_property1.id], - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - self.availability_plan1.rule_ids[0].quota, - initial_quota, - "A rule value shouldnt overwrite with the default values " - "another rules for the same day and room type", - ) - - def test_several_availability_plans(self): - """ - If several availability plans are set, the wizard should create as - many rules as availability plans. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - availability_plan2 = self.env["pms.availability.plan"].create( - { - "name": "Second availability plan for TEST", - "pms_pricelist_ids": [self.pricelist1.id], - } - ) - expected_av_plans = [ - self.availability_plan1.id, - availability_plan2.id, - ] - date_from = fields.date.today() - date_to = fields.date.today() - vals_wizard = { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [ - ( - 6, - 0, - [ - self.availability_plan1.id, - availability_plan2.id, - ], - ) - ], - "room_type_ids": [(6, 0, [room_type_double.id])], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_av_plans), - set( - self.env["pms.availability.plan.rule"] - .search([("room_type_id", "=", room_type_double.id)]) - .mapped("availability_plan_id") - .ids - ), - "The wizard should create as many rules as availability plans given.", - ) - - def test_several_room_types_availability_plan(self): - """ - If several room types are set, the wizard should create as - many rules as room types. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Single Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - expected_room_types = [ - room_type_double.id, - room_type_single.id, - ] - date_from = fields.date.today() - date_to = fields.date.today() - vals_wizard = { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "room_type_ids": [ - ( - 6, - 0, - [room_type_double.id, room_type_single.id], - ) - ], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_room_types), - set( - self.env["pms.availability.plan.rule"] - .search([("availability_plan_id", "=", self.availability_plan1.id)]) - .mapped("room_type_id") - .ids - ), - "The wizard should create as many rules as room types given.", - ) - - def test_several_properties_availability_plan(self): - """ - If several properties are set, the wizard should create as - many rules as properties. - """ - # ARRANGE - pms_property2 = self.env["pms.property"].create( - { - "name": "MY 2nd PMS TEST", - "company_id": self.env.ref("base.main_company").id, - } - ) - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - room_type_double.pms_property_ids = [ - (6, 0, [self.pms_property1.id, pms_property2.id]) - ] - expected_properties = [ - self.pms_property1.id, - pms_property2.id, - ] - date_from = fields.date.today() - date_to = fields.date.today() - vals_wizard = { - "massive_changes_on": "availability_plan", - "availability_plan_ids": [(6, 0, [self.availability_plan1.id])], - "room_type_ids": [(6, 0, [room_type_double.id])], - "pms_property_ids": [(6, 0, [self.pms_property1.id, pms_property2.id])], - "start_date": date_from, - "end_date": date_to, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_properties), - set( - self.env["pms.availability.plan.rule"] - .search([("availability_plan_id", "=", self.availability_plan1.id)]) - .mapped("pms_property_id") - .ids - ), - "The wizard should create as many rules as properties given.", - ) - - # MASSIVE CHANGE WIZARD TESTS ON PRICELIST ITEMS - - def test_pricelist_items_create(self): - """ - Pricelist items should be created consistently for 1,2,3,4 days - subtests: {1 day -> 1 pricelist item, n days -> n pricelist items} - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - for days in [0, 1, 2, 3]: - with self.subTest(k=days): - # ARRANGE - num_exp_items_to_create = days + 1 - self.pricelist1.item_ids = False - # ACT - self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "start_date": fields.date.today(), - "end_date": fields.date.today() + datetime.timedelta(days=days), - "room_type_ids": [(6, 0, [room_type_double.id])], - "pms_property_ids": [self.pms_property1.id], - } - ).apply_massive_changes() - # ASSERT - self.assertEqual( - len(self.pricelist1.item_ids if self.pricelist1.item_ids else []), - num_exp_items_to_create, - "the number of rules created by the wizard should include all the " - "days between start and finish (both included)", - ) - - def test_num_pricelist_items_create_no_room_type(self): - """ - Pricelist items should be created consistently for all rooms & days. - (days * num rooom types) - Create pricelist item for 4 days and for all room types. - """ - # ARRANGE - date_from = fields.date.today() - date_to = fields.date.today() + datetime.timedelta(days=3) - num_room_types = self.env["pms.room.type"].search_count( - [ - "|", - ("pms_property_ids", "=", False), - ("pms_property_ids", "in", self.pms_property1.id), - ] - ) - num_exp_items_to_create = ((date_to - date_from).days + 1) * num_room_types - # ACT - self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "start_date": date_from, - "end_date": date_to, - "pms_property_ids": [self.pms_property1.id], - } - ).apply_massive_changes() - # ASSERT - self.assertEqual( - len(self.pricelist1.item_ids), - num_exp_items_to_create, - "the number of rules created by the wizard should consider all " - "room types when one is not applied", - ) - - def test_value_pricelist_items_create(self): - """ - The value of the rules created is setted properly. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - price = 20 - min_quantity = 3 - vals = { - "pricelist_id": self.pricelist1, - "date_start": date_from, - "date_end": date_to, - "compute_price": "fixed", - "applied_on": "0_product_variant", - "product_id": room_type_double.product_id, - "fixed_price": price, - "min_quantity": min_quantity, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "start_date": date_from, - "end_date": date_to, - "room_type_ids": [(6, 0, [room_type_double.id])], - "price": price, - "min_quantity": min_quantity, - "pms_property_ids": [self.pms_property1.id], - } - ).apply_massive_changes() - vals["date_start_consumption"] = date_from - vals["date_end_consumption"] = date_to - del vals["date_start"] - del vals["date_end"] - # ASSERT - for key in vals: - with self.subTest(k=key): - self.assertEqual( - self.pricelist1.item_ids[0][key], - vals[key], - "The value of " + key + " is not correctly established", - ) - - @freeze_time("1980-12-01") - def test_day_of_week_pricelist_items_create(self): - """ - Pricelist items for each day of week should be created. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - test_case_week_days = [ - [1, 0, 0, 0, 0, 0, 0], - [0, 1, 0, 0, 0, 0, 0], - [0, 0, 1, 0, 0, 0, 0], - [0, 0, 0, 1, 0, 0, 0], - [0, 0, 0, 0, 1, 0, 0], - [0, 0, 0, 0, 0, 1, 0], - [0, 0, 0, 0, 0, 0, 1], - ] - date_from = fields.date.today() - date_to = date_from + datetime.timedelta(days=6) - wizard = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "room_type_ids": [(6, 0, [room_type_double.id])], - "start_date": date_from, - "end_date": date_to, - "pms_property_ids": [self.pms_property1.id], - } - ) - for index, test_case in enumerate(test_case_week_days): - with self.subTest(k=test_case): - # ARRANGE - wizard.write( - { - "apply_on_monday": test_case[0], - "apply_on_tuesday": test_case[1], - "apply_on_wednesday": test_case[2], - "apply_on_thursday": test_case[3], - "apply_on_friday": test_case[4], - "apply_on_saturday": test_case[5], - "apply_on_sunday": test_case[6], - } - ) - self.pricelist1.item_ids = False - # ACT - wizard.apply_massive_changes() - pricelist_items = self.pricelist1.item_ids.sorted( - key=lambda s: s.date_start_consumption - ) - # ASSERT - self.assertTrue( - pricelist_items[index].date_start_consumption.timetuple()[6] - == index - and test_case[index], - "Rule not created on correct day of week", - ) - - def test_several_pricelists(self): - """ - If several pricelist are set, the wizard should create as - many pricelist items as pricelists. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - pricelist2 = self.env["product.pricelist"].create( - { - "name": "test pricelist 2", - } - ) - expected_pricelists = [self.pricelist1.id, pricelist2.id] - date_from = fields.date.today() - date_to = fields.date.today() - vals_wizard = { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id, pricelist2.id])], - "room_type_ids": [(6, 0, [room_type_double.id])], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_pricelists), - set( - self.env["product.pricelist.item"] - .search([("product_id", "=", room_type_double.product_id.id)]) - .mapped("pricelist_id") - .ids - ), - "The wizard should create as many items as pricelists given.", - ) - - def test_several_room_types_pricelist(self): - """ - If several room types are set, the wizard should create as - many pricelist items as room types. - """ - # ARRANGE - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Single Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - expected_product_ids = [ - room_type_double.product_id.id, - room_type_single.product_id.id, - ] - vals_wizard = { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "room_type_ids": [ - ( - 6, - 0, - [room_type_double.id, room_type_single.id], - ) - ], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_product_ids), - set( - self.env["product.pricelist.item"] - .search([("pricelist_id", "=", self.pricelist1.id)]) - .mapped("product_id") - .ids - ), - "The wizard should create as many items as room types given.", - ) - - def test_one_board_service_room_type_no_board_service(self): - """ - Call to wizard with one board service room type and no - board service. - The wizard must create as many pricelist items as there - are services on the given board service. - """ - # ARRANGE - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - board_service_only_breakfast = self.env["pms.board.service"].create( - { - "name": "Test Only Breakfast", - "default_code": "CB1", - } - ) - service_breakfast = self.env["product.product"].create( - {"name": "Test Breakfast"} - ) - board_service_single = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_single.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - board_service_line_single_1 = self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "board_services", - "board_service_room_type_ids": [ - ( - 6, - 0, - [board_service_single.id], - ) - ], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "consumption_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "=", board_service_line_single_1.product_id.id), - ] - ) - # ASSERT - self.assertIn( - service_breakfast, - items_created.mapped("product_id"), - "The wizard must create as many pricelist items as there " - "are services on the given board service.", - ) - - def test_one_board_service_room_type_with_board_service(self): - """ - Call to wizard with one board service room type and - board service. - The wizard must create one pricelist items with - the board service given. - """ - # ARRANGE - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - board_service_only_breakfast = self.env["pms.board.service"].create( - { - "name": "Test Only Breakfast", - "default_code": "CB1", - } - ) - service_breakfast = self.env["product.product"].create( - {"name": "Test Breakfast"} - ) - board_service_single = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_single.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - board_service_line_single_1 = self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "board_services", - "board_service_room_type_ids": [ - ( - 6, - 0, - [board_service_single.id], - ) - ], - "board_service": board_service_line_single_1.product_id.id, - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "consumption_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "=", board_service_line_single_1.product_id.id), - ] - ) - # ASSERT - self.assertIn( - service_breakfast, - items_created.mapped("product_id"), - "The wizard must create one pricelist items with " - " the board service given.", - ) - - def test_several_board_service_room_type_no_board_service(self): - """ - Call to wizard with several board service room type and no - board service. - The wizard must create as many pricelist items as there - are services on the given board services. - """ - # ARRANGE - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - board_service_only_breakfast = self.env["pms.board.service"].create( - { - "name": "Test Only Breakfast", - "default_code": "CB1", - } - ) - board_service_half_board = self.env["pms.board.service"].create( - { - "name": "Test Half Board", - "default_code": "CB2", - } - ) - service_breakfast = self.env["product.product"].create( - {"name": "Test Breakfast"} - ) - service_dinner = self.env["product.product"].create({"name": "Test Dinner"}) - board_service_single = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_single.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - board_service_double = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_double.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_dinner.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - product_ids_expected = ( - board_service_double.pms_board_service_id.board_service_line_ids.mapped( - "product_id" - ).ids - + board_service_single.pms_board_service_id.board_service_line_ids.mapped( - "product_id" - ).ids - ) - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "board_services", - "board_service_room_type_ids": [ - ( - 6, - 0, - [ - board_service_single.id, - board_service_double.id, - ], - ) - ], - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "consumption_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "in", product_ids_expected), - ] - ) - # ASSERT - self.assertEqual( - set(product_ids_expected), - set(items_created.mapped("product_id").ids), - "The wizard should create as many pricelist items as there" - " are services on the given board services.", - ) - - def test_several_board_service_room_type_with_board_service(self): - - """ - Call to wizard with several board service room types and - board service. - The wizard must create as many pricelist items as there - are services on the given board services. - """ - # ARRANGE - room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - board_service_only_breakfast = self.env["pms.board.service"].create( - { - "name": "Test Only Breakfast", - "default_code": "CB1", - } - ) - board_service_half_board = self.env["pms.board.service"].create( - { - "name": "Test Half Board", - "default_code": "CB2", - } - ) - service_breakfast = self.env["product.product"].create( - {"name": "Test Breakfast"} - ) - service_dinner = self.env["product.product"].create({"name": "Test Dinner"}) - board_service_single = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_single.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - board_service_double = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": room_type_double.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_only_breakfast.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_breakfast.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": service_dinner.id, - "pms_board_service_id": board_service_half_board.id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - board_service_id_double = board_service_double.pms_board_service_id - board_service_id_single = board_service_single.pms_board_service_id - product_ids_expected = list( - set(board_service_id_double.board_service_line_ids.mapped("product_id").ids) - & set( - board_service_id_single.board_service_line_ids.mapped("product_id").ids - ) - ) - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "board_services", - "board_service_room_type_ids": [ - ( - 6, - 0, - [ - board_service_single.id, - board_service_double.id, - ], - ) - ], - "board_service": service_breakfast.id, - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "consumption_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "in", product_ids_expected), - ] - ) - # ASSERT - self.assertEqual( - set(product_ids_expected), - set(items_created.mapped("product_id").ids), - "The wizard should create as many pricelist items as there" - " are services on the given board services.", - ) - - def test_service(self): - """ - Call to wizard with one service (product_id) - The wizard must create one pricelist items with - the given service (product_id). - """ - # ARRANGE - service_spa = self.env["product.product"].create({"name": "Test Spa"}) - date_from = fields.date.today() - date_to = fields.date.today() - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "service", - "service": service_spa.id, - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "consumption_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "=", service_spa.id), - ] - ) - # ASSERT - self.assertIn( - service_spa.id, - items_created.mapped("product_id").ids, - "The wizard should create one pricelist items with" - " the given service (product_id).", - ) - - def test_sale_dates(self): - """ - Call to wizard with one service (product_id) - and dates of SALE - The wizard must create one pricelist items with - the given service (product_id) and dates of SALE. - """ - # ARRANGE - service_spa = self.env["product.product"].create({"name": "Test Spa"}) - date_from = fields.date.today() - date_to = fields.date.today() - wizard_result = self.env["pms.massive.changes.wizard"].create( - { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "service", - "service": service_spa.id, - "pms_property_ids": [self.pms_property1.id], - "start_date": date_from, - "end_date": date_to, - "date_types": "sale_dates", - } - ) - # ACT - wizard_result.apply_massive_changes() - items_created = self.env["product.pricelist.item"].search( - [ - ("pricelist_id", "=", self.pricelist1.id), - ("pms_property_ids", "=", self.pms_property1.id), - ("product_id", "=", service_spa.id), - ] - ) - expected_dates = [ - datetime.datetime.combine(date_from, datetime.datetime.min.time()), - datetime.datetime.combine(date_to, datetime.datetime.max.time()), - ] - # ASSERT - self.assertEqual( - expected_dates, - items_created.mapped("date_start") + items_created.mapped("date_end"), - "The wizard should create one pricelist items with" - " the given service (product_id) and dates of sale.", - ) - - def test_several_properties_pricelist(self): - """ - If several properties are set, the wizard should create as - many items as properties. - """ - # ARRANGE - service_spa = self.env["product.product"].create({"name": "Test Spa"}) - pms_property2 = self.env["pms.property"].create( - { - "name": "MY 2nd PMS TEST", - "company_id": self.env.ref("base.main_company").id, - } - ) - date_from = fields.date.today() - date_to = fields.date.today() - expected_properties = [ - self.pms_property1.id, - pms_property2.id, - ] - vals_wizard = { - "massive_changes_on": "pricelist", - "pricelist_ids": [(6, 0, [self.pricelist1.id])], - "apply_pricelists_on": "service", - "service": service_spa.id, - "pms_property_ids": [(6, 0, [self.pms_property1.id, pms_property2.id])], - "start_date": date_from, - "end_date": date_to, - "date_types": "sale_dates", - } - # ACT - self.env["pms.massive.changes.wizard"].create( - vals_wizard - ).apply_massive_changes() - # ASSERT - self.assertEqual( - set(expected_properties), - set( - self.env["product.pricelist.item"] - .search([("pricelist_id", "=", self.pricelist1.id)]) - .mapped("pms_property_ids") - .ids - ), - "The wizard should create as many items as properties given.", - ) diff --git a/pms/tests/test_pms_wizard_split_join_swap_reservation.py b/pms/tests/test_pms_wizard_split_join_swap_reservation.py deleted file mode 100644 index c1f6853ef..000000000 --- a/pms/tests/test_pms_wizard_split_join_swap_reservation.py +++ /dev/null @@ -1,979 +0,0 @@ -import datetime - -from odoo.exceptions import UserError - -from .common import TestPms - - -class TestPmsWizardSplitJoinSwapReservation(TestPms): - def setUp(self): - super().setUp() - # pms.availability.plan - self.test_availability_plan = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - - # pms.room.type - self.test_room_type_single = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Single Test", - "default_code": "SNG_Test", - "class_id": self.room_type_class1.id, - } - ) - # pms.room.type - self.test_room_type_double = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Double Test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - - # create rooms - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 101", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 102", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - - self.partner1 = self.env["res.partner"].create({"name": "Antón"}) - - # UNIFY TESTS # review - def test_unify_reservation_avail_should(self): - """ - Check that, if there is availability, a reservation with several - rooms on different days can be unified into a one room reservation. - ------------ - Create a reservation with room1.Then, in the first reservation line, - the room is changed to room2.The reservation_join() method of the wizard - is launched, passing the reservation and room2 as parameters and it is - verified that room2 is found in all the reservation lines. - - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | | r1 | | | | - | Double 102 | | r1 | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r1.reservation_line_ids[0].room_id = self.room2 - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservation_join( - r1, self.room2 - ) - # ASSERT - self.assertEqual( - r1.reservation_line_ids.mapped("room_id"), - self.room2, - "The unify operation should assign the indicated room to all nights", - ) - - def test_unify_reservation_avail_not(self): - """ - Check that you cannot unify a reservation with two different rooms - because there is no availability in the required room. - ---------- - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | r2 | | | | - | Double 102 | r0 | r0 | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=2), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "room_type_id": self.test_room_type_double.id, - "partner_id": self.partner1.id, - } - ) - r2.flush() - # ACT & ASSERT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_join( - r1, self.room1 - ) - - def test_unify_reservation_avail_not_room_exist(self): - """ - Check that you cannot unify a reservation with two different rooms - because there the required room does not exists. - """ - - # ARRANGE - - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r2.flush() - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_join( - r2, self.env["pms.room"] - ) - - # SWAP TESTS - def test_swap_reservation_rooms_01(self): - # TEST CASE - """ - Check that the rooms of two different reservations was swapped correctly - by applying the reservations_swap() method of the wizard. - ------------ - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | r1 | r1 | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room1.id, - self.room2.id, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_02(self): - """ - Check that two rooms from two different reservations are swapped - correctly. - ------------------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | | r1 | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | | r1 | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room1.id, - self.room2.id, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_03(self): - """ - Check that two rooms from two different reservations are swapped - correctly. - ------------------- - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | | r1 | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | | r1 | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=1), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room2.id, - self.room1.id, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_04(self): - # TEST CASE - """ - Check that two rooms from two different reservations are swapped - correctly. - source: r1 - target: r2 - -------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | | | | | - | Double 102 | r1 | r1 | r2 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room1.id, - self.room2.id, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_05(self): - """ - Check that two rooms from two different reservations are swapped - correctly. - source: r2 - target: r1 - --------------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | r1 | r1 | | | | | - +------------+------+------+------+----+----+----+ - - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=2), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room2.id, - self.room1.id, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_06(self): - """ - Check that the room is exchanged correctly for every day because there - is no reservation for another room in those days. - --------------------------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | | | | | | | - | Double 102 | r1 | r1 | r1 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | r1 | | | | - | Double 102 | | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room2.id, - self.room1.id, - ) - # ASSERT - self.assertTrue(r1.reservation_line_ids.room_id == self.room1) - - def test_swap_reservation_rooms_gap_01(self): - """ - Check that three rooms from three different reservations are swapped - correctly. - ----------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r0 | | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | r0 | | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - - # ARRANGE - - r0 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=2), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room1.id, - self.room2.id, - ) - # ASSERT - self.assertTrue( - r0.reservation_line_ids.room_id == self.room2 - and r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - def test_swap_reservation_rooms_gap_02(self): - # TEST CASE - """ - Check that three rooms from three different reservations are swapped - correctly. - ----------- - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r0 | | r1 | | | | - | Double 102 | r2 | r2 | r2 | | | | - +------------+------+------+------+----+----+----+ - - State after swap - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r2 | r2 | r2 | | | | - | Double 102 | r0 | | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r0 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=1), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now() + datetime.timedelta(days=2), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r2 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - r2.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room2.id, - self.room1.id, - ) - # ASSERT - self.assertTrue( - r0.reservation_line_ids.room_id == self.room2 - and r1.reservation_line_ids.room_id == self.room2 - and r2.reservation_line_ids.room_id == self.room1 - ) - - # NOT VALID TEST CASES - def test_swap_reservation_not_valid_01(self): - """ - Check that an error is thrown if you try to pass a room that is - not reserved for those days to the reservations_swap() method. - --------------------------- - Swap room1 with room2 should raise an error because room1 has - no reservation between checkin & checkout provided. - - Initial state - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | | | | | | | - | Double 102 | r1 | r1 | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - - # ASSERT & ACT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservations_swap( - datetime.datetime.now(), - datetime.datetime.now() + datetime.timedelta(days=3), - self.room1.id, - self.room2.id, - ) - - # SPLIT TESTS - def test_split_reservation_check_room_splitted_valid_01(self): - """ - A reservation is created with preferred room. The room for 1st night - is switched to another room. - ------------------- - - Expected result: - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | | r1 | r1 | | | | - | Double 102 | r1 | | | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, datetime.date.today(), self.room2 - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids[0].room_id == self.room2 - and r1.reservation_line_ids[1:].room_id == self.room1 - ) - - def test_split_reservation_check_room_splitted_valid_02(self): - """ - A reservation is created with preferred room. The room for 1st - night is switched to another room - -------------- - - Expected result: - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | r1 | | | | | - | Double 102 | | | r1 | | | | - +------------+------+------+------+----+----+----+ - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, - ( - datetime.datetime( - year=datetime.date.today().year, - month=datetime.date.today().month, - day=datetime.date.today().day, - ) - + datetime.timedelta(days=2) - ).date(), - self.room2, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids[2].room_id == self.room2 - and r1.reservation_line_ids[:1].room_id == self.room1 - ) - - def test_split_reservation_check_room_splitted_valid_03(self): - """ - A reservation is created with preferred room. The room for 1st - night is switched to another room. - ----------- - - Expected result: - +------------+------+------+------+----+----+----+ - | room/date | 01 | 02 | 03 | 04 | 05 | 06 | - +------------+------+------+------+----+----+----+ - | Double 101 | r1 | | r1 | | | | - | Double 102 | | r1 | | | | | - +------------+------+------+------+----+----+----+""" - - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, - ( - datetime.datetime( - year=datetime.date.today().year, - month=datetime.date.today().month, - day=datetime.date.today().day, - ) - + datetime.timedelta(days=1) - ).date(), - self.room2, - ) - # ASSERT - self.assertTrue( - r1.reservation_line_ids[1].room_id == self.room2 - and r1.reservation_line_ids[0].room_id == self.room1 - and r1.reservation_line_ids[2].room_id == self.room1 - ) - - def test_split_reservation_check_room_splitted_not_valid_01(self): - """ - Try to split the reservation for one night and set with a non valid room. - ---------- - Create a reservation for room1. Then create a room and it is deleted. The - reservation_split method is launched but an error should appear because - the room does not exist. - """ - - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - room_not_exist = self.room3 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Double 103", - "room_type_id": self.test_room_type_double.id, - "capacity": 2, - } - ) - room_not_exist.unlink() - # ACT & ASSERT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, datetime.datetime.now(), room_not_exist - ) - - def test_split_reservation_check_room_splitted_not_valid_02(self): - # TEST CASE - """ - Try to split the reservation for one night and that night - doesn't belongto reservation. - --------------- - A reservation is created with a date interval of 3 days. - After the reservation_split() method is launched, passing - that reservation but with a date interval of 100 days, - this should throw an error. - """ - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT & ASSERT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, datetime.datetime.now() + datetime.timedelta(days=100), self.room1 - ) - - def test_split_reservation_check_room_splitted_not_valid_03(self): - - """ - Try to split the reservation for one night and the reservation - not exists. - ------------- - A reservation is created, but it is not the reservation that is - passed to the reservation_split() method, one that does not exist - is passed to it, this should throw an error. - """ - - # ARRANGE - - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT & ASSERT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - self.env["pms.reservation"], datetime.datetime.now(), self.room2 - ) - - def test_split_reservation_check_room_splitted_not_valid_04(self): - """ - Try to split the reservation to one room and the room is not available. - --------------- - A reservation is created with room2 as favorite_room. Another reservation - is created for the same days with room1. An attempt is made to separate - the room from the second reservation using the reservations_split() method, - passing it the same days as the reservations and room2, but this should - throw an error because room2 is not available for those days. - """ - # ARRANGE - - self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room2.id, - "partner_id": self.partner1.id, - } - ) - r1 = self.env["pms.reservation"].create( - { - "pms_property_id": self.pms_property1.id, - "checkin": datetime.datetime.now(), - "checkout": datetime.datetime.now() + datetime.timedelta(days=3), - "adults": 2, - "preferred_room_id": self.room1.id, - "partner_id": self.partner1.id, - } - ) - r1.flush() - # ACT & ASSERT - with self.assertRaises(UserError): - self.env["pms.reservation.split.join.swap.wizard"].reservation_split( - r1, datetime.datetime.now(), self.room2 - ) diff --git a/pms/tests/test_product_template.py b/pms/tests/test_product_template.py deleted file mode 100644 index b0f49aaf8..000000000 --- a/pms/tests/test_product_template.py +++ /dev/null @@ -1,304 +0,0 @@ -import datetime - -from odoo import fields -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestProductTemplate(TestPms): - def setUp(self): - super().setUp() - self.room_type = self.env["pms.room.type"].create( - { - "name": "Room type test", - "default_code": "DBL_Test", - "class_id": self.room_type_class1.id, - } - ) - self.room = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Room test", - "room_type_id": self.room_type.id, - "capacity": 2, - } - ) - self.partner = self.env["res.partner"].create({"name": "partner1"}) - self.board_service = self.env["pms.board.service"].create( - { - "name": "Board service test", - "default_code": "BST", - } - ) - - def test_bs_consumed_on_after(self): - """ - Create a one day reservation with a board service configured to - consume after reservation night. - Date of service line with consumed on 'after' should match checkout date. - """ - # ARRANGE - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "after", - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": product.id, - "pms_board_service_id": self.board_service.id, - } - ) - board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type.id, - "pms_board_service_id": self.board_service.id, - } - ) - date_checkin = fields.date.today() - date_checkout = fields.date.today() + datetime.timedelta(days=1) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": date_checkin, - "checkout": date_checkout, - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "board_service_room_id": board_service_room_type.id, - } - ) - # ASSERT - self.assertEqual( - reservation.service_ids.service_line_ids.date, - date_checkout, - "Date of service line with consumed on 'after' should match checkout date.", - ) - - def test_bs_consumed_on_before(self): - """ - Create a one day reservation with a board service configured to - consume before reservation night. - Date of service line with consumed on 'before' should match checkin date. - """ - # ARRANGE - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "before", - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": product.id, - "pms_board_service_id": self.board_service.id, - } - ) - board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type.id, - "pms_board_service_id": self.board_service.id, - } - ) - date_checkin = fields.date.today() - date_checkout = fields.date.today() + datetime.timedelta(days=1) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": date_checkin, - "checkout": date_checkout, - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "board_service_room_id": board_service_room_type.id, - } - ) - # ASSERT - self.assertEqual( - reservation.service_ids.service_line_ids.date, - date_checkin, - "Date of service line with consumed on 'before' should match checkin date.", - ) - - def test_bs_daily_limit_equal(self): - """ - Create a one day reservation with a board service configured with - daily limit = 2 and capacity = 2 - Reservation should created succesfully. - """ - # ARRANGE - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "daily_limit": 2, - "per_person": True, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": product.id, - "pms_board_service_id": self.board_service.id, - } - ) - board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type.id, - "pms_board_service_id": self.board_service.id, - } - ) - date_checkin = fields.date.today() - date_checkout = fields.date.today() + datetime.timedelta(days=1) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": date_checkin, - "checkout": date_checkout, - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "board_service_room_id": board_service_room_type.id, - } - ) - # ASSERT - self.assertEqual( - reservation.service_ids.service_line_ids.day_qty, - self.room.capacity, - "The reservation should have been created.", - ) - - def test_bs_daily_limit_lower(self): - """ - Create a one day reservation with a board service configured with - daily limit = 2 and capacity = 1 - Reservation should created succesfully. - """ - # ARRANGE - self.room.capacity = 1 - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "daily_limit": 2, - "per_person": True, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": product.id, - "pms_board_service_id": self.board_service.id, - } - ) - board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type.id, - "pms_board_service_id": self.board_service.id, - } - ) - date_checkin = fields.date.today() - date_checkout = fields.date.today() + datetime.timedelta(days=1) - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": date_checkin, - "checkout": date_checkout, - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "board_service_room_id": board_service_room_type.id, - } - ) - # ASSERT - # self.assertTrue(reservation, "The reservation should have been created.") - # ASSERT - self.assertEqual( - reservation.service_ids.service_line_ids.day_qty, - self.room.capacity, - "The reservation should have been created.", - ) - - def test_bs_daily_limit_greater(self): - """ - Create a one day reservation with a board service configured with - daily limit = 1 and capacity = 2 - Reservation creation should fail. - """ - # ARRANGE - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "type": "service", - "daily_limit": 1, - "list_price": 15.0, - "per_person": True, - } - ) - self.env["pms.board.service.line"].create( - { - "product_id": product.id, - "pms_board_service_id": self.board_service.id, - } - ) - board_service_room_type = self.env["pms.board.service.room.type"].create( - { - "pms_room_type_id": self.room_type.id, - "pms_board_service_id": self.board_service.id, - } - ) - date_checkin = fields.date.today() - date_checkout = fields.date.today() + datetime.timedelta(days=1) - # ACT & ASSERT - with self.assertRaises( - ValidationError, msg="Reservation created but it shouldn't" - ): - self.env["pms.reservation"].create( - { - "checkin": date_checkin, - "checkout": date_checkout, - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "board_service_room_id": board_service_room_type.id, - "adults": 2, - } - ) - - # TODO: Review this test - def _test_bs_is_extra_bed(self): - # ARRANGE - product = self.env["product.product"].create( - { - "name": "Product test", - "per_day": True, - "consumed_on": "after", - "is_extra_bed": True, - } - ) - self.room.capacity = 1 - extra_bed_service = self.env["pms.service"].create( - { - "is_board_service": False, - "product_id": product.id, - } - ) - self.room.extra_beds_allowed = 1 - # ACT - reservation = self.env["pms.reservation"].create( - { - "checkin": fields.date.today(), - "checkout": fields.date.today() + datetime.timedelta(days=1), - "room_type_id": self.room_type.id, - "pms_property_id": self.pms_property1.id, - "partner_id": self.partner.id, - "service_ids": [extra_bed_service.id], - } - ) - reservation._check_adults() - reservation.flush() - - # TODO: pending tests (need review) -> per_day, per_person (with board service?) diff --git a/pms/tests/test_shared_room.py b/pms/tests/test_shared_room.py deleted file mode 100644 index 2408805c4..000000000 --- a/pms/tests/test_shared_room.py +++ /dev/null @@ -1,487 +0,0 @@ -import datetime - -from odoo import fields -from odoo.exceptions import ValidationError - -from .common import TestPms - - -class TestPmsSharedRoom(TestPms): - def setUp(self): - super().setUp() - # create a room type availability - self.room_type_availability = self.env["pms.availability.plan"].create( - { - "name": "Availability plan for TEST", - "pms_pricelist_ids": [(6, 0, [self.pricelist1.id])], - } - ) - - self.bed_class = self.env["pms.room.type.class"].create( - { - "name": "Bed Class 1", - "default_code": "B1", - } - ) - - # create room type - self.room_type_test = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Shared Test", - "default_code": "SHT", - "class_id": self.room_type_class1.id, - } - ) - - self.room_type_bed = self.env["pms.room.type"].create( - { - "pms_property_ids": [self.pms_property1.id], - "name": "Bed Type Test", - "default_code": "BTT", - "class_id": self.bed_class.id, - } - ) - - # create shared room - self.room1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Shared 101", - "room_type_id": self.room_type_test.id, - "capacity": 2, - } - ) - - # create beds in room1 - self.r1bed1 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "101 (1)", - "room_type_id": self.room_type_bed.id, - "capacity": 1, - "parent_id": self.room1.id, - } - ) - - self.r1bed2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "101 (2)", - "room_type_id": self.room_type_bed.id, - "capacity": 2, - "parent_id": self.room1.id, - } - ) - - # create partner - self.partner1 = self.env["res.partner"].create( - { - "firstname": "Jaime", - "lastname": "García", - "email": "jaime@example.com", - "birthdate_date": "1983-03-01", - "gender": "male", - } - ) - - def test_count_avail_beds_with_room_occupied(self): - """ - Check that not allow to create a bed reservation with a room occupied - ---------------- - Create a room1 reservation and check that the beds room real avail is 0 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.room1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).availability, - 0, - "Beds avaialbility should be 0 for room occupied", - ) - - def test_count_avail_shared_room_with_one_bed_occupied(self): - """ - Check that not allow to create a shared room reservation with a bed occupied - ---------------- - Create a room1's bed reservation and check that the room1 real avail is 0 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_test.id, - ).availability, - 0, - "Shared Room avaialbility should be 0 if it has a bed occupied", - ) - - def test_avail_in_room_type_with_shared_rooms(self): - """ - Check that a shared room's bed occupied not - affect the avail on other rooms with the - same room type - ---------------- - Create other room like room_type_test (room2) - Create a room1's bed reservation and check that the room1 - Check that room_type_test real avail is 1 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - self.room2 = self.env["pms.room"].create( - { - "pms_property_id": self.pms_property1.id, - "name": "Shared 102", - "room_type_id": self.room_type_test.id, - "capacity": 2, - } - ) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_test.id, - ).availability, - 1, - "Room not shared affect by the shared room's avail with the same type", - ) - - def test_count_avail_beds_with_one_bed_occupied(self): - """ - Check the avail of a bed when it has - a room with other beds occupied - ---------------- - Create a room1's bed (it has 2 beds) - reservation and check that the beds avail = 1 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - res1 = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - res1.flush() - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).availability, - 1, - "Beds avaialbility should be 1 if it has 1 of 2 beds occupied", - ) - - def test_not_avail_beds_with_room_occupied(self): - """ - Check that not allow to select a bed with a room occupied - ---------------- - Create a room1 reservation and check that the beds are not available - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.room1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertNotIn( - self.r1bed1.id, - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).free_room_ids.ids, - "room's bed should not be available " "because the entire room is reserved", - ) - - def test_not_avail_shared_room_with_one_bed_occupied(self): - """ - Check that not allow to select a shared - room with a bed occupied - ---------------- - Create a room1's bed reservation and check - that the room1 real avail is not available - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertNotIn( - self.room1.id, - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).free_room_ids.ids, - "Entire Shared room should not be available " - "becouse it has a bed occupied", - ) - - def test_avail_beds_with_one_bed_occupied(self): - """ - Check the select of a bed when it has a - room with other beds occupied - ---------------- - Create a room1's bed (it has 2 beds) reservation - and check that the other bed is avail - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ASSERT - self.assertIn( - self.r1bed2.id, - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).free_room_ids.ids, - "The bed2 of the shared room should be available", - ) - - def test_not_allowed_reservation_in_bed_with_room_occuppied(self): - """ - Check the constrain that not allow to create a reservation in a bed in a - room with other reservation like shared - ---------------- - Create a room1's reservation and the try to create a reservation - in the room1's bed, we expect an error - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.room1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Reservation created on a bed whose room was already occupied", - ): - r_test = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - r_test.flush() - - def test_not_allowed_reservation_in_shared_room_with_bed_occuppied(self): - """ - Check the constrain that not allow to create a reservation - in a shared room in a bed reservation - ---------------- - Create a room1's bed reservation and the try to create - a reservation in the room1, we expect an error - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - - # ACT & ASSERT - with self.assertRaises( - ValidationError, - msg="Reservation created in a full shared " - "room that already had beds occupied", - ): - r_test = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.room1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - r_test.flush() - - def check_room_shared_availability_released_when_canceling_bed_reservations(self): - """ - Check that check availability in shared room is - released when canceling bed reservations - ---------------- - Create a room1's bed reservation and then cancel it, - check that the room1 real avail is 1 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - r1 = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.r1bed1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - r1.action_cancel() - - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_test.id, - ).availability, - 1, - "The parent room avail dont update " "when cancel child room reservation", - ) - - def check_bed_availability_released_when_canceling_parent_room_reservations(self): - """ - Check that check availability in child room is - released when canceling the parent rooms - ---------------- - Create a room1 reservation and then cancel it, - check that the beds real avail is 2 - """ - - # ARRANGE - today = fields.date.today() - tomorrow = fields.date.today() + datetime.timedelta(days=1) - - # ACT - r1 = self.env["pms.reservation"].create( - { - "partner_id": self.partner1.id, - "preferred_room_id": self.room1.id, - "checkin": today, - "checkout": tomorrow, - "pms_property_id": self.pms_property1.id, - } - ) - r1.action_cancel() - - # ASSERT - self.assertEqual( - self.pms_property1.with_context( - checkin=today, - checkout=tomorrow, - room_type_id=self.room_type_bed.id, - ).availability, - 2, - "The child room avail dont update when " "cancel parent room reservation", - ) diff --git a/pms/views/account_bank_statement_views.xml b/pms/views/account_bank_statement_views.xml deleted file mode 100644 index 331a331db..000000000 --- a/pms/views/account_bank_statement_views.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - account.bank.statement - - - - - - - - diff --git a/pms/views/account_journal_views.xml b/pms/views/account_journal_views.xml deleted file mode 100644 index f787708c8..000000000 --- a/pms/views/account_journal_views.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - account.journal - - - - - - - - - diff --git a/pms/views/account_move_views.xml b/pms/views/account_move_views.xml deleted file mode 100644 index d6fa4eba8..000000000 --- a/pms/views/account_move_views.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - account.move - - - - - - - - - - - - - - diff --git a/pms/views/account_payment_views.xml b/pms/views/account_payment_views.xml deleted file mode 100644 index 161f2b19f..000000000 --- a/pms/views/account_payment_views.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - account.payment - - - - - - - - - diff --git a/pms/views/assets.xml b/pms/views/assets.xml deleted file mode 100644 index 0ff4d6887..000000000 --- a/pms/views/assets.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/pms/views/product_pricelist_item_views.xml b/pms/views/product_pricelist_item_views.xml deleted file mode 100644 index 41e7ebc22..000000000 --- a/pms/views/product_pricelist_item_views.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - product.pricelist.item - - - - - - - - - - - - - - - - - - [('id', 'in',allowed_board_service_product_ids)] - - - - - product.pricelist.item - - - - - - - - - - - - - - - - - Pricelists Items - ir.actions.act_window - product.pricelist.item - {'group_by':'pricelist_id'} - - tree - - diff --git a/pms/views/product_pricelist_views.xml b/pms/views/product_pricelist_views.xml deleted file mode 100644 index ff7870024..000000000 --- a/pms/views/product_pricelist_views.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - product.pricelist - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
- - -
diff --git a/pms/views/product_template_views.xml b/pms/views/product_template_views.xml deleted file mode 100644 index 736533666..000000000 --- a/pms/views/product_template_views.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - view.product.template.form.inherited - product.template - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pms/views/res_company_views.xml b/pms/views/res_company_views.xml deleted file mode 100644 index c06670022..000000000 --- a/pms/views/res_company_views.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - res.company - - - - - - - - - - - - diff --git a/pms/views/res_partner_views.xml b/pms/views/res_partner_views.xml deleted file mode 100644 index 5ab2c6581..000000000 --- a/pms/views/res_partner_views.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - Reservations - pms.reservation - [('folio_id.partner_id', 'in', "TODO: O2m de partner a folios")] - - - Folios - pms.folio - [('partner_id', '=',active_id)] - - - Customers - res.partner - kanban,tree,form - [('is_agency', '=',False)] - - - Agencies - res.partner - kanban,tree,form - [('is_agency', '=',True)] - - - - res.partner.view.form - res.partner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - res.partner.form.data - res.partner - - -
- -
-

- -

-
- - - - - - - - - - - - - - - - - - -
-
- - -
diff --git a/pms/views/res_users_views.xml b/pms/views/res_users_views.xml deleted file mode 100644 index c3799e6aa..000000000 --- a/pms/views/res_users_views.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - res.users - - - - - - - - - - - diff --git a/pms/views/reservation_portal_templates.xml b/pms/views/reservation_portal_templates.xml deleted file mode 100644 index 703fe512c..000000000 --- a/pms/views/reservation_portal_templates.xml +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - - - - diff --git a/pms/views/traveller_report_template.xml b/pms/views/traveller_report_template.xml deleted file mode 100644 index c83630596..000000000 --- a/pms/views/traveller_report_template.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - - diff --git a/pms/views/webclient_templates.xml b/pms/views/webclient_templates.xml deleted file mode 100644 index 61c2147a7..000000000 --- a/pms/views/webclient_templates.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - -