diff --git a/.travis.yml b/.travis.yml index 73d8cbe4b..af5b1191a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,10 +20,11 @@ jobs: include: - stage: test env: - - TESTS=1 ODOO_REPO="odoo/odoo" MAKEPOT="1" + - TESTS=1 ODOO_REPO="odoo/odoo" MAKEPOT="1" OPTIONS="--load + web,multi_pms_properties" - stage: test env: - - TESTS=1 ODOO_REPO="OCA/OCB" + - TESTS=1 ODOO_REPO="OCA/OCB" OPTIONS="--load web,multi_pms_properties" env: global: - VERSION="14.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0" diff --git a/README.md b/README.md index 0b7a4a07e..1422e824e 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,12 @@ Available addons addon | version | summary --- | --- | --- [pms](pms/) | 14.0.1.0.0 | A property management system +[multi_pms_properties](multi_pms_properties/) | 14.0.1.0.0 | Multiproperty support +[pms_housekeeping](pms_housekeeping/) | 14.0.1.0.0 | Housekeeping feature +[pms_l10n_es](pms_l10n_es/) | 14.0.1.0.0 | Spanish localization support +[pms_rooming_xls](pms_rooming_xls/) | 14.0.1.0.0 | Management rooming + + [//]: # (end addons) diff --git a/multi_pms_properties/README.rst b/multi_pms_properties/README.rst new file mode 100644 index 000000000..732d4a153 --- /dev/null +++ b/multi_pms_properties/README.rst @@ -0,0 +1,97 @@ +==================== +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 new file mode 100644 index 000000000..16fb7d2d4 --- /dev/null +++ b/multi_pms_properties/__init__.py @@ -0,0 +1,64 @@ +# 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 new file mode 100644 index 000000000..4c5f81107 --- /dev/null +++ b/multi_pms_properties/__manifest__.py @@ -0,0 +1,17 @@ +# © 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/models.py b/multi_pms_properties/models.py new file mode 100644 index 000000000..a2c0e7050 --- /dev/null +++ b/multi_pms_properties/models.py @@ -0,0 +1,186 @@ +# 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 new file mode 100644 index 000000000..eb93871f1 --- /dev/null +++ b/multi_pms_properties/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* `Commit [Sun] `: + + * Dario Lodeiros + * Eric Antones + * Sara Lago diff --git a/multi_pms_properties/readme/DESCRIPTION.rst b/multi_pms_properties/readme/DESCRIPTION.rst new file mode 100644 index 000000000..d0d40fd9d --- /dev/null +++ b/multi_pms_properties/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..b6b2f665f --- /dev/null +++ b/multi_pms_properties/readme/INSTALL.rst @@ -0,0 +1,7 @@ +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 new file mode 100644 index 000000000..daa058b5f --- /dev/null +++ b/multi_pms_properties/readme/USAGE.rst @@ -0,0 +1,5 @@ +* 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 new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/multi_pms_properties/static/description/icon.png differ diff --git a/multi_pms_properties/static/description/index.html b/multi_pms_properties/static/description/index.html new file mode 100644 index 000000000..51d37f953 --- /dev/null +++ b/multi_pms_properties/static/description/index.html @@ -0,0 +1,444 @@ + + + + + + +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 new file mode 100644 index 000000000..c80a139bc --- /dev/null +++ b/multi_pms_properties/tests/__init__.py @@ -0,0 +1,4 @@ +# 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 new file mode 100644 index 000000000..d4e9e2183 --- /dev/null +++ b/multi_pms_properties/tests/common.py @@ -0,0 +1,20 @@ +# 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 new file mode 100644 index 000000000..eabf61aa1 --- /dev/null +++ b/multi_pms_properties/tests/multi_pms_properties_tester.py @@ -0,0 +1,17 @@ +# 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 new file mode 100644 index 000000000..10f81e022 --- /dev/null +++ b/multi_pms_properties/tests/test_multi_pms_properties.py @@ -0,0 +1,41 @@ +# 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/oca_dependencies.txt b/oca_dependencies.txt index ca3c726ba..f28a53f0f 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -1 +1,2 @@ -# See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt +partner-contact +reporting-engine diff --git a/pms/README.rst b/pms/README.rst index 31c4eee92..c7dc5bd70 100644 --- a/pms/README.rst +++ b/pms/README.rst @@ -25,11 +25,11 @@ PMS (Property Management System) |badge1| |badge2| |badge3| |badge4| |badge5| -This module is an all-in-one property management system (PMS) focused on medium-sized hotels +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 hotel properties with multi-hotel and multi-company support, including your rooms inventory, -reservations, check-in, daily reports, board services, rate and restriction plans among other hotel functionalities. +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. @@ -44,20 +44,20 @@ reservations, check-in, daily reports, board services, rate and restriction plan Installation ============ -This module depends on modules ``base``, ``sale_stock``, ``account_payment_return``, ``partner_firstname``, -and ``account_cancel``. Ensure yourself to have all them in your addons list. +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 Settings > Users & Companies > Hotels > Your Hotel. +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 https://roomdoo.com. +To use this module, please, read the complete user guide at ``_. Bug Tracker =========== @@ -75,18 +75,21 @@ Credits Authors ~~~~~~~ -* Dario Lodeiros -* Alexadre Diaz -* Pablo Quesada -* Jose Luis Algara +* Commit [Sun] Contributors ~~~~~~~~~~~~ -* Dario Lodeiros * Alexandre Díaz * Pablo Quesada * Jose Luis Algara +* `Commit [Sun] `: + + * Dario Lodeiros + * Eric Antones + * Sara Lago + * Brais Abeijon + * Miguel Padin Maintainers ~~~~~~~~~~~ diff --git a/pms/__init__.py b/pms/__init__.py index 22280bdac..a4616f410 100644 --- a/pms/__init__.py +++ b/pms/__init__.py @@ -2,4 +2,5 @@ from . import models from . import wizards -from .init_hook import post_init_hook +from . import controllers +from .init_hook import pre_init_hook diff --git a/pms/__manifest__.py b/pms/__manifest__.py index f27f6e821..859c769f1 100644 --- a/pms/__manifest__.py +++ b/pms/__manifest__.py @@ -8,11 +8,7 @@ "development_status": "Alpha", "category": "Generic Modules/Property Management System", "website": "https://github.com/OCA/pms", - "author": "Dario Lodeiros, " - "Alexadre Diaz, " - "Pablo Quesada, " - "Jose Luis Algara, " - "Odoo Community Association (OCA)", + "author": "Commit [Sun], Odoo Community Association (OCA)", "license": "AGPL-3", "application": True, "installable": True, @@ -23,6 +19,7 @@ # "partner_firstname", # "email_template_qweb", "sale", + "multi_pms_properties", ], "data": [ "security/pms_security.xml", @@ -33,29 +30,33 @@ "report/pms_folio.xml", "report/pms_folio_templates.xml", # "templates/pms_email_template.xml", - "views/general.xml", "data/menus.xml", + "wizards/wizard_payment_folio.xml", + "wizards/folio_make_invoice_advance_views.xml", + "wizards/wizard_folio.xml", + "wizards/wizard_folio_changes.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_floor_views.xml", - "views/pms_folio_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_room_type_restriction_views.xml", - "views/pms_room_type_restriction_item_views.xml", - "views/pms_service_views.xml", - "views/pms_service_line_views.xml", + "views/pms_availability_plan_views.xml", + "views/pms_availability_plan_rule_views.xml", "views/pms_shared_room_views.xml", "views/res_partner_views.xml", "views/product_pricelist_views.xml", @@ -63,8 +64,12 @@ "views/pms_sale_channel.xml", "views/product_template_views.xml", "views/webclient_templates.xml", - "views/ir_sequence_views.xml", - "wizards/wizard_reservation.xml", + "views/account_journal_views.xml", + "views/folio_portal_templates.xml", + "views/reservation_portal_templates.xml", + "wizards/wizard_split_join_swap_reservation.xml", + "wizards/wizard_massive_changes.xml", + "wizards/wizard_advanced_filters.xml", ], "demo": [ "demo/pms_master_data.xml", @@ -73,6 +78,7 @@ ], "qweb": [ "static/src/xml/pms_base_templates.xml", + "static/src/xml/reservation_group_button_views.xml", ], - "post_init_hook": "post_init_hook", + "pre_init_hook": "pre_init_hook", } diff --git a/pms/controllers/__init__.py b/pms/controllers/__init__.py new file mode 100644 index 000000000..52d463f19 --- /dev/null +++ b/pms/controllers/__init__.py @@ -0,0 +1 @@ +from . import pms_portal diff --git a/pms/controllers/pms_portal.py b/pms/controllers/pms_portal.py new file mode 100644 index 000000000..3eeffcd74 --- /dev/null +++ b/pms/controllers/pms_portal.py @@ -0,0 +1,216 @@ +from odoo import _, http +from odoo.exceptions import AccessError, MissingError +from odoo.http import request + +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} + return self._get_page_view_values( + folio, access_token, values, "my_folios_history", False, **kwargs + ) + + @http.route( + ["/my/folios", "/my/folios/page/"], + type="http", + auth="user", + 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="user", 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) + + +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="user", + website=True, + ) + def portal_my_reservations( + 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() + 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="user", + 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") + # for attachment in reservation_sudo.attachment_ids: + # attachment.generate_access_token() + values = self._reservation_get_page_view_values( + reservation_sudo, access_token, **kw + ) + return request.render("pms.portal_my_reservation_detail", values) diff --git a/pms/data/cron_jobs.xml b/pms/data/cron_jobs.xml index 015e40e32..c780b2373 100644 --- a/pms/data/cron_jobs.xml +++ b/pms/data/cron_jobs.xml @@ -15,7 +15,7 @@ name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 09:00:00')" /> - model.auto_no_show() + model.auto_arrival_delayed() @@ -28,7 +28,7 @@ code - model.auto_no_checkout() + model.auto_departure_delayed() diff --git a/pms/data/menus.xml b/pms/data/menus.xml index 4eb21769f..46b5751a4 100644 --- a/pms/data/menus.xml +++ b/pms/data/menus.xml @@ -5,33 +5,48 @@ name="PMS Management" sequence="8" web_icon="pms,static/description/icon.png" - groups="pms.group_pms_user,pms.group_pms_call" /> + + + diff --git a/pms/data/pms_data.xml b/pms/data/pms_data.xml index 7eafee0f0..685754758 100644 --- a/pms/data/pms_data.xml +++ b/pms/data/pms_data.xml @@ -2,14 +2,13 @@ - - Restriction Plan + + Availability Plan My Property - Rua Street Demo, s/n Commitsun city @@ -18,6 +17,8 @@ commitsun@hootel.com https://www.commitsun.com + + diff --git a/pms/data/pms_sequence.xml b/pms/data/pms_sequence.xml index 952b46c00..e0047bc4c 100644 --- a/pms/data/pms_sequence.xml +++ b/pms/data/pms_sequence.xml @@ -1,12 +1,28 @@ - PMS Folio pms.folio - F/ - 5 + F/%(y)s + %(sec)s + 4 + + + + PMS Reservation + pms.reservation + R/%(y)s + %(sec)s + 4 + + + + PMS Checkin + pms.checkin.partner + C/%(y)s + %(sec)s + 4 diff --git a/pms/demo/pms_folio.xml b/pms/demo/pms_folio.xml index a5b48079e..63d8651bc 100644 --- a/pms/demo/pms_folio.xml +++ b/pms/demo/pms_folio.xml @@ -5,6 +5,8 @@ + + + + + + + + + out + + + + + + + + out + + + + + + + + + + normal + + + + normal + + normal + + normal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + Agalia + + + + + + + + Pilgrim Leon + + + + + + + + + + + + + + - + - + - - + + Ground Floor - + First Floor - + Second Floor @@ -32,50 +135,52 @@ 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 + ECO 21.00 Single - SNG + SNG 20.00 Double - DBL + DBL 25.00 Triple - TRP + TRP 35.00 Conference Room - CFR + 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 - - 1 + + 10 + @@ -171,6 +284,7 @@ False True True + after Extra Bed @@ -181,7 +295,6 @@ False 1 True - True Late Check-out @@ -218,16 +331,17 @@ BreakFast + BB - fixed Half Board + HB - fixed FullBoard + FB - fixed - fixed - fixed - + - - fixed - fixed - fixed @@ -297,21 +404,11 @@ Used for closing of rooms for extra privacy. - - - Restriction Plan Demo - - - My pms Demo - - - - Prop. Demo Suite - SUI + SUI 21.00 @@ -319,7 +416,7 @@ Prop. Demo Views - VIE + VIE 20.00 + 1 + + "out" + + 2 @@ -41,34 +46,42 @@ + + 1 + + 2 + + 1 + + 1 @@ -84,9 +97,11 @@ + + 1 @@ -101,62 +116,76 @@ + + 1 + + 1 + + 1 1 + + 1 + + 1 + + 2 + + 2 @@ -169,9 +198,11 @@ /> + + 1 @@ -179,26 +210,32 @@ + + 2 + + 2 + + 2 @@ -211,54 +248,66 @@ /> + + 2 + + 1 1 + + 2 + + 2 + + 3 + + 3 @@ -272,9 +321,11 @@ /> + + 1 @@ -288,9 +339,11 @@ + + 3 @@ -304,9 +357,11 @@ /> + + 2 @@ -328,28 +383,35 @@ + + + + + + + diff --git a/pms/i18n/es.po b/pms/i18n/es.po index 8e101c9fa..7c5aba43a 100644 --- a/pms/i18n/es.po +++ b/pms/i18n/es.po @@ -1,8249 +1,5265 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * hotel +# * pms # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-06-04 19:38+0000\n" -"PO-Revision-Date: 2019-06-04 21:40+0200\n" -"Last-Translator: <>\n" +"POT-Creation-Date: 2021-02-02 09:55+0000\n" +"PO-Revision-Date: 2021-02-08 09:56+0100\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: es\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.3\n" -#. module: hotel -#: model:mail.template,body_html:hotel.mail_template_hotel_cancel +#. module: pms +#: model:room.closure.reason,description:pms.pms_room_closure_reason_1 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" -" \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" -" \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" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" www.aldahotels.com\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Tu reserva se ha cancelado en ${object.company_id.property_name}
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"\n" -"
\n" -"
Hola ${object.partner_id.firstname}
\n" -" Tu reserva en ${object.company_id.property_name} se ha anulado correctamente. No es necesario que hagas nada más.\n" -" Si la cancelación conlleva la devolución de alguna cantidad, nos pondremos en contacto contigo.\n" -" En caso de que tengas alguna duda, estaremos encantados de atenderte.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
Contactar\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Cancelación\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Datos de tu reserva cancelada
\n" -" ${object.partner_id.name}\n" -"
\n" -" % if object.partner_id.contact_address:\n" -" ${object.partner_id.contact_address}
\n" -" % endif\n" -"
\n" -" % for rline in object.get_grouped_reservations_json('cancelled'):\n" -" ${rline['num']} x ${rline['room_type']['name']}\n" -" % if rline['childrens'] > 0:\n" -" (${rline['adults']} Adults + ${rline['childrens']} Childrens)\n" -" % else:\n" -" (${rline['adults']} Adults)\n" -" %endif\n" -" \n" -"
\n" -" Entrada: ${format_tz(rline['checkin'], format=\"%d de %B de %Y\")}
\n" -" Salida: ${format_tz(rline['checkout'], format=\"%d de %B de %Y\")}
\n" -" Nº de noches: ${rline['nights']}

\n" -" % endfor\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Pago\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
IMPORTES
\n" -" Noches: ${len(object.reservation_ids[0].reservation_lines)}
\n" -" Base imponible: ${object.amount_untaxed} €
\n" -" I.V.A (10%): ${object.amount_tax} €
\n" -" Precio total: ${object.amount_total} €
\n" -" Coste de cancelación: [[importe]]
\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" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
NUESTRAS REDES SOCIALES 
\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" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Facebook\"\n" -" \n" -"
Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Dale a Me gusta
\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" -" \n" -" \n" -"
\n" -" \n" -" \"Instagram\"\n" -" \n" -"
Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Twitter\"\n" -" \n" -"
Twitter
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Esperamos verte pronto!
\n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico, así como de la Ley Orgánica 15/1999 del 13 de Diciembre de Protección de Datos de Carácter Personal y demás legislación concordante, se le informa que sus datos personales figuran en un fichero automatizado cuya responsabilidad es de ALDA COMPOSTELA S.L. Praza da Algalia de Arriba, 3 C.P. 15704 Santiago de Compostela. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y solo serán utilizados para los fines propios de nuestra actividad. Para ejercer sus derechos de acceso, rectificación, cancelación u oposición debe enviar un correo electrónico a info@aldahotels.com indicándonos la opción a realizar. Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" +" Used for closing of rooms for extra privacy.\n" " " msgstr "" "\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" -" \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" -" \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" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" www.aldahotels.com\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Tu reserva se ha cancelado en ${object.company_id.property_name}
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"\n" -"
\n" -"
Hola ${object.partner_id.firstname}
\n" -" Tu reserva en ${object.company_id.property_name} se ha anulado correctamente. No es necesario que hagas nada más.\n" -" Si la cancelación conlleva la devolución de alguna cantidad, nos pondremos en contacto contigo.\n" -" En caso de que tengas alguna duda, estaremos encantados de atenderte.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
Contactar\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Cancelación\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Datos de tu reserva cancelada
\n" -" ${object.partner_id.name}\n" -"
\n" -" % if object.partner_id.contact_address:\n" -" ${object.partner_id.contact_address}
\n" -" % endif\n" -"
\n" -" % for rline in object.get_grouped_reservations_json('cancelled'):\n" -" ${rline['num']} x ${rline['room_type']['name']}\n" -" % if rline['childrens'] > 0:\n" -" (${rline['adults']} Adults + ${rline['childrens']} Childrens)\n" -" % else:\n" -" (${rline['adults']} Adults)\n" -" %endif\n" -" \n" -"
\n" -" Entrada: ${format_tz(rline['checkin'], format=\"%d de %B de %Y\")}
\n" -" Salida: ${format_tz(rline['checkout'], format=\"%d de %B de %Y\")}
\n" -" Nº de noches: ${rline['nights']}

\n" -" % endfor\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Pago\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
IMPORTES
\n" -" Noches: ${len(object.reservation_ids[0].reservation_lines)}
\n" -" Base imponible: ${object.amount_untaxed} €
\n" -" I.V.A (10%): ${object.amount_tax} €
\n" -" Precio total: ${object.amount_total} €
\n" -" Coste de cancelación: [[importe]]
\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" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
NUESTRAS REDES SOCIALES 
\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" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Facebook\"\n" -" \n" -"
Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Dale a Me gusta
\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" -" \n" -" \n" -"
\n" -" \n" -" \"Instagram\"\n" -" \n" -"
Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Twitter\"\n" -" \n" -"
Twitter
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Esperamos verte pronto!
\n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico, así como de la Ley Orgánica 15/1999 del 13 de Diciembre de Protección de Datos de Carácter Personal y demás legislación concordante, se le informa que sus datos personales figuran en un fichero automatizado cuya responsabilidad es de ALDA COMPOSTELA S.L. Praza da Algalia de Arriba, 3 C.P. 15704 Santiago de Compostela. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y solo serán utilizados para los fines propios de nuestra actividad. Para ejercer sus derechos de acceso, rectificación, cancelación u oposición debe enviar un correo electrónico a info@aldahotels.com indicándonos la opción a realizar. Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_product_variant_count +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_count msgid "# Product Variants" -msgstr "# Variantes de producto" +msgstr "Variantes del Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sales_count -msgid "# Sales" -msgstr "# Ventas" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_count -msgid "# of Orders" -msgstr "# de Pedidos" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_penalty_late +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__penalty_late msgid "% Penalty Late" -msgstr "% Penalización cancelación tarde" +msgstr "% Penalización por cancelación fuera de tiempo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_penalty_noshow +#. 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: hotel -#: code:addons/hotel/models/hotel_service_line.py:70 +#. module: pms +#: code:addons/pms/models/pms_service_line.py:0 #, python-format msgid "%s limit exceeded for %s" -msgstr "%s limite excedido por %s" +msgstr "%s límite excedido por %s" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:658 +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 #, python-format -msgid "%s people do not fit in this room! ;)" -msgstr "%s personas no caben en esta habitación!" +msgid "%s not found in checkins (%s)" +msgstr "%s no encontrado en los checkins (%s)" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "&nbsp;on&nbsp;" -msgstr "&nbsp;en&nbsp;" +#. module: pms +#: code:addons/pms/models/pms_reservation_line.py:0 +#, python-format +msgid "%s: No room available." +msgstr "%s: Habitación no disponible." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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.report_folio_document msgid "" -"Cancelled Reservation!\n" -" Reserva cancelada!\n" -" Invoices" -msgstr "Factura" +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 +#, python-format +msgid "'%s' is not a valid phone" +msgstr "'%s' no es un teléfono válido" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Pending Checks" -msgstr "Checkins Pendientes" +#. module: pms +#: model:ir.actions.report,print_report_name:pms.action_report_folio +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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "" +"\n" +" Cancelled Reservation!\n" +" \n" +" \n" +" ¡Reserva Cancelada!\n" +" \n" +" \n" -" ${rline['num']} x ${rline['room_type']['name']}\n" -" % if rline['childrens'] == 0:\n" -" (${rline['adults']} Adultos)\n" -" % else:\n" -" (${rline['adults']} Adultos + ${rline['childrens']} Niños)\n" -" % endif\n" -"
\n" -" \n" -" Entrada: ${format_tz(rline['checkin']+ ' 00:00:00', format=\"%d de %B de %Y\")}
\n" -" Salida: ${format_tz(rline['checkout']+ ' 00:00:00', format=\"%d de %B de %Y\")}
\n" -" Nº de noches: ${rline['nights']}

\n" -"\n" -" % endfor\n" -"\n" -"
\n" -"

Información importante

\n" -"\t\t\t\t\tEn caso de cancelar tu reserva, podrás hacerlo de manera gratuita hasta las 23:59 horas del día anterior a tu llegada.\n" -"\t\t\t\t\t
Esta reserva está sujeta al pago de la primera noche antes de las 15:00 h del día de entrada. En caso que la tarjeta no sea válida, nos pondremos en contacto contigo para que nos facilites un nuevo método de pago. De no poder verificar correctamente la tarjeta, tu reserva podrá ser cancelada.
\n" -"\t\t\t\t En reservas con tarifas no reembolsables no se podrá ni cancelar ni modificar, por ello no se reembolsará el dinero. En este tipo de tarifas, se procederá a cargar el importe total de la reserva en el momento de su confirmación, en la tarjeta facilitada. \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" -" \n" -" \n" -" \n" -" \n" -"
Mapa
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Ver\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Importes\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
IMPORTES
\n" -" Noches: ${object.get_grouped_reservations_json('confirm')|sum(attribute='nights')}\n" -"
\n" -" Base imponible: ${object.amount_untaxed} €
\n" -" I.V.A (10%): ${object.amount_tax} €
\n" -" Precio total: ${object.amount_total} €
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Habitacion\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
Información de la\n" -" habitación
\n" -" % set room_type_ids = object.reservation_ids.filtered('to_send').mapped('room_type_id.id')\n" -" % set room_types = user.env['hotel.room.type'].browse(room_type_ids)\n" -" % for room_type in room_types:\n" -"\n" -" % if room_type.product_id.name:\n" -"
\n" -" ${room_type.product_id.name}\n" -"
\n" -" % else:\n" -"
\n" -" Habitación ${loop.index}\n" -"
\n" -" % endif\n" -"
\n" -" Esta habitación cuenta con TV, Wi-Fi gratuita, calefacción y baño privado.\n" -"
\n" -" % endfor\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Información\n" -" adicional
\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" -" \"Coche\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cómo acceder
\n" -" En coche\n" -"
\n" -"

\n" -"
\n" -" Pulse en este enlace,\n" -" para\n" -" conocer como llegar desde su ubicación actual\n" -"

\n" -"\n" -"

Si vienes en coche, podrás aparcar en los alrededores del hotel, aunque cuentan con zona azul, de lunes a viernes, de 10:00 a 14:00 h y de 16:00 a 20:00 h. Los sábados de 10:00 a 14:00 h. También disponemos de convenio con un parking en la misma calle del hotel.

\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Bus\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cómo acceder
\n" -" En autobús o tren\n" -"
Si vienes en autobús, la mayoría de líneas tienen parada en la Plaza de Galicia. Una vez en esta parada, el hotel se cuentra a 5 minutos andando.
\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" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
${object.company_id.city}
Ciudad declarada Patrimonio de la Humanidad por la UNESCO y meta de una milenaria ruta de peregrinación: el Camino de Santiago.
\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" -"
\n" -" \"\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
${object.company_id.property_name}
El Hotel Alda San Carlos cuenta con una ubicación privilegiada. Situado frente al Parlamento de Galicia, está a un paso de la zona comercial y de compras; y a 300 metros de la zona monumental, donde se encuentran la Catedral de Santiago, la Praza do Obradoiro o la Praza da Quintana.
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
NUESTRAS REDES SOCIALES
\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Facebook\"\n" -" \n" -"
\n" -" Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Dale\n" -" a Me gusta
\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" -" \n" -" \n" -"
\n" -" \n" -" \"Instagram\"\n" -" \n" -"
\n" -" Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Twitter\"\n" -" \n" -"
\n" -" Twitter
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por\n" -" alojarte\n" -" con nosotros!
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
“En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico (LSSI-CE), así como lo dispuesto en el Reglamento General de Protección de Datos y demás legislación concordante, le informamos de que sus datos personales figuran en un sistema de tratamiento automatizado cuya responsabilidad es de Alda Compostela S.L., con dirección postal a efecto de notificación en PLAZA DE ALGALIA DE ARRIBA, Nº 3 – 15704 SANTIAGO DE COMPOSTELA. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y serán tratados con la finalidad de atender su solicitud de información o contacto, así como mantenerle informado de nuestros productos y servicios, actuales o futuros. Los datos no se cederán a terceros salvo en los casos en que exista una obligación legal. Para ejercer sus derechos de acceso, rectificación, cancelación, oposición, limitación, supresión y/o portabilidad debe enviar un correo electrónico a protecciondatos@aldahotels.com” “Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.”
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"ECO\"\n" -" Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" " +"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 "" -"\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" -" \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" -" \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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" www.aldahotels.com\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Confirmación de reserva\n" -" en\n" -" ${object.company_id.property_name}
\n" -"

__

\n" -"
Hola ${object.partner_id.firstname}
\n" -" Tu reserva en ${object.company_id.property_name} queda confirmada. Te esperamos el día ${object.reservation_ids[0].checkin[8:10]} del ${object.reservation_ids[0].checkin[5:7]} de\n" -" ${object.reservation_ids[0].checkin[0:4]}. Si podemos ayudarte en cualquier tipo de gestión, no dudes en hacérnoslo saber.
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
Contactar\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" -" \n" -" \n" -" \n" -" \n" -"
¿Llegarás más\n" -" tarde de las 17:00 horas?
\n" -"

__

\n" -"
En ese caso te rogamos que te pongas en contacto con nosotros para facilitarte las instrucciones\n" -" necesarias.
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Contactar\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" -" Servicios
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Info\"\n" -" Información turística
\n" -" \"Wifi\"\n" -" Wi-Fi gratuito
\n" -" \"Restauracion\"\n" -" Desayunos
\n" -" \"Parking\"\n" -" Parking concertado
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Datos de tu\n" -" reserva
\n" -" ${object.partner_id.name}\n" -"
\n" -" % if object.partner_id.contact_address:\n" -" ${object.partner_id.contact_address}
\n" -" % endif\n" -" % if object.partner_id.phone:\n" -" Tel.: ${object.partner_id.phone}
\n" -" % endif\n" -" % if object.partner_id.mobile:\n" -" Mov.: ${object.partner_id.mobile}
\n" -" % endif\n" -"
\n" -" % for rline in object.get_grouped_reservations_json('confirm'):\n" -" \n" -" ${rline['num']} x ${rline['room_type']['name']}\n" -" % if rline['childrens'] == 0:\n" -" (${rline['adults']} Adultos)\n" -" % else:\n" -" (${rline['adults']} Adultos + ${rline['childrens']} Niños)\n" -" % endif\n" -"
\n" -"
\n" -" Entrada: ${format_tz(rline['checkin']+ ' 00:00:00', format=\"%d de %B de %Y\")}
\n" -" Salida: ${format_tz(rline['checkout']+ ' 00:00:00', format=\"%d de %B de %Y\")}
\n" -" Nº de noches: ${rline['nights']}

\n" -"\n" -" % endfor\n" -"\n" -"
\n" -"

Información importante

\n" -"\t\t\t\t\tEn caso de cancelar tu reserva, podrás hacerlo de manera gratuita hasta las 23:59 horas del día anterior a tu llegada.\n" -"\t\t\t\t\t
Esta reserva está sujeta al pago de la primera noche antes de las 15:00 h del día de entrada. En caso que la tarjeta no sea válida, nos pondremos en contacto contigo para que nos facilites un nuevo método de pago. De no poder verificar correctamente la tarjeta, tu reserva podrá ser cancelada.
\n" -"\t\t\t\t En reservas con tarifas no reembolsables no se podrá ni cancelar ni modificar, por ello no se reembolsará el dinero. En este tipo de tarifas, se procederá a cargar el importe total de la reserva en el momento de su confirmación, en la tarjeta facilitada.
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Mapa
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Ver\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" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Importes\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
IMPORTES
\n" -" Noches: ${object.get_grouped_reservations_json('confirm')|sum(attribute='nights')}\n" -"
\n" -" Base imponible: ${object.amount_untaxed} €
\n" -" I.V.A (10%): ${object.amount_tax} €
\n" -" Precio total: ${object.amount_total} €
\n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Habitacion\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
Información de la\n" -" habitación
\n" -" % set room_type_ids = object.reservation_ids.filtered('to_send').mapped('room_type_id.id')\n" -" % set room_types = user.env['hotel.room.type'].browse(room_type_ids)\n" -" % for room_type in room_types:\n" -"\n" -" % if room_type.product_id.name:\n" -"
\n" -" ${room_type.product_id.name}\n" -"
\n" -" % else:\n" -"
\n" -" Habitación ${loop.index}\n" -"
\n" -" % endif\n" -"
\n" -" Esta habitación cuenta con TV, Wi-Fi gratuita, calefacción y baño privado.\n" -"
\n" -" % endfor\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" -"
Información\n" -" adicional
\n" -" \n" -" \n" -"

__

\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Coche\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cómo acceder
\n" -" En coche\n" -"
\n" -"

\n" -"
\n" -" Pulse en este enlace,\n" -" para\n" -" conocer como llegar desde su ubicación actual\n" -"

\n" -"\n" -"

Si vienes en coche, podrás aparcar en los alrededores del hotel, aunque cuentan con zona azul, de lunes a viernes, de 10:00 a 14:00 h y de 16:00 a 20:00 h. Los sábados de 10:00 a 14:00 h. También disponemos de convenio con un parking en la misma calle del hotel.

\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"Bus\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cómo acceder
\n" -" En autobús o tren\n" -"
Si vienes en autobús, la mayoría de líneas tienen parada en la Plaza de Galicia. Una vez en esta parada, el hotel se cuentra a 5 minutos andando.
\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
${object.company_id.city}
Ciudad declarada Patrimonio de la Humanidad por la UNESCO y meta de una milenaria ruta de peregrinación: el Camino de Santiago.
\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" -"
\n" -" \"\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
${object.company_id.property_name}
El Hotel Alda San Carlos cuenta con una ubicación privilegiada. Situado frente al Parlamento de Galicia, está a un paso de la zona comercial y de compras; y a 300 metros de la zona monumental, donde se encuentran la Catedral de Santiago, la Praza do Obradoiro o la Praza da Quintana.
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
NUESTRAS REDES SOCIALES
\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" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Facebook\"\n" -" \n" -"
\n" -" Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Dale\n" -" a Me gusta
\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" -" \n" -" \n" -"
\n" -" \n" -" \"Instagram\"\n" -" \n" -"
\n" -" Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \"Twitter\"\n" -" \n" -"
\n" -" Twitter
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"\n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por\n" -" alojarte\n" -" con nosotros!
\n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
“En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico (LSSI-CE), así como lo dispuesto en el Reglamento General de Protección de Datos y demás legislación concordante, le informamos de que sus datos personales figuran en un sistema de tratamiento automatizado cuya responsabilidad es de Alda Compostela S.L., con dirección postal a efecto de notificación en PLAZA DE ALGALIA DE ARRIBA, Nº 3 – 15704 SANTIAGO DE COMPOSTELA. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y serán tratados con la finalidad de atender su solicitud de información o contacto, así como mantenerle informado de nuestros productos y servicios, actuales o futuros. Los datos no se cederán a terceros salvo en los casos en que exista una obligación legal. Para ejercer sus derechos de acceso, rectificación, cancelación, oposición, limitación, supresión y/o portabilidad debe enviar un correo electrónico a protecciondatos@aldahotels.com” “Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.”
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \"ECO\"\n" -" Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -"
\n" -" \n" -"
\n" -"
" +"Descripción del producto que quiere comunicarle a sus clientes. Esta descripción será copiada en " +"todas las órdenes de venta, órdenes de entrega y Facturas del Cliente" -#. module: hotel -#: model:mail.template,body_html:hotel.mail_template_hotel_exit +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__description_sale 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" -" \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" -" \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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
www.aldahotels.com\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por tu visita!\n" -"
\n" -"

__

\n" -"
Hola ${object.partner_id.firstname},
\n" -" Esperamos que hayas disfrutado de la ciudad, y que muy especialmente te hayas sentido a gusto en nuestro alojamiento. Todo el equipo de ${object.company_id.property_name} te agradece tu estancia en nuestro centro y te desea un feliz regreso.
\n" -" Recibe un cordial saludo y esperamos volver a verte.
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Disfruta de tu descuento de cliente\n" -"
\n" -"

__

\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Solo por ser cliente de Alda Hotels disfruta, automáticamente, de hasta un 10% de descuento en cualquiera de nuestros establecimientos, totalmente transferible y sin fecha de caducidad.
\n" -"
\n" -"
\n" -" \"Descuento\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" -"
¿Tienes algo que comentarnos?\n" -"
\n" -"

__

\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cada día intentamos dar un mejor servicio, es por ello que si quieres aportar alguna propuesta o crítica constructiva, te invitamos a utilizar el siguiente formulario. Estamos encantados de recibir tus propuestas. Todas serán leídas y tenidas en cuenta, y atenderemos aquellas que nos permitan nuestros medios y posibilidades.
\n" -"
\n" -" \n" -" \n" -"
Entrar al formulario ▶\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" -" \"Localización\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
nuestros alojamientos
Descubre dónde estamos\n" -"
Estamos presentes a lo largo del territorio peninsular. Si quieres saber dónde puedes alojarte con nosotros, pincha en el mapa.
\n" -"
\n" -"
\n" -" \"Mapa\"\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" -" \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" -" \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" -"
NUESTRAS REDES SOCIALES\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\"Facebook\"\n" -"
Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"\n" -" \n" -"
Dale a Me gusta
\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" -" \n" -" \n" -"
\"Instagram\"\n" -"
Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\"Twitter\"\n" -"
Twitter\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por alojarte con nosotros!\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico, así como de la Ley Orgánica 15/1999 del 13 de Diciembre de Protección de Datos de Carácter Personal y demás legislación concordante, se le informa que sus datos personales figuran en un fichero automatizado cuya responsabilidad es de ALDA COMPOSTELA S.L. Praza da Algalia de Arriba, 3 C.P. 15704 Santiago de Compostela. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y solo serán utilizados para los fines propios de nuestra actividad. Para ejercer sus derechos de acceso, rectificación, cancelación u oposición debe enviar un correo electrónico a info@aldahotels.com indicándonos la opción a realizar. Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -"
\n" -" \n" -"
\n" -"
" +"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 "" -"\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" -" \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" -" \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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
www.aldahotels.com\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por tu visita!\n" -"
\n" -"

__

\n" -"
Hola ${object.partner_id.firstname},
\n" -" Esperamos que hayas disfrutado de la ciudad, y que muy especialmente te hayas sentido a gusto en nuestro alojamiento. Todo el equipo de ${object.company_id.property_name} te agradece tu estancia en nuestro centro y te desea un feliz regreso.
\n" -" Recibe un cordial saludo y esperamos volver a verte.
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Disfruta de tu descuento de cliente\n" -"
\n" -"

__

\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Solo por ser cliente de Alda Hotels disfruta, automáticamente, de hasta un 10% de descuento en cualquiera de nuestros establecimientos, totalmente transferible y sin fecha de caducidad.
\n" -"
\n" -"
\n" -" \"Descuento\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" -"
¿Tienes algo que comentarnos?\n" -"
\n" -"

__

\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Cada día intentamos dar un mejor servicio, es por ello que si quieres aportar alguna propuesta o crítica constructiva, te invitamos a utilizar el siguiente formulario. Estamos encantados de recibir tus propuestas. Todas serán leídas y tenidas en cuenta, y atenderemos aquellas que nos permitan nuestros medios y posibilidades.
\n" -"
\n" -" \n" -" \n" -"
Entrar al formulario ▶\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" -" \"Localización\"\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
nuestros alojamientos
Descubre dónde estamos\n" -"
Estamos presentes a lo largo del territorio peninsular. Si quieres saber dónde puedes alojarte con nosotros, pincha en el mapa.
\n" -"
\n" -"
\n" -" \"Mapa\"\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" -" \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" -" \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" -"
NUESTRAS REDES SOCIALES\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" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\"Facebook\"\n" -"
Facebook
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Toda la actualidad de nuestros alojamientos, así como ofertas y promociones.
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"\n" -" \n" -"
Dale a Me gusta
\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" -" \n" -" \n" -"
\"Instagram\"\n" -"
Instagram
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Cada detalle cuenta, y es por eso que tratamos de reflejarlo en nuestras fotos.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
#Entra\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" -" \n" -" \n" -" \n" -"
\"Twitter\"\n" -"
Twitter\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
 \n" -"
\n" -"
Propuestas al minuto para hacer de tu viaje una experiencia inmejorable.\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -" \n" -"
Síguenos\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
¡Muchas gracias por alojarte con nosotros!\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -"
\n" -" \"Alda\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
En cumplimiento de la Ley 34/2002 de Servicios de la Sociedad de la Información y del Comercio Electrónico, así como de la Ley Orgánica 15/1999 del 13 de Diciembre de Protección de Datos de Carácter Personal y demás legislación concordante, se le informa que sus datos personales figuran en un fichero automatizado cuya responsabilidad es de ALDA COMPOSTELA S.L. Praza da Algalia de Arriba, 3 C.P. 15704 Santiago de Compostela. Los datos personales que existen en nuestro poder están protegidos por nuestra Política de Privacidad y solo serán utilizados para los fines propios de nuestra actividad. Para ejercer sus derechos de acceso, rectificación, cancelación u oposición debe enviar un correo electrónico a info@aldahotels.com indicándonos la opción a realizar. Este correo podría ser confidencial. Si recibe este e-mail por error, por favor elimínelo, así como cualquier documento adjunto, y notifíquelo a su emisor. Si usted no es el destinatario del mensaje, sepa que no está permitida ninguna difusión, copia o utilización no autorizada.
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Antes de imprimir este mensaje, compruebe que es verdaderamente necesario. El medioambiente es cosa de todos. \n" -"
\n" -"
\n" -" \n" -"
\n" -"
" +"Descripción del Producto que quiere comunicarle a sus clientes. La descripción será copiada a todas " +"las Órdenes de Venta, Órdenes de Entrega y Facturas del Cliente" -#. module: hotel -#: code:addons/hotel/models/hotel_checkin_partner.py:132 -#, python-format -msgid "A Checkin Guest is configured like a company, modify it in contact form if its a mistake" -msgstr "Uno de los huéspedes en el checkin está configurado como compañía, modifícalo en su ficha de contacto si es un error (no se pueden hacer checkin a compañías)" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_description_sale -#: model:ir.model.fields,help:hotel.field_hotel_shared_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 "Descripción que quieras comunicar a tus cleintes. Este descripción será copiada en los pedidos de venta, y otros documentos de cliente" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_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 "Una descripción del producto que quiera comunicar a sus clientes. Esta descripción se copiará a cada pedido de venta, albarán de salida y factura de cliente." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_description_purchase -msgid "A description of the Product that you want to communicate to your vendors. This description will be copied to every Purchase Order, Receipt and Vendor Bill/Credit Note." -msgstr "Una descripción del producto que quiere comunicar a sus proveedores. Esta descripción se reflejará en todos los pedidos de compra, recibos y facturas de proveedor." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_description -msgid "A precise description of the Product, used only for internal information purposes." -msgstr "Una descripción precisa del producto, usada sólo para propósitos de información interna." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_type +#. module: pms +#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__advance_payment_method msgid "" -"A stockable product is a product for which you manage stock. The \"Inventory\" app has to be installed.\n" -"A consumable product, on the other hand, is a product for which stock is not managed.\n" -"A service is a non-material product you provide.\n" -"A digital content is a non-material product you sell online. The files attached to the products are the one that are sold on the e-commerce such as e-books, music, pictures,... The \"Digital Product\" module has to be installed." +"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 "" -"Un producto almacenable es un producto para el que usted gestiona el stock. La aplicación \"Inventario\" debe instalarse.\n" -"Por el contrario, un producto consumible es un producto para el que no se gestiona el stock.\n" -"Un servicio es un producto no material que usted proporciona.\n" -"Un contenido digital es un producto no material que vende en línea. Los archivos adjuntos a los productos son los que se venden en el comercio electrónico, tales como libros electrónicos, música, fotos, ... El módulo \"Producto Digital\" debe instalado." +"Se emite una factura estándar con todas las líneas del pedido listas para facturar, de acuerdo con " +"su política de facturación (en función de la cantidad pedida o entregada)." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_deposit_account_id +#. 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 "" +"Un producto almacenado es un producto para el que se gestiona su stock. La aplicación del " +"inventario debe estar instalada.\n" +"Un producto consumible es un producto cuyo stock no se gestiona.\n" +"Un servicio es un producto no material que proporciona." + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__user_ids +msgid "Accepted Users" +msgstr "Usuarios Aceptados" + +#. module: pms +#: 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 "Aviso de Acceso" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__property_account_payable_id +msgid "Account Payable" +msgstr "Cuenta por Pagar" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__property_account_receivable_id +msgid "Account Receivable" +msgstr "Cuenta por Cobrar" + +#. module: pms +#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deposit_account_id msgid "Account used for deposits" -msgstr "Cuenta utilizada para los depósitos" +msgstr "Cuenta Utilizada para Depósitos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_needaction +#. 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 "Acción requerida" +msgstr "Acción Necesaria" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_checkin_partner +#. module: pms +#: model:ir.actions.act_window,name:pms.action_checkin_partner msgid "Action checkin" -msgstr "Acción Checkin" +msgstr "Acción de checkin" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_active -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_active -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_active -#: model:ir.model.fields,field_description:hotel.field_hotel_room_active -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_active -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_active -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_active -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_active +#. 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_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_availability_plan__active +#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__active +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__active msgid "Active" msgstr "Activo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__active_lang_count +msgid "Active Lang Count" +msgstr "Recuento de Idiomas Activos" + +#. 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 "Actividades" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -msgid "Add Folios" -msgstr "Añadir Fichas" +#. 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 "Activity Exception Decoration" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_company_additional_hours -msgid "Additional Hours" -msgstr "Horas adicionales" +#. 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 "Estado de la actividad" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Address" -msgstr "Dirección" +#. 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 "Activity Type Icon" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_adults -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_adults +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "Add a note" +msgstr "Añadir Una Nota" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "Add a product" +msgstr "Añadir Un Producto" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "Add a section" +msgstr "Añadir Una Sección" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__additional_info +msgid "Additional info" +msgstr "Información adicional" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__type +msgid "Address Type" +msgstr "Tipo de Dirección" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__adults msgid "Adults" msgstr "Adultos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_advance_inv_id -msgid "Advance Inv" -msgstr "Facturar adelanto" +#. 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 "Filtros Avanzados" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:246 -#, python-format -msgid "Advance: %s" -msgstr "Importe: %s" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard +msgid "Advanced filters" +msgstr "Filtros Avanzados" -#. module: hotel -#: selection:product.template,consumed_on:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__product_template__consumed_on__after msgid "After night" msgstr "Después de la noche" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -msgid "Agencia" +#. module: pms +#: 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 "Agencia" -#. module: hotel -#: selection:hotel.cancelation.rule,apply_on_late:0 -#: selection:hotel.cancelation.rule,apply_on_noshow:0 +#. 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 "Todos los días" +msgstr "Todos los Días" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:393 +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "All days" +msgstr "Todos los Días" + +#. 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 "Todos los emails y documentos enviados a este contacto van a ser traducidos a este idioma." + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__allowed_method_ids +msgid "Allowed Method" +msgstr "Método Permitido" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__allowed_pricelist_ids +msgid "Allowed Pricelist" +msgstr "Tarifa Permitida" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity__allowed_property_ids +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__allowed_property_ids +#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__allowed_property_ids +#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form +msgid "Allowed Properties" +msgstr "Propiedades Permitidas" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__allowed_room_ids +#: model:ir.model.fields,field_description:pms.field_pms_reservation_wizard__allowed_rooms +msgid "Allowed Rooms" +msgstr "Habitaciones Permitidas" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room__allowed_property_ids +msgid "Allowed properties" +msgstr "Propiedades permitidas" + +#. module: pms +#: code:addons/pms/models/pms_room_type.py:0 #, python-format -msgid "All Folios must hace the same pricelist" -msgstr "Todas las fichas deben tener la mis tarifa" +msgid "Already exists another room type with the same code and properties" +msgstr "Ya existe otro tipo de habitación con el mismo código y las mismas propiedades" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_action_hotel_room_amenity_view_form +#. module: pms +#: model:ir.ui.menu,name:pms.menu_action_pms_room_amenity_view_form msgid "Amenities" -msgstr "Características" +msgstr "Instalaciones" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_amenity_type +#. module: pms +#: model:ir.model,name:pms.model_pms_amenity_type msgid "Amenities Type" -msgstr "Tipo de Característica" +msgstr "Tipo de Instalaciones" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_room_amenity_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__room_amenity_ids msgid "Amenities in this category" -msgstr "Características en esta categoría" +msgstr "Instalaciones en esta categoría" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_amenity -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form +#. 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 "Características" +msgstr "Instalación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_room_amenity_type_id -msgid "Amenity Catagory" -msgstr "Categoría" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity__room_amenity_type_id +msgid "Amenity Category" +msgstr "Categoría de la instalación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_name -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_name -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity__name msgid "Amenity Name" -msgstr "Nombre" +msgstr "Nombre de la instalación" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_amenity_type_view_form +#. module: pms +#: 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 "Tipo de categoría" +msgstr "Tipo de la instalación" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_action_hotel_room_amenity_type_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity_type__name +msgid "Amenity Type Name" +msgstr "Nombre del Tipo de la instalación" + +#. module: pms +#: model:ir.ui.menu,name:pms.menu_action_pms_room_amenity_type_view_form msgid "Amenity Types" -msgstr "Tipos de categoría" +msgstr "Tipos de Instalación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_amount -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_amount -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_amount -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_amount -#: model:ir.ui.view,arch_db:hotel.account_payment_view_tree_folio -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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 +#: model_terms:ir.ui.view,arch_db:pms.report_folio_document msgid "Amount" -msgstr "Importe" +msgstr "Cantidad" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:69 +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Amount from %s to %s %s \n" -msgstr "Importe de %s a %s %s \n" +msgstr "Cantidad deste %s hasta %s %s\n" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Amounts" msgstr "Cantidades" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_analytic_account_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__analytic_account_id msgid "Analytic Account" -msgstr "Cuenta analítica" +msgstr "Cuenta Analítica" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_analytic_tag_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_analytic_tag_ids +#. 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 "Etiquetas Analíticas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_applied_on -msgid "Applied On" -msgstr "Aplicad en" +#. 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 "Líneas Analíticas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Arriva Hour" -msgstr "Hora Llegada" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "Applicable on" +msgstr "Aplicable en" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_real_checkin -msgid "Arrival" -msgstr "Llegada" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_invoice_filter_days_form +msgid "Apply" +msgstr "Aplicar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_arrival_hour -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_arrival_hour +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_all_week +msgid "Apply Availability Rule for the whole week" +msgstr "Aplicar Regla de Disponibilidad Para Toda la semana" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_friday +msgid "Apply Availability Rule on fridays" +msgstr "Aplicar Regla de Disponibilidad los viernes" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_monday +msgid "Apply Availability Rule on mondays" +msgstr "Aplicar Regla de Disponibilidad los lunes" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_saturday +msgid "Apply Availability Rule on saturdays" +msgstr "Aplicar Regla de Disponibilidad los sábados" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_sunday +msgid "Apply Availability Rule on sundays" +msgstr "Aplicar Regla de Disponibilidad los domingos" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_thursday +msgid "Apply Availability Rule on thursdays" +msgstr "Aplicar Regla de Disponibilidad los jueves" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_tuesday +msgid "Apply Availability Rule on tuesdays" +msgstr "Aplicar Regla de Disponibilidad los martes" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__apply_on_wednesday +msgid "Apply Availability Rule on wednesdays" +msgstr "Aplicar Regla de Disponibilidad los miércoles" + +#. 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 "Aplicar Tarifa" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "Apply changes" +msgstr "Aplicar Cambios" + +#. module: pms +#: 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 "Hora de llegada" +msgstr "Hora de Llegada" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -msgid "Articles" -msgstr "Artículos" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__default_arrival_hour +msgid "Arrival Hour (GMT)" +msgstr "Hora de Llegada (GMT)" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_floor_id -#: model:ir.model.fields,help:hotel.field_hotel_shared_room_floor_id -msgid "At which floor the room is located." -msgstr "En qué piso está ubicada la habitación." +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room__ubication_id +#: model:ir.model.fields,help:pms.field_pms_shared_room__ubication_id +msgid "At which ubication the room is located." +msgstr "Ubicación en la que está localizada la habitación." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_attribute_value_ids -msgid "Attributes" -msgstr "Atributos" +#. 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 "Nº de adjuntos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_auto_invoice -msgid "Auto Payment Invoice" -msgstr "Auto Payment Invoice" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_template_attribute_value_ids +msgid "Attribute Values" +msgstr "Valores del Atributo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_preconfirm +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__preconfirm msgid "Auto confirm to Save" -msgstr "Auto confirmar al Guardar" +msgstr "Guardar Automáticamente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_autoassign -msgid "Autoassign" -msgstr "Autoasignar" - -#. module: hotel -#: model:ir.actions.server,name:hotel.autocheckout_reservations_ir_actions_server -#: model:ir.cron,cron_name:hotel.autocheckout_reservations -#: model:ir.cron,name:hotel.autocheckout_reservations +#. 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 "Checkout automático de reservas pasadas" +msgstr "Checkout automático para reservas ya pasadas" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_auto_invoice -msgid "Automatic validation and link payment to invoice" -msgstr "Automatic validation and link payment to invoice" +#. 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 "Cambio de estado a Reservas No Checkout" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_barcode +#. 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 "Cambio de estado a Reservas No Show" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__avail_readonly +msgid "Avail Readonly" +msgstr "Disponibilidad solo lectura" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_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 "Plan de Disponibilidad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_plan__name +msgid "Availability Plan Name" +msgstr "Nombre del Plan de Disponibilidad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__availability_plan_id +msgid "Availability Plan to apply massive changes" +msgstr "Plan de Disponibilidad para aplicar cambios masivos" + +#. module: pms +#: model:ir.ui.menu,name:pms.reservation_availability_rules_menu +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_rule_view_form +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_view_tree +msgid "Availability Plans" +msgstr "Planes de Disponibilidad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__availability_results +msgid "Availability Results" +msgstr "Resultados de la Disponibilidad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_plan__rule_ids +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_view_form +msgid "Availability Rules" +msgstr "Reglas de Disponibilidad" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_rule_view_tree +msgid "Availability rules" +msgstr "Reglas de Disponibilidad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__num_rooms_available +msgid "Available rooms" +msgstr "Habitaciones Disponibles" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__bank_account_count +msgid "Bank" +msgstr "Cuenta Bancaria" + +#. module: pms +#: model:ir.model,name:pms.model_account_bank_statement +msgid "Bank Statement" +msgstr "Bank Statement" + +#. module: pms +#: model:ir.model,name:pms.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "Línea del Extracto Bancario" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__bank_ids +msgid "Banks" +msgstr "Bancos" + +#. 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 "Código de barras" +msgstr "Código de Barras" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_list_price -msgid "Base price to compute the customer price. Sometimes called the catalog price." -msgstr "Precio base para calcular el precio de los clientes. A veces llamado precio de catálogo." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_bed_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__bed_ids msgid "Bed" msgstr "Cama" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_beds -#: model:ir.ui.view,arch_db:hotel.hotel_shared_shared_room_view_kanban +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__beds +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_shared_room_view_kanban msgid "Beds" msgstr "Camas" -#. module: hotel -#: selection:product.template,consumed_on:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__product_template__consumed_on__before msgid "Before night" -msgstr "Antes de la Noche" +msgstr "Antes de la noche" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_image -msgid "Big-sized image" -msgstr "Imagen grande" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__bill_rooms +msgid "Bill Rooms" +msgstr "Facturar Habitaciones" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__bill_services +msgid "Bill Services" +msgstr "Facturar Servicios" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__is_blacklisted +msgid "Blacklist" +msgstr "Lista Negra" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__mobile_blacklisted +msgid "Blacklisted Phone Is Mobile" +msgstr "El teléfono de la lista negra es un móvil" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__phone_blacklisted +msgid "Blacklisted Phone is Phone" +msgstr "Blacklisted Phone is Phone" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_board_service__name msgid "Board Name" -msgstr "Nombre" +msgstr "Nombre del Servicio de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_hotel_board_service_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_hotel_board_service_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_board_service_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_board_service_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_board_service_room_id +#. module: pms +#: model:ir.actions.act_window,name:pms.action_pms_board_service_room_type_view +#: 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_reservation__board_service_room_id msgid "Board Service" -msgstr "Servicio" +msgstr "Servicio de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_board_service_line_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_board_service_line_ids -#: model:ir.ui.view,arch_db:hotel.hotel_board_service_form -#: model:ir.ui.view,arch_db:hotel.hotel_board_service_room_type_form +#. 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 +#: 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 "Línea de BoardService" +msgstr "Línea del Servicio de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_hotel_board_service_room_type_id +#. 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 "Board Service Room" +msgstr "Habitación del Servicio de Habitación" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_board_service_room_type +#. module: pms +#: model:ir.model,name:pms.model_pms_board_service_room_type msgid "Board Service included in Room" -msgstr "BoardServices incluidos en la habitación" +msgstr "Servicio de Habitación incluído en la Habitación" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_board_service_form_tree -#: model:ir.model,name:hotel.model_hotel_board_service -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_board_service_room_type_ids -#: model:ir.ui.menu,name:hotel.menu_open_hotel_board_service_form_tree -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_view_form +#. 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.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 msgid "Board Services" -msgstr "Servicios Incluidos" +msgstr "Servicios de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_booking_pending -msgid "Booking pending" -msgstr "Reservas Pendientes" +#. module: pms +#. openerp-web +#: code:addons/pms/static/src/xml/reservation_group_button_views.xml:0 +#, python-format +msgid "Booking Engine" +msgstr "Motor de Reservas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__message_bounce +msgid "Bounce" +msgstr "Devolver" + +#. module: pms +#: model:pms.board.service,name:pms.pms_board_service_0 +msgid "BreakFast" +msgstr "Desayuno" + +#. module: pms +#: model:product.product,name:pms.pms_service_0 +#: model:product.template,name:pms.pms_service_0_product_template +msgid "Breakfast Buffet" +msgstr "Desayuno Buffet" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search msgid "By Day" -msgstr "Por día" +msgstr "Por Día" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search msgid "By Month" msgstr "Por Mes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search msgid "By Week" -msgstr "Por semana" +msgstr "Por Semana" -#. module: hotel -#: selection:hotel.folio.wizard,channel_type:0 -msgid "Call" -msgstr "Call" - -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -#: selection:hotel.service,channel_type:0 -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_call_center -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_call_center -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__call msgid "Call Center" -msgstr "Call Center" +msgstr "Centro de Llamadas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_can_confirm -msgid "Can Confirm" -msgstr "Puede Confirmar" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__can_create_folio +msgid "Can Create Folio" +msgstr "Puede Crear un Folio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_purchase_ok +#. 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 "Se puede ampliar la imagen 1024" + +#. 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 "Se puede ampliar la imagen variante 1024" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__purchase_ok msgid "Can be Purchased" msgstr "Puede ser comprado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_rental -msgid "Can be Rent" -msgstr "Puede ser alquilado" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sale_ok +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__sale_ok msgid "Can be Sold" msgstr "Puede ser vendido" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_wizard_massive_changes_price -msgid "" -"Can use '+','-' or '%'...\n" -"Examples:\n" -" a) +12.3 \t> Increase the price in 12.3\n" -" b) -1.45% \t> Substract 1.45%\n" -" c) 45 \t\t> Sets the price to 45" -msgstr "" -"Puedes usar '+','-' o '%'...\n" -"Ejemplo:\n" -" a) +12.3 \t> Incrementa el precio en 12.3\n" -" b) -1.45% \t> Reducde un 1.45%\n" -" c) 45 \t\t> Establece el precio en 45" - -#. module: hotel -#: code:addons/hotel/wizard/duplicate_reservation.py:25 -#, python-format -msgid "Can't duplicate splitted reservations" -msgstr "No se pueden duplicar las reservas divididas" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -#: model:ir.ui.view,arch_db:hotel.service_on_day_view_form -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -#: model:ir.ui.view,arch_db:hotel.view_hotel_duplicate_reservation_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_changes_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_price_change_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_split_reservation_wizard +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard +#: model_terms:ir.ui.view,arch_db:pms.folio_wizard +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +#: model_terms:ir.ui.view,arch_db:pms.pms_invoice_filter_days_form +#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard +#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv +#: model_terms:ir.ui.view,arch_db:pms.wizard_payment_folio_view_form msgid "Cancel" msgstr "Cancelar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_cancel_discount +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__cancel_discount msgid "Cancel Discount (%)" -msgstr "Descuento Cancelación (%)" +msgstr "Descuento por Cancelación (%)" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Cancel Folio" -msgstr "Cancelar Ficha" +msgstr "Cancelar Folio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Cancel Reservation" msgstr "Cancelar Reserva" -#. module: hotel -#: model:mail.template,subject:hotel.mail_template_hotel_cancel -msgid "Cancelación de su reserva en ${object.company_id.property_name}" -msgstr "Cancelación de su reserva en ${object.company_id.property_name}" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_product_pricelist__cancelation_rule_id +msgid "Cancelation Policy" +msgstr "Política de Cancelación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_company_default_cancel_policy_days -msgid "Cancelation Days" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__name +msgid "Cancelation Rule" +msgstr "Regla de Cancelación" + +#. 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 "Reglas de Cancelación" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__default_cancel_policy_days +msgid "Cancellation Days" msgstr "Días de Cancelación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_product_pricelist_cancelation_rule_id -msgid "Cancelation Policy" -msgstr "Políticas de cancelación" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form +msgid "Cancellation policies" +msgstr "Políticas de Cancelación" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_cancelation_rule -#: model:ir.model,name:hotel.model_hotel_cancelation_rule -#: model:ir.ui.menu,name:hotel.menu_hotel_cancelation_rule -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_form -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_view_tree -msgid "Cancelation Rules" -msgstr "Reglas de cancelación" - -#. module: hotel -#: selection:hotel.checkin.partner,state:0 selection:hotel.folio,state:0 -#: selection:hotel.reservation,state:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__cancelled +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__cancel +#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__cancelled +#: 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 "Cancelado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_capacity -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_kanban +#. module: pms +#: code:addons/pms/models/ir_config_parameter.py:0 +#, python-format +msgid "Cannot delete this parameter" +msgstr "No puede borrar este parámetro" + +#. 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 "Capacidad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_route_from_categ_ids -msgid "Category Routes" -msgstr "Rutas de categoría" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_uom_category_id +msgid "Category" +msgstr "Categoría" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_cancelled_reason -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_cancelled_reason +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__cancelled_reason +#: model:ir.model.fields,field_description:pms.field_pms_reservation__cancelled_reason msgid "Cause of cancelled" -msgstr "Causa de cancelación" +msgstr "Causa de la Cancelación" -#. module: hotel -#: model:ir.model,name:hotel.model_room_closure_reason -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_out_service_description +#. 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 "Causa de fuera de servicio" +msgstr "Causa de estar Fuera de Servicio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_closed -msgid "Change Closed" -msgstr "Cambiar Cerrado" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.move_form +msgid "Change Period" +msgstr "Período de Cambio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_closed_arrival -msgid "Change Closed Arrival" -msgstr "Cambiar Cerrado para Llegadas" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search +msgid "Channel" +msgstr "Canal" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_closed_departure -msgid "Change Closed Departure" -msgstr "Cambiar Cerrado para salida" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__channel_ids +msgid "Channels" +msgstr "Canales" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_change_discount -msgid "Change Discounts" -msgstr "Cambiar Descuentos" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_max_stay -msgid "Change Max Stay" -msgstr "Cambiar máxima estancia" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_max_stay_arrival -msgid "Change Max Stay Arrival" -msgstr "Cambiar Max estancia llegada\t" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_min_stay -msgid "Change Min Stay" -msgstr "Cambiar Minima Estancia" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_change_min_stay_arrival -msgid "Change Min Stay Arrival" -msgstr "Cambiar Minima Estancia Llegada" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_change_price -msgid "Change Prices" -msgstr "Cambiar Precios" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_checkin -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_checkin -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_checkin -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_checkin +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin msgid "Check In" msgstr "Check In" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_checkout -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_checkout -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_checkout -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_checkout +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkout +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Check Out" msgstr "Check Out" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 "Comprobar que el contacto es una compañía, de otra manera es una persona" + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_property__employee +msgid "Check this box if this contact is an Employee." +msgstr "Marque esta casilla si este contacto es un Empleado." + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form +msgid "Check-in hours" +msgstr "Horas del Check-in" + +#. 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 "Datos del Checkin" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Checkin Date" -msgstr "Fecha Checkin" +msgstr "Fecha del Checkin" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkin Detalle" +msgstr "Detalles del Checkin" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_checkin_partner_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_checkin_partner_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__checkin_partner_ids +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_ids msgid "Checkin Partner" -msgstr "Checkin Cliente" +msgstr "Cliente del Checkin" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_checkin_partner_pending_count -msgid "Checkin Pending" -msgstr "Checkin Pendiente" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_checkin_partner_pending_count +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_pending_count msgid "Checkin Pending Num" -msgstr "Checkin Pending Num" +msgstr "Número Pendiente del Checkin" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__checkin_sequence_id +msgid "Checkin Sequence" +msgstr "Secuencia del Checkin" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_today +msgid "Checkin Today" +msgstr "Checkin Hoy" + +#. 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 by Day" -msgstr "Checkin por día" +msgstr "Checkin por Día" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 by Month" -msgstr "Checkin por mes" +msgstr "Checkin por Meses" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 by Week" msgstr "Checkin por Semana" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_checkin_partner_count -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_checkin_partner_count +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_partner_count msgid "Checkin counter" -msgstr "Contador de Checkin" +msgstr "Nº de Checkin" -#. module: hotel -#: code:addons/hotel/models/hotel_folio.py:564 -#: model:ir.ui.menu,name:hotel.menu_hotel_checkin_partner +#. module: pms +#: code:addons/pms/models/pms_folio.py:0 model:ir.ui.menu,name:pms.menu_pms_checkin_partner #, python-format msgid "Checkins" -msgstr "Checkin" +msgstr "Checkins" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkins Mañana" +msgstr "Checkins mañana" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkins a 7 días" +msgstr "Checkins para 7 días" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkout by Day" msgstr "Checkout por Día" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkout by Month" msgstr "Checkout por Mes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Checkout by Week" -msgstr "Checkout por Semana" +msgstr "Checkout por Seamana" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_children -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_children +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__children msgid "Children" msgstr "Niños" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_city -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_city -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__children_occupying +msgid "Children occupying" +msgstr "Niños que ocupan" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard +msgid "Choose The Details" +msgstr "Escoja los detalles" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__city msgid "City" msgstr "Ciudad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type_class__name msgid "Class Name" -msgstr "Nombre de Categoría" +msgstr "Nombre de clase" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_closed -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_closed +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__closed +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Closed" msgstr "Cerrado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_closed_arrival -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_closed_arrival +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed_arrival +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__closed_arrival +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Closed Arrival" -msgstr "Cerrar Salida" +msgstr "***Llegada cerrada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_closed_departure -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_closed_departure +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__closed_departure +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__closed_departure msgid "Closed Departure" -msgstr "Cerrar Llegada" +msgstr "Salida cerrada***" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_closure_reason_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_closure_reason_id -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "Closed departure" +msgstr "Salida cerrada***" + +#. 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 +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Closure Reason" -msgstr "Motivo de Cierre" +msgstr "Razón de Cierre" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_hotel_room_closure_reason_form_tree +#. module: pms +#: model:ir.ui.menu,name:pms.menu_pms_room_closure_reason_form_tree msgid "Closure Reasons" -msgstr "Motivos de Cierre" +msgstr "Razones de Cierre" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Closure reason" -msgstr "Motivo de Cierre" +msgstr "Razón de Cierre" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_code_class -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_code_type +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__code_type +#: model:ir.model.fields,field_description:pms.field_pms_room_type_class_default_code msgid "Code" msgstr "Código" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_color +#. 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 "Índice de color" +msgstr "Índice de Color" -#. module: hotel -#: model:ir.model,name:hotel.model_res_company +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__combination_indices +msgid "Combination Indices" +msgstr "Índices combinados" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__commercial_partner_id +msgid "Commercial Entity" +msgstr "Entidad Comercial" + +#. 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 "Comisión" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "Commission Amount" +msgstr "Importe de la Comisión" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__commission_amount +msgid "Commission amount" +msgstr "Importe de la Comisión" + +#. 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 "Porcentaje de la Comisión (%)" + +#. module: pms +#: model:ir.model,name:pms.model_res_company msgid "Companies" msgstr "Compañías" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_company_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_company_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_company_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_company_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_company_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__ref_company_ids +msgid "Companies that refers to partner" +msgstr "Compañías que se refieren a un cliente" + +#. module: pms +#: 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_res_users__company_id msgid "Company" msgstr "Compañía" -#. module: hotel -#: model:ir.ui.menu,name:hotel.configuration_others -#: model:ir.ui.menu,name:hotel.hotel_configuration_menu +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__company_name +msgid "Company Name" +msgstr "Nombre de la Compañía" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__commercial_company_name +msgid "Company Name Entity" +msgstr "Nombre de la Entidad de la Compañía" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__company_type +msgid "Company Type" +msgstr "Tipo de Compañía" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__partner_gid +msgid "Company database ID" +msgstr "ID de la Base de Datos de la Compañía" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__contact_address +msgid "Complete Address" +msgstr "Dirección Completa" + +#. module: pms +#: model:pms.room.type.class,name:pms.pms_room_type_class_1 +msgid "Conference" +msgstr "Conferencia" + +#. 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 "Habitación para Conferencias" + +#. module: pms +#: model:ir.ui.menu,name:pms.configuration_others model:ir.ui.menu,name:pms.pms_configuration_menu msgid "Configuration" msgstr "Configuración" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Confirm" msgstr "Confirmar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_confirm -msgid "Confirm Reservations" -msgstr "Confirmar Reservas" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Confirm Sale" -msgstr "Confirmar venta" +msgstr "Confirmar Venta" -#. module: hotel -#: model:mail.template,subject:hotel.mail_template_hotel_reservation -msgid "Confirmación de los detalles de su reserva en ${object.company_id.property_name}" -msgstr "Confirmación de los detalles de su reserva en ${object.company_id.property_name}" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_confirmation_date +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__confirmation_date msgid "Confirmation Date" -msgstr "Fecha de confirmación" +msgstr "Fecha de Confirmación" -#. module: hotel -#: selection:hotel.folio,state:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__confirm msgid "Confirmed" msgstr "Confirmado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_consumed_on -#: model:ir.model.fields,field_description:hotel.field_product_product_consumed_on -#: model:ir.model.fields,field_description:hotel.field_product_template_consumed_on -msgid "Consumed" -msgstr "Consumed" +#. module: pms +#: model:pms.amenity.type,name:pms.pms_amenity_type_1 +msgid "Connectivity" +msgstr "Conectividad" -#. module: hotel -#: model:ir.model,name:hotel.model_res_partner +#. 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 "Consumido" + +#. module: pms +#: model:ir.model,name:pms.model_res_partner +#: model:ir.model.fields,field_description:pms.field_pms_property__child_ids msgid "Contact" msgstr "Contacto" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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 "Contact Invoiced" msgstr "Contacto Facturado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_standard_price +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view +msgid "Contact image" +msgstr "Imagen de contacto" + +#. module: pms +#: model:ir.model.fields,help:pms.field_folio_sale_line__product_uom_category_id +msgid "" +"Conversion between Units of Measure can only occur if they belong to the same category. The " +"conversion will be made based on the ratios." +msgstr "" +"La conversión entre unidades de medida solo pueden ocurrir si pertenecen a la misma categoría. La " +"conversión se realizará basada en las proporciones." + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__standard_price msgid "Cost" -msgstr "Precio de coste" +msgstr "Precio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_cost_method -msgid "Cost Method" -msgstr "Método de coste" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__cost_currency_id +msgid "Cost Currency" +msgstr "Moneda del Precio" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_standard_price -msgid "Cost used for stock valuation in standard price and as a first price to set in average/fifo. Also used as a base price for pricelists. Expressed in the default unit of measure of the product." -msgstr "Precio de coste utilizado para la valoración de existencias en precio estándar y como primer precio para establecer en promedio/fifo. También se utiliza como precio base para las tarifas. Expresado en la unidad de medida predeterminada del producto." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__payment_token_count +msgid "Count Payment Token" +msgstr "Contar Señal de Pago" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_cost_method -msgid "Costing Method" -msgstr "Método de coste" +#. 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 "Nº emails devueltos por este contacto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_country_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_country_id -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_invoice_country_id +#: model:ir.model.fields,field_description:pms.field_pms_property__country_id msgid "Country" msgstr "País" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.folio_wizard +msgid "Create Folio" +msgstr "Crear Folio" + +#. 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 "Crear Factura" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -msgid "Create Invoices" -msgstr "Crear facturas" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv +msgid "Create and View Invoice" +msgstr "Crear y Ver Factura" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -msgid "Create Reservations" -msgstr "Crear Reservas" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -msgid "Create and View Invoices" -msgstr "Crear y ver facturas" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Create by Day" -msgstr "Crear por día" +msgstr "Crear por Día" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Create by Month" msgstr "Crear por Mes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 "Create by Week" msgstr "Crear por Semana" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.actions.act_window,name:pms.action_view_folio_advance_payment_inv +msgid "Create invoices" +msgstr "Crear Facturas" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Created By" msgstr "Creado por" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_create_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_create_uid -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_create_uid -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_create_uid -#: model:ir.model.fields,field_description:hotel.field_service_on_day_create_uid +#. 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_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_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_ubication__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_folio_wizard__create_uid +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__create_uid +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__create_uid +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__create_uid +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__create_uid +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__create_uid msgid "Created by" msgstr "Creado por" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_create_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_create_date -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_create_date -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_create_date -#: model:ir.model.fields,field_description:hotel.field_service_on_day_create_date +#. 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_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_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_ubication__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_folio_wizard__create_date +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__create_date +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__create_date +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__create_date +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__create_date +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__create_date msgid "Created on" msgstr "Creado en" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Creation Date" msgstr "Fecha de Creación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_credit_card_details -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_credit_card_details -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_credit_card_details -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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 "Datos de tarjeta" +msgstr "Detalles de la Tarjeta de Crédito" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_currency_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_currency_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_currency_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_currency_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__credit_limit +msgid "Credit Limit" +msgstr "Límite de crédito" + +#. 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 msgid "Currency" msgstr "Moneda" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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 "Actualmente dentro" +msgstr "Reserva Actual" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_qty_available -msgid "" -"Current quantity of products.\n" -"In a context with a single Stock Location, this includes goods stored at this Location, or any of its children.\n" -"In a context with a single Warehouse, this includes goods stored in the Stock Location of this Warehouse, or any of its children.\n" -"stored in the Stock Location of the Warehouse of this Shop, or any of its children.\n" -"Otherwise, this includes goods stored in any Stock Location with 'internal' type." -msgstr "" -"Cantidad actual de los productos.\n" -"En un contexto de una sola ubicación de Stock, esto incluye los bienes almacenados en esta ubicación, o cualquiera de sus hijas.\n" -"En un contexto de un solo almacén, esto incluye los bienes almacenados en la ubicación de Stock de ese almacén, o cualquiera de sus hijas.\n" -"En cualquier otro caso, esto incluye los bienes almacenados en cualquier ubicación de Stock de tipo 'Interna'." +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form +msgid "Current Property" +msgstr "Propiedad Actual" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_partner_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_partner_id -#: model:ir.ui.view,arch_db:hotel.account_payment_view_tree_folio -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__product_custom_attribute_value_ids +msgid "Custom Values" +msgstr "Valores Personalizados" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__folio_partner_id +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search msgid "Customer" msgstr "Cliente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sale_delay -msgid "Customer Lead Time" -msgstr "Plazo de entrega del cliente" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__property_payment_term_id +msgid "Customer Payment Terms" +msgstr "Términos de Pago del Cliente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_partner_ref +#. module: pms +#: 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 "URL del Portal del Cliente" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__customer_rank +msgid "Customer Rank" +msgstr "Rango del Cliente" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__partner_ref msgid "Customer Ref" -msgstr "Ref. Cliente" +msgstr "Ref. del Cliente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_client_order_ref +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__client_order_ref msgid "Customer Reference" -msgstr "Referencia de cliente" +msgstr "Referencia del Cliente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_deposit_taxes_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_taxes_id -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form +#. 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 "Impuestos de cliente" +msgstr "Impuestos del Cliente" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_hotel_customer +#. module: pms +#: model:ir.ui.menu,name:pms.menu_pms_customer msgid "Customers" msgstr "Clientes" -#. module: hotel -#: selection:product.pricelist,pricelist_type:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__product_pricelist__pricelist_type__daily msgid "Daily Plan" msgstr "Plan Diario" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_daily_limit -#: model:ir.model.fields,field_description:hotel.field_product_product_daily_limit -#: model:ir.model.fields,field_description:hotel.field_product_template_daily_limit +#. 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 "Límite diario" +msgstr "Límite Diario" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_date -#: model:ir.model.fields,field_description:hotel.field_service_on_day_date +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__date_ids +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_room_type_availability_rule__date +#: model:ir.model.fields,field_description:pms.field_pms_service_line__date +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__date msgid "Date" msgstr "Fecha" -#. module: hotel -#: code:addons/hotel/models/hotel_room_type.py:149 +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__from_date +msgid "Date From" +msgstr "Fecha Desde" + +#. module: pms +#: code:addons/pms/models/pms_room_type.py:0 #, python-format msgid "Date From and days are mandatory" -msgstr "Fecha desde y días son obligatorios" +msgstr "La Fecha Desde y los Días son Obligatorios" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_date_order +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__date_order msgid "Date Order" -msgstr "Fecha de pedido" +msgstr "Fecha del Pedido" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:71 +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Date from %s to %s \n" -msgstr "Fecha de %s a %s \n" +msgstr "Fecha deste %s hasta %s \n" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_message_last_post -msgid "Date of the last message posted on the record." -msgstr "Fecha del último mensaje publicado en el registro." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_confirmation_date +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_folio__confirmation_date msgid "Date on which the folio is confirmed." -msgstr "Fecha en la que la Ficha fue confirmada" +msgstr "Fecha en la cual se confirma el folio." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Day Pricing" -msgstr "Precio día" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__to_date +msgid "Date to" +msgstr "Fecha hasta" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_tree +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_invoice_filter_days_form +msgid "Dates to invoice" +msgstr "Fechas para facturar" + +#. module: pms +#: 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 "Días" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_days_intime +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_intime msgid "Days Late" -msgstr "Max. días para cancelar en tiempo" +msgstr "Nº de días pre-checkin" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_days_qty -msgid "Days Qty" -msgstr "Cantida/día" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__deduct_down_payments +msgid "Deduct down payments" +msgstr "Deducir Pagos Iniciales" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_connector_config_settings_default_arrival_hour -#: model:ir.model.fields,field_description:hotel.field_res_config_settings_default_arrival_hour -msgid "Default Arrival Hour (GMT)" -msgstr "Hora de Llegada por defecto (GMT)" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_checkin_partner_arrival_hour -#: model:ir.model.fields,help:hotel.field_hotel_reservation_arrival_hour +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_reservation__arrival_hour msgid "Default Arrival Hour (HH:MM)" -msgstr "Hora de Llegada por defecto (HH:MM)" +msgstr "Hora de llegada por defecto (HH:MM)" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_connector_config_settings_default_departure_hour -#: model:ir.model.fields,field_description:hotel.field_res_config_settings_default_departure_hour -msgid "Default Departure Hour (GMT)" -msgstr "Hora de Salida por defecto (GMT)" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_checkin_partner_departure_hour -#: model:ir.model.fields,help:hotel.field_hotel_reservation_departure_hour +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_reservation__departure_hour msgid "Default Departure Hour (HH:MM)" -msgstr "Hora de Salida por defecto (HH:MM)" +msgstr "Hora de Salida por Defecto (HH:MM)" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_uom_id -msgid "Default Unit of Measure used for all stock operation." -msgstr "Unidad de medida por defecto utilizada para todas las operaciones de stock." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_quota +msgid "Default Quota" +msgstr "Cuota por defecto" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_uom_po_id -msgid "Default Unit of Measure used for purchase orders. It must be in the same category than the default unit of measure." -msgstr "Unidad de medida predeterminada utilizada para los pedidos de compra. Debe estar en la misma categoría que la unidad de medida predeterminada." +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__supplier_taxes_id +msgid "Default taxes used when buying the product." +msgstr "Impuestos aplicados por defecto cuando se compra un producto." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Delete" -msgstr "Eliminar" +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__taxes_id +msgid "Default taxes used when selling the product." +msgstr "Impuestos aplicados por defecto cuando se vende un producto." -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:80 +#. 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 "Unidad de medida por defecto usada para todas las operaciones de stock." + +#. 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 "" +"Unidad de medida por defecto usada para los pedidos de compra. Debe estar en la misma categoría que " +"las unidades de medida por defecto." + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__seller_ids +msgid "Define vendor pricelists." +msgstr "Definir las tarifas del proveedor." + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__trust +msgid "Degree of trust you have in this debtor" +msgstr "Grado de confianza que tiene en este deudor" + +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Deleted payment: %s %s " -msgstr "Pago eliminado: %s %s " +msgstr "Pago Eliminado: %s %s " -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_real_checkout -msgid "Departure" -msgstr "Salida" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_departure_hour -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_departure_hour +#. module: pms +#: 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 "Hora de Salida" -#. module: hotel -#: code:addons/hotel/models/hotel_checkin_partner.py:111 +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__default_departure_hour +msgid "Departure Hour (GMT)" +msgstr "Hora de Salida (GMT)" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__departure_today +msgid "Departure Today" +msgstr "Salidas Hoy" + +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 #, python-format msgid "Departure date (%s) is prior to arrival on %s" -msgstr "La fecha de salida (%s) is menos que la de Llegada %s" +msgstr "La hora de salida (%s) es anterior a la llegada en %s" -#. module: hotel -#: code:addons/hotel/models/hotel_checkin_partner.py:122 -#, python-format -msgid "Departure date, is prior to arrival. Check it now. %s" -msgstr "La fecha de salida es menor que la de Llegada %s" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Departure our" -msgstr "Hora de salida" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_route_ids -msgid "Depending on the modules installed, this will allow you to define the route of the product: whether it will be bought, manufactured, MTO/MTS,..." -msgstr "Dependiendo de los módulos instalados, este permite definir la ruta del producto: si será comprado, facturado, bajo pedido o desde stock..." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_name -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_description -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_description -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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.report_folio_document msgid "Description" msgstr "Descripción" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Description in Guest Documents" -msgstr "Description in Guest Documents" +msgstr "Descripción en Documentos Invitados" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description_pickingout -msgid "Description on Delivery Orders" -msgstr "Descripción en los pedidos de Entrega" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description_picking -msgid "Description on Picking" -msgstr "Descripción en Albarán" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description_pickingin -msgid "Description on Receptions" -msgstr "Descripción en Recepciones" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form +#. 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 +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form msgid "Descriptions" msgstr "Descripciones" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_partner_main_partner_id -#: model:ir.model.fields,field_description:hotel.field_res_users_main_partner_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__main_partner_id +#: model:ir.model.fields,field_description:pms.field_res_partner__main_partner_id +#: model:ir.model.fields,field_description:pms.field_res_users__main_partner_id msgid "Destination Partner fusion" -msgstr "Destination Partner fusion" +msgstr "Fusión de Clientes de Destino" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "Detail" +msgstr "Detalles" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__detail_origin +msgid "Detail Origin" +msgstr "Origen de los Detalles" + +#. module: pms +#: model:product.product,name:pms.pms_service_5 +#: model:product.template,name:pms.pms_service_5_product_template +msgid "Dinner" +msgstr "Cena" + +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_sale_channel__channel_type__direct +msgid "Direct" +msgstr "Directo" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__channel_type_id +#: model:ir.model.fields,field_description:pms.field_pms_reservation__channel_type_id +msgid "Direct Sale Channel" +msgstr "Canal de Venta Directo" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "Disc.%" +msgstr "Desc.%" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.report_folio_document msgid "Disc.(%)" msgstr "Desc.(%)" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_discount +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__discount +#: model:ir.model.fields,field_description:pms.field_pms_service_line__discount msgid "Discount" -msgstr "Discount" +msgstr "Descuento" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_discount -#: model:ir.model.fields,field_description:hotel.field_hotel_service_discount -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_discount +#. 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__discount msgid "Discount (%)" -msgstr "Descuento (%)" +msgstr "Descuento" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_discount +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__discount msgid "Discount (€)" msgstr "Descuento (€)" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Discount Room" -msgstr "Habitación con descuento" +msgstr "Descuento en la Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_service_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_display_name -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_display_name -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_display_name -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_display_name -#: model:ir.model.fields,field_description:hotel.field_service_on_day_display_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_service_line__cancel_discount +msgid "Discount cancel" +msgstr "Descuento por cancelación" + +#. 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_ir_sequence__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_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_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_ubication__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_folio_wizard__display_name +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__display_name +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__display_name +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__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_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_payment_folio__display_name msgid "Display Name" -msgstr "Nombre mostrado" +msgstr "Nombre Mostrado" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Done" -msgstr "Hecho" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__display_type +msgid "Display Type" +msgstr "Tipo Mostrado" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.folio.wizard,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -#: selection:hotel.service,channel_type:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_advanced_filters_wizard__pms_domain +msgid "Domain" +msgstr "Dominio" + +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__door msgid "Door" msgstr "Puerta" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:134 +#. 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 "Doble" + +#. module: pms +#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 #, python-format msgid "Down Payment" msgstr "Adelanto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_amount +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__amount msgid "Down Payment Amount" -msgstr "Cantidad de pago anticipado" +msgstr "Cantidad del Adelanto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_product_id -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__fixed_amount +msgid "Down Payment Amount (Fixed)" +msgstr "Cantidad del Adelanto (Fija)" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__product_id msgid "Down Payment Product" -msgstr "Producto de pago anticipado" +msgstr "Producto del Adelanto" -#. module: hotel -#: selection:folio.advance.payment.inv,advance_payment_method:0 +#. module: pms +#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 +#, python-format +msgid "Down Payment: %s" +msgstr "Adelanto: %s" + +#. module: pms +#: code:addons/pms/models/pms_folio.py:0 +#, python-format +msgid "Down Payments" +msgstr "Adelantos" + +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__fixed msgid "Down payment (fixed amount)" -msgstr "Adelanto (Cantidad fija)" +msgstr "Adelanto (Cantidad Fija)" -#. module: hotel -#: selection:folio.advance.payment.inv,advance_payment_method:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__percentage msgid "Down payment (percentage)" msgstr "Adelanto (Porcentaje)" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:131 +#. module: pms +#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 #, python-format msgid "Down payment of %s%%" msgstr "Adelanto de %s%%" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_duplicate_reservation_wizard -msgid "Duplicate" -msgstr "Duplicar" +#. 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 "" +"Los adelantos se realizan cuando se crean las facturas de un folio. No serán copiados cuando se " +"duplique un folio." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_duplicate_reservation_wizard -msgid "Duplicate Rerservation" -msgstr "Duplicar Reserva" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view +msgid "Draft" +msgstr "Borrador" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_duplicate_reservation -msgid "Duplicate Reservation" -msgstr "Duplicar Reserva" +#. module: pms +#. openerp-web +#: code:addons/pms/static/src/xml/pms_base_templates.xml:0 +#, python-format +msgid "Dropdown menu" +msgstr "Menú Desplegable" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation_line.py:49 +#. module: pms +#: code:addons/pms/models/pms_reservation_line.py:0 #, python-format msgid "Duplicated reservation line date" -msgstr "Fecha duplicada en la reserva" +msgstr "Fecha de linea de reserva duplicada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_email -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_email -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_email -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_email +#. 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 "Email" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_email -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_email +#. 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 "Económico" + +#. 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 "" +"El cliente (no el usuario), o el usuario compartido. Indicó que el cliente actual no tiene acceso o " +"éste es limitado a la creación de datos compartidos." + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__email msgid "Email" msgstr "Email" -#. module: hotel -#: model:ir.model,name:hotel.model_mail_compose_message -msgid "Email composition wizard" -msgstr "Asistente de redacción de correo electrónico." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__employee +msgid "Employee" +msgstr "Empleado/a" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_date_end -msgid "End Date" -msgstr "Fecha de finalización" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__date_end_overnight +msgid "End Date Overnight" +msgstr "Fin Noche Pernocta" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_arrival -msgid "Enter Date" -msgstr "Fecha de entrada" +#. module: pms +#: model:ir.model.fields,help:pms.field_product_pricelist_item__date_end_overnight +msgid "End date to apply daily pricelist items" +msgstr "Fecha límite para aplicar los ítems de la tarifa diaria" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_departure -msgid "Exit Date" -msgstr "Fecha salida" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__arrival +msgid "Enter" +msgstr "Entrada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_account_expense_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkin_datetime +msgid "Exact Arrival" +msgstr "Llegada Exacta" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__checkout_datetime +msgid "Exact Departure" +msgstr "Salida exacta" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__departure +msgid "Exit" +msgstr "Salida" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__property_account_expense_id msgid "Expense Account" -msgstr "Cuenta de gasto" +msgstr "Cuenta de Gastos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_extra_beds_allowed +#. 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 "" +"Los gastos y las tarifas del proveedor pueden ser refacturadas al cliente. Con esta opción, un " +"gasto validado puede ser refacturado al cliente a su coste o precio de venta ." + +#. module: pms +#: model:product.product,name:pms.pms_service_1 +#: model:product.template,name:pms.pms_service_1_product_template +msgid "Extra Bed" +msgstr "Cama Supletoria" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room__extra_beds_allowed msgid "Extra beds allowed" -msgstr "Permitir camas supletorias" +msgstr "Camas Supletorias Permtidas" -#. module: hotel -#: selection:hotel.cancelation.rule,apply_on_late:0 -#: selection:hotel.cancelation.rule,apply_on_noshow:0 +#. 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 "" +"Campo utilizado para almacenar números de teléfono. Ayudan a acelerar búsquedas y comparaciones." + +#. module: pms +#: model:ir.actions.act_window,name:pms.pms_invoice_filter_days_action +#: model:ir.model,name:pms.model_pms_invoice_filter_days +msgid "Filter Days" +msgstr "Filtrar Días" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__filter_wizard_id +msgid "Filter Wizard" +msgstr "Filtrar Asistentes" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.move_form +msgid "Filter-days" +msgstr "Filtrar-días" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard +msgid "Filters" +msgstr "Filtros" + +#. 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 "Primer día" +msgstr "Primer Día" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_fiscal_position_id +#. module: pms +#: model:pms.ubication,name:pms.pms_ubication_1 +msgid "First Floor" +msgstr "Primer Piso" + +#. 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 "Posición fiscal" +msgstr "Posición Fiscal" -#. module: hotel -#: selection:hotel.board.service,price_type:0 -#: selection:hotel.board.service.room.type,price_type:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_board_service__price_type__fixed +#: model:ir.model.fields.selection,name:pms.selection__pms_board_service_room_type__price_type__fixed msgid "Fixed" msgstr "Fijo" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_floor_form_tree +#. module: pms +#: model:ir.actions.act_window,name:pms.open_pms_ubication_form_tree msgid "Floor Structure" -msgstr "Estructura de Pisos" +msgstr "Estructura del Piso" -#. module: hotel -#: model:ir.actions.report,name:hotel.action_report_folio -#: model:ir.model.fields,field_description:hotel.field_account_invoice_folio_ids -#: model:ir.model.fields,field_description:hotel.field_account_payment_folio_id -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_folio_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_folio_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_folio_id -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_folio_id -#: model:ir.model.fields,field_description:hotel.field_payment_return_folio_id -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model:ir.actions.act_window,name:pms.open_pms_folio1_form_tree_all +#: model:ir.actions.report,name:pms.action_report_folio +#: 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_payment__folio_ids +#: 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_wizard_payment_folio__folio_id +#: 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 "Ficha" +msgstr "Folio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model:ir.model,name:pms.model_folio_advance_payment_inv +msgid "Folio Advance Payment Invoice" +msgstr "Facturas de Pago Avanzadas del Folio" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Folio Form" -msgstr "Formulario de Ficha" +msgstr "Forma del Folio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_account_move_line__folio_line_ids +msgid "Folio Lines" +msgstr "Líneas del Folio" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__name msgid "Folio Number" -msgstr "Número de Ficha" +msgstr "Número del folio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_tree +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_tree msgid "Folio Pending Amount" -msgstr "Pagos Pendiente en la Ficha" +msgstr "Cantidad pendiente del Folio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_folio_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_folio_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_folio_wizard_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_account_payment__folio_id +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__folio_id +msgid "Folio Reference" +msgstr "Referencia del Folio" + +#. module: pms +#: model:ir.model,name:pms.model_folio_sale_line +msgid "Folio Sale Line" +msgstr "Línea de Venta del Folio" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__folio_sequence_id +msgid "Folio Sequence" +msgstr "Secuencia del Folio" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__state +msgid "Folio Status" +msgstr "Estado del Folio" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__folio_wizard_id +#: model:ir.model.fields,field_description:pms.field_pms_num_rooms_selection__folio_wizard_id msgid "Folio Wizard" -msgstr "Ficha Wizard" +msgstr "Asistente del Folio" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.hotel_partner_folios -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_folio_ids -#: model:ir.model.fields,field_description:hotel.field_res_partner_folios_count -#: model:ir.model.fields,field_description:hotel.field_res_users_folios_count -#: model:ir.ui.menu,name:hotel.menu_open_hotel_folio1_form_tree_all -#: model:ir.ui.view,arch_db:hotel.res_partner_view_form -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv +#. module: pms +#: model:ir.actions.act_window,name:pms.action_wizard_folio +msgid "Folio creation" +msgstr "Creación del Folio" + +#. module: pms +#: model:ir.ui.menu,name:pms.menu_pms_folio_wizard +msgid "Folio wizard" +msgstr "Asistente del Folio" + +#. 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_line__folio_ids +#: 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 +#: model:ir.ui.menu,name:pms.menu_open_pms_folio1_form_tree_all +#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form msgid "Folios" -msgstr "Fichas" +msgstr "Folios" -#. module: hotel -#: model:ir.model,name:hotel.model_folio_advance_payment_inv -msgid "Folios Advance Payment Invoice" -msgstr "Folios Advance Payment Invoice" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_folio_ids -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_reservation_ids -msgid "Folios grouped" -msgstr "Folios grouped" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.res_partner_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form msgid "Folios related with this contact" -msgstr "Fichas de este contacto" +msgstr "Folios relacionados con este contacto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_follower_ids +#. 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 "Seguidores" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_channel_ids +#. 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 "Seguidores (Canales)" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_partner_ids +#. 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 "Seguidores (Empresas)" +msgstr "Seguidores (Clientes)" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_virtual_available -msgid "Forecast Quantity" -msgstr "Cantidad prevista" +#. 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 "Font awesome icon e.g. fa-tasks" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_virtual_available -msgid "" -"Forecast quantity (computed as Quantity On Hand - Outgoing + Incoming)\n" -"In a context with a single Stock Location, this includes goods stored in this location, or any of its children.\n" -"In a context with a single Warehouse, this includes goods stored in the Stock Location of this Warehouse, or any of its children.\n" -"Otherwise, this includes goods stored in any Stock Location with 'internal' type." -msgstr "" -"Cantidad prevista (calculada como cantidad a mano - saliente + entrante)\n" -"En un contexto de una sola ubicación de stock, esto incluye los bienes almacenados en esta ubicación, o cualquiera de sus hijas.\n" -"En un contexto de un solo almacén, esto incluye los bienes almacenados en la ubicación de stock de ese almacén, o cualquiera de sus hijas.\n" -"En cualquier otro caso, esto incluye los bienes almacenados en cualquier ubicación de stock de tipo 'Interna'." +#. 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 "Formato de la Hora de Llegada (HH:MM) Error:%s" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dfr +#. 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 "Formato de la Hora de Salida (HH:MM) Error:%s" + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_property__email_formatted +msgid "Format email address \"Name \"" +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 msgid "Friday" msgstr "Viernes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "From " -msgstr "Desde " +#. module: pms +#: model:ir.model.fields,field_description:pms.field_account_bank_statement_line__from_reservation +#: model:ir.model.fields,field_description:pms.field_account_move__from_reservation +#: model:ir.model.fields,field_description:pms.field_account_payment__from_reservation +msgid "From Reservation" +msgstr "Desde la reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_invoice_from_folio -msgid "From Folio" -msgstr "Desde Ficha" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkin +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__start_date +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__start_date +msgid "From:" +msgstr "Desde:" -#. module: hotel -#: selection:hotel.folio,invoice_status:0 -#: selection:hotel.reservation,invoice_status:0 -#: selection:hotel.service,invoice_status:0 +#. module: pms +#: model:pms.board.service,name:pms.pms_board_service_2 +msgid "FullBoard" +msgstr "Pensión Completa" + +#. 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 "Facturada" +msgstr "Totalmente Facturada" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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: hotel -#: code:addons/hotel/models/hotel_board_service_room_type.py:22 +#. module: pms +#: code:addons/pms/models/pms_board_service_room_type.py:0 #, python-format msgid "Generic" -msgstr "Generica" +msgstr "Genérico/a" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_reservation_view_tree -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_tree +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__quota +#: model:ir.model.fields,help:pms.field_pms_room_type_availability_rule__quota +msgid "Generic Quota assigned." +msgstr "Cuota Genérica 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 "Entrar" +msgstr "Llega" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_packaging_ids +#. 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 "Da las diferentes formas de empaquetar el mismo producto." +msgstr "Ofrece diferentes formas de empaquetar el mismo producto." -#. module: hotel -#: selection:hotel.wizard.massive.changes,applied_on:0 -msgid "Global" -msgstr "Global" +#. module: pms +#: model:pms.ubication,name:pms.pms_ubication_0 +msgid "Ground Floor" +msgstr "Planta Baja" -#. module: hotel -#: model:mail.template,subject:hotel.mail_template_hotel_exit -msgid "Gracias por alojarse con nosotros en ${object.company_id.property_name}" -msgstr "Gracias por alojarse con nosotros en ${object.company_id.property_name}" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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" +msgstr "Agrupar Por" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_search -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_search +#. 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..." +msgstr "Agrupar Por..." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_group_folios -msgid "Group Folios" -msgstr "Agrupar Fichas" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Guest" -msgstr "Huésped" +msgstr "Invitado/a" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_connector_config_settings_default_arrival_hour -#: model:ir.model.fields,help:hotel.field_connector_config_settings_default_departure_hour -#: model:ir.model.fields,help:hotel.field_res_config_settings_default_arrival_hour -#: model:ir.model.fields,help:hotel.field_res_config_settings_default_departure_hour +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_has_cancelled_reservations_to_send -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_has_cancelled_reservations_to_send -msgid "Has Cancelled Reservations To Send" -msgstr "Has Cancelled Reservations To Send" +#. module: pms +#: model:ir.model,name:pms.model_ir_http +msgid "HTTP Routing" +msgstr "Ruta HTTP//Enrutamiento" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_has_checkout_to_send -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_has_checkout_to_send -msgid "Has Checkout To Send" -msgstr "Has Checkout To Send" +#. module: pms +#: model:pms.amenity,name:pms.pms_amenity_2 +msgid "Hair Dryer" +msgstr "Secador de Pelo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_has_confirmed_reservations_to_send -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_has_confirmed_reservations_to_send -msgid "Has Confirmed Reservations To Send" -msgstr "Has Confirmed Reservations To Send" +#. module: pms +#: model:pms.board.service,name:pms.pms_board_service_1 +msgid "Half Board" +msgstr "Media Pensión" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_invoice_has_folios_outstanding +#. 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 en Ficha" +msgstr "Tiene Folios Pendientes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Hotel" -msgstr "Hotel" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__has_unreconciled_entries +msgid "Has Unreconciled Entries" +msgstr "Has Unreconciled Entries" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_board_service_room_type_view -msgid "Hotel Board Service" -msgstr "Hotel Board Service" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__has_down_payments +msgid "Has down payments" +msgstr "Tiene Pagos Iniciales" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_hotel_board_service_room_type_ids -msgid "Hotel Board Service Room Type" -msgstr "Hotel Board Service por tipo de habitación" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_board_service_view_tree -msgid "Hotel Board Services" -msgstr "Servicios incluidos" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_tree -msgid "Hotel By Day" -msgstr "Hotel por día" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Hotel Default" -msgstr "Emparejado" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Hotel Default Hours" -msgstr "Horario por Defecto del Hotel" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_folio1_form_tree_all -#: model:ir.model,name:hotel.model_hotel_folio -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_tree -msgid "Hotel Folio" -msgstr "Ficha de reservas" - -#. module: hotel -#: model:ir.ui.menu,name:hotel.hotel_management_menu -msgid "Hotel Management" -msgstr "Gestión del Hotel" - -#. module: hotel -#: model:res.groups,name:hotel.group_hotel_call -msgid "Hotel Management / CallCenter" -msgstr "Hotel Management / CallCenter" - -#. module: hotel -#: model:res.groups,name:hotel.group_hotel_user -msgid "Hotel Management / User" -msgstr "Hotel Management / User" - -#. module: hotel -#: model:res.groups,name:hotel.group_hotel_manager -msgid "Hotel Management/ Manager" -msgstr "Hotel Management/ Manager" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_massive_change -msgid "Hotel Massive Change" -msgstr "Cambios Masivos" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_reservation_form_tree_all -#: model:ir.model,name:hotel.model_hotel_reservation -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_tree -msgid "Hotel Reservation" -msgstr "Reserva del hotel" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_wizard_reservations -msgid "Hotel Reservation Wizard" -msgstr "Hotel Reservation Wizard" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_room_form -#: model:ir.model,name:hotel.model_hotel_room -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_tree -msgid "Hotel Room" -msgstr "Habitaciones" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_room_amenity_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_search -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_list -msgid "Hotel Room Amenities" -msgstr "Características de Habitación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_amenity_type_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_amenity_type_view_list -msgid "Hotel Room Amenities Type" -msgstr "Tipos de Características de Habitación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_closure_reason_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_closure_reason_view_tree -msgid "Hotel Room Closure Reason" -msgstr "Motivos de Cierre de habitaciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_room_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_room_type_id -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_class_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_view_tree -msgid "Hotel Room Type" -msgstr "Tipo de Habitación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_class_view_tree -msgid "Hotel Room Type Class" -msgstr "Categoría de Habitación" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_room_amenity_type_view_form -msgid "Hotel Room amenity Type" -msgstr "Hotel Room amenity Type" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.product_template_view_form -msgid "Hotel Service" -msgstr "Servicio" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_service_line_form -#: model:ir.actions.act_window,name:hotel.action_hotel_services_form -msgid "Hotel Services" -msgstr "Servicios" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_service -msgid "Hotel Services and its charges" -msgstr "Hotel Services and its charges" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_shared_room_form -#: model:ir.model,name:hotel.model_hotel_shared_room -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_tree -#: model:ir.ui.view,arch_db:hotel.hotel_shared_shared_room_view_search -msgid "Hotel Shared Room" -msgstr "Habitación Compartida" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_id -msgid "Hotel Type Class" -msgstr "Hotel Type Class" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_floor_view_form -msgid "Hotel Ubication" -msgstr "Ubicación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_floor_view_tree -msgid "Hotel Ubications" -msgstr "Ubicaciones" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_reservation_ids -msgid "Hotel room reservation detail." -msgstr "Detalle de la reserva" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_service_ids -msgid "Hotel services detail provide to customer and it will include in main Invoice." -msgstr "Hotel services detail provide to customer and it will include in main Invoice." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_id -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_id -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_id -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_id -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_id -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_id_5487 -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_id -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_id -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_id -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_id -#: model:ir.model.fields,field_description:hotel.field_service_on_day_id +#. 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_ir_sequence__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_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_cancelation_rule__id +#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__id +#: model:ir.model.fields,field_description:pms.field_pms_ubication__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_folio_wizard__id +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__id +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__id +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__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_users__id +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__id +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__id msgid "ID" -msgstr "ID (identificación)" +msgstr "ID" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -msgid "If a Hotel Folio is done, you cannot modify it manually anymore. However, you will still be able to invoice. This is used to freeze the Hotel Folio." -msgstr "If a Hotel Folio is done, you cannot modify it manually anymore. However, you will still be able to invoice. This is used to freeze the Hotel Folio." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__im_status +msgid "IM Status" +msgstr "Estado del IM" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_message_unread -msgid "If checked new messages require your attention." -msgstr "Si está marcado, hay nuevos mensajes que requieren su atención" +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_message_needaction +#. 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: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 hay nuevos mensajes que requieren su atención." +msgstr "Si está marcado, los mensajes nuevos requieren su atención." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_partner_invoice_lang -#: model:ir.model.fields,help:hotel.field_hotel_reservation_partner_invoice_lang -msgid "If the selected language is loaded in the system, all documents related to this contact will be printed in this language. If not, it will be English." -msgstr "Si el idioma seleccionado está cargado en el sistema, todos los documentos relacionados con el contacto se imprimirán en este idioma. Si no, se imprimirán en inglés." +#. 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 "Si está marcado, algunos mensajes tienen un error de entrega." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_restriction_active -msgid "If unchecked, it will allow you to hide the restriction plan without removing it." -msgstr "If unchecked, it will allow you to hide the restriction plan without removing it." +#. 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: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:470 +#. 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_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 "" +"If the sanitized phone number is on the blacklist, the contact won't receive mass mailing sms " +"anymore, from any list" + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type_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 +#: code:addons/pms/models/pms_shared_room.py:0 #, python-format -msgid "If you want drop the line, use the trash icon" -msgstr "If you want drop the line, use the trash icon" +msgid "" +"If you want to eliminate beds in the room you must deactivate the beds from your " +"form" +msgstr "Si quiere eliminar camas de la habitación debe desactivar las camas de su formulario" -#. module: hotel -#: code:addons/hotel/models/hotel_shared_room.py:42 -#, python-format -msgid "If you want to eliminate beds in the room you must deactivate the beds from your form" -msgstr "If you want to eliminate beds in the room you must deactivate the beds from your form" +#. module: pms +#: 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_image -#: model:ir.model.fields,help:hotel.field_hotel_service_product_image -msgid "Image of the product variant (Big-sized image of product template if false). It is automatically resized as a 1024x1024px image, with aspect ratio preserved." -msgstr "Imagen de la variante del producto (Imagen grande de la plantilla del producto en caso de que esté vacía). Se redimensionará automáticamente como una imagen 1024x1024px, manteniendo la proporción." +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_image_medium -msgid "Image of the product variant (Medium-sized image of product template if false)." -msgstr "Imagen de la variante del producto (Imagen mediana de la plantilla del producto en caso de ser falso)." +#. 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_128 +#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_128 +msgid "Image 128" +msgstr "Imagen 128" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_image_small -msgid "Image of the product variant (Small-sized image of product template if false)." -msgstr "Imagen de la variante del producto (Imagen pequeña de la plantilla del producto en caso de ser falso)." +#. 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: hotel -#: selection:hotel.reservation,cancelled_reason:0 +#. 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,field_description:pms.field_pms_reservation_line__impacts_quota +msgid "Impacts quota" +msgstr "Cuota de Impactos" + +#. 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.selection,name:pms.selection__pms_reservation__cancelled_reason__intime msgid "In time" msgstr "A tiempo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_customer_sleep_here -msgid "Include customer" -msgstr "Incluir cliente" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__included +msgid "Included" +msgstr "Incluído" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_deposit_account_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_account_income_id +#. 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" +msgstr "Cuenta de Ingresos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_incoming_qty -msgid "Incoming" -msgstr "Entrada" +#. 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 "" +"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." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_reservation_customer_sleep_here -msgid "Indicates if the customer sleeps in this room" -msgstr "Indica si el cliente duerme en esta habitación" +#. 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 "" +"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." -#. module: hotel -#: model:ir.actions.server,name:hotel.Guest_reservation_reminder_24hrs_ir_actions_server -#: model:ir.cron,cron_name:hotel.Guest_reservation_reminder_24hrs -#: model:ir.cron,name:hotel.Guest_reservation_reminder_24hrs -msgid "Inform Guest About Reservation Before 24 Hours" -msgstr "Inform Guest About Reservation Before 24 Hours" +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_sale_channel__channel_type__indirect +msgid "Indirect" +msgstr "Indirecto" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form +#. 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 +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form msgid "Information" msgstr "Información" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_categ_id -msgid "Internal Category" -msgstr "Categoría interna" +#. module: pms +#: code:addons/pms/models/pms_room_type.py:0 +#, python-format +msgid "Integrity error: There's multiple room types with code %swith the same code 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_internal_comment -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_internal_comment -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_folio_internal_comment +#. module: pms +#: 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 de la Ficha" +msgstr "Notas Internas del Folio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_internal_comment -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_internal_comment +#. 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 sobre el Cliente" +msgstr "Notas Internas del Cliente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_default_code -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_default_code +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_amenity__default_code +#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_code msgid "Internal Reference" -msgstr "Referencia interna" +msgstr "Referencias Internas" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_barcode +#. 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 de producto." +msgstr "Número de artículo internacional usado para la identificación del producto." -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1250 +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 #, python-format -msgid "Invalid Nights! Max is '%d'" -msgstr "Núm de noches inválidad! Máximo s on '%d'" +msgid "Invalid domain operator %s" +msgstr "Operador del dominio no válido %s" -#. module: hotel -#: code:addons/hotel/models/res_config.py:84 +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 #, python-format -msgid "Invalid arrival hour (Format: HH:mm)" -msgstr "Hora de llegada no válida (Formato: HH:mm)" +msgid "Invalid domain operator %s for left of checkin" +msgstr "Operador del dominio no válido %s para left of checkin" -#. module: hotel -#: code:addons/hotel/models/res_config.py:86 +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 #, python-format -msgid "Invalid departure hour (Format: HH:mm)" -msgstr "Hora de salida no válida (Formato: HH:mm)" +msgid "Invalid domain right operand %s" +msgstr "El operador de la derecha del dominio no es válido %s" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_stock_inventory -msgid "Inventory Location" -msgstr "Ubicación de inventario" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_valuation -msgid "Inventory Valuation" -msgstr "Valoración del inventario" - -#. module: hotel -#: model:ir.model,name:hotel.model_account_invoice +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_warn msgid "Invoice" msgstr "Factura" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_partner_invoice_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_id -msgid "Invoice Address" -msgstr "Dirección de 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search -msgid "Invoice Contact" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_invoice_id +#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_invoice_id +msgid "Invoice Address" msgstr "Dirección de Facturación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_invoice_count -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_invoice_count +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_agency +#: model:ir.model.fields,field_description:pms.field_res_partner__invoice_agency +#: model:ir.model.fields,field_description:pms.field_res_users__invoice_agency +msgid "Invoice Agency" +msgstr "Agencia de Facturación" + +#. 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 "Invoice Count" +msgstr "Cuenta de Facturación" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_view_folio_advance_payment_inv -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -msgid "Invoice Folio" -msgstr "Facturar Ficha" +#. 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: hotel -#: model:ir.model,name:hotel.model_account_invoice_line -msgid "Invoice Line" -msgstr "Linea de Factura" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_line_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_invoice_line_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_invoice_line_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_invoice_line_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__invoice_lines +#: model:ir.model.fields,field_description:pms.field_pms_reservation__move_line_ids +#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__move_line_ids +#: model_terms:ir.ui.view,arch_db:pms.pms_invoice_filter_days_form msgid "Invoice Lines" -msgstr "Líneas de la factura" +msgstr "Líneas de Facturación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_invoice_status -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_invoice_status -#: model:ir.model.fields,field_description:hotel.field_hotel_service_invoice_status +#. 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 factura" +msgstr "Estado de Facturación" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_partner_invoice_id -msgid "Invoice address for current Invoice." -msgstr "Dirección de facturación para la factura actúal" +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_folio__partner_invoice_id +msgid "Invoice address for current group." +msgstr "Dirección de facturación para el grupo actual." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_partner_invoice_id -#: model:ir.model.fields,help:hotel.field_hotel_reservation_partner_invoice_id -msgid "Invoice address for current sales order." -msgstr "Dirección de facturación para el pedido de venta actual." +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_reservation__partner_invoice_id +msgid "Invoice address for current reservation." +msgstr "Dirección de facturación para la reserva actual." -#. module: hotel -#: selection:folio.advance.payment.inv,advance_payment_method:0 -msgid "Invoiceable lines (deduct down payments)" -msgstr "Líneas Facturas (restando los adelantos)" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_qty_invoiced -#: model:ir.model.fields,field_description:hotel.field_hotel_service_qty_invoiced +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation_line__invoiced +#: model:ir.model.fields,field_description:pms.field_pms_service__qty_invoiced +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Invoiced" msgstr "Facturado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_invoice_ids -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_invoiced +#: model:ir.model.fields,field_description:pms.field_pms_reservation__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_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Invoices" msgstr "Facturas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_invoice_policy +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_is_board_service +#. 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 msgid "Is Board Service" -msgstr "Es un BoardService" +msgstr "Es Servicio de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_is_follower +#. 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 un seguidor" +msgstr "Es Seguidor" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_overbooking +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__overbooking msgid "Is Overbooking" msgstr "Es Overbooking" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_is_product_variant +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__is_product_variant msgid "Is Product Variant" -msgstr "Is Product Variant" +msgstr "Es Variante de Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_reselling +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__reselling msgid "Is Reselling" -msgstr "Es Reventa" +msgstr "Es reventa" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_product_pricelist_is_staff -msgid "Is Staff" -msgstr "Es Staff" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__is_company +msgid "Is a Company" +msgstr "Es una compañía" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_partner_is_agency -#: model:ir.model.fields,field_description:hotel.field_res_users_is_agency -msgid "Is Tour Operator" -msgstr "Es Operadora Tuística" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_is_extra_bed -#: model:ir.model.fields,field_description:hotel.field_product_product_is_extra_bed -#: model:ir.model.fields,field_description:hotel.field_product_template_is_extra_bed +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__is_downpayment +msgid "Is a down payment" +msgstr "Es un pago inicial" + +#. 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 cama supletoria" +msgstr "Es una cama supletoria" -#. module: hotel -#: code:addons/hotel/models/hotel_checkin_partner.py:146 +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 #, python-format msgid "It is not yet checkin day!" -msgstr "Aún no ha llegado el día del Checkin!" +msgstr "¡Aún no es el día del checkin!" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio +#. module: pms +#: model:ir.model,name:pms.model_pms_invoice_filter_days_items +msgid "Item Days" +msgstr "Items por Día" + +#. 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,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 "Apuntes contables" +msgstr "Artículos Diarios" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:73 +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Journal from %s to %s" -msgstr "Journal from %s to %s" +msgstr "Diario desde %s hasta %s" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_account_income_id +#. 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 "Mantenga este campo vacío para usar el valor predeterminado de la categoría del producto." +msgstr "Mantener este campo vacío para usar el valor por defecto de la categoría del producto." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_lang -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_lang +#. 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 "Idioma" +msgstr "Lenguaje" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_last_post -msgid "Last Message Date" -msgstr "Fecha del último mensaje" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_floor___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_folio___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_service___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days___last_update -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation___last_update -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv___last_update -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason___last_update -#: model:ir.model.fields,field_description:hotel.field_service_on_day___last_update +#. 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_ir_sequence____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_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_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_ubication____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_folio_wizard____last_update +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days____last_update +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items____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_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_availability_plan____last_update +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule____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_shared_room____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_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_payment_folio____last_update msgid "Last Modified on" msgstr "Última modificación en" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_last_updated_res -msgid "Last Updated" -msgstr "Actualizado el" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_room_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_service_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_write_uid -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_write_uid -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_write_uid -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_write_uid -#: model:ir.model.fields,field_description:hotel.field_service_on_day_write_uid +#. 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_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_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_ubication__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_folio_wizard__write_uid +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__write_uid +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__write_uid +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__write_uid +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_uid +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_uid msgid "Last Updated by" -msgstr "Última actualización de" +msgstr "Última Actualización por" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_type_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_amenity_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_room_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_write_date -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_write_date -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_write_date -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_write_date -#: model:ir.model.fields,field_description:hotel.field_service_on_day_write_date +#. 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_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_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_ubication__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_folio_wizard__write_date +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__write_date +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days_items__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_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_availability_plan__write_date +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__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_shared_room__write_date +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__write_date +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__write_date msgid "Last Updated on" -msgstr "Última actualización en" +msgstr "Última Actualización en" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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.pms_reservation_view_form msgid "Lastname, Firstname" -msgstr "Apellidos, Nombre" +msgstr "Apellido, Nombre" -#. module: hotel -#: selection:hotel.reservation,cancelled_reason:0 -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_form +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 "Late Check-out" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Late Payment" -msgstr "Pago restrasado" +msgstr "Retraso en el pago" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_apply_on_late +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_late msgid "Late apply on" -msgstr "Apllicar cancelación tardía en" +msgstr "Aplicar Late" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_days_late +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__days_late msgid "Late first days" -msgstr "Tardía en los días inciales" +msgstr "Primeros días Late" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Lates and NoShows" -msgstr "Impagos y NoShows" +msgstr "Lates y NoShows" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv -msgid "Lines" -msgstr "Líneas" +#. 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: hotel -#: model:ir.model,name:hotel.model_line_advance_inv -msgid "Lines Advance Invoice" -msgstr "Lines Advance Invoice" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__left_for_checkin +msgid "Left For Checkin" +msgstr "Left For Checkin" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_room_amenity_ids +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__room_amenity_ids msgid "List of Amenities." -msgstr "Lista de características" +msgstr "Lista de Instalaciones." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_reservation_adults -#: model:ir.model.fields,help:hotel.field_hotel_reservation_wizard_adults +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_reservation__adults msgid "List of adults there in guest list. " -msgstr "Adultos en la lista de huéspedes." +msgstr "Lista de adultos que hay en la lista de invitados " -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_localizator +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__localizator msgid "Localizator" msgstr "Localizador" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_location_id -msgid "Location" -msgstr "Ubicación" - -#. module: hotel -#: selection:hotel.folio,state:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__done msgid "Locked" msgstr "Bloqueado" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.folio.wizard,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -#: selection:hotel.service,channel_type:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 "Mail" +msgstr "Correo" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_valuation -msgid "" -"Manual: The accounting entries to value the inventory are not posted automatically.\n" -" Automated: An accounting arrival is automatically created to value the inventory when a product enters or leaves the company." -msgstr "" -"Manual: Los registros contables de valoración del inventario no se publican automáticamente.\n" -" Automatizado: Se crea automáticamente un registro contable para evaluar el inventario cuando un producto entra o sale de la empresa." +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_service_type +#. module: pms +#: model:room.closure.reason,name:pms.pms_room_closure_reason_0 +msgid "Maintenance" +msgstr "Mantenimiento" + +#. 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" +"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 "" -"Establecer la cantidad en el pedido de forma manual: La factura se crea según cantidad introducida manualmente en el pedido, sin crear una cuenta analítica\n" -"Partes de horas en contrato: La factura se crea según las horas registradas en el parte de horas relacionado.\n" -"Crear tarea y controlar horas: Crea una tarea a la hora de validar el pedido de venta y la factura se crea según las horas registradas en dicha tarea." +"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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_prepaid_warning_days +#. 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 "Margen en días para crear un aviso si no se ha registrado un adelanto de pago" +msgstr "El margen en días para crear un aviso si el pago avanzado no fue registrado" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_changes_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_price_change_wizard -msgid "Massive Change" -msgstr "Cambiar" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_changes_wizard -msgid "Massive Change & Close" -msgstr "Cambios Masivos & Cerrar" - -#. module: hotel -#: model:ir.ui.menu,name:hotel.hotel_massive_change -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_changes_wizard +#. module: pms +#: model:ir.ui.menu,name:pms.menu_pms_room_massive_changes_wizard msgid "Massive Changes" msgstr "Cambios Masivos" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Massive Day Prices" -msgstr "Cambiar precios" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.product_pricelist_view_form +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_view_form +msgid "Massive changes" +msgstr "Cambios Masivos" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_massive_price_change_reservation_days -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_price_change_wizard -msgid "Massive Price Change" -msgstr "Cambiar precios" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__massive_changes_on +msgid "Massive changes on" +msgstr "Cambios Masivos en" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_max_rooms -msgid "Max" -msgstr "Max" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_max_adult -msgid "Max Adult" -msgstr "Max. Adultos" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "Max. Avail." +msgstr "Disp. Máx." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_max_child -msgid "Max Child" -msgstr "Max. Niños" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_avail +#: model:ir.model.fields,field_description:pms.field_pms_room_type__default_max_avail +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__max_avail +msgid "Max. Availability" +msgstr "Disponibilidad Máx" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_max_stay -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_max_stay +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__max_stay +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Max. Stay" -msgstr "Max. Estancia" +msgstr "Estancia Máx" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_max_stay_arrival -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_max_stay_arrival +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__max_stay_arrival +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__max_stay_arrival +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Max. Stay Arrival" -msgstr "Max. Estancia Llegada" +msgstr "Máx. Estancia Llegada" -#. module: hotel -#: code:addons/hotel/models/hotel_room_type_restriction_item.py:43 +#. module: pms +#: code:addons/pms/models/pms_room_type_availability_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_room_type_availability_rule.py:0 #, python-format msgid "Max. Stay Arrival can't be less than zero" -msgstr "Max. Stay Arrival can't be less than zero" +msgstr "Máx. Estancia Llegada no puede ser menor que cero" -#. module: hotel -#: code:addons/hotel/models/hotel_room_type_restriction_item.py:40 +#. module: pms +#: code:addons/pms/models/pms_room_type_availability_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_room_type_availability_rule.py:0 #, python-format msgid "Max. Stay can't be less than zero" -msgstr "Max. Stay can't be less than zero" +msgstr "La Estancia Máxima no puede ser menor que cero" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form msgid "Max. days InTime before Checkin" -msgstr "Máx. días en tiempo antes del checkin" +msgstr "Máximo de días a tiempo antes del Checkin" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_cancelation_rule_days_intime +#. 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 "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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_image_medium -msgid "Medium-sized image" -msgstr "Imagen de tamaño mediano" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sale_line_warn_msg +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_massive_changes_wizard__max_avail +#: model:ir.model.fields,help:pms.field_pms_room_type_availability_rule__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,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 la línea de pedido de venta" +msgstr "Mensaje para línea de pedido de ventas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_ids +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_min_stay -msgid "Min. Days" -msgstr "Min. Days" +#. module: pms +#: model:pms.amenity,name:pms.pms_amenity_5 +msgid "Microwave oven" +msgstr "Horno microondas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_min_stay -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_min_stay +#. 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_massive_changes_wizard__min_stay +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__min_stay +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Min. Stay" -msgstr "Min. Estancia" +msgstr "Estancia mínima" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_min_stay_arrival -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_min_stay_arrival +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__min_stay_arrival +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__min_stay_arrival +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Min. Stay Arrival" -msgstr "Mín. Estancia Llegada" +msgstr "Min. Estancia Llegada" -#. module: hotel -#: code:addons/hotel/models/hotel_room_type_restriction_item.py:35 +#. module: pms +#: code:addons/pms/models/pms_room_type_availability_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_room_type_availability_rule.py:0 #, python-format msgid "Min. Stay can't be less than zero" -msgstr "Min. estancia no puede ser menos que cero" +msgstr "La estancia mínima no puede ser menor que cero" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_orderpoint_ids -msgid "Minimum Stock Rules" -msgstr "Reglas de stock mínimo" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_mobile -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_mobile -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_mobile -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_mobile +#. 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 msgid "Mobile" msgstr "Móvil" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_form -msgid "Modifications" -msgstr "Modifications" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard +msgid "Model" +msgstr "Modelo" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Modify" -msgstr "Modificar" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dmo +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Monday" msgstr "Lunes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search -msgid "My Reservations" -msgstr "Mis Reservas" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__move_ids +msgid "Move" +msgstr "Asiento Contable" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_name -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_name -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_name -#: model:ir.model.fields,field_description:hotel.field_room_closure_reason_name -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__move_line_ids +msgid "Move Line" +msgstr "Apunte Contable" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.res_users_view_form +msgid "Multi Properties" +msgstr "Multipropiedad" + +#. 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.pms_room_view_form +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_view_form msgid "Name" msgstr "Nombre" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form -msgid "Name in reports" -msgstr "Nombre en Informes" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__name_updated +msgid "Name Updated" +msgstr "Nombre Actualizado" -#. module: hotel -#: code:addons/hotel/models/hotel_folio.py:99 -#: code:addons/hotel/models/hotel_folio.py:412 -#: code:addons/hotel/models/hotel_folio.py:416 -#: code:addons/hotel/models/hotel_folio.py:418 +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form +msgid "Name in reports" +msgstr "Nombre en los Informes" + +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 code:addons/pms/models/pms_folio.py:0 #, python-format msgid "New" msgstr "Nuevo" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_new_discount -msgid "New Discount" -msgstr "Nuevo Descuento" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_price_reservation_days_new_price -msgid "New Price" -msgstr "Nuevo Precio" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_date_deadline +#. 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 "Siguiente plazo de actividad" +msgstr "Fecha Límite para la Próxima Actividad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_summary +#. 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" +msgstr "Resumen de la Siguiente Actividad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_type_id +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_nights -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_nights -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_split_reservation_nights -#: model:ir.ui.view,arch_db:hotel.view_folio_advance_payment_inv +#. 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: hotel -#: code:addons/hotel/models/hotel_reservation.py:575 +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 #, python-format msgid "No Checkins!" -msgstr "Sin Checkins!" +msgstr "No Checkins!" -#. module: hotel -#: selection:hotel.reservation,cancelled_reason:0 -#: model:ir.ui.view,arch_db:hotel.hotel_cancelation_rule_form +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__no_checkout +msgid "No Checkout" +msgstr "No Checkout" + +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__cancelled_reason__noshow +#: model:ir.model.fields.selection,name:pms.selection__pms_reservation__state__no_show +#: model_terms:ir.ui.view,arch_db:pms.pms_cancelation_rule_form msgid "No Show" msgstr "No Show" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_apply_on_noshow +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__apply_on_noshow msgid "No Show apply on" -msgstr "No Show aplicar en" +msgstr "Aplicar No Show en" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:574 +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 #, python-format msgid "No checkin was made for this reservation" -msgstr "No se ha llegado a realizar ningún checkin en esta reserva!" +msgstr "Ningún checkin fue realizado en esta reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_days_noshow +#. 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 en los días inciales" +msgstr "NoShow los primeros días" -#. module: hotel -#: selection:hotel.folio,reservation_type:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__normal msgid "Normal" msgstr "Normal" -#. module: hotel -#: selection:hotel.folio,invoice_status:0 -#: selection:hotel.reservation,invoice_status:0 -#: selection:hotel.service,invoice_status:0 +#. 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 +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 que facturar" +msgstr "Nada para Facturar" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_res_company_cardex_warning -msgid "Notice under the signature on the traveler's ticket." -msgstr "Notice under the signature on the traveler's ticket." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_duplicate_reservation_num -msgid "Num. New Reservations" -msgstr "Num. Nuevas reservas" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_needaction_counter -msgid "Number of Actions" -msgstr "Número de acciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_rooms_num -msgid "Number of Rooms" -msgstr "Number of Rooms" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_reservation_children -#: model:ir.model.fields,help:hotel.field_hotel_reservation_wizard_children -msgid "Number of children there in guest list." -msgstr "Número de niños en la lista de huéspedes." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_message_needaction_counter -msgid "Number of messages which requires an action" -msgstr "Número de mensajes que requieren una acción" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_message_unread_counter -msgid "Number of unread messages" -msgstr "Número de mensajes no leidos" - -#. module: hotel -#: selection:hotel.checkin.partner,state:0 selection:hotel.reservation,state:0 -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search -msgid "On Board" -msgstr "Dentro" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -msgid "On Board Tomorrow" -msgstr "Personas Dentro Mañana" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Only Room" -msgstr "Solo Habitación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Only Services" -msgstr "Solo Servicios" - -#. module: hotel -#: sql_constraint:hotel.room.type.restriction.item:0 -msgid "Only can exists one restriction in the same day for the same room type!" -msgstr "Only can exists one restriction in the same day for the same room type!" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Open Master" -msgstr "Abrir Principal" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_bottom_tree -msgid "Open Reservation Room Detail" -msgstr "Abrir detalles de reserva" - -#. module: hotel -#. openerp-web -#: code:addons/hotel/static/src/js/views/list/list_controller.js:20 +#. module: pms +#: code:addons/pms/wizards/folio_make_invoice_advance.py:0 #, python-format -msgid "Open Wizard" -msgstr "Abrir Wizard" +msgid "Nothing to invoice" +msgstr "Nada paraFacturar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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_rooms +msgid "Number of Rooms" +msgstr "Número de Habitaciones" + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_reservation__children +msgid "Number of children there in guest list." +msgstr "Numero de niños en la lista de invitados." + +#. 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_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,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_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,field_description:pms.field_pms_reservation_line__occupies_availability +msgid "Occupies" +msgstr "Ocupa" + +#. 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 "On Board" + +#. 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 "On Board Tomorrow" +msgstr "On Board Mañana" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "Only Room" +msgstr "Solo la habitación" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "Only Services" +msgstr "Colo los servicios" + +#. module: pms +#: model:ir.model.constraint,message:pms.constraint_pms_room_type_availability_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/wizards/wizard_payment_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 by\n" +" pricelist (or without pricelist)" +msgstr "" +"Solo se puede configurar un servicio de habitación por defecto para cada tarifa (o sin tarifa)" + +#. 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_terms:ir.ui.view,arch_db:pms.report_folio_document msgid "Order #" msgstr "Pedido #" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_date_order +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_advance_payment_inv__count +msgid "Order Count" +msgstr "Recuento de Pedidos" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__date_order msgid "Order Date" -msgstr "Fecha de pedido" +msgstr "Fecha del Pedido" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_invoice_policy +#. 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 based on the quantity the customer ordered.\n" -"Delivered Quantity: Invoiced based on the quantity the vendor delivered (time or deliveries)." +"Ordered Quantity: Invoice quantities ordered by the customer.\n" +"Delivered Quantity: Invoice quantities delivered to the customer." msgstr "" -"Cantidad ordenada: Factura basada en la cantidad pedida por el cliente.\n" -"Cantidad entregada: Facturada en función de la cantidad entregada por el proveedor (tiempo o entregas)." +"Cantidad pedida: facturas ordenadas por el cliente.\n" +"Cantiadad entregada: facturas entregadas al cliente." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__origin +msgid "Origin" +msgstr "Origen" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Other data" -msgstr "Otra información" +msgstr "Otra fecha" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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: hotel -#: selection:hotel.checkin.partner,state:0 selection:hotel.reservation,state:0 -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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: hotel -#: selection:hotel.folio,reservation_type:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__out +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Out of Service" msgstr "Fuera de Servicio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Out service description" -msgstr "Descripción Fuera de Servicio" +msgstr "Descripción de Fuera de Servicio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_outgoing_qty -msgid "Outgoing" -msgstr "Saliente" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_invoice_outstanding_folios_debits_widget +#. 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 "Outstanding Folios Debits Widget" +msgstr "Widget para los Débitos pendientes del folio" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:193 -#, python-format -msgid "Outstanding credits" -msgstr "Crédito Pendiente" - -#. module: hotel -#: code:addons/hotel/models/inherited_account_invoice.py:82 +#. module: pms +#: code:addons/pms/models/account_move.py:0 #, python-format msgid "Outstanding credits in Folio" -msgstr "Pagos por asignar en la Ficha" +msgstr "Créditos pendientes en Folio" -#. module: hotel -#: code:addons/hotel/models/inherited_account_invoice.py:85 -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:196 +#. module: pms +#: code:addons/pms/models/account_move.py:0 #, python-format msgid "Outstanding debits" -msgstr "Débito Pendiente" +msgstr "Débitos pendientes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Overbookings" msgstr "Overbookings" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Paid Amount" -msgstr "Cantidad Pagada" +#. module: pms +#: model:ir.model,name:pms.model_pms_folio +msgid "PMS Folio" +msgstr "PMS Folio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_parent_reservation -msgid "Parent Reservation" -msgstr "Reserva padre" +#. module: pms +#: model:ir.ui.menu,name:pms.pms_management_menu +msgid "PMS Management" +msgstr "Gestión del PMS" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_partner_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_id +#. 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 +msgid "Paid" +msgstr "Pagado/a" + +#. 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 +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_checkin_partner__partner_id +#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_id +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__partner_id +#: model:ir.model.fields,field_description:pms.field_pms_reservation__partner_id +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__partner_id +#: model_terms:ir.ui.view,arch_db:pms.folio_wizard msgid "Partner" -msgstr "Empresa" +msgstr "Cliente" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Partner Note" -msgstr "Nota de Cliente" +msgstr "Nota del Cliente" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Partner Notes" msgstr "Notas del Cliente" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:74 -#: code:addons/hotel/models/inherited_account_payment.py:116 -#: code:addons/hotel/models/inherited_account_payment.py:124 -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_payment_ids +#. 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 ID de Impuestos" + +#. 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: hotel -#: code:addons/hotel/models/inherited_account_payment.py:67 +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Payment %s modified: \n" -msgstr "Pago %s modificado: \n" +msgstr "Pago % sModificado:\n" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Payment Date" -msgstr "Fecha de pago" - -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:85 +#. module: pms +#: code:addons/pms/models/account_payment.py:0 #, python-format msgid "Payment Deleted" -msgstr "Pago eliminado" +msgstr "Pago Borrado" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Payment Matching" -msgstr "Asignación de Pagos" +#. module: pms +#: model:ir.actions.act_window,name:pms.action_payment_folio +msgid "Payment Folio" +msgstr "Pago del Folio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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 "Método de pago" +msgstr "Método de Pago" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search msgid "Payment Pending" -msgstr "Pagos Pendientes" +msgstr "Pendiente de Pago" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__reference msgid "Payment Ref." -msgstr "Referencia de Pago" +msgstr "Ref. del Pago." -#. module: hotel -#: code:addons/hotel/models/inherited_payment_return.py:26 -#, python-format -msgid "Payment Return" -msgstr "Devolución" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_state +msgid "Payment Status" +msgstr "Estado del Pago" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_refund_amount -msgid "Payment Returns" -msgstr "Devoluciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_payment_term_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__payment_term_id msgid "Payment Terms" -msgstr "Plazos de pago" +msgstr "Términos del Pago" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:115 +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__payment_token_ids +msgid "Payment Tokens" +msgstr "Señales del 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 cómo método de pago" +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: hotel -#: model:ir.model,name:hotel.model_payment_return -msgid "Payment return" -msgstr "Devolución de cobro" - -#. module: hotel -#: code:addons/hotel/models/inherited_account_invoice.py:29 -#: model:ir.model,name:hotel.model_account_payment -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_invoices_paid -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. 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__invoices_paid +#: model:ir.model.fields,field_description:pms.field_pms_folio__move_line_ids #, python-format msgid "Payments" msgstr "Pagos" -#. module: hotel -#: selection:hotel.checkin.partner,state:0 selection:hotel.reservation,state:0 +#. 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_folio__checkins_ratio +#: 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__reservation_pending_arrival_ids +msgid "Pending Arrival Rooms" +msgstr "Habitaciones Pendientes de Llegada" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__ratio_checkin_data +#: model:ir.model.fields,field_description:pms.field_pms_reservation__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 "Por entrar" +msgstr "Llegada Pendiente" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_pending_amount -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_folio_pending_amount +#. 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 in Folio" -msgstr "Pendiente en Ficha" +msgstr "Pendiente en Folio" -#. module: hotel -#: selection:hotel.board.service,price_type:0 -#: selection:hotel.board.service.room.type,price_type:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_board_service__price_type__percent +#: model:ir.model.fields.selection,name:pms.selection__pms_board_service_room_type__price_type__percent msgid "Percent" msgstr "Porcentaje" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_company_default_cancel_policy_percent +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__default_cancel_policy_percent msgid "Percent to pay" -msgstr "Porcentaje a pagas" +msgstr "Porcentaje a pagar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_tree +#. 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 "Contactos" +msgstr "Personas" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.folio.wizard,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -#: selection:hotel.service,channel_type:0 -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_phone -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_phone -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: code:addons/pms/models/pms_reservation_line.py:0 +#, python-format +msgid "Persons can't be higher than room capacity" +msgstr "Las personas no pueden ser mayores que la capacidad de la habitación" + +#. module: pms +#: code:addons/pms/models/pms_reservation.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_folio__phone +#: model:ir.model.fields,field_description:pms.field_pms_property__phone +#: model:ir.model.fields,field_description:pms.field_pms_reservation__phone +#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__phone msgid "Phone" msgstr "Teléfono" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:382 -#, python-format -msgid "Please define an accounting sales journal for this company." -msgstr "Please define an accounting sales journal for this company." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__phone_sanitized_blacklisted +msgid "Phone Blacklisted" +msgstr "Lista negra de Teléfonos" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:490 +#. module: pms +#: code:addons/pms/models/pms_folio.py:0 #, python-format -msgid "Please define income account for this product: \"%s\" (id:%d) - or for its category: \"%s\"." -msgstr "Please define income account for this product: \"%s\" (id:%d) - or for its category: \"%s\"." +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: hotel -#: selection:hotel.reservation,state:0 +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_board_service__pms_board_service_room_type_ids +msgid "Pms Board Service Room Type" +msgstr "Pms Board Service Room Type" + +#. module: pms +#: 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_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_reservation__pms_property_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:ir.model.fields,field_description:pms.field_pms_shared_room__pms_property_ids +msgid "Pms Property" +msgstr "Pms Property" + +#. 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.selection,name:pms.selection__pms_reservation__state__draft msgid "Pre-reservation" msgstr "Pre-reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_prepaid_warning_days -msgid "Prepaid Warning Days" -msgstr "Días de aviso de Prepago" +#. 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 "" +"Método de pago preferido para pagar a este proveedor. Esto es usado para filtrar las facturas del " +"proveedor por el método de pago preferido para registrar pagos en masa. Casos de uso: crear " +"archivos bancarios para transferencias por lotes, verificar ejecuciones." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_price -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_price -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_price +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_price_room -msgid "Price Room" -msgstr "Precio Habitación" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_reduce +msgid "Price Reduce" +msgstr "Precio Reducido" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_price_subtotal -msgid "Price Subtotal" -msgstr "Subtotal del precio" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_price_tax -msgid "Price Tax" -msgstr "Importe Impuesto" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_price_total -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_price_total +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_total msgid "Price Total" -msgstr "Precio Total" +msgstr "Precio total" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_price_unit -msgid "Price Unit" -msgstr "Precio Unidad" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_price -msgid "Price by Room" -msgstr "Precio por habitación" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__price_per_room +msgid "Price per room" +msgstr "Precio pro habitación" -#. module: hotel -#: selection:hotel.wizard.massive.changes,section:0 -#: model:ir.model,name:hotel.model_product_pricelist -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_pricelist_id +#. module: pms +#: model:ir.model,name:pms.model_product_pricelist +#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__pricelist_id +#: model:ir.model.fields,field_description:pms.field_pms_folio__pricelist_id +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__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.selection,name:pms.selection__pms_massive_changes_wizard__massive_changes_on__pricelist +#: model:ir.ui.menu,name:pms.pricelist_menu model_terms:ir.ui.view,arch_db:pms.folio_wizard +#: 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 "Tarifas" +msgstr "Tarifa" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_pricelist_item_ids -msgid "Pricelist Item" -msgstr "Item de Lista de precios" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_items_to_overwrite +msgid "Pricelist Items To Overwrite" +msgstr "Items de la tarefa a sobrescribir" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_item_ids -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_view_form -msgid "Pricelist Items" -msgstr "Items de Lista de precios" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_product_pricelist_pricelist_type +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_pricelist_id -#: model:ir.model.fields,help:hotel.field_hotel_folio_wizard_pricelist_id -#: model:ir.model.fields,help:hotel.field_hotel_reservation_pricelist_id +#. 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 de la ficha actúal" +msgstr "Tarifa para el Folio Actual." -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_cancelation_rule_pricelist_ids +#. 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 "Items de la tarifa para sobrescribir en los cambios masivos" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_cancelation_rule__pricelist_ids msgid "Pricelist that use this rule" -msgstr "Tarifa usada en esta regla" +msgstr "Tarifas que usan esta regla" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_to_print -#: model:ir.model.fields,field_description:hotel.field_hotel_service_to_print -msgid "Print" -msgstr "Imprimir" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__pricelist_id +msgid "Pricelist to apply massive changes" +msgstr "Tarifas a aplicar en los cambios masivos" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_reservation_to_print -#: model:ir.model.fields,help:hotel.field_hotel_service_to_print -msgid "Print in Folio Report" -msgstr "Imprimir Ficha" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_plan__pms_pricelist_ids +msgid "Pricelists" +msgstr "Tarifas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__priority +msgid "Priority" +msgstr "Prioridad" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_amenity_view_form msgid "Procurement" -msgstr "Procurement" +msgstr "Obtención" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_product_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_line_product_id -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_line_product_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_product_variant_id -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search msgid "Product" msgstr "Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_attribute_line_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__attribute_line_ids msgid "Product Attributes" -msgstr "Atributos del producto" +msgstr "Atributos del Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_product_image +#. 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" +msgstr "Imagen del Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_packaging_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__packaging_ids msgid "Product Packages" -msgstr "Paquetes de productos" +msgstr "Paquetes del Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_connector_config_settings_default_pricelist_id -#: model:ir.model.fields,field_description:hotel.field_res_config_settings_default_pricelist_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__default_pricelist_id msgid "Product Pricelist" -msgstr "Tarifa" +msgstr "Tarifa del Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_product_id +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_id msgid "Product Room Type" -msgstr "Product Room Type" +msgstr "Producto del Tipo de Habitación" -#. module: hotel -#: model:ir.model,name:hotel.model_product_template -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_product_tmpl_id +#. module: pms +#: model:ir.model,name:pms.model_product_template +#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_tmpl_id msgid "Product Template" msgstr "Plantilla de producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_type +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__type msgid "Product Type" -msgstr "Tipo de producto" +msgstr "Tipo de Producto" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_stock_production -msgid "Production Location" -msgstr "Ubicación de producción" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_product_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_product_variant_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__product_variant_ids msgid "Products" -msgstr "Productos" +msgstr "Prductos" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_res_company_additional_hours -msgid "Provide the min hours value for check in, checkout days, whatever the hours will be provided here based on that extra days will be calculated." -msgstr "Proporcione el valor de las horas mínimas para el check in, los días de salida, cualquiera que sea el horario que se proporcionará aquí en base a los días adicionales que se calcularán." +#. 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 "Prop. Demo Suite" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description_purchase +#. 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_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_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_cancelation_rule__pms_property_ids +#: model:ir.model.fields,field_description:pms.field_pms_ubication__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_availability_plan__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_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_users__pms_property_ids +#: model:ir.model.fields,field_description:pms.field_room_closure_reason__pms_property_ids +#: model:ir.ui.menu,name:pms.pms_property_menu +msgid "Properties" +msgstr "Proiedades" + +#. module: pms +#: model:ir.model,name:pms.model_pms_property +#: model:ir.model.fields,field_description:pms.field_account_bank_statement__property_id +#: model:ir.model.fields,field_description:pms.field_account_journal__pms_property_ids +#: model:ir.model.fields,field_description:pms.field_ir_sequence__pms_property_id +#: model:ir.model.fields,field_description:pms.field_pms_property__partner_id +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__pms_property_id +#: model:ir.model.fields,field_description:pms.field_res_users__pms_property_id +#: model_terms:ir.ui.view,arch_db:pms.ir_sequence_view_form +#: model_terms:ir.ui.view,arch_db:pms.ir_sequence_view_tree +msgid "Property" +msgstr "Propiedad" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form +msgid "Property Configuration" +msgstr "Configuración de la Propiedad" + +#. module: pms +#: model:res.groups,name:pms.group_pms_call +msgid "Property Management / CallCenter" +msgstr "Mantenimiento de la Propiedad/ Centro de Llamadas" + +#. module: pms +#: model:res.groups,name:pms.group_pms_user +msgid "Property Management / User" +msgstr "Mantenimiento de la Propiedad / Usuarios" + +#. module: pms +#: model:res.groups,name:pms.group_pms_manager +msgid "Property Management/ Manager" +msgstr "Mantenimiento de la Propiedad/ 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_search +#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_tree +msgid "Property Room" +msgstr "Habitación de la Propiedad" + +#. 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 de la Propiedad" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__class_id +msgid "Property Type Class" +msgstr "Clase del Tipo de la propiedad" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_form +msgid "Property Ubication" +msgstr "Ubicación de la Propiedad" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_ubication_view_tree +msgid "Property Ubications" +msgstr "Ubicaciones de la Propiedad" + +#. module: pms +#: code:addons/pms/models/pms_room_type.py:0 +#, python-format +msgid "Property isn't allowed in Room Type Class" +msgstr "La propiedad no está permitida en la clase del Tipo de Habitación" + +#. module: pms +#: code:addons/pms/models/pms_amenity.py:0 code:addons/pms/models/pms_room.py:0 +#: code:addons/pms/models/pms_room_type_availability_rule.py:0 +#: code:addons/pms/models/product_pricelist.py:0 code:addons/pms/models/product_pricelist_item.py:0 +#, python-format +msgid "Property not allowed" +msgstr "Propiedad no permitida" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_tree +msgid "Property settings summary" +msgstr "Resumen de la configuración de la propiedad" + +#. 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" +msgstr "Descripción de Compra" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_uom_po_id +#. 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 compra" +msgstr "Unidad de medida de la compra" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_qty_at_date -#: model:ir.model.fields,field_description:hotel.field_hotel_service_product_qty -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_product_uom_qty -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_qty -#: model:ir.model.fields,field_description:hotel.field_service_on_day_product_qty -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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.report_folio_document msgid "Quantity" msgstr "Cantidad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_qty_available -msgid "Quantity On Hand" -msgstr "Cantidad a mano" +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_incoming_qty +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__quota +#: model:ir.model.fields,field_description:pms.field_pms_room_type_availability_rule__quota +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard +msgid "Quota" +msgstr "Cuota" + +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__default_quota msgid "" -"Quantity of planned incoming products.\n" -"In a context with a single Stock Location, this includes goods arriving to this Location, or any of its children.\n" -"In a context with a single Warehouse, this includes goods arriving to the Stock Location of this Warehouse, or any of its children.\n" -"Otherwise, this includes goods arriving to any Stock Location with 'internal' type." +"Quota assigned to the own Booking Engine given no availability rules. Use `-1` for managing no " +"quota." msgstr "" -"Cantidad de productos entrantes planificados.\n" -"En un contexto con una única ubicación de stock, esto incluye los bienes que llegan a esta ubicación o cualquiera de sus hijos.\n" -"En un contexto con un solo Almacén, esto incluye los bienes que llegan a la Ubicación de stock de este Almacén, o cualquiera de sus hijos.\n" -"De lo contrario, esto incluye bienes que llegan a cualquier Ubicación de Stock con tipo 'interno'." +"Cuota asignada al propio Motor de Reservas sin reglas de disponibilidad. Utilice '-1' para " +"gestionar la ausencia de cuota." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_outgoing_qty -msgid "" -"Quantity of planned outgoing products.\n" -"In a context with a single Stock Location, this includes goods leaving this Location, or any of its children.\n" -"In a context with a single Warehouse, this includes goods leaving the Stock Location of this Warehouse, or any of its children.\n" -"Otherwise, this includes goods leaving any Stock Location with 'internal' type." -msgstr "" -"Cantidad de productos salientes planificados.\n" -"En un contexto con una única ubicación de stock, esto incluye bienes que salen de esta ubicación o cualquiera de sus hijos.\n" -"En un contexto con un solo Almacén, esto incluye los bienes que salen de la Ubicación de stock de este Almacén, o cualquiera de sus hijos.\n" -"De lo contrario, esto incluye bienes que salgan de cualquier Stock Stock con tipo 'interno'." - -#. module: hotel -#: selection:hotel.folio,state:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__draft msgid "Quotation" -msgstr "Presupuesto" +msgstr "Cotización" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.report_folio_document msgid "Quotation #" -msgstr "Presupuesto # " +msgstr "Cotización #" -#. module: hotel -#: selection:hotel.folio,state:0 +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__state__sent msgid "Quotation Sent" -msgstr "Presupuesto Enviado" +msgstr "Cotización Envíada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_description_dates -msgid "Range" -msgstr "Rango" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_expense_policy +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__expense_policy msgid "Re-Invoice Expenses" -msgstr "Gastos de Re-factura" +msgstr "Gastos de re-facturación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_code +#. 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_advanced_filters_wizard__pms_model_id +msgid "Recipients Model" +msgstr "Modelo de 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:ir.model.fields,field_description:pms.field_pms_property__ref +#: model:ir.model.fields,field_description:pms.field_pms_room_type__code msgid "Reference" msgstr "Referencia" -#. module: hotel -#: code:addons/hotel/models/hotel_folio.py:322 -#: code:addons/hotel/models/hotel_reservation.py:1090 -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio +#. 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 "Registrar pago" +msgstr "Registro de pago" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_parent_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_parent_id +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__folio_advance_payment_inv__advance_payment_method__delivered +msgid "Regular invoice" +msgstr "Factura regual" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__parent_id msgid "Related Company" -msgstr "Empresa relacionada" +msgstr "Compañía relacionada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_reordering_max_qty -msgid "Reordering Max Qty" -msgstr " Abasteciendo cant. max." +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_reordering_min_qty -msgid "Reordering Min Qty" -msgstr " Abasteciendo cant. min." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_nbr_reordering_rules -msgid "Reordering Rules" -msgstr "Reglas de abastecimiento" - -#. module: hotel -#: model:ir.ui.menu,name:hotel.hotel_reports_menu +#. module: pms +#: model:ir.ui.menu,name:pms.pms_reports_menu msgid "Reports" -msgstr "Informes" +msgstr "Reportes" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_reservation_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_reservation_id -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_reservation_id -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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_folio__reservation_ids +#: model:ir.model.fields,field_description:pms.field_pms_reservation_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 msgid "Reservation" -msgstr "Reserva" +msgstr "Reservas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_name +#. module: pms +#: model:ir.actions.act_window,name:pms.room_type_availability_action +msgid "Reservation Availability Plans" +msgstr "Planes de Disponibilidad para las Reservas" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__name msgid "Reservation Description" -msgstr "Descripción de Reserva" +msgstr "Descripción de la Reserva" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Reservation Detail" msgstr "Detalle de la Reserva" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Reservation Details" -msgstr "Detalles de la Reseva" +msgstr "Detalles de la Reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_reservation_line_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_invoice_filter_days__reservation_line_ids +#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_line_ids msgid "Reservation Line" -msgstr "Reservation Line" +msgstr "Línea de la Reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_invoice_line_reservation_line_ids -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_reservation_line_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_account_move_line__reservation_line_ids msgid "Reservation Lines" -msgstr "Reservation Lines" +msgstr "Líneas de la Reserva" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_reservation_no -msgid "Reservation No" -msgstr "Nº de Reserva" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Reservation Notes" -msgstr "Notas" +msgstr "Notas de la Reserva" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_open_hotel_reservation_form_tree_all -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. 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_open_pms_reservation_form_tree_all +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Reservation Rooms" -msgstr "Reservas" +msgstr "Habitaciones de la Reserva" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_search +#. 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 "Servicio" +msgstr "Servicios de la Reserva" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Reservation Services" -msgstr "Servicios" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Reservation Total" -msgstr "Total Reserva" +msgstr "Total de la Reserva" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -msgid "Reservation Wizard" -msgstr "Reservation Wizard" +#. module: pms +#: model:ir.model,name:pms.model_pms_room_type_availability_plan +msgid "Reservation availability plan" +msgstr "Plan de Disponibilidad de la Reserva" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:645 -#, python-format -msgid "Reservation has no adults" -msgstr "La reserva no tiene adultos" +#. module: pms +#: model:ir.model,name:pms.model_pms_room_type_availability_rule +msgid "Reservation rule by day" +msgstr "Regla por día de la Reserva" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:643 -#, python-format -msgid "Reservation persons can't be higher than room capacity" -msgstr "Las personas de la reserva no pueden superiores a la capacidad de la habitación" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.room_type_restriction_action -msgid "Reservation restrictions" -msgstr "Restricciones" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.hotel_partner_reservations -#: model:ir.model.fields,field_description:hotel.field_account_invoice_line_reservation_ids -#: model:ir.model.fields,field_description:hotel.field_res_partner_reservations_count -#: model:ir.model.fields,field_description:hotel.field_res_users_reservations_count -#: model:ir.ui.menu,name:hotel.menu_all_folio -#: model:ir.ui.view,arch_db:hotel.res_partner_view_form +#. 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_account_move_line__reservation_ids +#: 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 +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__reservation_ids +#: model:ir.ui.menu,name:pms.menu_all_folio +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_calendar +#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form msgid "Reservations" msgstr "Reservas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.res_partner_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__reservations_pending_count +msgid "Reservations Pending Count" +msgstr "Recuento de reservas pendientes" + +#. module: pms +#: model:ir.model,name:pms.model_pms_reservation_line +msgid "Reservations by day" +msgstr "Reservas por día" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.res_partner_view_form msgid "Reservations related with this contact" -msgstr "Reservas de este contacto" +msgstr "Reservas relacionadas con este contacto" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Reservations to 1 month" -msgstr "Reservas a 1 mes" +msgstr "Reservas por 1 mes" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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" +msgstr "Reservas por 14 días" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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" +msgstr "Reservas por 7 días" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_tree -msgid "Reserved Unit Type" -msgstr "Tipo Reservado" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_reservation_wizard_ids -msgid "Resevations" -msgstr "Reservas" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_user_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_responsible_id -msgid "Responsible" -msgstr "Responsable" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_ids -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_view_form -msgid "Restriction Items" -msgstr "Elementos de Restricción" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_restriction_id -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_restriction_id -msgid "Restriction Plan" -msgstr "Plan de Restricciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_name -msgid "Restriction Plan Name" -msgstr "Nombre del Plan de Restricciones" - -#. module: hotel -#: selection:hotel.wizard.massive.changes,section:0 -#: model:ir.model.fields,field_description:hotel.field_connector_config_settings_default_restriction_id -#: model:ir.model.fields,field_description:hotel.field_res_config_settings_default_restriction_id -#: model:ir.ui.menu,name:hotel.reservation_restriction_menu -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_item_view_form -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_item_view_tree -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_view_form -#: model:ir.ui.view,arch_db:hotel.room_type_restriction_view_tree -msgid "Restrictions" -msgstr "Restricciones" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -msgid "Retun Payments" -msgstr "Devoluciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_return_ids -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Return" -msgstr "Devolver" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Return Amount" -msgstr "Cantidad devuelta" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Return Date" -msgstr "Fecha devolución" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Return Method" -msgstr "Método devolución" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.report_folio_document -msgid "Return Ref." -msgstr "Referencia devolución" - -#. module: hotel -#: code:addons/hotel/models/inherited_payment_return.py:25 -#, python-format -msgid "Return of %s registered" -msgstr "Return of %s registered" - -#. module: hotel -#: code:addons/hotel/models/hotel_folio.py:371 -#, python-format -msgid "Returns" -msgstr "Devoluciones" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_reservation_id -#: model:ir.ui.menu,name:hotel.menu_hotel_room -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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_reservation_wizard__options +#: model:ir.model.fields,field_description:pms.field_pms_service__reservation_id +#: model:ir.model.fields,field_description:pms.field_pms_service_line__room_id +#: model:ir.ui.menu,name:pms.menu_pms_room model:pms.room.type.class,name:pms.pms_room_type_class_0 +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Room" msgstr "Habitación" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_type_view_form +#. module: pms +#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_view_form +#: 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" +msgstr "Instalaciones de la habitación" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_room_closure_reason_form_tree +#. 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 instalaciones 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.model.constraint,message:pms.constraint_pms_room_type_class_default_code_unique +msgid "Room Class Code must be unique!" +msgstr "El código de la clase de habitación debe ser único!" + +#. 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" +msgstr "Razón de cierre de la habitación" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Room Line" -msgstr "Línea de habitación" +msgstr "Línea de la habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_reservation_ids -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -msgid "Room Lines" -msgstr "Líneas de habitación" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_name -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room__name +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__name msgid "Room Name" -msgstr "Nombre Habitación" +msgstr "Nombre de la Habitación" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -msgid "Room No" -msgstr "Habitación No" +#. module: pms +#: model:ir.model.constraint,message:pms.constraint_pms_reservation_line_rule_availability +msgid "Room Occupied" +msgstr "Habitación Ocupada" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_price_room_services_set +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_checkin_partner_kanban_view +msgid "Room Reservation" +msgstr "Reservas de la habitacion" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_room_services_set msgid "Room Services Total" -msgstr "Room Services Total" +msgstr "Servicios totales de la habitación" -#. module: hotel -#: selection:hotel.wizard.massive.changes,applied_on:0 -#: model:ir.actions.act_window,name:hotel.open_hotel_room_type_form_tree -#: model:ir.model,name:hotel.model_hotel_room_type -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_hotel_room_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_room_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_room_type_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_restriction_item_room_type_id -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_room_type_id -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form +#. 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_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_id +#: 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_availability_rule__room_type_id +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__room_type_id +#: 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_shared_room_view_form msgid "Room Type" msgstr "Tipo de Habitación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_room_amenity_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__room_amenity_ids msgid "Room Type Amenities" -msgstr "Room Type Amenities" +msgstr "Instalaciones del tipo de habitación" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.open_hotel_room_type_class_form_tree -#: model:ir.model,name:hotel.model_hotel_room_type_class +#. 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 msgid "Room Type Class" -msgstr "Room Type Class" +msgstr "Clase del Top de Habitacion" -#. module: hotel -#: sql_constraint:hotel.room.type:0 -msgid "Room Type Code must be unique!" -msgstr "El código de la habitación debe ser único!" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_kanban -#: model:ir.ui.view,arch_db:hotel.hotel_shared_shared_room_view_kanban +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_kanban +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_shared_room_view_kanban msgid "Room Type:" msgstr "Tipo de Habitación:" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_room_type_wizard_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_room_type_ids -#: model:ir.ui.menu,name:hotel.menu_open_hotel_room_type_form_tree +#. module: pms +#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_form_tree msgid "Room Types" msgstr "Tipos de Habitación" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_amenity +#. module: pms +#: model:ir.model,name:pms.model_pms_amenity msgid "Room amenities" -msgstr "Características" +msgstr "Instalaciones de la habitación" -#. module: hotel -#: code:addons/hotel/models/hotel_shared_room.py:40 +#. module: pms +#: model:ir.actions.act_window,name:pms.action_pms_room_amenity_type_view_form +msgid "Room amenity Type" +msgstr "Tipo de instalación de la habitación" + +#. module: pms +#: code:addons/pms/models/pms_shared_room.py:0 #, python-format msgid "Room beds can't be less than one" -msgstr "Room beds can't be less than one" +msgstr "Las camas de la habitación no pueden ser menores que uno" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1171 +#. 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 "La fecha de entrada debe ser menor que la fecha de salida!" +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: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_reservation_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_room_ids -#: model:ir.ui.menu,name:hotel.menu_open_hotel_room_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_bottom_tree +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_folio__reservation_ids +msgid "Room reservation detail." +msgstr "Detalles de la reserva de la habitación." + +#. 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 "Alojamiento/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.ui.menu,name:pms.menu_open_pms_room_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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_room_type_id -msgid "Rooms Type" -msgstr "Rooms Type" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.room_type_availability_view_form +msgid "Rules" +msgstr "Reglas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_route_ids -msgid "Routes" -msgstr "Rutas" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__rules_to_overwrite +msgid "Rules To Overwrite" +msgstr "Reglas a sobreescribir" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_description_sale -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_description_sale -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_description_sale +#. 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.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 "Error de entrega de SMS" + +#. 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:ir.ui.menu,name:pms.menu_open_pms_sale_channel_form_tree +#: 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 must be entered" +msgstr "El Canal de Venta debe ser Indicado" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room__description_sale +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__description_sale msgid "Sale Description" -msgstr "Descripción de venta" +msgstr "Descipción de la Venta" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_lst_price -msgid "Sale Price" -msgstr "Precio de venta" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "Sale Details" +msgstr "Detalles de la Venta" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_channel_type -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_channel_type -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_channel_type -#: model:ir.model.fields,field_description:hotel.field_hotel_service_channel_type +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__sale_line_ids +msgid "Sale Line" +msgstr "Línea de Venta" + +#. module: pms +#: 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 "Cuenta del Pedido de Venta" + +#. 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 "Canal de ventas" +msgstr "Canales de Venta" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sale_line_warn +#. 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_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 ventas" +msgstr "Línea de Pedido de Venta" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_list_price +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__list_price msgid "Sales Price" -msgstr "Precio de venta" +msgstr "Precio de Ventas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_user_id +#. 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 msgid "Salesperson" -msgstr "Comercial" +msgstr "Vendedor" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dsa +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__phone_sanitized +msgid "Sanitized Number" +msgstr "Sanitized Number" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Saturday" msgstr "Sábado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_payment_save_date -msgid "Save Date" -msgstr "fehca guardada\t" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.advanced_filters_wizard +msgid "Search" +msgstr "Buscar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_payment_save_journal_id -msgid "Save Journal" -msgstr "Diario Guardado" +#. module: pms +#: model:pms.ubication,name:pms.pms_ubication_2 +msgid "Second Floor" +msgstr "Segundo Piso" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_section +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__folio_sale_line__display_type__line_section msgid "Section" msgstr "Sección" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_segmentation_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_segmentation_ids -msgid "Segmentation" -msgstr "Segmentation" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: 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_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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_categ_id +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__categ_id msgid "Select category for the current product" -msgstr "Seleccione la categoría para el producto actual." +msgstr "Seleccione una categoría para el producto actual" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_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 "Si selecciona la opción \"Aviso\" se notificará a los usuarios con el mensaje, si selecciona \"Mensaje de bloqueo\" se lanzará una excepción con el mensaje y se bloqueará el flujo. El mensaje debe escribirse en el siguiente campo." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__num_rooms_selected +msgid "Selected rooms" +msgstr "Habitaciones Seleccionadas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Send Cancel Email" -msgstr "Enviar Mail de Cancelación" +#. 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: hotel -#: model:ir.actions.act_window,name:hotel.action_view_folio_send_confirm_mail -msgid "Send Confirm Mail" -msgstr "Enviar Mail de Confirmación" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__self +msgid "Self" +msgstr "Self" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Send Confirmation Email" -msgstr "Enviar Mail de Confirmación" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Send Exit Email" -msgstr "Enviar Mail de Salida" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_room_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_service_sequence -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_sequence +#. module: pms +#: model:ir.model,name:pms.model_ir_sequence +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__sequence +#: model:ir.model.fields,field_description:pms.field_pms_ubication__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_shared_room__sequence msgid "Sequence" msgstr "Secuencia" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_service_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_service_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_product_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_product_id -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_product_id -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_service_id -#: model:ir.model.fields,field_description:hotel.field_service_on_day_product_id -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard +#. 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_reservation__service_ids +#: model:ir.model.fields,field_description:pms.field_pms_service__product_id +#: model:ir.model.fields,field_description:pms.field_pms_service_line__product_id +#: model_terms:ir.ui.view,arch_db:pms.product_template_view_form msgid "Service" -msgstr "Servicio\t" +msgstr "Servicio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_report_view_tree +#. 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 "Servicios por día" +msgstr "Servicio por día" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_service_line_ids -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_service__service_line_ids +#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_form msgid "Service Line" msgstr "Línea de servicio" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Service Lines" -msgstr "Líneas de servicio" +msgstr "Líneas del servicio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_service_id +#. 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 "Service Room" +msgstr "Habitación del Servicio" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_name +#. 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 msgid "Service description" msgstr "Descripción del servicio" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_service_on_day -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -#: model:ir.ui.view,arch_db:hotel.service_on_day_view_form -msgid "Service on Day" -msgstr "Servicio en día" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_invoice_line_service_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_service_wizard_ids -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_folio_wizard -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_service_view_tree +#. 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_account_move_line__service_ids +#: model:ir.model.fields,field_description:pms.field_wizard_payment_folio__service_ids +#: 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_view_tree msgid "Services" msgstr "Servicios" -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_service_line -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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" +msgstr "Servicios por día" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_price_services +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__price_services msgid "Services Total" -msgstr "Total Servicios" +msgstr "Servicios totales" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_hotel_service_line +#. 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" +msgstr "Servicios por día" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_board_service_line +#. 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,name:pms.model_pms_board_service_line msgid "Services on Board Service included" -msgstr "Servicios incluidos en el BoardService" +msgstr "Servicios incluidos en el Servicio de Habitación" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_board_service_room_type_line +#. module: pms +#: model:ir.model,name:pms.model_pms_board_service_room_type_line msgid "Services on Board Service included in Room" -msgstr "Servicios incluidos en el BoardService de la habitación" +msgstr "***Servicios de habi" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.service_on_day_view_form -msgid "Set Service" -msgstr "Set Service" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Set To Draft" -msgstr "Establecer en borrador" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Set default arrival hour" -msgstr "Establecer hora de llegada por defecto" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Set default departure hour" -msgstr "Establecer hora de salida por defecto" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Set pricelist default" -msgstr "Establcer tarifa por defecto" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Set restrictions default" -msgstr "Establcer plan de restricciones por defecto" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.view_hotel_config_settings -msgid "Set time-zone" -msgstr "Establcer Zona Horaria" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "Set to Done" -msgstr "Pasar a Hecho" +msgstr "Liso para Finalizar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form msgid "Set to Draft" -msgstr "Cambiar a borrador" +msgstr "Poner en borrador" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_shared_folio +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_property_views_form +msgid "Settings" +msgstr "Ajustes" + +#. 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 "Compartir Ficha" +msgstr "Folio Compartido" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_shared_room_id -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_shared_room +#. module: pms +#: model:ir.actions.act_window,name:pms.action_pms_shared_room_form +#: model:ir.model,name:pms.model_pms_shared_room +#: model:ir.model.fields,field_description:pms.field_pms_room__shared_room_id +#: model:ir.model.fields,field_description:pms.field_pms_room_type__shared_room +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_tree +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_shared_room_view_search msgid "Shared Room" msgstr "Habitación Compartida" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_open_hotel_shared_room_form +#. module: pms +#: model:ir.ui.menu,name:pms.menu_open_pms_shared_room_form msgid "Shared Rooms" msgstr "Habitaciones Compartidas" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 Tomorrow" -msgstr "Mostrar todas las entradas de Mañana" +msgstr "Mostrar todos los checkin para mañana" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search +#. 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 todas las entradas de mañana" +msgstr "Mostrar todos los checkin que entrarán mañana" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 la reservas con fecha de entrada antes de 14 días" +msgstr "Mostrar todas las reservas las cuales la fecha de entrada es anterior a 14 días" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 la reservas con fecha de entrada antes de 17 días" +msgstr "Mostrar todas las reservas las cuales la fecha de entrada es anterior a 7 días" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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 la reservas con fecha de entrada antes de 30 días" +msgstr "Mostrar todas las reservas en las que la fecha de entrada es anterior a 1 mes aprox" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_show_in_calendar -#: model:ir.model.fields,field_description:hotel.field_product_product_show_in_calendar -#: model:ir.model.fields,field_description:hotel.field_product_template_show_in_calendar +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__show_in_calendar +#: model:ir.model.fields,field_description:pms.field_product_product__show_in_calendar +#: model:ir.model.fields,field_description:pms.field_product_template__show_in_calendar msgid "Show in Calendar" -msgstr "Mostrar en el Calendario" +msgstr "Mostrar en el calendario" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_image_small -msgid "Small-sized image" -msgstr "Imagen de tamaño pequeño" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__signup_expiration +msgid "Signup Expiration" +msgstr "Caducidad del Registro" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_show_in_calendar -#: model:ir.model.fields,help:hotel.field_product_product_show_in_calendar -#: model:ir.model.fields,help:hotel.field_product_template_show_in_calendar +#. 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 "Signup URL" + +#. 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 "Individual" + +#. 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:ir.model.fields,help:pms.field_pms_room_type__show_in_calendar +#: model:ir.model.fields,help:pms.field_product_product__show_in_calendar +#: model:ir.model.fields,help:pms.field_product_template__show_in_calendar msgid "Specifies if the product is shown in the calendar information." -msgstr "Especificar si el producto es mostrado en la información del Calendario" +msgstr "Especifica si el producto se muestra en la información del calendario." -#. module: hotel -#: selection:hotel.cancelation.rule,apply_on_late:0 -#: selection:hotel.cancelation.rule,apply_on_noshow:0 +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_sale_ok -msgid "Specify if the product can be selected in a sales order line." -msgstr "Especifique si un producto puede ser seleccionado en un pedido de venta." - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -#: model:ir.ui.view,arch_db:hotel.view_hotel_split_reservation_wizard -msgid "Split" -msgstr "Dividir" - -#. module: hotel -#: model:ir.actions.act_window,name:hotel.action_hotel_split_reservation -#: model:ir.ui.view,arch_db:hotel.view_hotel_split_reservation_wizard -msgid "Split Reservation" -msgstr "Dividir Reserva" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_splitted +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_reservation__splitted msgid "Splitted" msgstr "Dividida" -#. module: hotel -#: selection:hotel.folio,reservation_type:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_folio__reservation_type__staff +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Staff" -msgstr "Staff" +msgstr "Personal" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_cost_method -msgid "" -"Standard Price: The products are valued at their standard cost defined on the product.\n" -" Average Cost (AVCO): The products are valued at weighted average cost.\n" -" First In First Out (FIFO): The products are valued supposing those that enter the company first will also leave it first." -msgstr "" -"Precio estándar: Los productos se valoran según su coste estándar definido en el producto.\n" -" Coste promedio (AVCO): Los productos se valoran según su coste promedio ponderado.\n" -" Primeras entradas, primeras salidas (FIFO): Los productos se valoran dando por hecho que los primeros en entrar en la empresa son también los primeros en salir." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_product_pricelist_item__date_start_overnight +msgid "Start Date Overnight" +msgstr "Fecha de Inicio Durante la Noche" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_date_start -msgid "Start Date" -msgstr "Fecha de Inicio" +#. module: pms +#: model:ir.model.fields,help:pms.field_product_pricelist_item__date_start_overnight +msgid "Start date to apply daily pricelist items" +msgstr "Fecha de inicio para aplicar los items de tarifa diarios" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_checkin_partner_state -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_state_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_line_state -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_state_id -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_state -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_activity_state -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_checkin_partner__state +#: model:ir.model.fields,field_description:pms.field_pms_folio__partner_invoice_state_id +#: model:ir.model.fields,field_description:pms.field_pms_property__state_id +#: 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 "State" msgstr "Estado" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_state -#: model:ir.model.fields,field_description:hotel.field_hotel_service_state +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__state +#: 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 msgid "Status" msgstr "Estado" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_activity_state +#. 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" @@ -8251,875 +5267,1019 @@ msgid "" "Planned: Future activities." msgstr "" "Estado basado en actividades\n" -"Vencida: la fecha tope ya ha pasado\n" -"Hoy: La fecha tope es hoy\n" -"Planificada: futuras actividades." +"Vencido: la fecha de vencimiento ya pasó\n" +"Hoy: la fecha de actividad es hoy\n" +"Planificado: actividades futuras." -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "Still to be paid" -msgstr "Aún por ser pagado" +msgstr "Todavía por pagar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_stock_fifo_manual_move_ids -msgid "Stock Fifo Manual Move" -msgstr "Stock Fifo Manual Move" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_stock_fifo_real_time_aml_ids -msgid "Stock Fifo Real Time Aml" -msgstr "Stock Fifo Real Time Aml" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_stock_account_input -msgid "Stock Input Account" -msgstr "Cuenta de entrada de stock" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_stock_move_ids -msgid "Stock Move" -msgstr "Movimiento de Stock" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_property_stock_account_output -msgid "Stock Output Account" -msgstr "Cuenta de salida de stock" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_stock_quant_ids -msgid "Stock Quant" -msgstr "Stock Quant" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_street -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_street2 -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_street -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_street2 +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__street msgid "Street" msgstr "Calle" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Street 2..." -msgstr "Calle 2..." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__street2 +msgid "Street2" +msgstr "Calle2" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "Street..." -msgstr "Calle..." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_price_subtotal -#: model:ir.model.fields,field_description:hotel.field_hotel_service_price_subtotal +#. 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 msgid "Subtotal" msgstr "Subtotal" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dsu +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard +msgid "Suggested rooms to unify the reservation:" +msgstr "Habitaciones sugeridas para unificar las reservas:" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Sunday" msgstr "Domingo" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form -msgid "Supplier Taxes" -msgstr "Impuestos Proveedor" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__supplier_rank +msgid "Supplier Rank" +msgstr "Rango de los proveedores" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_amenity_view_form +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_vat -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_vat -msgid "TIN" -msgstr "NIF" +#. 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 esta propiedad" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search +#. 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.pms_folio_view_search msgid "Tables Detail" -msgstr "Tables Detail" +msgstr "Detalles de la tabla" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_partner_invoice_vat -#: model:ir.model.fields,help:hotel.field_hotel_reservation_partner_invoice_vat -msgid "Tax Identification Number. Fill it if the company is subjected to taxes. Used by the some of the legal statements." -msgstr "Número de identificación fiscal. Llénelo si la compañía está sujeta a impuestos. Usado por algunos documentos legales." +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__category_id +msgid "Tags" +msgstr "Etiquetas" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_amount_tax -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_price_tax -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_tax_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_tax_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_price_tax -#: model:ir.model.fields,field_description:hotel.field_hotel_service_tax_ids -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_tax_ids -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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.report_folio_document msgid "Taxes" msgstr "Impuestos" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_deposit_taxes_id +#. 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 +msgid "Taxes Amount" +msgstr "Cuenta de impuestos" + +#. module: pms +#: model:ir.model.fields,help:pms.field_folio_advance_payment_inv__deposit_taxes_id msgid "Taxes used for deposits" -msgstr "Impuestos usados para depósitos" +msgstr "Tasas utilizadas para depósitos" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_pricelist_id +#. 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_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_room_type__pricelist_id msgid "Technical field. Used for searching on pricelists, not stored in database." -msgstr "Campo técnico. Se utiliza para buscar en lista de precios, no almacenadas en la base de datos." +msgstr "Campo técnico. Usado para buscar e las tarifas, no se almacena en la base de datos." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_stock_move_ids -#: model:ir.model.fields,help:hotel.field_hotel_room_type_stock_quant_ids -msgid "Technical: used to compute quantities." -msgstr "Técnico: se utiliza para calcular las cantidades." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_note +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__note msgid "Terms and conditions" msgstr "Términos y condiciones" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_active -#: model:ir.model.fields,help:hotel.field_hotel_room_type_class_active -msgid "The active field allows you to hide the category without removing it." -msgstr "The active field allows you to hide the category without removing it." +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_folio_advance_payment_inv_amount -msgid "The amount to be invoiced in advance, taxes excluded." -msgstr "El importe a facturar por adelantado, impuestos excluidos." +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_folio_analytic_account_id +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_folio__analytic_account_id msgid "The analytic account related to a folio." -msgstr "The analytic account related to a folio." +msgstr "La cuenta analítica relacionada con un folio." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_sale_delay -msgid "The average delay in days between the confirmation of the customer order and the delivery of the finished products. It's the time you promise to your customers." -msgstr "El retraso medio en días entre la confirmación del pedido de cliente y la entrega de los productos finales. Es el tiempo que promete a sus clientes." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_account_expense_id -msgid "The expense is accounted for when a vendor bill is validated, except in anglo-saxon accounting with perpetual inventory valuation in which case the expense (Cost of Goods Sold account) is recognized at the customer invoice validation. If the field is empty, it uses the one defined in the product category." -msgstr "El gasto se contabiliza cuando se valida una factura del proveedor, excepto en la contabilidad anglosajona con valoración perpetua del inventario, en cuyo caso el gasto (cuenta del coste de los bienes vendidos) se reconoce en la validación de la factura del cliente. Si el campo está vacío, usa el definido en la categoría del producto." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_connector_config_settings_tz_hotel -#: model:ir.model.fields,help:hotel.field_res_config_settings_tz_hotel -msgid "The hotel's timezone, used to manage date and time values in reservations It is important to set a value for this field." -msgstr "The hotel's timezone, used to manage date and time values in reservations It is important to set a value for this field." - -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:237 +#. module: pms +#: code:addons/pms/models/pms_room.py:0 #, python-format -msgid "The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product." -msgstr "The product used to invoice a down payment should be of type 'Service'. Please use another product or update this product." +msgid "The capacity of the room must be greater than 0." +msgstr "La capacidad de la habitación debe ser mayor que 0." -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:235 +#. module: pms +#: code:addons/pms/models/res_users.py:0 #, python-format -msgid "The product used to invoice a down payment should have an invoice policy set to \"Ordered quantities\". Please update your deposit product to be able to create a deposit invoice." -msgstr "The product used to invoice a down payment should have an invoice policy set to \"Ordered quantities\". Please update your deposit product to be able to create a deposit invoice." +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: hotel -#: code:addons/hotel/models/hotel_reservation.py:700 -#: code:addons/hotel/models/hotel_reservation.py:1199 +#. module: pms +#: code:addons/pms/models/account_journal.py:0 #, python-format -msgid "The room already is completed" -msgstr "La habitación ya está completa" +msgid "The company of the properties must match the company on account journal" +msgstr "**La compañía de las propiedades debe coincidir con la compañía del diario de cuenta" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_lst_price -msgid "The sale price is managed from the product template. Click on the 'Variant Prices' button to set the extra attribute prices." -msgstr "El precio de venta se gestiona desde la plantilla del producto. Haga clic en el botón 'Precios variantes' para establecer los precios adicionales de los atributos." +#. module: pms +#: code:addons/pms/models/product_template.py:0 +#, python-format +msgid "The company of the properties must match the company on the room type" +msgstr "La compañía de las propiedades deben coincidir con la compañía del tipo de habitación" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:127 +#. 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_res_users__company_id +msgid "The default company for this user." +msgstr "La compañía por defecto para este usuario." + +#. 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_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_property__user_id +msgid "The internal user in charge of this contact." +msgstr "El usuario interno a cargo de este contacto." + +#. 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 +#: 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 'Service'.\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_id +msgid "The property this user is currently working for." +msgstr "Propiedad para la que el usuario está trabajando actualmente." + +#. module: pms +#: code:addons/pms/models/pms_reservation.py:0 +#, python-format +msgid "The room already is completed (%s)" +msgstr "La habitación ya está completa (%s)" + +#. 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 +#: 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 adelanto debe ser positivo" +msgstr "El valor del pago inicial debe ser positivo." -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_volume -msgid "The volume in m3." -msgstr "El volumen en m3." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_weight -msgid "The weight of the contents in Kg, not including any packaging, etc." -msgstr "El peso del contenido en Kg, sin incluir empaquetado, etc..." - -#. module: hotel -#: code:addons/hotel/wizard/wizard_reservation.py:392 +#. module: pms +#: code:addons/pms/models/pms_folio.py:0 #, python-format -msgid "There are not enough rooms!" -msgstr "No hay suficientes habitaciones!" +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: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:123 +#. module: pms +#: code:addons/pms/models/pms_board_service_room_type.py:0 #, python-format -msgid "There is no income account defined for this product: \"%s\". You may have to install a chart of account from Accounting app, settings menu." -msgstr "There is no income account defined for this product: \"%s\". You may have to install a chart of account from Accounting app, settings menu." +msgid "This Board Service in this Room can't repeat without pricelist" +msgstr "Este servicio de habitación en esta habitación no se puede repetir sin tarifa" -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:259 -#, python-format -msgid "There is no invoiceable line." -msgstr "No hay líneas facturables" - -#. module: hotel -#: code:addons/hotel/models/hotel_board_service_room_type.py:105 +#. module: pms +#: code:addons/pms/models/pms_board_service_room_type.py:0 #, python-format msgid "This Board Service in this Room can't repeat pricelist" -msgstr "No puedes repetir el BoardService con la misma tarifa en la misma habitación" +msgstr "Este servicio de habiación para está habitación no puede repetir la tarifa" -#. module: hotel -#: code:addons/hotel/models/hotel_board_service_room_type.py:115 -#, python-format -msgid "This Board Service in this Room can't repeat without pricelist" -msgstr "No puedes repetir el BoardService sin tarifa en la misma habitación" +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_image_variant -msgid "This field holds the image used as image for the product variant, limited to 1024x1024px." -msgstr "Este campo contiene la imagen usada como imagen de la variante del producto, limitada a 1024x1024px." +#. 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: hotel -#: code:addons/hotel/models/hotel_checkin_partner.py:139 +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_property__tz +msgid "" +"This field is used in order to define in which timezone the arrival/departure will work." +msgstr "Este campo es usado en una compra para definir en que zona horaria será la llegada/salida." + +#. 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 "" +"This field is used to search on email address as the primary email field can contain more than " +"strictly an email address." + +#. module: pms +#: code:addons/pms/models/pms_checkin_partner.py:0 #, python-format msgid "This guest is already registered in the room" -msgstr "Este huésped ya está registrado en ésta habitación" +msgstr "El invitado ya está registrado en la habitación" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1377 -#, python-format -msgid "This is the parent reservation" -msgstr "Esta es la reserva padre" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_price_extra +#. 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 "Ésta es la suma de los precios extra de todos los atributos" +msgstr "Esta es la suma del precio extra de todos los atributos" -#. module: hotel -#: code:addons/hotel/models/inherited_account_payment.py:103 +#. 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 pay is related with more than one Reservation." -msgstr "Este pago esta vínculado con más de una Reserva." +msgid "This reservation cannot be check out" +msgstr "No se puede hacer el checkout de la reserva" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1299 -#, python-format -msgid "This reservation can't be unified" -msgstr "Esta reserva no se puede unificar" +#. 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: hotel -#: code:addons/hotel/models/hotel_reservation.py:1328 -#, python-format -msgid "This reservation can't be unified: They all need to be in the same room" -msgstr "Esta reserva no se puede unificar: todos deben estar en la misma habitación" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "" +"This reservation is part of splitted reservation, you can try to\n" +" unify the reservation here" +msgstr "" +"Esta reserva forma parte de una reserva partida, puede intentar\n" +"\t\tunificar la reserva aquí" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "This reservation has other reservantions and/or services in the folio, you can check it in the" -msgstr "Esta reserva tiene otras reservas y/o servicios en la ficha, puedes revisarlo en " - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "This reservation is part of splitted reservation!, you can check it in the" -msgstr "Esta reserva es solo una parte de una reserva dividida, puedes revisarlo en " - -#. module: hotel -#: code:addons/hotel/wizard/wizard_reservation.py:479 -#, python-format -msgid "This room is occupied!, please, choice other room or change the reservation date" -msgstr "Esta habitación está ocupada, elige otra habitación u otras fechas para la estancia" - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_shared_room +#. module: pms +#: model:ir.model.fields,help:pms.field_pms_room_type__shared_room msgid "This room type is reservation by beds" -msgstr "This room type is reservation by beds" +msgstr "Este tipo de habitación se reserva por camas" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_stock_production -msgid "This stock location will be used, instead of the default one, as the source location for stock moves generated by manufacturing orders." -msgstr "Se usará esta ubicación de stock, en lugar de la predeterminada, como la ubicación origen para los movimientos de stock generados por las órdenes de fabricación." - -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_stock_inventory -msgid "This stock location will be used, instead of the default one, as the source location for stock moves generated when you do an inventory." -msgstr "Se usará esta ubicación de existencias, en lugar de la predeterminada, como la ubicación origen para los movimientos de stock generados cuando se realizan inventarios." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dth +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Thursday" msgstr "Jueves" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_connector_config_settings_tz_hotel -#: model:ir.model.fields,field_description:hotel.field_res_config_settings_tz_hotel +#. 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" +msgstr "Zona Horaria" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_to_assign -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_to_assign -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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_reservation__to_assign +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_search msgid "To Assign" -msgstr "Por Asignar" +msgstr "Asignar" -#. module: hotel -#: selection:hotel.folio,invoice_status:0 -#: selection:hotel.reservation,invoice_status:0 -#: selection:hotel.service,invoice_status:0 -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_qty_to_invoice -#: model:ir.model.fields,field_description:hotel.field_hotel_service_qty_to_invoice -#: model:ir.model.fields,field_description:hotel.field_line_advance_inv_to_invoice +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_service__qty_to_invoice +#: 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 "A facturar" +msgstr "Facturar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_to_send -msgid "To Send" -msgstr "A enviar" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__qty_to_invoice +#: model:ir.model.fields,field_description:pms.field_pms_reservation__qty_to_invoice +msgid "To Invoice Quantity" +msgstr "Facturar Cantidad" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_to_be_cleaned +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room__to_be_cleaned msgid "To be Cleaned" -msgstr "Para ser limpiada" +msgstr "Para ser limpiado" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_checkin_partner_view_search -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. 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" +msgstr "Entrar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_search msgid "To invoice" -msgstr "A Facturar" +msgstr "Facturar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__checkout +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__end_date +#: model:ir.model.fields,field_description:pms.field_pms_massive_changes_wizard__end_date +msgid "To:" +msgstr "Hasta:" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_service_line_view_search msgid "Today" msgstr "Hoy" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_service_line_view_search +#. 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: hotel -#: code:addons/hotel/wizard/wizard_reservation.py:127 -#, python-format -msgid "Too many rooms!" -msgstr "Demasiadas habitaciones!" - -#. module: hotel -#: code:addons/hotel/wizard/duplicate_reservation.py:47 -#, python-format -msgid "Too much duplicated reservations! There are no '%d' free rooms" -msgstr "¡Demasiadas reservas duplicadas! No hay habitaciones libres '%d'" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_amount_total -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_wizard_total -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_price_total -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_price -#: model:ir.model.fields,field_description:hotel.field_hotel_service_price_total -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_price_total +#. 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 msgid "Total" msgstr "Total" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_total_price -#: model:ir.ui.view,arch_db:hotel.report_folio_document +#. 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 de cuentas por pagar" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_wizard__total_price_folio +#: model_terms:ir.ui.view,arch_db:pms.report_folio_document msgid "Total Price" msgstr "Precio Total" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_total_rooms_count +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__credit +msgid "Total Receivable" +msgstr "Total de cuentas por cobrar" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__total_rooms_count msgid "Total Rooms Count" -msgstr "Total Habitaciones" +msgstr "Nº Total de habitaciones" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_tree +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__price_tax +msgid "Total Tax" +msgstr "Tasa total" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_tree msgid "Total amount" -msgstr "Cantidad Total" +msgstr "Cantidad total" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_account_payment_amount_total_folio -msgid "Total amount in folio" -msgstr "Monto total en ficha de reserva" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_tree +#. 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 "Total debt" +msgstr "Deuda total" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_agency -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_agency -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_search +#. 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_terms:ir.ui.view,arch_db:pms.pms_folio_view_search msgid "Tour Operator" -msgstr "Operadora Turística" +msgstr "Tour Operador" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -msgid "Tour operador" -msgstr "Tour operador" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_service_type +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__service_type msgid "Track Service" -msgstr "Servicio de seguimiento" +msgstr "Servicio de Seguimiento" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_tracking -msgid "Tracking" -msgstr "Seguimiento" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__transaction_ids +msgid "Transactions" +msgstr "Transacciones" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dtu +#. 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 "Triple" + +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Tuesday" msgstr "Martes" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_price_type -#: model:ir.model.fields,field_description:hotel.field_hotel_board_service_room_type_rel_price_type -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_reservation_type -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_reservation_type +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_board_service__price_type +#: model:ir.model.fields,field_description:pms.field_pms_board_service_room_type__price_type +#: model:ir.model.fields,field_description:pms.field_pms_folio__reservation_type +#: model:ir.model.fields,field_description:pms.field_pms_reservation__reservation_type msgid "Type" -msgstr "Tipo" +msgstr "TIpo" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_open_hotel_room_type_class_form_tree +#. module: pms +#: model:ir.ui.menu,name:pms.menu_open_pms_room_type_class_form_tree msgid "Type Class" -msgstr "Categoría" +msgstr "Tipo de Clase" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_class_room_type_ids +#. 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: hotel -#: model:ir.model,name:hotel.model_hotel_floor -#: model:ir.model.fields,field_description:hotel.field_hotel_room_floor_id -#: model:ir.model.fields,field_description:hotel.field_hotel_shared_room_floor_id -#: model:ir.ui.view,arch_db:hotel.hotel_room_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_shared_room_view_form +#. module: pms +#: model:ir.model,name:pms.model_pms_ubication +#: model:ir.model.fields,field_description:pms.field_pms_room__ubication_id +#: model:ir.model.fields,field_description:pms.field_pms_shared_room__ubication_id +#: model_terms:ir.ui.view,arch_db:pms.pms_room_view_form +#: model_terms:ir.ui.view,arch_db:pms.pms_shared_room_view_form msgid "Ubication" msgstr "Ubicación" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_floor_name +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_ubication__name msgid "Ubication Name" -msgstr "Nombre Ubicación" +msgstr "Nombre de la Ubicación" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_open_hotel_floor_form_tree -msgid "Ubitacions" +#. module: pms +#: model:ir.ui.menu,name:pms.menu_open_pms_ubication_form_tree +msgid "Ubications" msgstr "Ubicaciones" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_partner_unconfirmed -#: model:ir.model.fields,field_description:hotel.field_res_users_unconfirmed +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__unconfirmed +#: model:ir.model.fields,field_description:pms.field_res_partner__unconfirmed +#: model:ir.model.fields,field_description:pms.field_res_users__unconfirmed msgid "Unconfirmed" msgstr "Sin Confirmar" -#. module: hotel -#: code:addons/hotel/wizard/duplicate_reservation.py:75 -#, python-format -msgid "Unexpected Error: Can't found a free room" -msgstr "Unexpected Error: Can't found a free room" - -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1285 -#, python-format -msgid "Unexpected error copying record. Can't split reservation!" -msgstr "Ouch!. No hemos podido dividir la reserva!" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.reservation_wizard msgid "Unify" -msgstr "Unir" +msgstr "Unificar" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_price_unit -#: model:ir.model.fields,field_description:hotel.field_hotel_service_price_unit -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_price_unit +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_reservation_view_form +msgid "Unify the reservation" +msgstr "Unificar la reserva" + +#. 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__price_unit +#: model:ir.model.fields,field_description:pms.field_pms_service_line__price_unit msgid "Unit Price" -msgstr "Precio unitario" +msgstr "Precio Único" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_per_day -#: model:ir.model.fields,field_description:hotel.field_hotel_service_per_day -#: model:ir.model.fields,field_description:hotel.field_product_product_per_day -#: model:ir.model.fields,field_description:hotel.field_product_template_per_day +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__per_day +#: model:ir.model.fields,field_description:pms.field_pms_service__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 "Incrementa una unidad por día" +msgstr "Incremento único/por unidad por día" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_per_person -#: model:ir.model.fields,field_description:hotel.field_product_product_per_person -#: model:ir.model.fields,field_description:hotel.field_product_template_per_person +#. 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 "Incrementa una unidad por persona" +msgstr "Incremento de unidad/ único por persona" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_uom_id +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_service_line_day_qty +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_unread +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_checkin_partner__state__draft +msgid "Unkown Guest" +msgstr "Invitado 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 sin leer" +msgstr "Mensajes no leídos" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_message_unread_counter +#. 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 "Contador de mensajes sin leer" +msgstr "Nº de mensajes sin leer" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_amount_untaxed +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio__amount_untaxed msgid "Untaxed Amount" -msgstr "Base imponible" +msgstr "Importe no tributable" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -msgid "Untaxed amount" -msgstr "Cantidad sin Impuestos" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_to_invoice +#: model:ir.model.fields,field_description:pms.field_pms_reservation__untaxed_amount_to_invoice +msgid "Untaxed Amount To Invoice" +msgstr "Importe no tributable a facturar" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_tree -msgid "Updated on" -msgstr "Actualizado el" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_folio_sale_line__untaxed_amount_invoiced +#: model:ir.model.fields,field_description:pms.field_pms_reservation__untaxed_amount_invoiced +msgid "Untaxed Invoiced Amount" +msgstr "Importe facturado no tributable" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.account_payment_view_form_folio -msgid "Validate" -msgstr "Validar" +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form +msgid "UoM" +msgstr "UoM" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_valuation -msgid "Valuation" -msgstr "Valoración" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_stock_value +#. 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,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_pms_num_rooms_selection__value msgid "Value" msgstr "Valor" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_image_variant +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_folio_availability_wizard__value_num_rooms_selected +msgid "Value Num Rooms Selected" +msgstr "Valor del número de habitaciones seleccionadas" + +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__image_variant_1920 msgid "Variant Image" -msgstr "Imagen de la variante" +msgstr "Imagen de Variante" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_price_extra +#. 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 adicional de la variante " +msgstr "Precio de variante extra" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_variant_seller_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__variant_seller_ids msgid "Variant Seller" -msgstr "Variante del vendedor" +msgstr "Vendedor de variantes" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_supplier_taxes_id +#. 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 "Impuestos de proveedor" +msgstr "Tasas del proveedor" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_seller_ids +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__seller_ids msgid "Vendors" msgstr "Proveedores" -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -msgid "Virtual Door" -msgstr "Virtual Door" - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_volume +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__volume msgid "Volume" msgstr "Volumen" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_warehouse_id -msgid "Warehouse" -msgstr "Almacén" +#. 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: hotel -#: code:addons/hotel/models/inherited_account_payment.py:103 -#, python-format -msgid "Warning" -msgstr "Aviso" - -#. module: hotel -#: code:addons/hotel/models/hotel_service.py:339 +#. module: pms +#: code:addons/pms/models/pms_service.py:0 #, python-format msgid "Warning for %s" -msgstr "Aviso para %s" +msgstr "Advertencia para %s" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_res_company_cardex_warning -msgid "Warning in Cardex" -msgstr "Aviso en Checkin" - -#. module: hotel -#: code:addons/hotel/wizard/wizard_reservation.py:254 -#, python-format -msgid "We cant create avoid folio" -msgstr "No podemos crear una ficha vacía" - -#. module: hotel -#: code:addons/hotel/wizard/wizard_reservation.py:223 -#, python-format -msgid "We need know the customer!" -msgstr "Necesitamos conoces el cliente!" - -#. module: hotel -#: code:addons/hotel/models/inherited_account_invoice.py:50 -#, python-format -msgid "We need the VAT and Country of the following companies" -msgstr "Necesitamos el NIF y el País de los siguientes contactos" - -#. module: hotel -#: code:addons/hotel/wizard/folio_make_invoice_advance.py:212 -#, python-format -msgid "We need the VAT of the customer" -msgstr "Necesitamos conocer el NIF del cliente" - -#. module: hotel -#: selection:hotel.folio,channel_type:0 -#: selection:hotel.reservation,channel_type:0 -#: selection:hotel.service,channel_type:0 -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_search +#. module: pms +#: model:ir.model.fields.selection,name:pms.selection__pms_service__channel_type__web msgid "Web" msgstr "Web" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_website_message_ids +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_website_message_ids +#. 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 comunicaciones del sitio web" +msgstr "Historial de comunicación del sitio web" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_wizard_massive_changes_dwe +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "Wednesday" msgstr "Miércoles" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_weight +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_room_type__weight msgid "Weight" msgstr "Peso" -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_folio_advance_payment_inv_advance_payment_method -msgid "What do you want to invoice?" -msgstr "¿Qué quiere facturar?" +#. 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: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_stock_account_input -msgid "When doing real-time inventory valuation, counterpart journal items for all incoming stock moves will be posted in this account, unless there is a specific valuation account set on the source location. When not set on the product, the one from the product category is used." -msgstr "Cuando se realiza una valoración de inventario en tiempo real, la contrapartida para todos los movimientos de entrada serán imputados en esta cuenta, a menos que se haya establecido una cuenta de valoración específica en la ubicación fuente. Cuando no se establece en el producto, se usa la establecida en la categoría." +#. module: pms +#: model:pms.amenity,name:pms.pms_amenity_4 +msgid "Wi-Fi" +msgstr "Wi-Fi" -#. module: hotel -#: model:ir.model.fields,help:hotel.field_hotel_room_type_property_stock_account_output -msgid "When doing real-time inventory valuation, counterpart journal items for all outgoing stock moves will be posted in this account, unless there is a specific valuation account set on the destination location. When not set on the product, the one from the product category is used." -msgstr "Cuando se realiza una valoración de inventario en tiempo real, la contrapartida para todos los movimientos de salida serán imputados en esta cuenta, a menos que se haya establecido una cuenta de valoración específica en la ubicación destino. Cuando no se establece en el producto, se usa la establecida en la categoría." +#. module: pms +#: model:ir.model,name:pms.model_pms_advanced_filters_wizard +msgid "Wizard for advanced filters" +msgstr "Asistente de filtros avanzados" -#. module: hotel -#: model:ir.ui.menu,name:hotel.menu_account_finance_xls_reports +#. 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 +#: model:ir.model,name:pms.model_pms_folio_wizard +msgid "" +"Wizard to check availability by room type and pricelist & creation of folios with its reservations" +msgstr "" +"Asistente para comprobar la disponibilidad por tipo de habitación y tarifa y creación de folios con " +"sus reservas" + +#. module: pms +#: model:ir.ui.menu,name:pms.menu_account_finance_xls_reports msgid "XLS Reports" msgstr "XLS Reports" -#. module: hotel -#: code:addons/hotel/models/inherited_account_invoice.py:119 +#. module: pms +#: code:addons/pms/wizards/wizard_invoice_filter_days.py:0 #, python-format -msgid "You cannot delete an invoice after it has been validated (and received a number). You can set it back to \"Draft\" state and modify its content, then re-confirm it." -msgstr "You cannot delete an invoice after it has been validated (and received a number). You can set it back to \"Draft\" state and modify its content, then re-confirm it." +msgid "You can not remove all lines for invoice" +msgstr "No se pueden eliminar todas las líneas de la factura" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:775 +#. module: pms +#: code:addons/pms/wizards/wizard_advanced_filters.py:0 #, python-format -msgid "You tried to change/confirm reservation with room those already reserved in this reservation period: %s " -msgstr "Estás intentando cambiar/confirmar una reserva con una habitación ya reservada en este periodo: %s " +msgid "You must add filters to perform the search" +msgstr "Debe añadir filtros para realizar la búsqueda" -#. module: hotel -#: code:addons/hotel/models/hotel_reservation.py:1185 -#, python-format -msgid "You tried to change/confirm reservation with room those already reserved in this reservation period: %s " -msgstr "Estás intentando hacer una reserva en una habitación que ya está reservada en este periódo: %s " - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "ZIP" -msgstr "C.P." - -#. module: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_folio_partner_invoice_zip -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_partner_invoice_zip +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_property__zip msgid "Zip" -msgstr "C.P." +msgstr "Zip" -#. module: hotel -#: sql_constraint:hotel.room.type.class:0 -msgid "code must be unique!" -msgstr "el código debe ser único!" +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_hotel_reservation_wizard_discount -#: model:ir.model.fields,field_description:hotel.field_hotel_room_type_wizard_discount -#: model:ir.model.fields,field_description:hotel.field_hotel_service_wizard_discount -msgid "discount" -msgstr "descuento" +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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 "email" -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_checkin_partner -msgid "hotel.checkin.partner" -msgstr "Checkins" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_folio_wizard -msgid "hotel.folio.wizard" -msgstr "hotel.folio.wizard" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_reservation_line -msgid "hotel.reservation.line" -msgstr "hotel.reservation.line" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_reservation_wizard -msgid "hotel.reservation.wizard" -msgstr "hotel.reservation.wizard" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_room_type_restriction -msgid "hotel.room.type.restriction" -msgstr "hotel.room.type.restriction" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_room_type_restriction_item -msgid "hotel.room.type.restriction.item" -msgstr "hotel.room.type.restriction.item" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_room_type_wizard -msgid "hotel.room.type.wizard" -msgstr "hotel.room.type.wizard" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_service_line -msgid "hotel.service.line" -msgstr "hotel.service.line" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_service_wizard -msgid "hotel.service.wizard" -msgstr "hotel.service.wizard" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_wizard_duplicate_reservation -msgid "hotel.wizard.duplicate.reservation" -msgstr "hotel.wizard.duplicate.reservation" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_wizard_massive_changes -msgid "hotel.wizard.massive.changes" -msgstr "hotel.wizard.massive.changes" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_wizard_massive_price_reservation_days -msgid "hotel.wizard.massive.price.reservation.days" -msgstr "hotel.wizard.massive.price.reservation.days" - -#. module: hotel -#: model:ir.model,name:hotel.model_hotel_wizard_split_reservation -msgid "hotel.wizard.split.reservation" -msgstr "hotel.wizard.split.reservation" - -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. 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: hotel -#: model:ir.model.fields,field_description:hotel.field_account_payment_save_amount -msgid "onchange_amount" -msgstr "onchange_amount" +#. module: pms +#: model:ir.model.fields,field_description:pms.field_pms_service__move_line_ids +msgid "move Lines" +msgstr "Apuntes Contables" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.service_on_day_view_form -#: model:ir.ui.view,arch_db:hotel.view_hotel_duplicate_reservation_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_changes_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_massive_price_change_wizard -#: model:ir.ui.view,arch_db:hotel.view_hotel_split_reservation_wizard +#. 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: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form -msgid "phone" -msgstr "teléfono" +#. module: pms +#: model:ir.actions.act_window,name:pms.action_pms_room_form +msgid "pms Room" +msgstr "pms Room" -#. module: hotel -#: model:ir.model,name:hotel.model_res_config_settings -msgid "res.config.settings" -msgstr "res.config.settings" +#. module: pms +#: model:ir.model,name:pms.model_pms_folio_availability_wizard +msgid "pms.folio.availability.wizard" +msgstr "pms.folio.availability.wizard" -#. module: hotel -#: model:ir.model,name:hotel.model_service_on_day -msgid "service.on.day" -msgstr "service.on.day" +#. module: pms +#: model:ir.model,name:pms.model_pms_num_rooms_selection +msgid "pms.num.rooms.selection" +msgstr "pms.num.rooms.selection" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_folio_view_form -msgid "these are the billing information associated with the booking client or the company (if a company is assigned). If you want to bill an independent contact, you can select it in the billing assistant" -msgstr "these are the billing information associated with the booking client or the company (if a company is assigned). If you want to bill an independent contact, you can select it in the billing assistant" +#. module: pms +#: model:ir.model,name:pms.model_pms_reservation_wizard +msgid "pms.reservation.wizard" +msgstr "pms.reservation.wizard" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_checkin_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.massive_changes_wizard msgid "" -"to\n" -" " +"pricelist items\n" +" will be overwritten:" msgstr "" -"hasta\n" -" " +"items de la tarifa\n" +" serán sobrescritas:" -#. module: hotel -#: model:ir.ui.view,arch_db:hotel.hotel_reservation_view_form +#. module: pms +#: model_terms:ir.ui.view,arch_db:pms.pms_folio_view_form msgid "" -"to\n" -" " +"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 "" -"hasta\n" -" " +"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" diff --git a/pms/init_hook.py b/pms/init_hook.py index 5f6e4e47a..5592fe58f 100644 --- a/pms/init_hook.py +++ b/pms/init_hook.py @@ -2,9 +2,15 @@ from odoo import SUPERUSER_ID from odoo.api import Environment -def post_init_hook(cr, _): +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 index 92f2ace63..5cb804757 100644 --- a/pms/models/__init__.py +++ b/pms/models/__init__.py @@ -3,14 +3,13 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import ir_http -from . import ir_sequence 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_floor +from . import pms_ubication from . import pms_folio from . import pms_reservation from . import pms_room @@ -21,11 +20,11 @@ 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_room_type_availability -from . import pms_room_type_restriction -from . import pms_room_type_restriction_item +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 @@ -42,3 +41,8 @@ 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 diff --git a/pms/models/account_bank_statement.py b/pms/models/account_bank_statement.py new file mode 100644 index 000000000..b01042797 --- /dev/null +++ b/pms/models/account_bank_statement.py @@ -0,0 +1,16 @@ +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 new file mode 100644 index 000000000..3a4c76050 --- /dev/null +++ b/pms/models/account_bank_statement_line.py @@ -0,0 +1,46 @@ +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 new file mode 100644 index 000000000..ca1266390 --- /dev/null +++ b/pms/models/account_journal.py @@ -0,0 +1,21 @@ +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, + ) diff --git a/pms/models/account_move.py b/pms/models/account_move.py index f8f01adbb..d9ac60d18 100644 --- a/pms/models/account_move.py +++ b/pms/models/account_move.py @@ -1,4 +1,3 @@ -# Copyright 2017 Alexandre Díaz # Copyright 2017 Dario Lodeiros # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import json @@ -12,10 +11,19 @@ class AccountMove(models.Model): # Field Declarations folio_ids = fields.Many2many( - comodel_name="pms.folio", compute="_compute_folio_origin" + 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", ) - pms_property_id = fields.Many2one("pms.property") - from_folio = fields.Boolean(compute="_compute_folio_origin") outstanding_folios_debits_widget = fields.Text( compute="_compute_get_outstanding_folios_JSON" ) @@ -23,38 +31,13 @@ class AccountMove(models.Model): compute="_compute_get_outstanding_folios_JSON" ) - # Compute and Search methods - def _compute_folio_origin(self): for inv in self: - inv.from_folio = False inv.folio_ids = False - folios = inv.mapped("invoice_line_ids.reservation_ids.folio_id") - folios |= inv.mapped("invoice_line_ids.service_ids.folio_id") + folios = inv.mapped("invoice_line_ids.folio_ids") if folios: - inv.from_folio = True inv.folio_ids = [(6, 0, folios.ids)] - # Action methods - - 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)], - } - - # Business methods def _compute_get_outstanding_folios_JSON(self): self.ensure_one() self.outstanding_folios_debits_widget = json.dumps(False) @@ -124,3 +107,20 @@ class AccountMove(models.Model): 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 index 82f22403a..515edf5d6 100644 --- a/pms/models/account_move_line.py +++ b/pms/models/account_move_line.py @@ -1,37 +1,75 @@ # 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 +from odoo import api, fields, models class AccountMoveLine(models.Model): _inherit = "account.move.line" # Fields declaration - reservation_ids = fields.Many2many( - "pms.reservation", - "reservation_move_rel", - "move_line_id", - "reservation_id", - string="Reservations", - readonly=True, + # 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", ) - service_ids = fields.Many2many( - "pms.service", - "service_line_move_rel", - "move_line_id", - "service_id", - string="Services", - readonly=True, - copy=False, + folio_ids = fields.Many2many( + string="Folios", + comodel_name="pms.folio", + relation="payment_folio_rel", + column1="move_id", + column2="folio_id", ) - reservation_line_ids = fields.Many2many( - "pms.reservation.line", - "reservation_line_move_rel", - "move_line_id", - "reservation_line_id", - string="Reservation Lines", - readonly=True, - copy=False, + 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 index 76742d9f3..271dacaf2 100644 --- a/pms/models/account_payment.py +++ b/pms/models/account_payment.py @@ -1,86 +1,17 @@ # 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 except_orm +from odoo import _, fields, models class AccountPayment(models.Model): _inherit = "account.payment" # Fields declaration - folio_id = fields.Many2one("pms.folio", string="Folio Reference") - amount_total_folio = fields.Float( - compute="_compute_folio_amount", - store=True, - string="Total amount in folio", + folio_id = fields.Many2one( + string="Folio Reference", + help="Folio in account payment", + comodel_name="pms.folio", ) - save_amount = fields.Monetary(string="onchange_amount") - save_date = fields.Date() - save_journal_id = fields.Integer() - - # Compute and Search methods - - @api.depends("state") - def _compute_folio_amount(self): - # FIXME: Finalize method - res = [] - fol = () - for payment in self: - if payment.folio_id: - fol = payment.env["pms.folio"].search( - [("id", "=", payment.folio_id.id)] - ) - else: - return - if not any(fol): - return - if len(fol) > 1: - raise except_orm( - _("Warning"), - _( - "This pay is related with \ - more than one Reservation." - ), - ) - else: - fol.compute_amount() - return res - - # Constraints and onchanges - # @api.onchange("amount", "payment_date", "journal_id") - # def onchange_amount(self): - # if self._origin: - # self.save_amount = self._origin.amount - # self.save_journal_id = self._origin.journal_id.id - # self.save_date = self._origin.payment_date - - # Action methods - # def return_payment_folio(self): - # journal = self.journal_id - # partner = self.partner_id - # amount = self.amount - # reference = self.communication - # account_move_lines = self.move_line_ids.filtered( - # lambda x: (x.account_id.internal_type == "receivable") - # ) - # return_line_vals = { - # "move_line_ids": [(6, False, [x.id for x in account_move_lines])], - # "partner_id": partner.id, - # "amount": amount, - # "reference": reference, - # } - # return_vals = { - # "journal_id": journal.id, - # "line_ids": [(0, 0, return_line_vals)], - # } - # return_pay = self.env["payment.return"].create(return_vals) - # if self.save_amount: - # self.amount = self.save_amount - # if self.save_date: - # self.payment_date = self.save_date - # if self.save_journal_id: - # self.journal_id = self.env["account.journal"].browse(self.save_journal_id) - # return_pay.action_confirm() # Business methods diff --git a/pms/models/folio_sale_line.py b/pms/models/folio_sale_line.py new file mode 100644 index 000000000..f907c4d87 --- /dev/null +++ b/pms/models/folio_sale_line.py @@ -0,0 +1,1013 @@ +# 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, + default="no", + 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_shipping_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_http.py b/pms/models/ir_http.py index 009c42652..603a58c16 100644 --- a/pms/models/ir_http.py +++ b/pms/models/ir_http.py @@ -27,10 +27,7 @@ class IrHttp(models.AbstractModel): for property in user.pms_property_ids ], }, - "display_switch_pms_property_menu": user.has_group( - "base.group_multi_company" - ) - and len(user.pms_property_ids) > 1, + "display_switch_pms_property_menu": len(user.pms_property_ids) > 1, } ) # TODO: This user context update should be placed in other function ¿? diff --git a/pms/models/ir_sequence.py b/pms/models/ir_sequence.py deleted file mode 100644 index 2749f4974..000000000 --- a/pms/models/ir_sequence.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class IrSequence(models.Model): - _inherit = "ir.sequence" - - pms_property_id = fields.Many2one("pms.property", string="Property") diff --git a/pms/models/payment_return.py b/pms/models/payment_return.py index c26d878d7..f3fd43634 100644 --- a/pms/models/payment_return.py +++ b/pms/models/payment_return.py @@ -7,12 +7,22 @@ class PaymentReturn(models.Model): _inherit = "payment.return" # Fields declaration - folio_id = fields.Many2one("pms.folio", string="Folio") - pms_property_id = fields.Many2one( - "pms.property", store=True, readonly=True, related="folio_id.pms_property_id" + 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, ) - - # Business methods def action_confirm(self): pay = super(PaymentReturn, self).action_confirm() diff --git a/pms/models/pms_amenity.py b/pms/models/pms_amenity.py index 3546434d8..026f09d71 100644 --- a/pms/models/pms_amenity.py +++ b/pms/models/pms_amenity.py @@ -6,15 +6,37 @@ from odoo import fields, models class PmsRoomAmenity(models.Model): _name = "pms.amenity" - _description = "Room amenities" + _description = "Room amenity" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Char("Amenity Name", translate=True, required=True) - pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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" ) - room_amenity_type_id = fields.Many2one("pms.amenity.type", "Amenity Category") - default_code = fields.Char("Internal Reference") - active = fields.Boolean("Active", default=True) - - # TODO: Constrain coherence pms_property_ids with amenity types pms_property_ids diff --git a/pms/models/pms_amenity_type.py b/pms/models/pms_amenity_type.py index 0db9e652f..ec982d55d 100644 --- a/pms/models/pms_amenity_type.py +++ b/pms/models/pms_amenity_type.py @@ -6,16 +6,35 @@ from odoo import fields, models class PmsRoomAmenityType(models.Model): _name = "pms.amenity.type" - _description = "Amenities Type" + _description = "Amenity Type" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Char("Amenity Type Name", translate=True, required=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( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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, ) - room_amenity_ids = fields.One2many( - "pms.amenity", "room_amenity_type_id", "Amenities in this category" + 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, ) - active = fields.Boolean("Active", default=True) - - # TODO: Constrain coherence pms_property_ids with amenities pms_property_ids diff --git a/pms/models/pms_availability.py b/pms/models/pms_availability.py new file mode 100644 index 000000000..cfc47107a --- /dev/null +++ b/pms/models/pms_availability.py @@ -0,0 +1,103 @@ +# 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 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, + ) + real_avail = fields.Integer( + string="Real Avail", + help="", + store=True, + readonly=True, + compute="_compute_real_avail", + ) + + _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", + ) + def _compute_real_avail(self): + for record in self: + Rooms = self.env["pms.room"] + RoomLines = self.env["pms.reservation.line"] + 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") + rooms_not_avail = RoomLines.search_count( + [ + ("date", "=", record.date), + ("room_id", "in", room_ids), + ("pms_property_id", "=", record.pms_property_id.id), + ("occupies_availability", "=", True), + # ("id", "not in", current_lines if current_lines else []), + ] + ) + record.real_avail = total_rooms - rooms_not_avail + + @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 new file mode 100644 index 000000000..21c5e677d --- /dev/null +++ b/pms/models/pms_availability_plan.py @@ -0,0 +1,332 @@ +# 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.exceptions import ValidationError +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): + 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 rooms_available( + self, + checkin, + checkout, + room_type_id=False, + current_lines=False, + pricelist_id=False, + pms_property_id=False, + ): + if current_lines and not isinstance(current_lines, list): + current_lines = [current_lines] + free_rooms = self.get_real_free_rooms( + checkin, checkout, room_type_id, current_lines, pms_property_id + ) + domain_rules = [ + ("date", ">=", checkin), + ( + "date", + "<=", + checkout, + ), # TODO: only closed_departure take account checkout date! + ] + if pms_property_id: + domain_rules.append(("pms_property_id", "=", pms_property_id)) + + if room_type_id: + domain_rules.append(("room_type_id", "=", room_type_id)) + if pricelist_id: + pricelist = self.env["product.pricelist"].browse(pricelist_id) + if pricelist and 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 self.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 + ) + elif not pricelist: + raise ValidationError(_("Pricelist not found")) + return free_rooms.sorted(key=lambda r: r.sequence) + + def get_real_free_rooms( + self, + checkin, + checkout, + room_type_id=False, + current_lines=False, + pms_property_id=False, + ): + Avail = self.env["pms.availability"] + 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() + domain = [ + ("date", ">=", checkin), + ("date", "<=", checkout - datetime.timedelta(1)), + ] + if not current_lines: + current_lines = [] + rooms_not_avail = ( + Avail.search(domain) + .reservation_line_ids.filtered(lambda l: l.id and l.id not in current_lines) + .room_id.ids + ) + domain_rooms = [] + if rooms_not_avail: + domain_rooms = [ + ("id", "not in", rooms_not_avail), + ] + if pms_property_id: + domain_rooms.append(("pms_property_id", "=", pms_property_id)) + if room_type_id: + domain_rooms.append(("room_type_id", "=", room_type_id)) + return self.env["pms.room"].search(domain_rooms) + + @api.model + def get_count_rooms_available( + self, + checkin, + checkout, + room_type_id, + pms_property_id, + current_lines=False, + pricelist_id=False, + ): + if current_lines and not isinstance(current_lines, list): + current_lines = [current_lines] + + avail = self.get_count_real_free_rooms( + checkin, checkout, room_type_id, pms_property_id, current_lines + ) + domain_rules = [ + ("date", ">=", checkin), + ( + "date", + "<=", + checkout, + ), # TODO: only closed_departure take account checkout date! + ("room_type_id", "=", room_type_id), + ("pms_property_id", "=", pms_property_id), + ] + if pricelist_id: + pricelist = self.env["product.pricelist"].browse(pricelist_id) + if pricelist and 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: + for item in rule_items: + if self.any_rule_applies(checkin, checkout, item): + return 0 + avail = min(rule_items.mapped("plan_avail")) + return avail + + def get_count_real_free_rooms( + self, + checkin, + checkout, + room_type_id, + pms_property_id, + current_lines=False, + ): + Avail = self.env["pms.availability"] + count_free_rooms = len( + self.env["pms.room.type"] + .browse(room_type_id) + .room_ids.filtered(lambda r: r.pms_property_id.id == pms_property_id) + ) + 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 avail in Avail.search( + [ + ("date", ">=", checkin), + ("date", "<=", checkout - datetime.timedelta(1)), + ("room_type_id", "=", room_type_id), + ("pms_property_id", "=", pms_property_id), + ] + ): + if avail.real_avail < count_free_rooms: + count_free_rooms = avail.real_avail + return count_free_rooms + + @api.model + def splitted_availability( + self, + checkin, + checkout, + room_type_id=False, + current_lines=False, + pricelist=False, + pms_property_id=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) + ]: + rooms_avail = self.rooms_available( + checkin=date_iterator, + checkout=date_iterator + datetime.timedelta(1), + room_type_id=room_type_id, + current_lines=current_lines, + pricelist_id=pricelist.id, + pms_property_id=pms_property_id, + ) + if len(rooms_avail) < 1: + return False + return True + + @api.model + def update_quota(self, pricelist_id, room_type_id, date, line): + 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 line.impacts_quota: + rule.quota -= 1 + return rule.id + + # the line has a rule item applied before + elif line.impacts_quota != 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", "=", line.impacts_quota)] + ) + + # restore quota in old rule item + if old_rule: + old_rule.quota += 1 + + return rule.id + + # in any case, check old rule item + if line.impacts_quota: + old_rule = self.env["pms.availability.plan.rule"].search( + [("id", "=", line.impacts_quota)] + ) + # 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 new file mode 100644 index 000000000..6ad60d831 --- /dev/null +++ b/pms/models/pms_availability_plan_rule.py @@ -0,0 +1,192 @@ +# 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.filtered("real_avail"): + 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 index ed4e63fae..2287dc0ca 100644 --- a/pms/models/pms_board_service.py +++ b/pms/models/pms_board_service.py @@ -1,34 +1,66 @@ # Copyright 2017 Dario Lodeiros # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +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 - # Fields declaration - name = fields.Char("Board Name", translate=True, size=64, required=True, index=True) - board_service_line_ids = fields.One2many( - "pms.board.service.line", "pms_board_service_id" + name = fields.Char( + string="Board Service Name", + help="Board Service Name", + required=True, + index=True, + size=64, + translate=True, ) - pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" - ) - pms_board_service_room_type_ids = fields.One2many( - "pms.board.service.room.type", "pms_board_service_id" - ) - price_type = fields.Selection( - [("fixed", "Fixed"), ("percent", "Percent")], - string="Type", - default="fixed", + 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( - "Amount", digits=("Product Price"), compute="_compute_board_amount", store=True + 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", ) - # Compute and Search methods @api.depends("board_service_line_ids.amount") def _compute_board_amount(self): for record in self: @@ -36,3 +68,66 @@ class PmsBoardService(models.Model): 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 index 6fbba0ea3..9be0d7d3c 100644 --- a/pms/models/pms_board_service_line.py +++ b/pms/models/pms_board_service_line.py @@ -6,26 +6,77 @@ 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"), + ) - # Default methods def _get_default_price(self): if self.product_id: return self.product_id.list_price - # Fields declaration - pms_board_service_id = fields.Many2one( - "pms.board.service", "Board Service", ondelete="cascade", required=True - ) - product_id = fields.Many2one("product.product", string="Product", required=True) - pms_property_ids = fields.Many2many( - "pms.property", related="pms_board_service_id.pms_property_ids" - ) - amount = fields.Float( - "Amount", digits=("Product Price"), default=_get_default_price - ) - - # Constraints and onchanges @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 index fae85fa23..33aeb7263 100644 --- a/pms/models/pms_board_service_room_type.py +++ b/pms/models/pms_board_service_room_type.py @@ -10,57 +10,58 @@ class PmsBoardServiceRoomType(models.Model): _rec_name = "pms_board_service_id" _log_access = False _description = "Board Service included in Room" + _check_pms_properties_auto = True - # Default Methods ang Gets - - def name_get(self): - result = [] - for res in self: - if res.pricelist_id: - name = u"{} ({})".format( - res.pms_board_service_id.name, - res.pricelist_id.name, - ) - else: - name = u"{} ({})".format(res.pms_board_service_id.name, _("Generic")) - result.append((res.id, name)) - return result - - # Fields declaration pms_board_service_id = fields.Many2one( - "pms.board.service", string="Board Service", - index=True, - ondelete="cascade", + 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, ) pms_room_type_id = fields.Many2one( - "pms.room.type", string="Room Type", - index=True, - ondelete="cascade", + help="Room Type for which this Board Service is available", required=True, - ) - pricelist_id = fields.Many2one( - "product.pricelist", string="Pricelist", required=False + index=True, + comodel_name="pms.room.type", + ondelete="cascade", + check_pms_properties=True, ) board_service_line_ids = fields.One2many( - "pms.board.service.room.type.line", "pms_board_service_room_type_id" - ) - pms_property_id = fields.Many2one( - "pms.property", - ) - price_type = fields.Selection( - [("fixed", "Fixed"), ("percent", "Percent")], - string="Type", - default="fixed", + 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( - "Amount", digits=("Product Price"), compute="_compute_board_amount", store=True + 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", ) - # Compute and Search methods @api.depends("board_service_line_ids.amount") def _compute_board_amount(self): for record in self: @@ -69,44 +70,22 @@ class PmsBoardServiceRoomType(models.Model): total += service.amount record.update({"amount": total}) - # Constraints and onchanges - @api.constrains("pricelist_id") - def constrains_pricelist_id(self): + @api.constrains("by_default") + def constrains_duplicated_board_defaul(self): for record in self: - if self.pricelist_id: - board_pricelist = self.env["pms.board.service.room.type"].search( - [ - ("pricelist_id", "=", record.pricelist_id.id), - ("pms_room_type_id", "=", record.pms_room_type_id.id), - ("pms_board_service_id", "=", record.pms_board_service_id.id), - ("id", "!=", record.id), - ] + default_boards = ( + record.pms_room_type_id.board_service_room_type_ids.filtered( + "by_default" ) - if board_pricelist: - raise UserError( - _("This Board Service in this Room can't repeat pricelist") - ) - else: - board_pricelist = self.env["pms.board.service.room.type"].search( - [ - ("pricelist_id", "=", False), - ("pms_room_type_id", "=", record.pms_room_type_id.id), - ("pms_board_service_id", "=", record.pms_board_service_id.id), - ("id", "!=", record.id), - ] - ) - if board_pricelist: - raise UserError( - _( - "This Board Service in this Room \ - can't repeat without pricelist" - ) - ) - - # Action methods + ) + # 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").read()[0] + 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") ] @@ -114,25 +93,42 @@ class PmsBoardServiceRoomType(models.Model): action["target"] = "new" return action - # ORM Overrides def init(self): self._cr.execute( "SELECT indexname FROM pg_indexes WHERE indexname = %s", - ("pms_board_service_id_pms_room_type_id_pricelist_id",), + ("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_pricelist_id \ + "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, pricelist_id)" + (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"]) ) + board_service = self.env["pms.board.service"].browse( + vals["pms_board_service_id"] + ) + properties = board_service.pms_property_ids + if "pms_room_type_id" in vals: + room_type = self.env["pms.room.type"].browse(vals["pms_room_type_id"]) + properties = ( + properties + room_type.pms_property_ids + if properties + else room_type.pms_property_ids + ) + if properties: + vals.update( + { + "pms_property_ids": properties, + } + ) return super(PmsBoardServiceRoomType, self).create(vals) def write(self, vals): @@ -142,7 +138,6 @@ class PmsBoardServiceRoomType(models.Model): ) return super(PmsBoardServiceRoomType, self).write(vals) - # Business methods @api.model def prepare_board_service_reservation_ids(self, board_service_id): """ diff --git a/pms/models/pms_board_service_room_type_line.py b/pms/models/pms_board_service_room_type_line.py index 8e89e1551..fb5038190 100644 --- a/pms/models/pms_board_service_room_type_line.py +++ b/pms/models/pms_board_service_room_type_line.py @@ -1,21 +1,73 @@ # Copyright 2017 Dario Lodeiros # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +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( - "pms.board.service.room.type", - "Board Service Room", - ondelete="cascade", + 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( - "product.product", "Product", required=True, readonly=True + 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("Amount", digits=("Product Price"), default=0.0) + 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 index 5d079e8f4..6e5bfd776 100644 --- a/pms/models/pms_cancelation_rule.py +++ b/pms/models/pms_cancelation_rule.py @@ -4,36 +4,85 @@ from odoo import fields, models -# TODO: refactoring to cancellation.rule class PmsCancelationRule(models.Model): _name = "pms.cancelation.rule" _description = "Cancelation Rules" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Char("Amenity Name", translate=True, required=True) + name = fields.Char( + string="Cancelation Rule", + required=True, + translate=True, + ) pricelist_ids = fields.One2many( - "product.pricelist", "cancelation_rule_id", "Pricelist that use this rule" + 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( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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 ) - active = fields.Boolean("Active", default=True) days_intime = fields.Integer( - "Days Late", help="Maximum number of days for free cancellation before Checkin" + 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", ) - penalty_late = fields.Integer("% Penalty Late", default="100") apply_on_late = fields.Selection( - [("first", "First Day"), ("all", "All Days"), ("days", "Specify days")], - "Late apply on", + 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", ) - days_late = fields.Integer("Late first days", default="2") - penalty_noshow = fields.Integer("% Penalty No Show", default="100") apply_on_noshow = fields.Selection( - [("first", "First Day"), ("all", "All Days"), ("days", "Specify days")], - "No Show apply on", + 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("NoShow first days", default="2") - - # TODO: Constrain coherence pms_property_ids pricelist and cancelation_rules + 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 index c364c8e2e..8d1a846cf 100644 --- a/pms/models/pms_checkin_partner.py +++ b/pms/models/pms_checkin_partner.py @@ -2,6 +2,9 @@ # Copyright 2018 Alexandre Diaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import json +import re + from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -9,43 +12,100 @@ from odoo.exceptions import ValidationError class PmsCheckinPartner(models.Model): _name = "pms.checkin.partner" _description = "Partner Checkins" + _rec_name = "identifier" + _check_pms_properties_auto = True - @api.model - def _get_default_pms_property(self): - # TODO: Change by property env variable (like company) - return self.env.user.pms_property_id - - # Fields declaration identifier = fields.Char( - "Identifier", - compute="_compute_identifier", - readonly=False, - store=True, + string="Identifier", + help="Checkin Partner Id", + readonly=True, + index=True, + default=lambda self: _("New"), ) partner_id = fields.Many2one( - "res.partner", + string="Partner", + help="Partner associated with checkin partner", + comodel_name="res.partner", domain="[('is_company', '=', False)]", ) - reservation_id = fields.Many2one("pms.reservation") + 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( - "pms.folio", - compute="_compute_folio_id", + 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( - "pms.property", default=_get_default_pms_property, required=True + 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", + readonly=False, + store=True, + compute="_compute_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", + compute="_compute_mobile", + store=True, + readonly=False, + ) + image_128 = fields.Image( + string="Image", + help="Checkin Partner Image, it corresponds with Partner Image associated", + related="partner_id.image_128", ) - name = fields.Char("Name", related="partner_id.name") - email = fields.Char("E-mail", related="partner_id.email") - mobile = fields.Char("Mobile", related="partner_id.mobile") - image_128 = fields.Image(related="partner_id.image_128") segmentation_ids = fields.Many2many( + string="Segmentation", + help="Segmentation tags to classify checkin partners", related="reservation_id.segmentation_ids", readonly=True, ) - arrival = fields.Datetime("Enter") - departure = fields.Datetime("Exit") + 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="State", + help="Status of the checkin partner regarding the reservation", + readonly=True, + store=True, selection=[ ("draft", "Unkown Guest"), ("precheckin", "Pending arrival"), @@ -53,10 +113,7 @@ class PmsCheckinPartner(models.Model): ("done", "Out"), ("cancelled", "Cancelled"), ], - string="State", compute="_compute_state", - store=True, - readonly=True, ) # Compute @@ -98,14 +155,28 @@ class PmsCheckinPartner(models.Model): else: record.state = "precheckin" - @api.model - def _checkin_mandatory_fields(self, depends=False): - # api.depends need "reservation_id.state" in de lambda function - if depends: - return ["reservation_id.state", "name"] - return ["name"] + @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: + record.name = record.partner_id.name - # Constraints and onchanges + @api.depends("partner_id", "partner_id.email") + def _compute_email(self): + for record in self: + if not record.email: + record.email = record.partner_id.email + + @api.depends("partner_id", "partner_id.mobile") + def _compute_mobile(self): + for record in self: + if not record.mobile: + record.mobile = record.partner_id.mobile @api.constrains("departure", "arrival") def _check_departure(self): @@ -129,23 +200,138 @@ class PmsCheckinPartner(models.Model): _("This guest is already registered in the room") ) - # CRUD + @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.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 - if not self._context.get("auto_create_checkin"): - reservation_id = vals.get("reservation_id") - if reservation_id: - reservation = self.env["pms.reservation"].browse(reservation_id) - draft_checkins = reservation.checkin_partner_ids.filtered( - lambda c: c.state == "draft" + 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"] ) - if len(draft_checkins) > 0 and vals.get("partner_id"): - draft_checkins[0].sudo().unlink() - return super(PmsCheckinPartner, self).create(vals) + pms_property = self.env["pms.property"].browse(pms_property_id) + vals["identifier"] = pms_property.folio_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") + ) - # Action methods + def write(self, vals): + res = super(PmsCheckinPartner, self).write(vals) + ResPartner = self.env["res.partner"] + if any(field in vals for field in ResPartner._get_key_fields()): + # Create Partner if get key field in the checkin + for record in self: + key = False + partner = False + if not record.partner_id: + partner_vals = {} + for field in self._checkin_partner_fields(): + if getattr(record, field): + partner_vals[field] = getattr(record, field) + if field in ResPartner._get_key_fields() and partner_vals.get( + field + ): + key = True + # REVIEW: if partner exist, we can merge? + partner = ResPartner.search( + [(field, "=", getattr(record, field))] + ) + if key: + if not partner: + partner = ResPartner.create(partner_vals) + record.partner_id = partner + + if any(field in vals for field in self._checkin_partner_fields()): + # Update partner when the checkin partner field is not set on the partner + for record in self: + if record.partner_id: + partner_vals = {} + for field in self._checkin_partner_fields(): + if not getattr(record.partner_id, field): + partner_vals[field] = getattr(record, field) + record.partner_id.write(partner_vals) + return res + + def unlink(self): + reservations = self.mapped("reservation_id") + res = super().unlink() + reservations._compute_checkin_partner_ids() + return res + + @api.model + def _checkin_mandatory_fields(self, depends=False): + # api.depends need "reservation_id.state" in the lambda function + if depends: + return ["reservation_id.state", "name"] + return ["name"] + + @api.model + def _checkin_partner_fields(self): + # api.depends need "reservation_id.state" in the lambda function + checkin_fields = self._checkin_mandatory_fields() + checkin_fields.extend(["mobile", "email"]) + 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) def action_on_board(self): for record in self: @@ -153,12 +339,16 @@ class PmsCheckinPartner(models.Model): raise ValidationError(_("It is not yet checkin day!")) if record.reservation_id.checkout <= fields.Date.today(): raise ValidationError(_("Its too late to checkin")) + if any( + not getattr(record, field) for field in self._checkin_mandatory_fields() + ): + raise ValidationError(_("Personal data is missing for check-in")) vals = { "state": "onboard", "arrival": fields.Datetime.now(), } record.update(vals) - if record.reservation_id.left_for_checkin: + if record.reservation_id.allowed_checkin: record.reservation_id.state = "onboard" def action_done(self): diff --git a/pms/models/pms_floor.py b/pms/models/pms_floor.py deleted file mode 100644 index b59ead9f8..000000000 --- a/pms/models/pms_floor.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2017 Dario Lodeiros -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class PmsFloor(models.Model): - _name = "pms.floor" - _description = "Ubication" - - # Fields declaration - name = fields.Char( - "Ubication Name", translate=True, size=64, required=True, index=True - ) - pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" - ) - sequence = fields.Integer("Sequence") diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 01460eb2b..1899af850 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -3,8 +3,11 @@ # 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__) @@ -14,8 +17,421 @@ class PmsFolio(models.Model): _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_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, + default=0, + 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", + readonly=True, + copy=False, + comodel_name="payment.transaction", + relation="folio_transaction_rel", + column1="folio_id", + column2="transaction_id", + ) + payment_term_id = fields.Many2one( + string="Payment Terms", + help="Pricelist 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", + ) + checkins_ratio = fields.Integer( + string="Pending Arrival Ratio", + compute="_compute_checkins_ratio", + ) + 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, + ) + email = fields.Char( + string="E-mail", help="Partner Email", related="partner_id.email" + ) + mobile = fields.Char( + string="Mobile", help="Partner Mobile", related="partner_id.mobile" + ) + phone = fields.Char( + string="Phone", help="Partner Phone", related="partner_id.phone" + ) + partner_internal_comment = fields.Text( + string="Internal Partner Notes", + help="Internal notes of the partner", + related="partner_id.comment", + ) + 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, + ) + reservation_pending_arrival_ids = fields.One2many( + string="Pending Arrival Rooms", + comodel_name="pms.checkin.partner", + compute="_compute_reservations_pending_arrival", + ) + reservations_pending_count = fields.Integer( + compute="_compute_reservations_pending_arrival" + ) + max_reservation_prior = fields.Integer( + string="Max reservation priority on the entire folio", + help="Max reservation priority on the entire folio", + compute="_compute_max_reservation_prior", + ) + 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, + ) - # Default Methods ang Gets def name_get(self): result = [] for folio in self: @@ -25,264 +441,118 @@ class PmsFolio(models.Model): result.append((folio.id, name)) return result - @api.model - def _default_diff_invoicing(self): - """ - If the guest has an invoicing address set, - this method return diff_invoicing = True, else, return False - """ - if "folio_id" in self.env.context: - folio = self.env["pms.folio"].browse([self.env.context["folio_id"]]) - if folio.partner_id.id == folio.partner_invoice_id.id: - return False - return True - - @api.model - def _get_default_pms_property(self): + def _default_note(self): return ( - self.env.user.pms_property_id - ) # TODO: Change by property env variable (like company) + self.env["ir.config_parameter"] + .sudo() + .get_param("account.use_invoice_terms") + and self.env.company.invoice_terms + or "" + ) - # Fields declaration - name = fields.Char( - string="Folio Number", readonly=True, index=True, default=lambda self: _("New") - ) - pms_property_id = fields.Many2one( - "pms.property", default=_get_default_pms_property, required=True - ) - partner_id = fields.Many2one( - "res.partner", compute="_compute_partner_id", tracking=True, ondelete="restrict" - ) - reservation_ids = fields.One2many( - "pms.reservation", - "folio_id", - readonly=False, - states={"done": [("readonly", True)]}, - help="Room reservation detail.", - ) - number_of_rooms = fields.Integer( - "Number of Rooms", - compute="_compute_number_of_rooms", - store="True", - ) - service_ids = fields.One2many( - "pms.service", - "folio_id", - readonly=False, - states={"done": [("readonly", True)]}, - help="Services detail provide to customer and it will " - "include in main Invoice.", - ) - company_id = fields.Many2one( - "res.company", - "Company", - required=True, - default=lambda self: self.env.company, - ) - analytic_account_id = fields.Many2one( - "account.analytic.account", - "Analytic Account", - readonly=True, - states={"draft": [("readonly", False)], "sent": [("readonly", False)]}, - help="The analytic account related to a folio.", - copy=False, - ) - currency_id = fields.Many2one( - "res.currency", - related="pricelist_id.currency_id", - string="Currency", - readonly=True, - required=True, - ondelete="restrict", - ) - pricelist_id = fields.Many2one( - "product.pricelist", - string="Pricelist", - ondelete="restrict", - compute="_compute_pricelist_id", - store=True, - readonly=False, - help="Pricelist for current folio.", - ) - commission = fields.Float( - string="Commission", - compute="_compute_commission", - store=True, - readonly=True, - default=0, - ) - user_id = fields.Many2one( - "res.users", - string="Salesperson", - index=True, - ondelete="restrict", - tracking=True, - compute="_compute_user_id", - store=True, - readonly=False, - ) - agency_id = fields.Many2one( - "res.partner", - string="Agency", - ondelete="restrict", - domain=[("is_agency", "=", True)], - ) - channel_type_id = fields.Many2one( - "pms.sale.channel", - string="Direct Sale Channel", - ondelete="restrict", - domain=[("channel_type", "=", "direct")], - ) - payment_ids = fields.One2many("account.payment", "folio_id", readonly=True) - # return_ids = fields.One2many("payment.return", "folio_id", readonly=True) - payment_term_id = fields.Many2one( - "account.payment.term", - string="Payment Terms", - ondelete="restrict", - compute="_compute_payment_term_id", - store=True, - readonly=False, - help="Pricelist for current folio.", - ) - checkin_partner_ids = fields.One2many("pms.checkin.partner", "folio_id") - move_ids = fields.Many2many( - "account.move", - string="Invoices", - compute="_compute_get_invoiced", - readonly=True, - copy=False, - compute_sudo=True, - ) - partner_invoice_id = fields.Many2one( - "res.partner", - string="Invoice Address", - compute="_compute_partner_invoice_id", - store=True, - readonly=False, - help="Invoice address for current group.", - ) - 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( - "account.fiscal.position", string="Fiscal Position" - ) - closure_reason_id = fields.Many2one("room.closure.reason") - segmentation_ids = fields.Many2many( - "res.partner.category", string="Segmentation", ondelete="restrict" - ) - client_order_ref = fields.Char(string="Customer Reference", copy=False) - reservation_type = fields.Selection( - [("normal", "Normal"), ("staff", "Staff"), ("out", "Out of Service")], - string="Type", - default=lambda *a: "normal", - ) - date_order = fields.Datetime( - string="Order Date", - required=True, - readonly=True, - index=True, - states={"draft": [("readonly", False)], "sent": [("readonly", False)]}, - copy=False, - default=fields.Datetime.now, - ) - confirmation_date = fields.Datetime( - string="Confirmation Date", - readonly=True, - index=True, - help="Date on which the folio is confirmed.", - copy=False, - ) - state = fields.Selection( - [ - ("draft", "Quotation"), - ("sent", "Quotation Sent"), - ("confirm", "Confirmed"), - ("done", "Locked"), - ("cancel", "Cancelled"), - ], - string="Status", - readonly=True, - copy=False, - index=True, - tracking=True, - default="draft", - ) - # Partner fields for being used directly in the Folio views--------- - email = fields.Char("E-mail", related="partner_id.email") - mobile = fields.Char("Mobile", related="partner_id.mobile") - phone = fields.Char("Phone", related="partner_id.phone") - partner_internal_comment = fields.Text( - string="Internal Partner Notes", related="partner_id.comment" - ) - # Payment Fields----------------------------------------------------- - credit_card_details = fields.Text("Credit Card Details") + def _get_report_base_filename(self): + self.ensure_one() + return "Folio %s" % self.name - # Amount Fields------------------------------------------------------ - pending_amount = fields.Monetary( - compute="_compute_amount", store=True, string="Pending in Folio" - ) - # refund_amount = fields.Monetary( - # compute="_compute_amount", store=True, string="Payment Returns" - # ) - invoices_paid = fields.Monetary( - compute="_compute_amount", - store=True, - tracking=True, - string="Payments", - ) - amount_untaxed = fields.Monetary( - string="Untaxed Amount", - store=True, - readonly=True, - compute="_compute_amount_all", - tracking=True, - ) - amount_tax = fields.Monetary( - string="Taxes", store=True, readonly=True, compute="_compute_amount_all" - ) - amount_total = fields.Monetary( - string="Total", - store=True, - readonly=True, - compute="_compute_amount_all", - tracking=True, - ) - # Checkin Fields----------------------------------------------------- - reservation_pending_arrival_ids = fields.One2many( - comodel_name="pms.checkin.partner", - string="Pending Arrival Rooms", - compute="_compute_reservations_pending_arrival", - ) - reservations_pending_count = fields.Integer( - compute="_compute_reservations_pending_arrival" - ) - # Invoice Fields----------------------------------------------------- - invoice_status = fields.Selection( - [ - ("invoiced", "Fully Invoiced"), - ("to invoice", "To Invoice"), - ("no", "Nothing to Invoice"), - ], - string="Invoice Status", - compute="_compute_get_invoiced", - store=True, - readonly=True, - default="no", - compute_sudo=True, - ) - # Generic Fields----------------------------------------------------- - internal_comment = fields.Text(string="Internal Folio Notes") - cancelled_reason = fields.Text("Cause of cancelled") - prepaid_warning_days = fields.Integer( - "Prepaid Warning Days", - help="Margin in days to create a notice if a payment \ - advance has not been recorded", - ) - sequence = fields.Integer(string="Sequence", default=10) + 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 - # Compute and Search methods @api.depends("reservation_ids", "reservation_ids.state") def _compute_number_of_rooms(self): for folio in self: @@ -290,23 +560,58 @@ class PmsFolio(models.Model): folio.reservation_ids.filtered(lambda a: a.state != "cancelled") ) + @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: + 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) + + @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") def _compute_pricelist_id(self): for folio in self: - if folio.partner_id and folio.partner_id.property_product_pricelist: - pricelist_id = folio.partner_id.property_product_pricelist.id - else: - pricelist_id = self.env.user.pms_property_id.default_pricelist_id.id - if folio.pricelist_id.id != pricelist_id: - # TODO: Warning change de pricelist? - folio.pricelist_id = pricelist_id if folio.agency_id and folio.agency_id.apply_pricelist: - pricelist_id = folio.agency_id.property_product_pricelist.id + folio.pricelist_id = folio.agency_id.property_product_pricelist.id + elif folio.partner_id and folio.partner_id.property_product_pricelist: + folio.pricelist_id = folio.partner_id.property_product_pricelist.id + elif not folio.pricelist_id.id: + folio.pricelist_id = folio.pms_property_id.default_pricelist_id.id @api.depends("agency_id") def _compute_partner_id(self): for folio in self: - if folio.agency_id and folio.agency_id.invoice_agency: + if folio.agency_id and folio.agency_id.invoice_to_agency: folio.partner_id = folio.agency_id.id elif not folio.partner_id: folio.partner_id = False @@ -314,14 +619,18 @@ class PmsFolio(models.Model): @api.depends("partner_id") def _compute_user_id(self): for folio in self: - folio.user_id = (folio.partner_id.user_id.id or self.env.uid,) + if not folio.user_id: + folio.user_id = (folio.partner_id.user_id.id or self.env.uid,) @api.depends("partner_id") - def _compute_partner_invoice_id(self): - self.partner_invoice_id = False - for folio in self: + def _compute_partner_invoice_ids(self): + for folio in self.filtered("partner_id"): + folio.partner_invoice_ids = False addr = folio.partner_id.address_get(["invoice"]) - folio.partner_invoice_id = addr["invoice"] + if not addr["invoice"] in folio.partner_invoice_ids.ids: + folio.partner_invoice_ids = [(4, addr["invoice"])] + # Avoid CacheMissing + self.filtered(lambda f: not f.partner_invoice_ids).partner_invoice_ids = False @api.depends("partner_id") def _compute_payment_term_id(self): @@ -342,198 +651,301 @@ class PmsFolio(models.Model): else: folio.commission = 0 - @api.depends( - "state", "reservation_ids.invoice_status", "service_ids.invoice_status" - ) + @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")) + + 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 not in status 'sale' or 'done', 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 Folio line is 'to invoice', - the whole Folio is 'to invoice' - - invoiced: if all Folio lines are invoiced, the Folio is invoiced. - - The invoice_ids are obtained thanks to the invoice lines of the - Folio 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 Folio. + - 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. """ - for folio in self.filtered("pricelist_id"): - move_ids = ( - folio.reservation_ids.mapped("move_line_ids") - .mapped("move_id") - .filtered(lambda r: r.type in ["out_invoice", "out_refund"]) - ) - invoice_ids = ( - folio.service_ids.mapped("move_line_ids") - .mapped("move_id") - .filtered(lambda r: r.type in ["out_invoice", "out_refund"]) - ) - # TODO: Search for invoices which have been 'cancelled' - # (filter_refund = 'modify' in 'account.move.refund') - # use like as origin may contains multiple references - # (e.g. 'SO01, SO02') - refunds = invoice_ids.search( + 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( [ - ("invoice_origin", "like", folio.name), - ("company_id", "=", folio.company_id.id), - ] - ).filtered(lambda r: r.type in ["out_invoice", "out_refund"]) - invoice_ids |= refunds.filtered(lambda r: folio.id in r.folio_ids.ids) - # Search for refunds as well - refund_ids = self.env["account.move"].browse() - if invoice_ids: - for inv in invoice_ids: - refund_ids += refund_ids.search( - [ - ("type", "=", "out_refund"), - ("invoice_origin", "=", inv.number), - ("invoice_origin", "!=", False), - ("journal_id", "=", inv.journal_id.id), - ] - ) - # Ignore the status of the deposit product - deposit_product_id = self.env[ - "sale.advance.payment.inv" - ]._default_product_id() - service_invoice_status = [ - service.invoice_status - for service in folio.service_ids - if service.product_id != deposit_product_id - ] - reservation_invoice_status = [ - reservation.invoice_status for reservation in folio.reservation_ids - ] - - if folio.state not in ("confirm", "done"): - invoice_status = "no" - elif any( - invoice_status == "to invoice" - for invoice_status in service_invoice_status - ) or any( - invoice_status == "to invoice" - for invoice_status in reservation_invoice_status - ): - invoice_status = "to invoice" - elif all( - invoice_status == "invoiced" - for invoice_status in service_invoice_status - ) or any( - invoice_status == "invoiced" - for invoice_status in reservation_invoice_status - ): - invoice_status = "invoiced" - else: - invoice_status = "no" - - folio.update( - { - "move_ids": move_ids.ids + refund_ids.ids, - "invoice_status": invoice_status, - } + ("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("reservation_ids.price_total", "service_ids.price_total") + @api.depends("sale_line_ids.price_total") def _compute_amount_all(self): """ Compute the total amounts of the SO. """ - for record in self.filtered("pricelist_id"): + for folio in self: amount_untaxed = amount_tax = 0.0 - amount_untaxed = sum(record.reservation_ids.mapped("price_subtotal")) + sum( - record.service_ids.mapped("price_subtotal") - ) - amount_tax = sum(record.reservation_ids.mapped("price_tax")) + sum( - record.service_ids.mapped("price_tax") - ) - record.update( + for line in folio.sale_line_ids: + amount_untaxed += line.price_subtotal + amount_tax += line.price_tax + folio.update( { - "amount_untaxed": record.pricelist_id.currency_id.round( - amount_untaxed - ), - "amount_tax": record.pricelist_id.currency_id.round(amount_tax), + "amount_untaxed": amount_untaxed, + "amount_tax": amount_tax, "amount_total": amount_untaxed + amount_tax, } ) @api.depends("reservation_ids", "reservation_ids.state") - def _compute_reservations_pending_arrival(self): - for record in self: - record.reservation_pending_arrival_ids = record.reservation_ids.filtered( - lambda r: r.state in ("draft", "precheckin") + 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") + ) ) - record.reservations_pending_count = len( - record.reservations_pending_arrival_ids + + @api.depends("checkin_partner_ids", "checkin_partner_ids.state") + def _compute_pending_checkin_data(self): + for folio in self: + 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"): + 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", "payment_ids", "reservation_type", "state") + @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): - acc_pay_obj = self.env["account.payment"] for record in self: if record.reservation_type in ("staff", "out"): vals = { "pending_amount": 0, "invoices_paid": 0, - # "refund_amount": 0, } record.update(vals) else: - total_inv_refund = 0 - payments = acc_pay_obj.search([("folio_id", "=", record.id)]) - total_paid = sum(pay.amount for pay in payments) - # return_lines = self.env["payment.return.line"].search( - # [ - # ("move_line_ids", "in", payments.mapped("move_line_ids.id")), - # ("return_id.state", "=", "done"), - # ] - # ) - # total_inv_refund = sum( - # pay_return.amount for pay_return in return_lines - # ) + journals = record.pms_property_id._get_payment_methods() + 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 == "cancelled": 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 - total_paid + total_inv_refund, - "invoices_paid": total_paid, - # "refund_amount": total_inv_refund, + "pending_amount": total - paid_out, + "invoices_paid": paid_out, + "payment_state": payment_state, } record.update(vals) - # Action methods + def _compute_max_reservation_prior(self): + for record in self: + reservation_priors = record.reservation_ids.mapped("priority") + record.max_reservation_prior = 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 != "cancelled" + ) + 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) + + 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.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) + 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.account_payment_view_form_folio").id + view_id = self.env.ref("pms.wizard_payment_folio_view_form").id return { "name": _("Register Payment"), "view_type": "form", "view_mode": "form", - "res_model": "account.payment", + "res_model": "wizard.payment.folio", "type": "ir.actions.act_window", "view_id": view_id, "context": { "default_folio_id": self.id, "default_amount": amount, - "default_payment_type": "inbound", - "default_partner_type": "customer", "default_partner_id": partner, - "default_communication": self.name, }, "target": "new", } def open_moves_folio(self): invoices = self.mapped("move_ids") - action = self.env.ref("account.action_move_out_invoice_type").read()[0] + 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: @@ -543,6 +955,13 @@ class PmsFolio(models.Model): 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 = [] @@ -577,27 +996,22 @@ class PmsFolio(models.Model): "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", } - # ORM Overrides - @api.model - def create(self, vals): - # TODO: Make sequence from property, not company - if vals.get("name", _("New")) == _("New") or "name" not in vals: - # TODO: change for property env variable - pms_property_id = ( - self.env.user.pms_property_id.id - if "pms_property_id" not in vals - else vals["pms_property_id"] - ) - vals["name"] = self.env["ir.sequence"].search( - [("pms_property_id", "=", pms_property_id)] - ).next_by_code("pms.folio") or _("New") - result = super(PmsFolio, self).create(vals) - return result + 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 - # Business methods def action_done(self): reservation_ids = self.mapped("reservation_ids") for line in reservation_ids: @@ -628,65 +1042,536 @@ class PmsFolio(models.Model): # create an analytic account if at least an expense product # if any([expense_policy != 'no' for expense_policy in - # self.order_line.mapped('product_id.expense_policy')]): + # self.sale_line_ids.mapped('product_id.expense_policy')]): # if not self.analytic_account_id: # self._create_analytic_account() return True # CHECKIN/OUT PROCESS - 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 != "cancelled" - ) - 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) + 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"} - def _get_tax_amount_by_group(self): + 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() - res = {} - for line in self.reservation_ids: - price_reduce = line.price_total - product = line.room_type_id.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"] - for line in self.service_ids: - price_reduce = line.price_unit * (1.0 - line.discount / 100.0) - taxes = line.tax_ids.compute_all( - price_reduce, quantity=line.product_qty, product=line.product_id - )["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 + return { + "type": "ir.actions.act_url", + "target": "self", + "url": self.get_portal_url(), + } - # Check that only one sale channel is selected - @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: - raise models.ValidationError(_("There must be only one sale channel")) + 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) + ) + + 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 + if partner_invoice_id + else self.partner_invoice_ids[0], + "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, + ): + 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) + + @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 diff --git a/pms/models/pms_property.py b/pms/models/pms_property.py index 76295607d..36f7c4257 100644 --- a/pms/models/pms_property.py +++ b/pms/models/pms_property.py @@ -18,56 +18,77 @@ class PmsProperty(models.Model): _inherits = {"res.partner": "partner_id"} _check_company_auto = True - # Fields declaration partner_id = fields.Many2one( - "res.partner", "Property", required=True, delegate=True, ondelete="cascade" + string="Property", + help="Current property", + comodel_name="res.partner", + required=True, + ondelete="cascade", ) company_id = fields.Many2one( - "res.company", - required=True, + 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( - "res.users", - "pms_property_users_rel", - "pms_property_id", - "user_id", 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", ) - room_ids = fields.One2many("pms.room", "pms_property_id", "Rooms") default_pricelist_id = fields.Many2one( - "product.pricelist", string="Product Pricelist", - required=True, help="The default pricelist used in this property.", - ) - default_restriction_id = fields.Many2one( - "pms.room.type.restriction", - "Restriction Plan", + comodel_name="product.pricelist", required=True, - help="The default restriction plan used in this property.", + default=lambda self: self.env.ref("product.list0").id, ) default_arrival_hour = fields.Char( - "Arrival Hour (GMT)", help="HH:mm Format", default="14:00" + string="Arrival Hour", help="HH:mm Format", default="14:00" ) default_departure_hour = fields.Char( - "Departure Hour (GMT)", help="HH:mm Format", default="12:00" + string="Departure Hour", help="HH:mm Format", default="12:00" ) - default_cancel_policy_days = fields.Integer("Cancellation Days") - default_cancel_policy_percent = fields.Float("Percent to pay") folio_sequence_id = fields.Many2one( - "ir.sequence", "Folio Sequence", check_company=True, copy=False + string="Folio Sequence", + help="The sequence that formed the name of the folio.", + check_company=True, + copy=False, + comodel_name="ir.sequence", ) - tz = fields.Selection( - _tz_get, - string="Timezone", - required=True, - default=lambda self: self.env.user.tz or "UTC", - help="This field is used in order to define \ - in which timezone the arrival/departure will work.", + 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, ) - # Constraints and onchanges @api.constrains("default_arrival_hour") def _check_arrival_hour(self): for record in self: @@ -96,12 +117,75 @@ class PmsProperty(models.Model): ) ) - def date_property_timezone(self, date): + def date_property_timezone(self, dt): self.ensure_one() tz_property = self.tz - date = pytz.timezone(tz_property).localize(date) - date = date.replace(tzinfo=None) - date = pytz.timezone(self.env.user.tz).localize(date) - date = date.astimezone(pytz.utc) - date = date.replace(tzinfo=None) - return date + 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): + 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), + ] + ) + 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 index 4855720fb..f62d4d13b 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -7,7 +7,6 @@ import time from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, float_compare, float_is_zero _logger = logging.getLogger(__name__) @@ -16,457 +15,603 @@ class PmsReservation(models.Model): _name = "pms.reservation" _description = "Reservation" _inherit = ["mail.thread", "mail.activity.mixin", "portal.mixin"] - _order = "priority desc, name" + _order = "priority desc, create_date desc, write_date desc" + # TODO: + # consider near_to_checkin & pending_notifications to order + _check_pms_properties_auto = True _check_company_auto = True - # Default Methods ang Gets - def _get_default_checkin(self): - folio = False - if "folio_id" in self._context: - folio = self.env["pms.folio"].search( - [("id", "=", self._context["folio_id"])] - ) - if folio and folio.reservation_ids: - return folio.reservation_ids[0].checkin - else: - return fields.Date.today() - - def _get_default_checkout(self): - folio = False - if "folio_id" in self._context: - folio = self.env["pms.folio"].search( - [("id", "=", self._context["folio_id"])] - ) - if folio and folio.reservation_ids: - return folio.reservation_ids[0].checkout - else: - return fields.Date.today() + datetime.timedelta(1) - - def _get_default_arrival_hour(self): - folio = False - # TODO: Change by property env variable (like company) - default_arrival_hour = self.env.user.pms_property_id.default_arrival_hour - if "folio_id" in self._context: - folio = self.env["pms.folio"].search( - [("id", "=", self._context["folio_id"])] - ) - if folio and folio.reservation_ids: - return folio.reservation_ids[0].arrival_hour - else: - return default_arrival_hour - - def _get_default_departure_hour(self): - folio = False - # TODO: Change by property env variable (like company) - default_departure_hour = self.env.user.pms_property_id.default_departure_hour - if "folio_id" in self._context: - folio = self.env["pms.folio"].search( - [("id", "=", self._context["folio_id"])] - ) - if folio and folio.reservation_ids: - return folio.reservation_ids[0].departure_hour - else: - return default_departure_hour - - @api.model - def _get_default_pms_property(self): - # TODO: Change by property env variable (like company) - return self.env.user.pms_property_id - - 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 - - @api.model - def _default_diff_invoicing(self): - """ - If the guest has an invoicing address set, - this method return diff_invoicing = True, else, return False - """ - if "reservation_id" in self.env.context: - reservation = self.env["pms.reservation"].browse( - [self.env.context["reservation_id"]] - ) - if reservation.partner_id.id == reservation.partner_invoice_id.id: - return False - return True - - # Fields declaration name = fields.Text( - "Reservation Description", - compute="_compute_name", - store=True, - readonly=False, - # required=True, + 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", ) - priority = fields.Integer(compute="_compute_priority", store="True", index=True) - preferred_room_id = fields.Many2one( - "pms.room", string="Room", - tracking=True, + 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)]", + domain="[" + "('id', 'in', allowed_room_ids)," + "('pms_property_id', '=', pms_property_id)," + "]", + tracking=True, + check_pms_properties=True, ) allowed_room_ids = fields.Many2many( - "pms.room", 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( - "pms.folio", string="Folio", - tracking=True, + 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( - "pms.board.service.room.type", 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( - "pms.room.type", string="Room Type", - tracking=True, - # required=True, - compute="_compute_room_type_id", - store=True, + 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", + compute="_compute_room_type_id", + tracking=True, + check_pms_properties=True, ) partner_id = fields.Many2one( - "res.partner", - tracking=True, + string="Customer", + help="Name of who made the reservation", + readonly=False, + store=True, + comodel_name="res.partner", ondelete="restrict", compute="_compute_partner_id", - store=True, - readonly=False, + tracking=True, + check_pms_properties=True, ) agency_id = fields.Many2one( - related="folio_id.agency_id", + string="Agency", + help="Agency that made the reservation", readonly=False, store=True, + related="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", - readonly=False, - store=True, + tracking=True, ) - partner_invoice_id = fields.Many2one( - "res.partner", - string="Invoice Address", - help="Invoice address for current reservation.", - compute="_compute_partner_invoice_id", - store=True, - readonly=False, + 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, ) - closure_reason_id = fields.Many2one(related="folio_id.closure_reason_id") company_id = fields.Many2one( - related="folio_id.company_id", string="Company", store=True, readonly=True + string="Company", + help="Company to which the reservation belongs", + readonly=True, + store=True, + related="folio_id.company_id", ) pms_property_id = fields.Many2one( - "pms.property", - default=_get_default_pms_property, # required=True + 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( - "pms.reservation.line", - "reservation_id", - compute="_compute_reservation_line_ids", - store=True, + 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( - "pms.service", - "reservation_id", - compute="_compute_service_ids", - store=True, + 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( - "product.pricelist", 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", - store=True, + 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 (%)", - compute="_compute_commission_percent", - store=True, + 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", - store=True, ) - # TODO: Warning Mens to update pricelist checkin_partner_ids = fields.One2many( - "pms.checkin.partner", - "reservation_id", - compute="_compute_checkin_partner_ids", - store=True, + 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( - "Pending Arrival", - compute="_compute_count_pending_arrival", + 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( - "Checkin Data", - compute="_compute_pending_checkin_data", + string="Checkin Data", + help="Data missing at checkin", store=True, + compute="_compute_pending_checkin_data", ) ratio_checkin_data = fields.Integer( string="Pending Checkin Data", + help="Proportion of guest data pending at checkin", compute="_compute_ratio_checkin_data", ) - ready_for_checkin = fields.Boolean(compute="_compute_ready_for_checkin") - left_for_checkin = fields.Boolean( - compute="_compute_left_for_checkin", search="_search_left_for_checkin" + 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", ) - checkin_today = fields.Boolean( - compute="_compute_checkin_today", search="_search_checkin_today" + 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", ) - departure_today = fields.Boolean( - compute="_compute_departure_today", search="_search_departure_today" + + 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 'cancelled', 'done', or 'departure_delayed'", + compute="_compute_allowed_cancel", + search="_search_allowed_cancel", + ) + segmentation_ids = fields.Many2many( - "res.partner.category", string="Segmentation", + help="Segmentation tags to classify reservations", + default=lambda self: self._get_default_segmentation(), + comodel_name="res.partner.category", ondelete="restrict", - default=_get_default_segmentation, ) currency_id = fields.Many2one( - "res.currency", - related="pricelist_id.currency_id", 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( - "account.tax", string="Taxes", - ondelete="restrict", + help="Taxes applied in the reservation", + readonly="False", + store=True, + compute="_compute_tax_ids", + comodel_name="account.tax", domain=["|", ("active", "=", False), ("active", "=", True)], ) - move_line_ids = fields.Many2many( - "account.move.line", - "reservation_move_rel", - "reservation_id", - "move_line_id", - string="Invoice Lines", - copy=False, - ) - analytic_tag_ids = fields.Many2many("account.analytic.tag", string="Analytic Tags") - localizator = fields.Char( - string="Localizator", compute="_compute_localizator", store=True - ) adults = fields.Integer( - "Adults", - tracking=True, - help="List of adults there in guest list. ", - compute="_compute_adults", - store=True, + 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( - "Children", + string="Children", + help="Number total of children there in guest list," + "whose presence counts or not", readonly=False, tracking=True, - help="Number of children there in guest list.", ) - to_assign = fields.Boolean("To Assign", tracking=True) + to_assign = fields.Boolean( + string="To Assign", + help="Technical field", + default=True, + tracking=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"), ("cancelled", "Cancelled"), - ("no_show", "No Show"), - ("no_checkout", "No Checkout"), + ("arrival_delayed", "Arrival Delayed"), + ("departure_delayed", "Departure delayed"), ], - string="Status", - default=lambda *a: "draft", - copy=False, - index=True, tracking=True, - readonly=True, ) reservation_type = fields.Selection( - related="folio_id.reservation_type", default=lambda *a: "normal" + string="Reservation Type", + help="Type of reservations. It can be 'normal', 'staff' or 'out of service", + default=lambda *a: "normal", + related="folio_id.reservation_type", ) splitted = fields.Boolean( - "Splitted", - compute="_compute_splitted", + 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", compute="_compute_rooms", store=True) - - credit_card_details = fields.Text(related="folio_id.credit_card_details") - cancelled_reason = fields.Selection( - [("late", "Late"), ("intime", "In time"), ("noshow", "No Show")], - string="Cause of cancelled", + 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, + 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, ", + required=True, + default=lambda self: self._get_default_checkin(), + copy=False, + tracking=True, + ) + checkout = fields.Date( + string="Check Out", + help="It is the checkout date of the reservation, ", + required=True, + default=lambda self: self._get_default_checkout(), + copy=False, tracking=True, ) - out_service_description = fields.Text("Cause of out of service") - checkin = fields.Date("Check In", required=True, default=_get_default_checkin) - checkout = fields.Date("Check Out", required=True, default=_get_default_checkout) arrival_hour = fields.Char( - "Arrival Hour", - default=_get_default_arrival_hour, - help="Default Arrival Hour (HH:MM)", + string="Arrival Hour", + help="Arrival Hour (HH:MM)", + readonly=False, + store=True, + compute="_compute_arrival_hour", ) departure_hour = fields.Char( - "Departure Hour", - default=_get_default_departure_hour, - help="Default Departure Hour (HH:MM)", + string="Departure Hour", + help="Departure Hour (HH:MM)", + readonly=False, + store=True, + compute="_compute_departure_hour", ) checkin_datetime = fields.Datetime( - "Exact Arrival", + 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( - "Exact Departure", + 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", ) - # TODO: As checkin_partner_count is a computed field, it can't not - # be used in a domain filer Non-stored field - # pms.reservation.checkin_partner_count cannot be searched - # searching on a computed field can also be enabled by setting the - # search parameter. The value is a method name returning a Domains checkin_partner_count = fields.Integer( - "Checkin counter", compute="_compute_checkin_partner_count" + string="Checkin counter", + help="Number of checkin partners in a reservation", + compute="_compute_checkin_partner_count", ) checkin_partner_pending_count = fields.Integer( - "Checkin Pending Num", + 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("Is Overbooking", default=False) - reselling = fields.Boolean("Is Reselling", default=False) - nights = fields.Integer("Nights", compute="_compute_nights", store=True) - origin = fields.Char("Origin", compute="_compute_origin", store=True) - detail_origin = fields.Char( - "Detail Origin", compute="_compute_detail_origin", store=True + 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_email = fields.Char( + string="E-mail", + help="E-mail of the checkin partner associated to the reservation", + related="partner_id.email", + ) + partner_mobile = fields.Char( + string="Mobile", + help="Mobile of the checkin partner associated to the reservation", + related="partner_id.mobile", + ) + partner_phone = fields.Char( + string="Phone", + help="Phone of the checkin partner associated to the reservation", + related="partner_id.phone", ) - folio_pending_amount = fields.Monetary(related="folio_id.pending_amount") - shared_folio = fields.Boolean(compute="_compute_shared") - # Used to notify is the reservation folio has other reservations/services - email = fields.Char("E-mail", related="partner_id.email") - mobile = fields.Char("Mobile", related="partner_id.mobile") - phone = fields.Char("Phone", related="partner_id.phone") partner_internal_comment = fields.Text( - string="Internal Partner Notes", related="partner_id.comment" + string="Internal Partner Notes", + help="Internal reservation comment", + related="partner_id.comment", ) + partner_requests = fields.Text( + string="Partner Requests", + help="Guest requests", + ) + folio_internal_comment = fields.Text( - string="Internal Folio Notes", related="folio_id.internal_comment" + string="Internal Folio Notes", + help="Internal comment for folio", + related="folio_id.internal_comment", + ) + preconfirm = fields.Boolean( + string="Auto confirm to Save", + help="Technical field that indicates the reservation is not comfirm yet", + default=True, ) - preconfirm = fields.Boolean("Auto confirm to Save", default=True) invoice_status = fields.Selection( - [ + string="Invoice Status", + help="The status of the invoices in folio. Can be 'invoiced'," + " 'to invoice' or 'no'.", + compute="_compute_invoice_status", + store=True, + readonly=True, + selection=[ + ("upselling", "Upselling Opportunity"), ("invoiced", "Fully Invoiced"), ("to invoice", "To Invoice"), ("no", "Nothing to Invoice"), ], - string="Invoice Status", - compute="_compute_invoice_status", - store=True, - readonly=True, default="no", ) - qty_to_invoice = fields.Float( - compute="_compute_get_to_invoice_qty", - string="To Invoice", - store=True, - readonly=True, - digits=("Product Unit of Measure"), + 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)]", ) - qty_invoiced = fields.Float( - compute="_compute_get_invoice_qty", - string="Invoiced", - store=True, - readonly=True, - digits=("Product Unit of Measure"), + 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_amount_room_services", + 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_amount_set", + 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, + ) + date_order = fields.Date( + string="Date Order", + help="Order date of reservation", + compute="_compute_date_order", store=True, + readonly=False, ) - # Compute and Search methods - @api.depends("checkin", "checkout", "room_type_id") - def _compute_name(self): - for reservation in self: - if ( - reservation.room_type_id - and reservation.checkin - and reservation.checkout - ): - checkin_str = reservation.checkin.strftime(DEFAULT_SERVER_DATE_FORMAT) - checkout_str = reservation.checkout.strftime(DEFAULT_SERVER_DATE_FORMAT) - reservation.name = ( - reservation.room_type_id.name - + ": " - + checkin_str - + " - " - + checkout_str - ) - else: - reservation.name = "/" + def _compute_date_order(self): + for record in self: + record.date_order = datetime.datetime.today() + # TODO: + # consider near_to_checkin & pending_notifications to order @api.depends("checkin") def _compute_priority(self): - # TODO: Logic priority (100 by example) - self.priority = 100 + for record in self: + record.priority = 0 + + # we can give weights for each condition + if not record.to_assign: + record.priority += 1 + if not record.allowed_checkin: + record.priority += 10 + if record.allowed_checkout: + record.priority += 100 + if record.state == "onboard" and record.folio_pending_amount > 0: + record.priority += 1000 + + @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): @@ -503,7 +648,12 @@ class PmsReservation(models.Model): ) @api.depends( - "reservation_line_ids.date", "overbooking", "state", "preferred_room_id" + "reservation_line_ids.date", + "reservation_line_ids.room_id", + "reservation_line_ids.occupies_availability", + "preferred_room_id", + "pricelist_id", + "pms_property_id", ) def _compute_allowed_room_ids(self): for reservation in self: @@ -513,36 +663,26 @@ class PmsReservation(models.Model): [("active", "=", True)] ) return - rooms_available = self.env[ - "pms.room.type.availability" - ].rooms_available( + rooms_available = self.env["pms.availability.plan"].rooms_available( checkin=reservation.checkin, checkout=reservation.checkout, - room_type_id=False, # Allow chosen any available room + room_type_id=False, # Allows to choose any available room current_lines=reservation.reservation_line_ids.ids, + pricelist_id=reservation.pricelist_id.id, + pms_property_id=reservation.pms_property_id.id, ) reservation.allowed_room_ids = rooms_available - @api.depends("reservation_type", "agency_id") + @api.depends("reservation_type", "agency_id", "folio_id") def _compute_partner_id(self): for reservation in self: if reservation.reservation_type == "out": reservation.partner_id = reservation.pms_property_id.partner_id.id - if reservation.folio_id: - reservation.partner_id = reservation.folio_id.partner_id - else: - reservation.partner_id = False - if not reservation.partner_id and reservation.agency_id: - reservation.partner_id = reservation.agency_id - - @api.depends("partner_id") - def _compute_partner_invoice_id(self): - for reservation in self: - if reservation.folio_id and reservation.folio_id.partner_id: - addr = reservation.folio_id.partner_id.address_get(["invoice"]) - else: - addr = reservation.partner_id.address_get(["invoice"]) - reservation.partner_invoice_id = addr["invoice"] + elif not reservation.partner_id: + if reservation.folio_id: + reservation.partner_id = reservation.folio_id.partner_id + elif reservation.agency_id: + reservation.partner_id = reservation.agency_id @api.depends("checkin", "checkout") def _compute_reservation_line_ids(self): @@ -582,6 +722,13 @@ class PmsReservation(models.Model): ("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 @@ -596,21 +743,54 @@ class PmsReservation(models.Model): 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") + @api.depends("partner_id", "agency_id") def _compute_pricelist_id(self): for reservation in self: - if reservation.folio_id: - pricelist_id = reservation.folio_id.pricelist_id.id - else: - pricelist_id = ( - reservation.partner_id.property_product_pricelist - and reservation.partner_id.property_product_pricelist.id - or self.env.user.pms_property_id.default_pricelist_id.id + if reservation.agency_id and reservation.agency_id.apply_pricelist: + reservation.pricelist_id = ( + reservation.agency_id.property_product_pricelist.id ) - if reservation.pricelist_id.id != pricelist_id: - # TODO: Warning change de pricelist? - reservation.pricelist_id = pricelist_id + elif ( + reservation.partner_id + and reservation.partner_id.property_product_pricelist + ): + reservation.pricelist_id = ( + reservation.partner_id.property_product_pricelist.id + ) + elif not reservation.pricelist_id.id: + if ( + reservation.folio_id + and len(reservation.folio_id.reservation_ids.mapped("pricelist_id")) + == 1 + ): + reservation.pricelist_id = ( + reservation.folio_id.reservation_ids.mapped("pricelist_id") + ) + else: + reservation.pricelist_id = ( + reservation.pms_property_id.default_pricelist_id.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): @@ -630,7 +810,7 @@ class PmsReservation(models.Model): ) elif leftover_unassigneds_count > 0: for i in range(0, leftover_unassigneds_count): - unassigned_checkins[i].sudo().unlink() + 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( @@ -646,9 +826,9 @@ class PmsReservation(models.Model): }, ) ) - reservation.with_context( - {"auto_create_checkin": True} - ).checkin_partner_ids = checkins_lst + 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): @@ -686,40 +866,44 @@ class PmsReservation(models.Model): / reservation.adults ) - def _compute_left_for_checkin(self): + def _compute_allowed_checkin(self): # Reservations still pending entry today for record in self: - record.left_for_checkin = ( + record.allowed_checkin = ( True if ( - record.state in ["draft", "confirm", "no_show"] + record.state in ["draft", "confirm", "arrival_delayed"] and record.checkin <= fields.Date.today() ) else False ) - def _search_left_for_checkin(self, operator, value): - if operator not in ("=",): - raise UserError( - _("Invalid domain operator %s for left of checkin", operator) + 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 ) - if value not in (True,): - raise UserError( - _("Invalid domain right operand %s for left of checkin", value) + def _compute_allowed_cancel(self): + # Reservations can be cancelled + for record in self: + record.allowed_cancel = ( + True + if (record.state not in ["cancelled", "done", "departure_delayed"]) + else False ) - today = fields.Date.context_today(self) - return [ - ("state", "in", ("draft", "confirm", "no_show")), - ("checkin", "<=", today), - ] - def _compute_ready_for_checkin(self): # Reservations with hosts data enought to checkin for record in self: record.ready_for_checkin = ( - record.left_for_checkin + record.allowed_checkin and len( record.checkin_partner_ids.filtered( lambda c: c.state == "precheckin" @@ -728,43 +912,46 @@ class PmsReservation(models.Model): >= 1 ) - def _compute_checkin_today(self): + 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("pms_property_id", "folio_id") + def _compute_arrival_hour(self): for record in self: - record.checkin_today = ( - True if record.checkin == fields.Date.today() else False - ) - # REVIEW: Late checkin?? (next day) + 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 - def _search_checkin_today(self, operator, value): - if operator not in ("=", "!="): - raise UserError(_("Invalid domain operator %s", operator)) - - if value not in (False, True): - raise UserError(_("Invalid domain right operand %s", value)) - - today = fields.Date.context_today(self) - - return [("checkin", operator, today)] - - def _compute_departure_today(self): + @api.depends("pms_property_id", "folio_id") + def _compute_departure_hour(self): for record in self: - record.departure_today = ( - True if record.checkout == fields.Date.today() else False - ) - - def _search_departure_today(self, operator, value): - if operator not in ("=", "!="): - raise UserError(_("Invalid domain operator %s", operator)) - - if value not in (False, True): - raise UserError(_("Invalid domain right operand %s", value)) - - searching_for_true = (operator == "=" and value) or ( - operator == "!=" and not value - ) - today = fields.Date.context_today(self) - - return [("checkout", searching_for_true, today)] + 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): @@ -798,99 +985,52 @@ class PmsReservation(models.Model): @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: - if len(reservation.reservation_line_ids.mapped("room_id")) > 1: + room_ids = reservation.reservation_line_ids.mapped("room_id.id") + if len(room_ids) > 1: reservation.splitted = True + reservation.preferred_room_id = False else: reservation.splitted = False - reservation.preferred_room_id = reservation.reservation_line_ids[ - 0 - ].room_id + if room_ids: + reservation.preferred_room_id = room_ids[0] - @api.depends("state", "qty_to_invoice", "qty_invoiced") + @api.depends( + "sale_line_ids", + "sale_line_ids.invoice_status", + ) def _compute_invoice_status(self): """ Compute the invoice status of a Reservation. Possible statuses: - - no: if the Folio is not in status 'sale' or 'done', we consider - that there is nothing to invoice. This is also hte default value - if the conditions of no other status is met. - - to invoice: we refer to the quantity to invoice of the line. - Refer to method `_compute_get_to_invoice_qty()` for more information - on how this quantity is calculated. - - invoiced: the quantity invoiced is larger or equal to the - quantity ordered. + Base on folio sale line invoice status """ - precision = self.env["decimal.precision"].precision_get( - "Product Unit of Measure" - ) for line in self: - if line.state == "draft": - line.invoice_status = "no" - elif not float_is_zero(line.qty_to_invoice, precision_digits=precision): - line.invoice_status = "to invoice" - elif ( - float_compare( - line.qty_invoiced, - len(line.reservation_line_ids), - precision_digits=precision, - ) - >= 0 - ): - line.invoice_status = "invoiced" + 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("qty_invoiced", "nights", "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 = len(line.reservation_line_ids) - line.qty_invoiced - else: - line.qty_to_invoice = 0 - - @api.depends("move_line_ids.move_id.state", "move_line_ids.quantity") - def _compute_get_invoice_qty(self): - """ - Compute the quantity invoiced. If case of a refund, the quantity - invoiced is decreased. We must check day per day and sum or - decreased on 1 unit per invoice_line - """ - for line in self: - qty_invoiced = 0.0 - for day in line.reservation_line_ids: - invoice_lines = day.move_line_ids.filtered( - lambda r: r.move_id.state != "cancel" - ) - qty_invoiced += len( - invoice_lines.filtered(lambda r: r.move_id.type == "out_invoice") - ) - len( - invoice_lines.filtered(lambda r: r.move_id.type == "out_refund") - ) - line.qty_invoiced = qty_invoiced - @api.depends("reservation_line_ids") def _compute_nights(self): for res in self: res.nights = len(res.reservation_line_ids) - @api.depends("folio_id", "checkin", "checkout") - def _compute_localizator(self): - # TODO: Compute localizator by reservation - for record in self: - record.localizator = fields.date.today() - @api.depends("service_ids.price_total") - def _compute_amount_room_services(self): + def _compute_price_services(self): for record in self: record.price_services = sum(record.mapped("service_ids.price_total")) @api.depends("price_services", "price_total") - def _compute_amount_set(self): + def _compute_price_room_services_set(self): for record in self: record.price_room_services_set = record.price_services + record.price_total @@ -938,10 +1078,140 @@ class PmsReservation(models.Model): } ) + 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 + + def _compute_checkin_partner_count(self): + for record in self: + if record.reservation_type != "out": + 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 + + 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), + ] + + 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), + ] + + 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", ("cancelled", "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_checkin(self): + folio = False + if "folio_id" in self._context: + folio = self.env["pms.folio"].search( + [("id", "=", self._context["folio_id"])] + ) + if folio and folio.reservation_ids: + return folio.reservation_ids[0].checkin + else: + return fields.Date.today() + + def _get_default_checkout(self): + folio = False + if "folio_id" in self._context: + folio = self.env["pms.folio"].search( + [("id", "=", self._context["folio_id"])] + ) + if folio and folio.reservation_ids: + return folio.reservation_ids[0].checkout + else: + return fields.Date.today() + datetime.timedelta(1) + + 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 + # TODO: Use default values on checkin /checkout is empty - @api.constrains( - "checkin", "checkout", "state", "preferred_room_id", "overbooking", "reselling" - ) + @api.constrains("checkin", "checkout", "state", "preferred_room_id", "overbooking") def check_dates(self): """ 1.-When date_order is less then checkin date or @@ -949,9 +1219,7 @@ class PmsReservation(models.Model): 3.-Check the reservation dates are not occuped """ for record in self: - if fields.Date.from_string(record.checkin) >= fields.Date.from_string( - record.checkout - ): + if record.checkin >= record.checkout: raise ValidationError( _( "Room line Check In Date Should be \ @@ -959,13 +1227,13 @@ class PmsReservation(models.Model): ) ) - @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("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("adults") def _check_adults(self): @@ -975,7 +1243,7 @@ class PmsReservation(models.Model): ) for room in record.reservation_line_ids.room_id: if record.adults + record.children_occupying > room.get_capacity( - len(extra_bed) + sum(extra_bed.mapped("product_qty")) ): raise ValidationError( _( @@ -1023,33 +1291,10 @@ class PmsReservation(models.Model): if record.agency_id and not record.agency_id.is_agency: raise ValidationError(_("booking agency with wrong configuration: ")) - # @api.constrains("reservation_type", "partner_id") - # def _check_partner_reservation(self): - # for reservation in self: - # if ( - # reservation.reservation_type == "out" - # and reservation.partner_id.id != \ - # reservation.pms_property_id.partner_id.id - # ): - # raise models.ValidationError( - # _("The partner on out reservations must be a property partner") - # ) - - # @api.constrains("closure_reason_id", "reservation_type") - # def _check_clousure_reservation(self): - # for reservation in self: - # if reservation.closure_reason_id and \ - # reservation.reservation_type != "out": - # raise models.ValidationError( - # _("Only the out reservations can has a clousure reason") - # ) - - # self._compute_tax_ids() TODO: refact - # Action methods def open_folio(self): - action = self.env.ref("pms.open_pms_folio1_form_tree_all").read()[0] + 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 @@ -1058,7 +1303,7 @@ class PmsReservation(models.Model): return action def open_reservation_form(self): - action = self.env.ref("pms.open_pms_reservation_form_tree_all").read()[0] + 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 @@ -1067,43 +1312,20 @@ class PmsReservation(models.Model): self.ensure_one() return self.folio_id.action_pay() - def action_pay_reservation(self): - self.ensure_one() - partner = self.partner_id.id - amount = min(self.price_room_services_set, self.folio_pending_amount) - note = self.folio_id.name + " (" + self.name + ")" - view_id = self.env.ref("pms.account_payment_view_form_folio").id - return { - "name": _("Register Payment"), - "view_type": "form", - "view_mode": "form", - "res_model": "account.payment", - "type": "ir.actions.act_window", - "view_id": view_id, - "context": { - "default_folio_id": self.folio_id.id, - "default_room_id": self.id, - "default_amount": amount, - "default_payment_type": "inbound", - "default_partner_type": "customer", - "default_partner_id": partner, - "default_communication": note, - }, - "target": "new", - } - def open_reservation_wizard(self): - rooms_available = self.env["pms.room.type.availability"].rooms_available( + rooms_available = self.env["pms.availability.plan"].rooms_available( checkin=self.checkin, checkout=self.checkout, current_lines=self.reservation_line_ids.ids, + pricelist_id=self.pricelist_id.id, + pms_property_id=self.pms_property_id.id, ) # REVIEW: check capacity room return { "view_type": "form", "view_mode": "form", "name": "Unify the reservation", - "res_model": "pms.reservation.wizard", + "res_model": "pms.reservation.split.join.swap.wizard", "target": "new", "type": "ir.actions.act_window", "context": { @@ -1111,7 +1333,6 @@ class PmsReservation(models.Model): }, } - # ORM Overrides @api.model def name_search(self, name="", args=None, operator="ilike", limit=100): if args is None: @@ -1135,14 +1356,36 @@ class PmsReservation(models.Model): result.append((res.id, name)) return result + # REVIEW: Is it necessary? + def copy_data(self, default=None): + rooms_available = self.env["pms.availability.plan"].rooms_available( + self.checkin, + self.checkout, + room_type_id=self.room_type_id.id, + pricelist_id=self.pricelist_id.id, + pms_property_id=self.pms_property_id.id, + ) + if self.preferred_room_id.id in rooms_available.ids: + default["preferred_room_id"] = self.preferred_room_id.id + if self.room_type_id.id in rooms_available.mapped("room_type_id.id"): + default["room_type_id"] = self.room_type_id.id + return super(PmsReservation, self).copy_data(default) + @api.model def create(self, vals): - if "folio_id" in vals: + if vals.get("folio_id"): folio = self.env["pms.folio"].browse(vals["folio_id"]) - elif "partner_id" in vals: + vals.update({"pms_property_id": folio.pms_property_id.id}) + elif "pms_property_id" in vals and ( + "partner_id" in vals or "agency_id" in vals + ): folio_vals = { - "partner_id": int(vals.get("partner_id")), + "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") # Create the folio in case of need # (To allow to create reservations direct) folio = self.env["pms.folio"].create(folio_vals) @@ -1152,40 +1395,36 @@ class PmsReservation(models.Model): "reservation_type": vals.get("reservation_type"), } ) + else: + raise ValidationError( + _("The client and 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() record = super(PmsReservation, self).create(vals) if record.preconfirm: record.confirm() return record - # Business methods - - def _compute_shared(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 - - def _autoassign(self): + def update_prices(self): self.ensure_one() - room_chosen = False - rooms_available = self.env["pms.room.type.availability"].rooms_available( - checkin=self.checkin, - checkout=self.checkout, - room_type_id=self.room_type_id.id or False, + 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, + ) ) - if rooms_available: - room_chosen = rooms_available[0] - else: - # We can split reserve night on multi rooms - room_chosen = False - return room_chosen @api.model def autocheckout(self): @@ -1207,26 +1446,6 @@ class PmsReservation(models.Model): self.ensure_one() self.overbooking = not self.overbooking - def generate_copy_values(self, checkin=False, checkout=False): - self.ensure_one() - return { - "name": self.name, - "adults": self.adults, - "children": self.children, - "checkin": checkin or self.checkin, - "checkout": checkout or self.checkout, - "folio_id": self.folio_id.id, - "state": self.state, - "overbooking": self.overbooking, - "reselling": self.reselling, - "price_total": self.price_total, - "price_tax": self.price_tax, - "price_subtotal": self.price_subtotal, - "splitted": self.splitted, - "room_type_id": self.room_type_id.id, - "preferred_room_id": self.preferred_room_id.id, - } - def confirm(self): for record in self: vals = {} @@ -1242,22 +1461,30 @@ class PmsReservation(models.Model): def action_cancel(self): for record in self: - cancel_reason = ( - "intime" - if self._context.get("no_penalty", False) - else record.compute_cancelation_reason() - ) - if self._context.get("no_penalty", False): - _logger.info("Modified Reservation - No Penalty") - record.write({"state": "cancelled", "cancelled_reason": cancel_reason}) - # record._compute_cancelled_discount() - record.folio_id._compute_amount() + # else state = cancelled + if not record.allowed_cancel: + raise UserError(_("This reservation cannot be cancelled")) + else: + cancel_reason = ( + "intime" + if self._context.get("no_penalty", False) + else record.compute_cancelation_reason() + ) + if self._context.get("no_penalty", False): + _logger.info("Modified Reservation - No Penalty") + record.write({"state": "cancelled", "cancelled_reason": cancel_reason}) + # record._compute_cancelled_discount() + record.folio_id._compute_amount() + + def action_assign(self): + for record in self: + record.to_assign = False def compute_cancelation_reason(self): self.ensure_one() pricelist = self.pricelist_id if pricelist and pricelist.cancelation_rule_id: - tz_property = self.env.user.pms_property_id.tz + tz_property = self.pms_property_id.tz today = fields.Date.context_today(self.with_context(tz=tz_property)) days_diff = ( fields.Date.from_string(self.checkin) - fields.Date.from_string(today) @@ -1270,54 +1497,10 @@ class PmsReservation(models.Model): return "intime" return False - def draft(self): - for record in self: - record.state = "draft" - record.reservation_line_ids.update({"cancel_discount": 0}) - - # INFO: This function is not in use and should include `dto` in the search - @api.model - def get_reservations_dates(self, dfrom, dto, room_type=False): - """ - @param self: The object pointer - @param dfrom: range date from - @param dto: range date to - @return: dictionary of lists with reservations (a hash of arrays!) - with the reservations dates between dfrom and dto - reservations_dates - {'2018-07-30': [pms.reservation(29,), pms.reservation(30,), - pms.reservation(31,)], - '2018-07-31': [pms.reservation(22,), pms.reservation(35,), - pms.reservation(36,)], - } - """ - domain = [("date", ">=", dfrom), ("date", "<", dto)] - lines = self.env["pms.reservation.line"].search(domain) - reservations_dates = {} - for record in lines: - reservations_dates.setdefault(record.date, []).append( - [record.reservation_id, record.reservation_id.room_type_id] - ) - return reservations_dates - - def _compute_checkin_partner_count(self): - for record in self: - if record.reservation_type != "out": - record.checkin_partner_count = len(record.checkin_partner_ids) - record.checkin_partner_pending_count = ( - record.adults + record.children - ) - len(record.checkin_partner_ids) - else: - record.checkin_partner_count = 0 - record.checkin_partner_pending_count = 0 - - 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 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( @@ -1325,7 +1508,7 @@ class PmsReservation(models.Model): ).action_done() return True - def action_checks(self): + def action_checkin_partner_view(self): self.ensure_one() tree_id = self.env.ref("pms.pms_checkin_partner_reservation_view_tree").id return { @@ -1339,10 +1522,14 @@ class PmsReservation(models.Model): "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_onboard(self): + def action_checkin_partner_onboard_view(self): self.ensure_one() kanban_id = self.env.ref("pms.pms_checkin_partner_kanban_view").id return { @@ -1355,23 +1542,27 @@ class PmsReservation(models.Model): "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_no_show(self): + def auto_arrival_delayed(self): # No show when pass 1 day from checkin day - no_show_reservations = self.env["pms.reservation"].search( + arrival_delayed_reservations = self.env["pms.reservation"].search( [ ("state", "in", ("draft", "confirm")), ("checkin", "<", fields.Date.today()), ] ) - no_show_reservations.state = "no_show" + arrival_delayed_reservations.state = "arrival_delayed" @api.model - def auto_no_checkout(self): + def auto_departure_delayed(self): # No checkout when pass checkout hour reservations = self.env["pms.reservation"].search( [ @@ -1381,32 +1572,12 @@ class PmsReservation(models.Model): ) for reservation in reservations: if reservation.checkout_datetime <= fields.Datetime.now(): - reservations.state = "no_checkout" + reservations.state = "departure_delayed" - def unify(self): - # TODO - return True - - def _compute_tax_ids(self): - for record in self: - # If company_id is set, always filter taxes by the company - folio = record.folio_id or self.env.context.get("default_folio_id") - product = self.env["product.product"].browse( - record.room_type_id.product_id.id - ) - record.tax_ids = product.taxes_id.filtered( - lambda r: not record.company_id or r.company_id == folio.company_id - ) - - @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")] - ) - reservation.preferred_room_id = False - else: - reservation.rooms = reservation.preferred_room_id.name + 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 index 3415178ff..1719581e6 100644 --- a/pms/models/pms_reservation_line.py +++ b/pms/models/pms_reservation_line.py @@ -14,71 +14,103 @@ class PmsReservationLine(models.Model): _name = "pms.reservation.line" _description = "Reservations by day" _order = "date" + _check_company_auto = True - # Default Methods ang Gets - - 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 - - # Fields declaration reservation_id = fields.Many2one( - "pms.reservation", string="Reservation", - ondelete="cascade", + 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( - "pms.room", string="Room", - ondelete="restrict", - compute="_compute_room_id", - store=True, + help="The room of a reservation. ", readonly=False, + store=True, + compute="_compute_room_id", + comodel_name="pms.room", + ondelete="restrict", + check_pms_properties=True, ) - move_line_ids = fields.Many2many( - "account.move.line", - "reservation_line_move_rel", - "reservation_line_id", - "move_line_id", - string="Invoice Lines", + + 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( - "pms.property", - store=True, + 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, ) - date = fields.Date("Date") - state = fields.Selection(related="reservation_id.state") price = fields.Float( string="Price", + help="The price in a reservation line", + store=True, + readonly=False, digits=("Product Price"), compute="_compute_price", - store=True, - readonly=False, ) cancel_discount = fields.Float( - string="Cancel Discount (%)", - digits=("Discount"), - default=0.0, - compute="_compute_cancel_discount", - store=True, + 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"), ) - discount = fields.Float(string="Discount (%)", digits=("Discount"), default=0.0) occupies_availability = fields.Boolean( string="Occupies", - compute="_compute_occupies_availability", - store=True, 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=False, + store=True, + compute="_compute_impact_quota", ) _sql_constraints = [ @@ -90,66 +122,122 @@ class PmsReservationLine(models.Model): ), ] - # Compute and Search methods - @api.depends("reservation_id.room_type_id") + 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.sorted(key=lambda r: (r.reservation_id, r.date)): - - # if the reservation has a room type and no room id - if line.reservation_id.room_type_id and not line.room_id: - + 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 - rooms_available = self.env[ - "pms.room.type.availability" - ].rooms_available( + rooms_available = self.env["pms.availability.plan"].rooms_available( checkin=line.reservation_id.checkin, checkout=line.reservation_id.checkout, - room_type_id=line.reservation_id.room_type_id.id, - current_lines=line._origin.reservation_id.reservation_line_ids.ids, + room_type_id=reservation.room_type_id.id + if not free_room_select + else False, + current_lines=line.reservation_id.reservation_line_ids.ids, + pricelist_id=line.reservation_id.pricelist_id.id, + pms_property_id=line.pms_property_id.id, ) - # if there is availability for the entire stay if rooms_available: # if the reservation has a preferred room - if line.reservation_id.preferred_room_id: + if reservation.preferred_room_id: # if the preferred room is available - if line.reservation_id.preferred_room_id in rooms_available: - line.room_id = line.reservation_id.preferred_room_id + if reservation.preferred_room_id in rooms_available: + line.room_id = reservation.preferred_room_id # if the preferred room is NOT available else: raise ValidationError( _("%s: No room available.") - % (line.reservation_id.preferred_room_id.name) + % (reservation.preferred_room_id.name) ) # 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.availability.plan"].splitted_availability( + checkin=line.reservation_id.checkin, + checkout=line.reservation_id.checkout, + room_type_id=line.reservation_id.room_type_id.id, + current_lines=line._origin.reservation_id.reservation_line_ids.ids, + pricelist=line.reservation_id.pricelist_id, + pms_property_id=line.pms_property_id.id, + ): + raise ValidationError( + _("%s: No room type available") + % (line.reservation_id.room_type_id.name) + ) - # if there is no availability for the entire stay without - # changing rooms (we assume a split reservation) + # 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", "=", line.reservation_id.room_type_id.id)] + [ + ("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, (line.reservation_id.checkout - line.date).days - ) + 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 = line.reservation_id.reservation_line_ids.ids + ids = reservation.reservation_line_ids.ids if ( self.env["pms.reservation.line"].search_count( [ @@ -170,12 +258,8 @@ class PmsReservationLine(models.Model): if room.id not in rooms_ranking else rooms_ranking[room.id] + 1 ) - if len(rooms_ranking) == 0: - raise ValidationError( - _("%s: No room type available") - % (line.reservation_id.room_type_id.name) - ) - else: + + if len(rooms_ranking) > 0: # we get the best score in the ranking best = max(rooms_ranking.values()) @@ -194,7 +278,7 @@ class PmsReservationLine(models.Model): line_past_night = self.env["pms.reservation.line"].search( [ ("date", "=", date_last_night), - ("reservation_id", "=", line.reservation_id.id), + ("reservation_id", "=", reservation.id), ] ) # if there is the night before and if the room @@ -215,9 +299,19 @@ class PmsReservationLine(models.Model): # 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_impact_quota(self): + for line in self: + reservation = line.reservation_id + 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, + line=line, + ) + @api.depends( "reservation_id", - "reservation_id.pricelist_id", "reservation_id.room_type_id", "reservation_id.reservation_type", "reservation_id.pms_property_id", @@ -231,7 +325,7 @@ class PmsReservationLine(models.Model): or not reservation.pms_property_id ): line.price = 0 - elif line._recompute_price(): + 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) @@ -239,7 +333,8 @@ class PmsReservationLine(models.Model): lang=partner.lang, partner=partner.id, quantity=1, - date=line.date, + date=line.reservation_id.date_order, + consumption_date=line.date, pricelist=reservation.pricelist_id.id, uom=product.uom_id.id, property=reservation.pms_property_id.id, @@ -251,8 +346,6 @@ class PmsReservationLine(models.Model): line.reservation_id.company_id, ) # TODO: Out of service 0 amount - else: - line.price = line._origin.price @api.depends("reservation_id.state", "reservation_id.overbooking") def _compute_occupies_availability(self): @@ -265,38 +358,15 @@ class PmsReservationLine(models.Model): else: line.occupies_availability = True - def _recompute_price(self): - # REVIEW: Conditional to avoid overriding already calculated prices, - # I'm not sure it's the best way - self.ensure_one() - origin = self._origin.reservation_id - new = self.reservation_id - price_fields = [ - "pricelist_id", - "room_type_id", - "reservation_type", - "pms_property_id", - ] - if ( - any(origin[field] != new[field] for field in price_fields) - or self._origin.price == 0 - ): - return True - return False - # 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 + # TODO: Review cancel logic # reservation = line.reservation_id # pricelist = reservation.pricelist_id # if reservation.state == "cancelled": - # # TODO: Set 0 qty on cancel room services change to compute day_qty - # # (view constrain service_line_days) - # for service in reservation.service_ids: - # service.service_line_ids.write({"day_qty": 0}) - # service._compute_days_qty() # if ( # reservation.cancelled_reason # and pricelist @@ -344,6 +414,30 @@ class PmsReservationLine(models.Model): # 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): @@ -365,35 +459,6 @@ class PmsReservationLine(models.Model): ) cancel_lines.day_qty = 0 - 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.constrains("room_id") def _check_adults(self): for record in self.filtered("room_id"): diff --git a/pms/models/pms_room.py b/pms/models/pms_room.py index 2dd600708..5511930cc 100644 --- a/pms/models/pms_room.py +++ b/pms/models/pms_room.py @@ -15,46 +15,87 @@ class PmsRoom(models.Model): _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, + ) + # TODO: design shared rooms + shared_room_id = fields.Many2one( + string="Shared Room", + help="The room can be sold by beds", + default=False, + comodel_name="pms.shared.room", + ) + 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", + ) + 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", + ) + ] - # Defaults and Gets def name_get(self): result = [] for room in self: name = room.name if room.room_type_id: - name += " [%s]" % room.room_type_id.code_type + name += " [%s]" % room.room_type_id.default_code result.append((room.id, name)) return result - # Fields declaration - name = fields.Char("Room Name", required=True) - pms_property_id = fields.Many2one( - "pms.property", - store=True, - readonly=True, - ) - room_type_id = fields.Many2one( - "pms.room.type", "Property Room Type", required=True, ondelete="restrict" - ) - shared_room_id = fields.Many2one("pms.shared.room", "Shared Room", default=False) - floor_id = fields.Many2one( - "pms.floor", "Ubication", help="At which floor the room is located." - ) - capacity = fields.Integer("Capacity") - to_be_cleaned = fields.Boolean("To be Cleaned", default=False) - extra_beds_allowed = fields.Integer( - "Extra beds allowed", default="0", required=True - ) - description_sale = fields.Text( - "Sale Description", - translate=True, - 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", - ) - active = fields.Boolean("Active", default=True) - sequence = fields.Integer("Sequence", default=0) - # Constraints and onchanges @api.constrains("capacity") def _check_capacity(self): @@ -70,6 +111,11 @@ class PmsRoom(models.Model): # Business methods def get_capacity(self, extra_bed=0): - if not self.shared_room_id: - return self.capacity + extra_bed - return self.capacity + for record in self: + if not record.shared_room_id: + 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 + return record.capacity diff --git a/pms/models/pms_room_closure_reason.py b/pms/models/pms_room_closure_reason.py index 48ad08e4a..a1135c623 100644 --- a/pms/models/pms_room_closure_reason.py +++ b/pms/models/pms_room_closure_reason.py @@ -7,9 +7,24 @@ class RoomClosureReason(models.Model): _name = "room.closure.reason" _description = "Cause of out of service" - # Fields declaration - name = fields.Char("Name", translate=True, required=True) - pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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, ) - description = fields.Text("Description", translate=True) diff --git a/pms/models/pms_room_type.py b/pms/models/pms_room_type.py index 105ffdaa6..f0bb28d61 100644 --- a/pms/models/pms_room_type.py +++ b/pms/models/pms_room_type.py @@ -1,5 +1,6 @@ # 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 @@ -15,82 +16,180 @@ class PmsRoomType(models.Model): _name = "pms.room.type" _description = "Room Type" _inherits = {"product.product": "product_id"} - _order = "sequence, code_type, name" + _order = "sequence,default_code,name" + _check_pms_properties_auto = True - # Fields declaration + 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( - "product.product", - "Product Room Type", + string="Product Room Type", + help="Product identifier associated with room type", + comodel_name="product.product", required=True, delegate=True, ondelete="cascade", ) - pms_property_ids = fields.Many2many( - "pms.property", - "pms_property_room_type_rel", - "room_type_id", - "pms_property_id", - ondelete="restrict", - string="Properties", + 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, ) - room_ids = fields.One2many("pms.room", "room_type_id", "Rooms") - class_id = fields.Many2one("pms.room.type.class", "Property Type Class") board_service_room_type_ids = fields.One2many( - "pms.board.service.room.type", "pms_room_type_id", string="Board Services" + 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( - "pms.amenity", - "pms_room_type_aminity_rel", - "room_type_ids", - "amenity_ids", string="Room Type Amenities", - help="List of 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, ) - code_type = fields.Char( - "Code", + default_code = fields.Char( + string="Code", + help="Identification code for a room type", required=True, ) - shared_room = fields.Boolean( - "Shared Room", default=False, help="This room type is reservation by beds" + # TODO: Session review to define shared room and "sales rooms packs" + is_shared_room = fields.Boolean( + string="Shared Room", + help="This room type is reservation by beds", + default=False, + ) + 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, ) - total_rooms_count = fields.Integer(compute="_compute_total_rooms", store=True) - active = fields.Boolean("Active", default=True) - sequence = fields.Integer("Sequence", default=0) default_max_avail = fields.Integer( - "Max. Availability", - default=-1, + 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( - "Default Quota", - default=-1, + string="Default Quota", help="Quota assigned to the own Booking Engine given no availability rules. " "Use `-1` for managing no quota.", + default=-1, ) - _sql_constraints = [ - ( - "code_type_pms_unique", - "unique(code_type)", - "Room Type Code must be unique", - ), - ] + def name_get(self): + result = [] + for room_type in self: + name = room_type.name + if self._context.get("checkin") and self._context.get("checkout"): + avail = self.env["pms.availability.plan"].get_count_rooms_available( + checkin=self._context.get("checkin"), + checkout=self._context.get("checkout"), + room_type_id=room_type.id, + pms_property_id=self._context.get("pms_property_id") or False, + pricelist_id=self._context.get("pricelist_id") or False, + ) + name += " (%s)" % avail + result.append((room_type.id, name)) + return result - # Constraints and onchanges @api.depends("room_ids", "room_ids.active") - def _compute_total_rooms(self): + 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", } ) @@ -101,68 +200,7 @@ class PmsRoomType(models.Model): record.product_id.unlink() return super().unlink() - # Business methods - def get_capacity(self): self.ensure_one() capacities = self.room_ids.mapped("capacity") return min(capacities) if any(capacities) else 0 - - @api.model - def get_rate_room_types(self, **kwargs): - """ - room_type_ids: Ids from room types to get rate, optional, if you - not use this param, the method return all room_types - from: Date from, mandatory - days: Number of days, mandatory - pricelist_id: Pricelist to use, optional - partner_id: Partner, optional - Return Dict Code Room Types: subdict with day, discount, price - """ - vals = {} - # room_type_ids = kwargs.get("room_type_ids", False) - # room_types = ( - # self.env["pms.room.type"].browse(room_type_ids) - # if room_type_ids - # else self.env["pms.room.type"].search([]) - # ) - date_from = kwargs.get("date_from", False) - days = kwargs.get("days", False) - discount = kwargs.get("discount", False) - if not date_from or not days: - raise ValidationError(_("Date From and days are mandatory")) - partner_id = kwargs.get("partner_id", False) - # partner = self.env["res.partner"].browse(partner_id) - # pricelist_id = kwargs.get( - # "pricelist_id", - # partner.property_product_pricelist.id - # and partner.property_product_pricelist.id - # or self.env.user.pms_property_id.default_pricelist_id.id, - # ) - vals.update( - { - "partner_id": partner_id if partner_id else False, - "discount": discount, - } - ) - rate_vals = {} - # TODO: Now it is computed field, We need other way to return rates - # for room_type in room_types: - # vals.update({"room_type_id": room_type.id}) - # room_vals = self.env["pms.reservation"].prepare_reservation_lines( - # date_from, - # days, - # pricelist_id=pricelist_id, - # vals=vals, - # update_old_prices=False, - # ) - # rate_vals.update( - # { - # room_type.id: [ - # item[2] for item in room_vals[ - # "reservation_line_ids" - # ] if item[2] - # ] - # } - # ) - return rate_vals diff --git a/pms/models/pms_room_type_availability.py b/pms/models/pms_room_type_availability.py deleted file mode 100644 index 4b62ae422..000000000 --- a/pms/models/pms_room_type_availability.py +++ /dev/null @@ -1,92 +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 datetime import timedelta - -from odoo import api, fields, models - - -class PmsRoomTypeAvailability(models.Model): - _name = "pms.room.type.availability" - _description = "Availability" - _inherit = "mail.thread" - - @api.model - def _default_max_avail(self): - return self.room_type_id.default_max_avail - - @api.model - def _default_quota(self): - return self.room_type_id.default_quota - - # Fields declaration - room_type_id = fields.Many2one( - "pms.room.type", "Room Type", required=True, ondelete="cascade" - ) - date = fields.Date( - "Date", - required=True, - tracking=True, - ) - quota = fields.Integer( - "Quota", - default=_default_quota, - tracking=True, - help="Generic Quota assigned.", - ) - max_avail = fields.Integer( - "Max. Availability", - default=-1, - readonly=True, - tracking=True, - help="Maximum simultaneous availability on own Booking Engine.", - ) - no_web = fields.Boolean( - "No Web", - default=False, - tracking=True, - help="Set zero availability to the own Booking Engine " - "even when the availability is positive,", - ) - - _sql_constraints = [ - ( - "unique_availability_room_type_rule_date", - "unique(room_type_id, date)", - "The availability rule for this date in this room type already exists, " - "modify it instead of trying to create a new one", - ), - ] - - # Business Methods - @api.model - def rooms_available( - self, checkin, checkout, room_type_id=False, current_lines=False - ): - domain = self._get_domain_reservations_occupation( - dfrom=checkin, - dto=checkout - timedelta(1), - current_lines=current_lines, - ) - reservation_lines = self.env["pms.reservation.line"].search(domain) - reservations_rooms = reservation_lines.mapped("room_id.id") - free_rooms = self.env["pms.room"].search([("id", "not in", reservations_rooms)]) - if room_type_id: - rooms_linked = ( - self.env["pms.room.type"].search([("id", "=", room_type_id)]).room_ids - ) - free_rooms = free_rooms & rooms_linked - return free_rooms.sorted(key=lambda r: r.sequence) - - @api.model - def _get_domain_reservations_occupation(self, dfrom, dto, current_lines=False): - if current_lines and not isinstance(current_lines, list): - current_lines = [current_lines] - domain = [ - ("date", ">=", dfrom), - ("date", "<=", dto), - ("occupies_availability", "=", True), - ("id", "not in", current_lines), - ] - return domain diff --git a/pms/models/pms_room_type_class.py b/pms/models/pms_room_type_class.py index ba448c839..179315ec7 100644 --- a/pms/models/pms_room_type_class.py +++ b/pms/models/pms_room_type_class.py @@ -1,7 +1,9 @@ # 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 fields, models +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError class PmsRoomTypeClass(models.Model): @@ -13,19 +15,108 @@ class PmsRoomTypeClass(models.Model): _name = "pms.room.type.class" _description = "Room Type Class" - _order = "sequence, name, code_class" + _order = "sequence, name, default_code" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Char("Class Name", required=True, translate=True) - # Relationship between models - pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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, ) - room_type_ids = fields.One2many("pms.room.type", "class_id", "Types") - code_class = fields.Char("Code") - active = fields.Boolean("Active", default=True) - sequence = fields.Integer("Sequence", default=0) - _sql_constraints = [ - ("code_class_unique", "unique(code_class)", "Room Class Code must be unique!") - ] + @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_room_type_restriction.py b/pms/models/pms_room_type_restriction.py deleted file mode 100644 index ea27914af..000000000 --- a/pms/models/pms_room_type_restriction.py +++ /dev/null @@ -1,37 +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 - - -class PmsRoomTypeRestriction(models.Model): - """The room type restriction is used as a daily restriction plan for room types - and therefore is related only with one property.""" - - _name = "pms.room.type.restriction" - _description = "Reservation restriction plan" - - # Default methods - @api.model - def _get_default_pms_property(self): - return self.env.user.pms_property_id or None - - # Fields declaration - name = fields.Char("Restriction Plan Name", required=True) - pms_property_id = fields.Many2one( - "pms.property", - "Property", - ondelete="restrict", - default=_get_default_pms_property, - ) - item_ids = fields.One2many( - "pms.room.type.restriction.item", - "restriction_id", - string="Restriction Items", - copy=True, - ) - active = fields.Boolean( - "Active", - default=True, - help="If unchecked, it will allow you to hide the " - "restriction plan without removing it.", - ) diff --git a/pms/models/pms_room_type_restriction_item.py b/pms/models/pms_room_type_restriction_item.py deleted file mode 100644 index e1cacc06a..000000000 --- a/pms/models/pms_room_type_restriction_item.py +++ /dev/null @@ -1,49 +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 PmsRoomTypeRestrictionItem(models.Model): - _name = "pms.room.type.restriction.item" - _description = "Reservation restriction by day" - - # Field Declarations - restriction_id = fields.Many2one( - "pms.room.type.restriction", "Restriction Plan", ondelete="cascade", index=True - ) - room_type_id = fields.Many2one( - "pms.room.type", "Room Type", required=True, ondelete="cascade" - ) - date = fields.Date("Date") - - min_stay = fields.Integer("Min. Stay") - min_stay_arrival = fields.Integer("Min. Stay Arrival") - max_stay = fields.Integer("Max. Stay") - max_stay_arrival = fields.Integer("Max. Stay Arrival") - closed = fields.Boolean("Closed") - closed_departure = fields.Boolean("Closed Departure") - closed_arrival = fields.Boolean("Closed Arrival") - - _sql_constraints = [ - ( - "room_type_registry_unique", - "unique(restriction_id, room_type_id, date)", - "Only can exists one restriction in the same \ - day for the same room type!", - ) - ] - - # Constraints and onchanges - - @api.constrains("min_stay", "min_stay_arrival", "max_stay", "max_stay_arrival") - def _check_min_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")) diff --git a/pms/models/pms_sale_channel.py b/pms/models/pms_sale_channel.py index 1daa07a59..1f60daab1 100644 --- a/pms/models/pms_sale_channel.py +++ b/pms/models/pms_sale_channel.py @@ -4,9 +4,37 @@ from odoo import fields, models class PmsSaleChannel(models.Model): _name = "pms.sale.channel" _description = "Sales Channel" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Text(string="Sale Channel Name") + name = fields.Text(string="Sale Channel Name", help="The name of the sale channel") channel_type = fields.Selection( - [("direct", "Direct"), ("indirect", "Indirect")], string="Sale Channel Type" + 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 index 6ff3facee..61b6835e7 100644 --- a/pms/models/pms_service.py +++ b/pms/models/pms_service.py @@ -5,7 +5,6 @@ import logging from datetime import timedelta from odoo import _, api, fields, models -from odoo.tools import float_compare, float_is_zero _logger = logging.getLogger(__name__) @@ -13,156 +12,247 @@ _logger = logging.getLogger(__name__) class PmsService(models.Model): _name = "pms.service" _description = "Services and its charges" + _check_pms_properties_auto = True - # Default methods - - 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 - - @api.model - def _default_folio_id(self): - if "folio_id" in self._context: - return self._context["folio_id"] - return False - - # Fields declaration name = fields.Char( - "Service description", - compute="_compute_name", - store=True, + string="Service description", + help="Service description", readonly=False, + store=True, + compute="_compute_name", ) product_id = fields.Many2one( - "product.product", "Service", ondelete="restrict", required=True + string="Service", + help="Product associated with this service", + required=True, + comodel_name="product.product", + ondelete="restrict", + check_pms_properties=True, ) folio_id = fields.Many2one( - "pms.folio", "Folio", ondelete="cascade", default=_default_folio_id + 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( - "pms.reservation", "Room", default=_default_reservation_id + 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( - "pms.service.line", - "service_id", - compute="_compute_service_line_ids", - store=True, + 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( - related="folio_id.company_id", string="Company", store=True, readonly=True + string="Company", + help="Company to which the service belongs", + readonly=True, + store=True, + related="folio_id.company_id", ) pms_property_id = fields.Many2one( - "pms.property", store=True, readonly=True, related="folio_id.pms_property_id" + 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( - "account.tax", string="Taxes", - compute="_compute_tax_ids", - store=True, + help="Taxes applied in the service", readonly=False, + store=True, + comodel_name="account.tax", domain=["|", ("active", "=", False), ("active", "=", True)], + compute="_compute_tax_ids", ) - move_line_ids = fields.Many2many( - "account.move.line", - "service_line_move_rel", - "service_id", - "move_line_id", - string="move Lines", - copy=False, + analytic_tag_ids = fields.Many2many( + string="Analytic Tags", + help="", + comodel_name="account.analytic.tag", ) - analytic_tag_ids = fields.Many2many("account.analytic.tag", string="Analytic Tags") currency_id = fields.Many2one( - related="folio_id.currency_id", store=True, string="Currency", readonly=True - ) - sequence = fields.Integer(string="Sequence", default=10) - state = fields.Selection(related="folio_id.state") - per_day = fields.Boolean(related="product_id.per_day", related_sudo=True) - product_qty = fields.Integer( - "Quantity", - compute="_compute_product_qty", + string="Currency", + help="The currency used in relation to the folio", + readonly=True, store=True, - readonly=False, + 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", ) - is_board_service = fields.Boolean() # Non-stored related field to allow portal user to # see the image of the product he has ordered product_image = fields.Binary( - "Product Image", related="product_id.image_1024", store=False, related_sudo=True + 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"), ], - string="Invoice Status", - compute="_compute_invoice_status", - store=True, - readonly=True, - default="no", ) 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"), ], - string="Sales Channel", - ) - price_unit = fields.Float( - "Unit Price", - digits=("Product Price"), - compute="_compute_price_unit", - store=True, - readonly=False, - ) - discount = fields.Float(string="Discount (%)", digits=("Discount"), default=0.0) - qty_to_invoice = fields.Float( - compute="_compute_get_to_invoice_qty", - string="To Invoice", - store=True, - readonly=True, - digits=("Product Unit of Measure"), - ) - qty_invoiced = fields.Float( - compute="_compute_get_invoice_qty", - string="Invoiced", - store=True, - readonly=True, - digits=("Product Unit of Measure"), ) price_subtotal = fields.Monetary( - string="Subtotal", readonly=True, store=True, compute="_compute_amount_service" + string="Subtotal", + help="Subtotal price without taxes", + readonly=True, + store=True, + compute="_compute_amount_service", ) price_total = fields.Monetary( - string="Total", readonly=True, store=True, compute="_compute_amount_service" + string="Total", + help="Total price without 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", ) # 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 @@ -188,7 +278,12 @@ class PmsService(models.Model): name += "\n" + product.description_sale service.name = name - @api.depends("reservation_id.checkin", "reservation_id.checkout", "product_id") + @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: @@ -205,13 +300,21 @@ class PmsService(models.Model): if consumed_on == "after": i += 1 idate = reservation.checkin + timedelta(days=i) - old_line = service._search_old_lines(idate) - if idate in [ - line.date for line in service.service_line_ids - ]: - # REVIEW: If the date is already - # cached (otherwise double the date) - pass + 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( ( @@ -220,11 +323,11 @@ class PmsService(models.Model): { "date": idate, "day_qty": day_qty, + "auto_qty": True, + "price_unit": price_unit, }, ) ) - else: - lines.append((4, old_line.id)) move_day = 0 if consumed_on == "after": move_day = 1 @@ -245,12 +348,10 @@ class PmsService(models.Model): ] ) ) - _logger.info(service) - _logger.info(lines) service.service_line_ids = lines else: - # TODO: Review (business logic refact) no per_day logic service if not service.service_line_ids: + price_unit = service._get_price_unit_line() service.service_line_ids = [ ( 0, @@ -258,13 +359,13 @@ class PmsService(models.Model): { "date": fields.Date.today(), "day_qty": day_qty, + "price_unit": price_unit, }, ) ] else: - # TODO: Service without reservation(room) but with folio¿? - # example: tourist tour in group if not service.service_line_ids: + price_unit = service._get_price_unit_line() service.service_line_ids = [ ( 0, @@ -272,231 +373,37 @@ class PmsService(models.Model): { "date": fields.Date.today(), "day_qty": day_qty, + "price_unit": price_unit, }, ) ] else: service.service_line_ids = False - def _search_old_lines(self, date): - self.ensure_one() - if isinstance(self._origin.id, int): - old_line = self._origin.service_line_ids.filtered(lambda r: r.date == date) - return old_line + # Default methods + + 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 - @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( - "product_id", - "service_line_ids", - "reservation_id.pricelist_id", - "reservation_id.pms_property_id", - "pms_property_id", - ) - def _compute_price_unit(self): - for service in self: - folio = service.folio_id - reservation = service.reservation_id - origin = reservation if reservation else folio - if origin: - if service._recompute_price(): - partner = origin.partner_id - pricelist = origin.pricelist_id - if reservation and service.is_board_service: - board_room_type = reservation.board_service_room_id - if board_room_type.price_type == "fixed": - service.price_unit = ( - self.env["pms.board.service.room.type.line"] - .search( - [ - ( - "pms_board_service_room_type_id", - "=", - board_room_type.id, - ), - ("product_id", "=", service.product_id.id), - ] - ) - .amount - ) - else: - service.price_unit = ( - reservation.price_total - * self.env["pms.board.service.room.type.line"] - .search( - [ - ( - "pms_board_service_room_type_id", - "=", - board_room_type.id, - ), - ("product_id", "=", service.product_id.id), - ] - ) - .amount - ) / 100 - else: - product = service.product_id.with_context( - lang=partner.lang, - partner=partner.id, - quantity=service.product_qty, - date=folio.date_order if folio else fields.Date.today(), - pricelist=pricelist.id, - uom=service.product_id.uom_id.id, - fiscal_position=False, - property=service.pms_property_id.id, - ) - service.price_unit = self.env[ - "account.tax" - ]._fix_tax_included_price_company( - service._get_display_price(product), - product.taxes_id, - service.tax_ids, - origin.company_id, - ) - else: - service.price_unit = service._origin.price_unit - else: - service.price_unit = 0 - - def _recompute_price(self): - # REVIEW: Conditional to avoid overriding already calculated prices, - # I'm not sure it's the best way - self.ensure_one() - # folio/reservation origin service - folio_origin = self._origin.folio_id - reservation_origin = self._origin.reservation_id - origin = reservation_origin if reservation_origin else folio_origin - # folio/reservation new service - folio_new = self.folio_id - reservation_new = self.reservation_id - new = reservation_new if reservation_new else folio_new - price_fields = [ - "pricelist_id", - "reservation_type", - "pms_property_id", - ] - if ( - any(origin[field] != new[field] for field in price_fields) - or self._origin.price_unit == 0 - ): - return True - return False - - @api.depends("qty_invoiced", "product_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_qty - line.qty_invoiced - else: - line.qty_to_invoice = 0 - - @api.depends("move_line_ids.move_id.state", "move_line_ids.quantity") - 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.move_line_ids: - if invoice_line.move_id.state != "cancel": - if invoice_line.move_id.type == "out_invoice": - qty_invoiced += invoice_line.uom_id._compute_quantity( - invoice_line.quantity, line.product_id.uom_id - ) - elif invoice_line.move_id.type == "out_refund": - qty_invoiced -= invoice_line.uom_id._compute_quantity( - invoice_line.quantity, line.product_id.uom_id - ) - line.qty_invoiced = qty_invoiced - - @api.depends("product_qty", "qty_to_invoice", "qty_invoiced") - def _compute_invoice_status(self): - """ - Compute the invoice status of a SO line. Possible statuses: - - no: if the SO is not in status 'sale' or 'done', - we consider that there is nothing to invoice. - This is also hte default value if the conditions of no other - status is met. - - to invoice: we refer to the quantity to invoice of the line. - Refer to method `_compute_get_to_invoice_qty()` for more information on - how this quantity is calculated. - - upselling: this is possible only for a product invoiced on ordered - quantities for which we delivered more than expected. - The could arise if, for example, a project took more time than - expected but we decided not to invoice the extra cost to the - client. This occurs onyl in state 'sale', so that when a Folio - is set to done, the upselling opportunity is removed from the list. - - invoiced: the quantity invoiced is larger or equal to the - quantity ordered. - """ - precision = self.env["decimal.precision"].precision_get( - "Product Unit of Measure" - ) - for line in self: - state = line.folio_id.state or "draft" - if state == "draft": - line.invoice_status = "no" - 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_qty, precision_digits=precision - ) - >= 0 - ): - line.invoice_status = "invoiced" - else: - line.invoice_status = "no" - - @api.depends("product_qty", "discount", "price_unit", "tax_ids") - def _compute_amount_service(self): - for service in self: - folio = service.folio_id - reservation = service.reservation_id - currency = folio.currency_id if folio else reservation.currency_id - product = service.product_id - price = service.price_unit * (1 - (service.discount or 0.0) * 0.01) - taxes = service.tax_ids.compute_all( - price, currency, service.product_qty, product=product - ) - service.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"], - } - ) - # Action methods def open_service_ids(self): - action = self.env.ref("pms.action_pms_services_form").read()[0] + 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" @@ -522,20 +429,12 @@ class PmsService(models.Model): reservation = self.reservation_id origin = folio if folio else reservation if origin.pricelist_id.discount_policy == "with_discount": - return product.with_context(pricelist=origin.pricelist_id.id).price - product_context = dict( - self.env.context, - partner_id=origin.partner_id.id, - date=folio.date_order if folio else fields.Date.today(), - uom=self.product_id.uom_id.id, - ) + return product.price final_price, rule_id = origin.pricelist_id.with_context( - product_context - ).get_product_price_rule( - self.product_id, self.product_qty or 1.0, origin.partner_id - ) + 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 + product._context )._get_real_price_currency( product, rule_id, @@ -547,12 +446,74 @@ class PmsService(models.Model): base_price = ( self.env["res.currency"] .browse(currency_id) - .with_context(product_context) + .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() @@ -563,3 +524,38 @@ class PmsService(models.Model): if self.product_id.per_person: qty = self.reservation_id.adults return qty + + def _get_price_unit_line(self, date=False): + self.ensure_one() + 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.pms_property_id.id, + ) + if date: + product_context["date_overnight"] = 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 index 18247e536..d583d4c5f 100644 --- a/pms/models/pms_service_line.py +++ b/pms/models/pms_service_line.py @@ -9,53 +9,230 @@ class PmsServiceLine(models.Model): _name = "pms.service.line" _description = "Service by day" _order = "date" + _rec_name = "service_id" + _check_pms_properties_auto = True - # Fields declaration service_id = fields.Many2one( - "pms.service", string="Service Room", - ondelete="cascade", + 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, ) - product_id = fields.Many2one(related="service_id.product_id", store=True) tax_ids = fields.Many2many( - "account.tax", string="Taxes", related="service_id.tax_ids", readonly="True" + 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( - "pms.property", store=True, readonly=True, related="service_id.pms_property_id" + 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("Date") - day_qty = fields.Integer("Units") - price_total = fields.Float( - "Price Total", compute="_compute_price_total", store=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( - "Unit Price", related="service_id.price_unit", readonly=True, store=True + string="Unit Price", + help="Price per unit of service", + digits=("Product Price"), ) - room_id = fields.Many2one( - string="Room", related="service_id.reservation_id", readonly=True, store=True + 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 without 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( - "Discount", related="service_id.discount", readonly=True, store=True + 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( - "Discount cancel", compute="_compute_cancel_discount" + 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, ) - # Compute and Search methods - @api.depends("day_qty", "service_id.price_total") - def _compute_price_total(self): + @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): """ - Used to reports + On board service the line discount is always + equal to reservation line discount """ for record in self: - if record.service_id.product_qty != 0: - record.price_total = ( - record.service_id.price_total * record.day_qty - ) / record.service_id.product_qty - else: - record.price_total = 0 + if record.is_board_service: + record.discount = ( + record.service_id.reservation_id.reservation_line_ids.filtered( + lambda l: l.date == record.date + ).discount + ) + elif not record.discount: + record.discount = 0 + + # TODO: Refact method and allowed cancelled single days + @api.depends("service_id.reservation_id.cancelled_reason") + def _compute_cancel_discount(self): + for line in self: + line.cancel_discount = 0 + # TODO: Review cancel logic + # reservation = line.reservation_id.reservation_id + # pricelist = reservation.pricelist_id + # if reservation.state == "cancelled": + # if ( + # reservation.cancelled_reason + # and pricelist + # and pricelist.cancelation_rule_id + # ): + # date_start_dt = fields.Date.from_string( + # reservation.checkin + # ) + # date_end_dt = fields.Date.from_string( + # reservation.checkout + # ) + # days = abs((date_end_dt - date_start_dt).days) + # rule = pricelist.cancelation_rule_id + # 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 + + # checkin = reservation.checkin + # dates = [] + # for i in range(0, days): + # dates.append( + # ( + # fields.Date.from_string(checkin) + timedelta(days=i) + # ).strftime(DEFAULT_SERVER_DATE_FORMAT) + # ) + # 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("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") diff --git a/pms/models/pms_shared_room.py b/pms/models/pms_shared_room.py index 22b10711e..8566db551 100644 --- a/pms/models/pms_shared_room.py +++ b/pms/models/pms_shared_room.py @@ -10,43 +10,63 @@ class PmsSharedRoom(models.Model): _name = "pms.shared.room" _description = "Shared Room" _order = "room_type_id, name" + _check_pms_properties_auto = True - # Fields declaration - name = fields.Char("Room Name", required=True) + name = fields.Char( + string="Room Name", help="Name of the shared room", required=True + ) + active = fields.Boolean( + string="Active", help="Determines if shared room is active", default=True + ) + sequence = fields.Integer( + string="Sequence", + help="Field used to change the position of the shared rooms in tree view." + "Changing the position changes the sequence", + required=True, + ) room_type_id = fields.Many2one( - "pms.room.type", - "Room Type", + string="Room Type", + help="Room type which the shared room belongs", + comodel_name="pms.room.type", required=True, ondelete="restrict", domain=[("shared_room", "=", True)], ) # TODO: properties relation pms_property_ids = fields.Many2many( - "pms.property", + string="Properties", + help="Properties with access to the element;" + " if not set, all properties can access", + comodel_name="pms.property", + relation="pms_shared_room_pms_property_rel", + column1="shared_room_id", + column2="pms_property_id", + check_pms_properties=True, ) - floor_id = fields.Many2one( - "pms.floor", - "Ubication", + ubication_id = fields.Many2one( + string="Ubication", + help="At which ubication the room is located.", + comodel_name="pms.ubication", ondelete="restrict", - help="At which floor the room is located.", ) bed_ids = fields.One2many( - "pms.room", - "shared_room_id", + string="Beds", + help="Beds in one room", + comodel_name="pms.room", + inverse_name="shared_room_id", readonly=True, ) - active = fields.Boolean("Active", default=True) - sequence = fields.Integer("Sequence", required=True) - beds = fields.Integer("Beds") + beds = fields.Integer( + string="Number Of Beds", help="Number of beds in a shared room" + ) description_sale = fields.Text( - "Sale Description", - translate=True, + 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, ) - # Constraints and onchanges @api.constrains("beds") def _constrain_beds(self): self.ensure_one() @@ -75,7 +95,7 @@ class PmsSharedRoom(models.Model): "capacity": 1, "room_type_id": self.room_type_id.id, "sequence": self.sequence, - "floor_id": self.floor_id.id if self.floor_id else False, + "ubication_id": self.ubication_id.id if self.ubication_id else False, "shared_room_id": self.id, } beds.append((0, False, bed_vals)) @@ -98,11 +118,11 @@ class PmsSharedRoom(models.Model): } ) - @api.constrains("floor_id") - def _constrain_floor_id(self): + @api.constrains("ubication_id") + def _constrain_ubication_id(self): self.bed_ids.write( { - "floor_id": self.floor_id.id, + "ubication_id": self.ubication_id.id, } ) diff --git a/pms/models/pms_ubication.py b/pms/models/pms_ubication.py new file mode 100644 index 000000000..5169eefcd --- /dev/null +++ b/pms/models/pms_ubication.py @@ -0,0 +1,50 @@ +# 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 index eb6ad46ba..82a91a3a1 100644 --- a/pms/models/product_pricelist.py +++ b/pms/models/product_pricelist.py @@ -1,7 +1,11 @@ # 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 fields, models +_logger = logging.getLogger(__name__) + class ProductPricelist(models.Model): """Before creating a 'daily' pricelist, you need to consider the following: @@ -10,17 +14,127 @@ class ProductPricelist(models.Model): """ _inherit = "product.pricelist" + _check_pms_properties_auto = True # Fields declaration pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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( - "pms.cancelation.rule", string="Cancelation Policy" + string="Cancelation Policy", + help="Cancelation Policy included in the room", + comodel_name="pms.cancelation.rule", + check_pms_properties=True, ) pricelist_type = fields.Selection( - [("daily", "Daily Plan")], string="Pricelist Type", default="daily" + 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 + ): + 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 + LEFT JOIN board_service_pricelist_item_rel board + ON item.id = board.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_overnight IS NULL + OR item.date_start_overnight <=%s) + AND (item.date_end_overnight IS NULL + OR item.date_end_overnight >=%s) + GROUP BY item.id + ORDER BY item.applied_on, + /* REVIEW: priotrity date sale / date overnight */ + item.date_end - item.date_start ASC, + item.date_end_overnight - item.date_start_overnight 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, + # on_board_service_bool, + # board_service_id, + 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) + 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 # Constraints and onchanges # @api.constrains("pricelist_type", "pms_property_ids") @@ -52,23 +166,17 @@ class ProductPricelist(models.Model): # ) # ) - def _compute_price_rule_get_items( - self, products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids - ): - items = super(ProductPricelist, self)._compute_price_rule_get_items( - products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids - ) - # Discard the rules with defined properties other than the context, - # and we reorder the rules to return the most concrete property rule first - if "property" in self._context: - items_filtered = items.filtered( - lambda i: not i.pms_property_ids - or self._context["property"] in i.pms_property_ids.ids - ) - return items_filtered.sorted( - key=lambda s: ( - (s.applied_on), - ((s.date_end - s.date_start).days), - ((not s.pms_property_ids, s), len(s.pms_property_ids)), - ) - ) + 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 index 0fcb9099c..267f145a1 100644 --- a/pms/models/product_pricelist_item.py +++ b/pms/models/product_pricelist_item.py @@ -5,7 +5,53 @@ from odoo import fields, models class ProductPricelistItem(models.Model): _inherit = "product.pricelist.item" + _check_pms_properties_auto = True pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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_overnight = fields.Date( + string="Start Date Overnight", + help="Start date to apply daily pricelist items", + ) + date_end_overnight = fields.Date( + string="End Date Overnight", + help="End date to apply daily pricelist items", + ) + on_board_service = fields.Boolean( + string="On Board Service", + help="Those included in Board Services", + ) + board_service_room_type_ids = fields.Many2many( + string="Board Services", + help="""Specify a Board services on Room Types.""", + comodel_name="pms.board.service.room.type", + relation="board_service_pricelist_item_rel", + column1="pricelist_item_id", + column2="board_service_id", + ondelete="cascade", + 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, ) diff --git a/pms/models/product_product.py b/pms/models/product_product.py new file mode 100644 index 000000000..2990f6ecd --- /dev/null +++ b/pms/models/product_product.py @@ -0,0 +1,43 @@ +from odoo import api, fields, models + + +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", + ) + + @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 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 index 8f788d13d..35311f80d 100644 --- a/pms/models/product_template.py +++ b/pms/models/product_template.py @@ -8,19 +8,39 @@ class ProductTemplate(models.Model): _inherit = "product.template" pms_property_ids = fields.Many2many( - "pms.property", string="Properties", required=False, ondelete="restrict" + 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", ) - per_day = fields.Boolean("Unit increment per day") - per_person = fields.Boolean("Unit increment per person") consumed_on = fields.Selection( - [("before", "Before night"), ("after", "After night")], - "Consumed", + string="Consumed", + help="Indicates when the product is consumed", + selection=[("before", "Before night"), ("after", "After night")], default="before", ) - daily_limit = fields.Integer("Daily limit") - is_extra_bed = fields.Boolean("Is extra bed", default=False) - show_in_calendar = fields.Boolean( - "Show in Calendar", - default=False, - help="Specifies if the product is shown in the calendar information.", + 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, ) diff --git a/pms/models/res_company.py b/pms/models/res_company.py index 393dc3ede..79135d45a 100644 --- a/pms/models/res_company.py +++ b/pms/models/res_company.py @@ -7,20 +7,9 @@ from odoo import fields, models class ResCompany(models.Model): _inherit = "res.company" - # Fields declaration - pms_property_ids = fields.One2many("pms.property", "company_id", "Properties") - # TODO: need extra explanation or remove otherwise - # additional_hours = fields.Integer('Additional Hours', - # help="Provide the min hours value for \ - # check in, checkout days, whatever \ - # the hours will be provided here based \ - # on that extra days will be \ - # calculated.") - # TODO: move the text to the default template for confirmed reservations - # cardex_warning = fields.Text( - # '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.") + pms_property_ids = fields.One2many( + string="Properties", + help="Properties with access to the element", + comodel_name="pms.property", + inverse_name="company_id", + ) diff --git a/pms/models/res_partner.py b/pms/models/res_partner.py index d715688e0..acaf9e88e 100644 --- a/pms/models/res_partner.py +++ b/pms/models/res_partner.py @@ -11,35 +11,60 @@ _logger = logging.getLogger(__name__) class ResPartner(models.Model): _inherit = "res.partner" - # Fields declaration - main_partner_id = fields.Many2one( - "res.partner", string="Destination Partner fusion" - ) reservations_count = fields.Integer( - "Reservations", compute="_compute_reservations_count" + string="Reservations", + help="Number of reservations of the partner", + compute="_compute_reservations_count", + ) + folios_count = fields.Integer( + string="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" ) - folios_count = fields.Integer("Folios", compute="_compute_folios_count") - unconfirmed = fields.Boolean("Unconfirmed", default=True) - is_agency = fields.Boolean("Is Agency") sale_channel_id = fields.Many2one( - "pms.sale.channel", string="Sale Channel", - ondelete="restrict", + 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, ) - default_commission = fields.Integer("Commission") - apply_pricelist = fields.Boolean("Apply Pricelist") - invoice_agency = fields.Boolean("Invoice Agency") - # Compute and Search methods 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, ) ] @@ -58,17 +83,14 @@ class ResPartner(models.Model): ] ) - # ORM Overrides @api.model def name_search(self, name, args=None, operator="ilike", limit=100): if not args: args = [] domain = [ - "|", "|", ("phone", operator, name), ("mobile", operator, name), - ("email", operator, name), ] partners = self.search( domain + args, @@ -93,3 +115,34 @@ class ResPartner(models.Model): raise models.ValidationError(_("Sale Channel must be entered")) 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): + return [] diff --git a/pms/models/res_users.py b/pms/models/res_users.py index 2a4123127..a7becc480 100644 --- a/pms/models/res_users.py +++ b/pms/models/res_users.py @@ -1,33 +1,28 @@ # 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 AccessError +from odoo.exceptions import ValidationError from odoo.http import request class ResUsers(models.Model): _inherit = "res.users" - # Default Methods ang Gets - @api.model - def _get_default_pms_property(self): - return self.env.user.pms_property_id - - # Fields declaration pms_property_id = fields.Many2one( - "pms.property", - string="Property", - default=_get_default_pms_property, - help="The property this user is currently working for.", + 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( - "pms.property", - "pms_property_users_rel", - "user_id", - "pms_property_id", string="Properties", - default=_get_default_pms_property, + 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 @@ -39,7 +34,24 @@ class ResUsers(models.Model): active_property_ids = list( map(int, request.httprequest.cookies.get("pms_pids", "").split(",")) ) - if any(pid not in user_property_ids for pid in active_property_ids): - raise AccessError(_("Access to unauthorized or invalid properties.")) + 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 index 357e6bf8d..940574e83 100644 --- a/pms/readme/CONFIGURE.rst +++ b/pms/readme/CONFIGURE.rst @@ -1,3 +1,3 @@ -You will find the hotel settings in Settings > Users & Companies > Hotels > Your Hotel. +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 index 5316e1c4f..91f25d79a 100644 --- a/pms/readme/CONTRIBUTORS.rst +++ b/pms/readme/CONTRIBUTORS.rst @@ -1,4 +1,10 @@ -* Dario Lodeiros * 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 index 5f6c71a7c..9001d9117 100644 --- a/pms/readme/DESCRIPTION.rst +++ b/pms/readme/DESCRIPTION.rst @@ -1,5 +1,5 @@ -This module is an all-in-one property management system (PMS) focused on medium-sized hotels +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 hotel properties with multi-hotel and multi-company support, including your rooms inventory, -reservations, check-in, daily reports, board services, rate and restriction plans among other hotel functionalities. +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 index 66a8ca6a8..1661ad5e7 100644 --- a/pms/readme/INSTALL.rst +++ b/pms/readme/INSTALL.rst @@ -1,2 +1,2 @@ -This module depends on modules ``base``, ``sale_stock``, ``account_payment_return``, ``partner_firstname``, -and ``account_cancel``. Ensure yourself to have all them in your addons list. +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 index 864ca126a..e6a897c6a 100644 --- a/pms/readme/USAGE.rst +++ b/pms/readme/USAGE.rst @@ -1 +1 @@ -To use this module, please, read the complete user guide at https://roomdoo.com. +To use this module, please, read the complete user guide at ``_. diff --git a/pms/report/pms_folio_templates.xml b/pms/report/pms_folio_templates.xml index dd0f15b47..48f3e4146 100644 --- a/pms/report/pms_folio_templates.xml +++ b/pms/report/pms_folio_templates.xml @@ -1,15 +1,16 @@ -