diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index c599137e..54248f54 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -991,7 +991,7 @@ def _compute_commission_amount(self): for reservation in self: if reservation.commission_percent > 0: reservation.commission_amount = ( - reservation.price_total * reservation.commission_percent + reservation.price_total * reservation.commission_percent / 100 ) else: reservation.commission_amount = 0 diff --git a/pms/models/product_template.py b/pms/models/product_template.py index 4b6a5db0..52df87a5 100644 --- a/pms/models/product_template.py +++ b/pms/models/product_template.py @@ -26,6 +26,7 @@ class ProductTemplate(models.Model): ) daily_limit = fields.Integer("Daily limit") is_extra_bed = fields.Boolean("Is extra bed", default=False) + is_crib = fields.Boolean("Is a baby crib", default=False) show_in_calendar = fields.Boolean( "Show in Calendar", default=False, diff --git a/pms/views/product_template_views.xml b/pms/views/product_template_views.xml index d19f73aa..0bd29194 100644 --- a/pms/views/product_template_views.xml +++ b/pms/views/product_template_views.xml @@ -15,6 +15,7 @@ options="{'no_create': True,'no_open': True}" /> + diff --git a/pms_data_bi/README.rst b/pms_data_bi/README.rst new file mode 100644 index 00000000..2609c67f --- /dev/null +++ b/pms_data_bi/README.rst @@ -0,0 +1,76 @@ +REVENUE EXPORTER +================ + +Export Odoo data for Revenue MyDataBI + +Usage +======= +To use this module, you need to: + +Create a user and give the "Hotel Management / Export data BI" permission. + +To connect to Odoo via xmlrpc there are examples in https://www.odoo.com/documentation/10.0/api_integration.html in the "Calling methods" section with examples in several languages. + +A python example: +import xmlrpclib + +url = 'https://www.example.org' + +username = 'username@example.org' + +password = '123passwordexample' + +db = 'example_db_name' + +common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(url)) + +uid = common.authenticate(db, username, password, {}) + +models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url)) + +models.execute_kw(db, uid, password,'data_bi','export_data_bi', [ 8, 1, '2018-01-01']) + +In the parameters of export_data_bi: + +archivo == 1 'Tarifa' + +archivo == 2 'Canal' + +archivo == 3 'Hotel' + +archivo == 4 'Pais' + +archivo == 5 'Regimen' + +archivo == 6 'Reservas' + +archivo == 7 'Capacidad' + +archivo == 8 'Tipo Habitación' + +archivo == 9 'Budget' + +archivo == 10 'Bloqueos' + +archivo == 11 'Motivo Bloqueo' + +archivo == 12 'Segmentos' + +archivo == 13 'Clientes' + +archivo == 14 'Estado Reservas' + +company_id == company's id or False for all + +fechafoto = start date to take data + +in the example recive 8 'Tipo Habitación' from company_id 1 from '2018-01-01' + + +Credits +======= + +Creator +------------ + +* Jose Luis Algara (Alda hotels) diff --git a/pms_data_bi/__init__.py b/pms_data_bi/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/pms_data_bi/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pms_data_bi/__manifest__.py b/pms_data_bi/__manifest__.py new file mode 100644 index 00000000..80585c05 --- /dev/null +++ b/pms_data_bi/__manifest__.py @@ -0,0 +1,24 @@ +# Copyright 2018-2021 Jose Luis Algara Toledo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "PMS Data Bi", + "summary": "Export hotel data for business intelligence", + "version": "14.0.3.0.0", + "license": "AGPL-3", + "author": "Jose Luis Algara (Alda hotels) , " + "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/pms", + "depends": ["pms", "pms_l10n_es"], + "category": "Generic Modules/Property Management System", + "data": [ + "views/budget.xml", + "views/inherit_pms_property.xml", + "views/inherit_res_users.xml", + "security/data_bi.xml", + "security/ir.model.access.csv", + ], + "demo": [], + "installable": True, + "auto_install": False, +} diff --git a/pms_data_bi/i18n/es.po b/pms_data_bi/i18n/es.po new file mode 100644 index 00000000..ee74eba2 --- /dev/null +++ b/pms_data_bi/i18n/es.po @@ -0,0 +1,323 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pms_data_bi +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-25 17:46+0000\n" +"PO-Revision-Date: 2021-02-25 18:47+0100\n" +"Last-Translator: Jose Luis Algara Toledo \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 2.3\n" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2018 +msgid "2018" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2019 +msgid "2019" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2020 +msgid "2020" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2021 +msgid "2021" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2022 +msgid "2022" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2023 +msgid "2023" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2024 +msgid "2024" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2025 +msgid "2025" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2026 +msgid "2026" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2027 +msgid "2027" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2028 +msgid "2028" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2029 +msgid "2029" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2030 +msgid "2030" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2031 +msgid "2031" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2032 +msgid "2032" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2033 +msgid "2033" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2034 +msgid "2034" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__year__2035 +msgid "2035" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__4 +msgid "April" +msgstr "Abril" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__8 +msgid "August" +msgstr "Agosto" + +#. module: pms_data_bi +#: model_terms:ir.ui.view,arch_db:pms_data_bi.view_filter_budget +msgid "Budget filters" +msgstr "Filtros de presupuestos" + +#. module: pms_data_bi +#: model:ir.actions.act_window,name:pms_data_bi.budget_act_window +#: model:ir.ui.menu,name:pms_data_bi.budget_menu +msgid "Budget for DataBI" +msgstr "Presupuesto para DataBi" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__create_uid +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__create_uid +msgid "Created by" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__create_date +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__create_date +msgid "Created on" +msgstr "" + +#. module: pms_data_bi +#: model_terms:ir.ui.view,arch_db:pms_data_bi.res_users_view_form +msgid "Data Bi export" +msgstr "" + +#. module: pms_data_bi +#: model_terms:ir.ui.view,arch_db:pms_data_bi.data_bi_view_company_form +msgid "DataBi MOP" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_res_users__data_bi_days +#: model_terms:ir.ui.view,arch_db:pms_data_bi.res_users_view_form +msgid "Days to download data" +msgstr "Días a descargar" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__12 +msgid "December" +msgstr "Diciembre" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__display_name +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__display_name +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_property__display_name +#: model:ir.model.fields,field_description:pms_data_bi.field_res_users__display_name +msgid "Display Name" +msgstr "Nombre Mostrado" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_property__expedia_rate +msgid "Expedia Rate DataBI" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__2 +msgid "February" +msgstr "Febrero" + +#. module: pms_data_bi +#: model_terms:ir.ui.view,arch_db:pms_data_bi.budget_form_view +msgid "Hotel Budget:" +msgstr "Presupuesto del Hotel:" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__id +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__id +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_property__id +#: model:ir.model.fields,field_description:pms_data_bi.field_res_users__id +msgid "ID" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,help:pms_data_bi.field_pms_property__expedia_rate +msgid "" +"It is the commission percentage negotiated with the Expedia " +"company, expressed with two digits. Example: 18 = 18% commission." +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__1 +msgid "January" +msgstr "Enero" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__7 +msgid "July" +msgstr "Julio" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__6 +msgid "June" +msgstr "Junio" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi____last_update +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget____last_update +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_property____last_update +#: model:ir.model.fields,field_description:pms_data_bi.field_res_users____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__write_uid +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_data_bi__write_date +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__write_date +msgid "Last Updated on" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__3 +msgid "March" +msgstr "Marzo" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__5 +msgid "May" +msgstr "Mayo" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__month +msgid "Month" +msgstr "Mes" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__11 +msgid "November" +msgstr "Noviembre" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__estancias +msgid "Number of Stays" +msgstr "Numero de estancias" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__10 +msgid "October" +msgstr "Octubre" + +#. module: pms_data_bi +#: code:addons/pms_data_bi/models/data_bi_old.py:0 +#, python-format +msgid "Out of Service" +msgstr "Fuera de servicio" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__pms_property_id +msgid "Pms Property" +msgstr "Propiedad PMS" + +#. module: pms_data_bi +#: model:ir.model,name:pms_data_bi.model_pms_property +#: model_terms:ir.ui.view,arch_db:pms_data_bi.view_filter_budget +msgid "Property" +msgstr "Propiedad" + +#. module: pms_data_bi +#: model:res.groups,name:pms_data_bi.group_pms_export_data +msgid "Property Management / Export data BI" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__room_nights +msgid "Room Nights" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__room_revenue +msgid "Room Revenue" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model.fields.selection,name:pms_data_bi.selection__pms_budget__month__9 +msgid "September" +msgstr "Septiembre" + +#. module: pms_data_bi +#: model:ir.model,name:pms_data_bi.model_res_users +msgid "Users" +msgstr "Usuarios" + +#. module: pms_data_bi +#: model:ir.model.fields,field_description:pms_data_bi.field_pms_budget__year +#: model_terms:ir.ui.view,arch_db:pms_data_bi.view_filter_budget +msgid "Year" +msgstr "Año" + +#. module: pms_data_bi +#: model:ir.model,name:pms_data_bi.model_data_bi +msgid "data_bi" +msgstr "" + +#. module: pms_data_bi +#: model:ir.model,name:pms_data_bi.model_pms_budget +msgid "pms.budget" +msgstr "" diff --git a/pms_data_bi/models/__init__.py b/pms_data_bi/models/__init__.py new file mode 100644 index 00000000..d9f91f6b --- /dev/null +++ b/pms_data_bi/models/__init__.py @@ -0,0 +1,4 @@ +from . import inherit_pms_property +from . import inherit_res_users +from . import budget +from . import data_bi diff --git a/pms_data_bi/models/budget.py b/pms_data_bi/models/budget.py new file mode 100644 index 00000000..240ac19e --- /dev/null +++ b/pms_data_bi/models/budget.py @@ -0,0 +1,59 @@ +# Copyright 2019-2021 Jose Luis Algara (Alda hotels) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +def get_years(): + """Return a year list, to select in year field.""" + year_list = [] + for i in range(2018, 2036): + year_list.append((str(i), str(i))) + return year_list + + +class Budget(models.Model): + """Establish and save the budget for DataBI control by revenue""" + + _name = "pms.budget" + + # fecha Primer día del mes + month = fields.Selection( + string="Month", + selection=[ + ("1", "January"), + ("2", "February"), + ("3", "March"), + ("4", "April"), + ("5", "May"), + ("6", "June"), + ("7", "July"), + ("8", "August"), + ("9", "September"), + ("10", "October"), + ("11", "November"), + ("12", "December"), + ], + required=True, + ) + year = fields.Selection(get_years(), string="Year", required=True) + room_nights = fields.Float("Room Nights", required=True, digits=(6, 2)) + # Número de Room Nights + room_revenue = fields.Float("Room Revenue", required=True, digits=(6, 2)) + # Ingresos por Reservas + estancias = fields.Integer("Number of Stays") # Número de Estancias + # ID_Tarifa numérico Código de la Tarifa + # ID_Canal numérico Código del Canal + # ID_Pais numérico Código del País + # ID_Regimen numérico Cóigo del Régimen + # ID_Tipo_Habitacion numérico Código del Tipo de Habitación + # iD_Segmento numérico Código del Segmento + # ID_Cliente numérico Código del Cliente + # Pension_Revenue numérico con dos decimales Ingresos por Pensión + pms_property_id = fields.Many2one( + "pms.property", + required=True, + ondelete="restrict", + default=lambda self: self.env.user.get_active_property_ids()[0], + ) diff --git a/pms_data_bi/models/data_bi.py b/pms_data_bi/models/data_bi.py new file mode 100644 index 00000000..0424a855 --- /dev/null +++ b/pms_data_bi/models/data_bi.py @@ -0,0 +1,714 @@ +############################################################################## +# +# Odoo, Open Source Management Solution +# Copyright (C) 2018 -2021 Alda Hotels +# Jose Luis Algara +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## +import json +import logging +from datetime import date, datetime, timedelta + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class DataBi(models.Model): + """Management and export data for MopSolution MyDataBI.""" + + _name = "data_bi" + + @api.model + def export_data_bi(self, archivo=0, default_property=False, fechafoto=False): + u"""Prepare a Json Objet to export data for MyDataBI. + + Generate a dicctionary to by send in JSON + archivo = response file type + archivo == 0 'ALL' + archivo == 1 'Tarifa' + archivo == 2 'Canal' + archivo == 3 'Hotel' + archivo == 4 'Pais' + archivo == 5 'Regimen' + archivo == 6 'Reservas' + archivo == 7 'Capacidad' + archivo == 8 'Tipo Habitación' + archivo == 9 'Budget' + archivo == 10 'Bloqueos' + archivo == 11 'Motivo Bloqueo' + archivo == 12 'Segmentos' + archivo == 13 'Clientes' + archivo == 14 'Estado Reservas' + archivo == 15 'Room names' + fechafoto = start date to take data + """ + if not fechafoto: + fechafoto = date.today().strftime("%Y-%m-%d") + _logger.warning( + "--- ### Init Export Data_Bi Module parameters: %s, %s, %s ### ---", + archivo, + default_property, + fechafoto, + ) + + if type(fechafoto) is dict: + fechafoto = date.today() + else: + fechafoto = datetime.strptime(fechafoto, "%Y-%m-%d").date() + + propertys = self.env["pms.property"].search([]) + if type(default_property) is int: + default_property = self.env["pms.property"].search( + [("id", "=", default_property)] + ) + if len(default_property) == 1: + propertys = default_property + + dias = self.env.user.data_bi_days + limit_ago = (fechafoto - timedelta(days=dias)).strftime("%Y-%m-%d") + + _logger.info("Export Data %s days ago. From %s", dias, limit_ago) + estado_array = [ + "draft", + "confirm", + "onboard", + "done", + "cancelled", + "no_show", + "no_checkout", + ] + + if archivo == 0: + dic_export = self.export_all(propertys, limit_ago, estado_array) + else: + dic_export = self.export_one(propertys, limit_ago, estado_array, archivo) + + # + # if (archivo == 0) or (archivo == 1): + # dic_tarifa = self.data_bi_tarifa(propertys) + # dic_export.append({"Tarifa": dic_tarifa}) + # + # if (archivo == 0) or (archivo == 2): + # dic_canal = self.data_bi_canal(propertys) + # dic_export.append({"Canal": dic_canal}) + # + # if (archivo == 0) or (archivo == 3): + # dic_hotel = self.data_bi_hotel() + # dic_export.append({"Hotel": dic_hotel}) + # + # if (archivo == 0) or (archivo == 4): + # dic_pais = self.data_bi_pais(propertys) + # dic_export.append({"Pais": dic_pais}) + # + # if (archivo == 0) or (archivo == 5): + # dic_regimen = self.data_bi_regimen(propertys) + # dic_export.append({"Regimen": dic_regimen}) + # + # if (archivo == 0) or (archivo == 10) or (archivo == 6): + # line_res = self.env["pms.reservation.line"].search( + # [("date", ">=", limit_ago)], order="id" + # ) + # + # if (archivo == 0) or (archivo == 6): + # dic_reservas = self.data_bi_reservas( + # propertys, + # line_res, + # estado_array, + # ) + # dic_export.append({"Reservas": dic_reservas}) + # + # if (archivo == 0) or (archivo == 7): + # dic_capacidad = self.data_bi_capacidad(propertys) + # dic_export.append({"Capacidad": dic_capacidad}) + # + # if (archivo == 0) or (archivo == 8): + # dic_tipo_habitacion = self.data_bi_habitacione(propertys) + # dic_export.append({"Tipo Habitación": dic_tipo_habitacion}) + # + # if (archivo == 0) or (archivo == 9): + # dic_budget = self.data_bi_budget(propertys) + # dic_export.append({"Budget": dic_budget}) + # + # if (archivo == 0) or (archivo == 10): + # dic_bloqueos = self.data_bi_bloqueos(propertys, line_res) + # dic_export.append({"Bloqueos": dic_bloqueos}) + # + # if (archivo == 0) or (archivo == 11): + # dic_moti_bloq = self.data_bi_moti_bloq(propertys) + # dic_export.append({"Motivo Bloqueo": dic_moti_bloq}) + # + # if (archivo == 0) or (archivo == 12): + # dic_segmentos = self.data_bi_segment(propertys) + # dic_export.append({"Segmentos": dic_segmentos}) + # + # if (archivo == 0) or (archivo == 13): + # dic_clientes = self.data_bi_client(propertys) + # dic_export.append({"Clientes": dic_clientes}) + # + # if (archivo == 0) or (archivo == 14): + # dic_estados = self.data_bi_estados(propertys, estado_array) + # dic_export.append({"Estado Reservas": dic_estados}) + # + # if (archivo == 0) or (archivo == 15): + # dic_rooms = self.data_bi_rooms(propertys) + # dic_export.append({"Nombre Habitaciones": dic_rooms}) + + dictionary_to_json = json.dumps(dic_export) + _logger.warning("--- ### End Export Data_Bi Module to Json ### ---") + return dictionary_to_json + + @api.model + def export_all(self, propertys, limit_ago, estado_array): + line_res = self.env["pms.reservation.line"].search( + [("date", ">=", limit_ago)], order="id" + ) + dic_reservas = self.data_bi_reservas( + propertys, + line_res, + estado_array, + ) + dic_export = [{"Tarifa": self.data_bi_tarifa(propertys)}, + {"Canal": self.data_bi_canal(propertys)}, + {"Hotel": self.data_bi_hotel()}, + {"Pais": self.data_bi_pais(propertys)}, + {"Regimen": self.data_bi_regimen(propertys)}, + {"Reservas": dic_reservas}, + {"Capacidad": self.data_bi_capacidad(propertys)}, + {"Tipo Habitación": self.data_bi_habitacione(propertys)}, + {"Budget": self.data_bi_budget(propertys)}, + {"Bloqueos": self.data_bi_bloqueos(propertys, line_res)}, + {"data_bi_moti_bloq": self.data_bi_moti_bloq(propertys)}, + {"Segmentos": self.data_bi_segment(propertys)}, + {"Clientes": self.data_bi_client(propertys)}, + {"Estado Reservas": self.data_bi_estados(propertys, estado_array)}, + {"Nombre Habitaciones": self.data_bi_rooms(propertys)}] + return dic_export + + @api.model + def export_one(self, propertys, limit_ago, estado_array, archivo): + if (archivo == 0) or (archivo == 10) or (archivo == 6): + line_res = self.env["pms.reservation.line"].search( + [("date", ">=", limit_ago)], order="id" + ) + dic_reservas = self.data_bi_reservas( + propertys, + line_res, + estado_array, + ) + dic_export = [] + if archivo == 1: + dic_export.append({"Tarifa": self.data_bi_tarifa(propertys)}) + elif archivo == 2: + dic_export.append({"Canal": self.data_bi_canal(propertys)}) + elif archivo == 3: + dic_export.append({"Hotel": self.data_bi_hotel()}) + elif archivo == 4: + dic_export.append({"Pais": self.data_bi_pais(propertys)}) + elif archivo == 5: + dic_export.append({"Regimen": self.data_bi_regimen(propertys)}) + elif archivo == 6: + dic_export.append({"Reservas": dic_reservas}) + elif archivo == 7: + dic_export.append({"Capacidad": self.data_bi_capacidad(propertys)}) + elif archivo == 8: + dic_export.append({"Tipo Habitación": self.data_bi_habitacione(propertys)}) + elif archivo == 9: + dic_export.append({"Budget": self.data_bi_budget(propertys)}) + elif archivo == 10: + dic_export.append({"Bloqueos": self.data_bi_bloqueos(propertys, line_res)}) + elif archivo == 11: + dic_export.append({"data_bi_moti_bloq": self.data_bi_moti_bloq(propertys)}) + elif archivo == 12: + dic_export.append({"Segmentos": self.data_bi_segment(propertys)}) + elif archivo == 13: + dic_export.append({"Clientes": self.data_bi_client(propertys)}) + elif archivo == 14: + dic_export.append({"Estado Reservas": self.data_bi_estados(propertys, estado_array)}) + elif archivo == 15: + dic_export.append({"Nombre Habitaciones": self.data_bi_rooms(propertys)}) + return dic_export + + @api.model + def data_bi_tarifa(self, propertys): + # Diccionario con las tarifas [1] + dic_tarifa = [] + + for prop in propertys: + tarifas = self.env["product.pricelist"].search_read( + [ + "|", + ("active", "=", False), + ("active", "=", True), + "|", + ("pms_property_ids", "=", prop.id), + ("pms_property_ids", "=", False), + ], + ["name"], + ) + _logger.info( + "DataBi: Calculating %s fees in %s", str(len(tarifas)), prop.name + ) + for tarifa in tarifas: + dic_tarifa.append( + { + "ID_Hotel": prop.id, + "ID_Tarifa": tarifa["id"], + "Descripcion": tarifa["name"], + } + ) + return dic_tarifa + + @api.model + def data_bi_canal(self, propertys): + # Diccionario con los Canales [2] + dic_canal = [] + channels = self.env["pms.sale.channel"].search([]) + _logger.info("DataBi: Calculating %s Channels", str(len(channels))) + for prop in propertys: + dic_canal.append( + {"ID_Hotel": prop.id, "ID_Canal": "0", "Descripcion": u"Ninguno"} + ) + for channel in channels: + dic_canal.append( + { + "ID_Hotel": prop.id, + "ID_Canal": channel["id"], + "Descripcion": channel["name"], + } + ) + return dic_canal + + @api.model + def data_bi_hotel(self): + # Diccionario con el/los nombre de los hoteles [3] + hoteles = self.env["pms.property"].search([]) + _logger.info("DataBi: Calculating %s hotel names", str(len(hoteles))) + + dic_hotel = [] + for hotel in hoteles: + dic_hotel.append({"ID_Hotel": hotel.id, "Descripcion": hotel.name}) + return dic_hotel + + @api.model + def data_bi_pais(self, propertys): + dic_pais = [] + # Diccionario con los nombre de los Paises usando los del INE [4] + paises = self.env["code.ine"].search_read([], ["code", "name"]) + _logger.info("DataBi: Calculating %s countries", str(len(paises))) + for prop in propertys: + dic_pais.append( + { + "ID_Hotel": prop.id, + "ID_Pais": "NONE", + "Descripcion": "No Asignado", + } + ) + for pais in paises: + dic_pais.append( + { + "ID_Hotel": prop.id, + "ID_Pais": pais["code"], + "Descripcion": pais["name"], + } + ) + return dic_pais + + @api.model + def data_bi_regimen(self, propertys): + # Diccionario con los Board Services [5] + dic_regimen = [] + board_services = self.env["pms.board.service"].search_read([]) + _logger.info("DataBi: Calculating %s board services", str(len(board_services))) + for prop in propertys: + dic_regimen.append( + { + "ID_Hotel": prop.id, + "ID_Regimen": 0, + "Descripcion": u"Sin régimen", + } + ) + for board_service in board_services: + if (not board_service["pms_property_ids"]) or ( + prop.id in board_service["pms_property_ids"] + ): + dic_regimen.append( + { + "ID_Hotel": prop.id, + "ID_Regimen": board_service["id"], + "Descripcion": board_service["name"], + } + ) + return dic_regimen + + @api.model + def data_bi_capacidad(self, propertys): + # Diccionario con las capacidades [7] + rooms = self.env["pms.room.type"].search_read([]) + _logger.info("DataBi: Calculating %s room capacity", str(len(rooms))) + dic_capacidad = [] + for prop in propertys: + for room in rooms: + if (not room["pms_property_ids"]) or ( + prop.id in room["pms_property_ids"] + ): + dic_capacidad.append( + { + "ID_Hotel": prop.id, + "Hasta_Fecha": ( + date.today() + timedelta(days=365 * 3) + ).strftime("%Y-%m-%d"), + "ID_Tipo_Habitacion": room["id"], + "Nro_Habitaciones": room["total_rooms_count"], + } + ) + return dic_capacidad + + @api.model + def data_bi_habitacione(self, propertys): + # Diccionario con Rooms types [8] + rooms = self.env["pms.room.type"].search([]) + _logger.info("DataBi: Calculating %s room types", str(len(rooms))) + dic_tipo_habitacion = [] + for prop in propertys: + for room in rooms: + if (not room.pms_property_ids) or ( + prop.id in room.pms_property_ids.ids + ): + dic_tipo_habitacion.append( + { + "ID_Hotel": prop.id, + "ID_Tipo_Habitacion": room["id"], + "Descripcion": room["name"], + "Estancias": room.get_capacity(), + } + ) + return dic_tipo_habitacion + + @api.model + def data_bi_budget(self, propertys): + # Diccionario con las previsiones Budget [9] + budgets = self.env["pms.budget"].search([]) + _logger.info("DataBi: Calculating %s budget", str(len(budgets))) + dic_budget = [] + for prop in propertys: + for budget in budgets: + if budget.pms_property_id.id == prop.id: + dic_budget.append( + { + "ID_Hotel": prop.id, + "Fecha": str(budget.year) + + "-" + + str(budget.month).zfill(2) + + "-01", + # 'ID_Tarifa': 0, + # 'ID_Canal': 0, + # 'ID_Pais': 0, + # 'ID_Regimen': 0, + # 'ID_Tipo_Habitacion': 0, + # 'ID_Cliente': 0, + "Room_Nights": budget.room_nights, + "Room_Revenue": budget.room_revenue, + # 'Pension_Revenue': 0, + "Estancias": budget.estancias, + } + ) + # Fecha fecha Primer día del mes + # ID_Tarifa numérico Código de la Tarifa + # ID_Canal numérico Código del Canal + # ID_Pais numérico Código del País + # ID_Regimen numérico Cóigo del Régimen + # ID_Tipo_Habitacion numérico Código del Tipo de Habitación + # iD_Segmento numérico Código del Segmento + # ID_Cliente numérico Código del Cliente + # Pension_Revenue numérico con dos decimales Ingresos por Pensión + return dic_budget + + @api.model + def data_bi_moti_bloq(self, propertys): + # Diccionario con Motivo de Bloqueos [11] + lineas = self.env["room.closure.reason"].search([]) + dic_moti_bloq = [] + _logger.info("DataBi: Calculating %s blocking reasons", str(len(lineas))) + for prop in propertys: + dic_moti_bloq.append( + { + "ID_Hotel": prop.id, + "ID_Motivo_Bloqueo": "B0", + "Descripcion": u"Ninguno", + } + ) + dic_moti_bloq.append( + { + "ID_Hotel": prop.id, + "ID_Motivo_Bloqueo": "ST", + "Descripcion": u"Staff", + } + ) + for linea in lineas: + if (not linea.pms_property_ids) or ( + prop.id in linea.pms_property_ids.ids + ): + dic_moti_bloq.append( + { + "ID_Hotel": prop.id, + "ID_Motivo_Bloqueo": "B" + str(linea.id), + "Descripcion": linea.name, + } + ) + return dic_moti_bloq + + @api.model + def data_bi_segment(self, propertys): + # Diccionario con Segmentación [12] + # TODO solo las que tienen un padre?... ver la gestion... etc.... + dic_segmentos = [] + lineas = self.env["res.partner.category"].search([]) + _logger.info("DataBi: Calculating %s segmentations", str(len(lineas))) + for prop in propertys: + for linea in lineas: + if linea.parent_id.name: + seg_desc = linea.parent_id.name + " / " + linea.name + dic_segmentos.append( + { + "ID_Hotel": prop.id, + "ID_Segmento": linea.id, + "Descripcion": seg_desc, + } + ) + return dic_segmentos + + @api.model + def data_bi_client(self, propertys): + # Diccionario con Clientes (OTAs y agencias) [13] + dic_clientes = [] + lineas = self.env["res.partner"].search([("is_agency", "=", True)]) + _logger.info("DataBi: Calculating %s Operators", str(len(lineas))) + for prop in propertys: + dic_clientes.append( + {"ID_Hotel": prop.id, "ID_Cliente": 0, "Descripcion": u"Ninguno"} + ) + for linea in lineas: + dic_clientes.append( + { + "ID_Hotel": prop.id, + "ID_Cliente": linea.id, + "Descripcion": linea.name, + } + ) + return dic_clientes + + @api.model + def data_bi_estados(self, propertys, estado_array): + # Diccionario con los Estados Reserva [14] + _logger.info("DataBi: Calculating states of the reserves") + dic_estados = [] + estado_array_txt = [ + "Borrador", + "Confirmada", + "Hospedandose", + "Checkout", + "Cancelada", + "No Show", + "No Checkout", + ] + for prop in propertys: + for i in range(0, len(estado_array)): + dic_estados.append( + { + "ID_Hotel": prop.id, + "ID_EstadoReserva": str(i), + "Descripcion": estado_array_txt[i], + } + ) + return dic_estados + + @api.model + def data_bi_rooms(self, propertys): + # Diccionario con las habitaciones [15] + dic_rooms = [] + rooms = self.env["pms.room"].search([]) + _logger.info("DataBi: Calculating %s name rooms.", str(len(rooms))) + for prop in propertys: + for room in rooms.filtered(lambda n: (n.pms_property_id.id == prop.id)): + dic_rooms.append( + { + "ID_Hotel": prop.id, + "ID_Room": room.id, + "Descripcion": room.name, + } + ) + return dic_rooms + + @api.model + def data_bi_bloqueos(self, propertys, lines): + # Diccionario con Bloqueos [10] + dic_bloqueos = [] + lines = lines.filtered( + lambda n: (n.reservation_id.reservation_type != "normal") + and (n.reservation_id.state != "cancelled") + ) + _logger.info("DataBi: Calculating %s Bloqued", str(len(lines))) + for line in lines: + + if line.pms_property_id.id in propertys.ids: + motivo = "0" + if line.reservation_id.reservation_type == "out": + motivo = ( + "B0" + if not line.reservation_id.closure_reason_id.id + else ("B" + str(line.reservation_id.closure_reason_id.id)) + ) + + elif line.reservation_id.reservation_type == "staff": + motivo = "ST" + dic_bloqueos.append( + { + "ID_Hotel": line.pms_property_id.id, + "Fecha_desde": line.date.strftime("%Y-%m-%d"), + "Fecha_hasta": (line.date + timedelta(days=1)).strftime( + "%Y-%m-%d" + ), + "ID_Tipo_Habitacion": line.reservation_id.room_type_id.id, + "ID_Motivo_Bloqueo": motivo, + "Nro_Habitaciones": 1, + } + ) + return dic_bloqueos + + @api.model + def data_bi_reservas(self, propertys, lines, estado_array): + # Diccionario con Reservas [6] + dic_reservas = [] + + for prop in propertys: + lineas = lines.filtered( + lambda n: (n.pms_property_id.id == prop.id) + and (n.reservation_id.reservation_type == "normal") + and (n.price > 0) + ) + _logger.info( + "DataBi: Calculating %s reservations in %s ", + str(len(lineas)), + prop.name, + ) + + for linea in lineas: + if linea.reservation_id.segmentation_ids: + id_segmen = linea.reservation_id.segmentation_ids[0].id + elif linea.reservation_id.folio_id.segmentation_ids: + id_segmen = linea.reservation_id.folio_id.segmentation_ids[0].id + else: + id_segmen = 0 + + regimen = ( + 0 + if not linea.reservation_id.board_service_room_id + else linea.reservation_id.board_service_room_id.id + ) + + cuna = 0 + for service in linea.reservation_id.service_ids: + if service.product_id.is_crib: + cuna += 1 + + canal = ( + linea.reservation_id.channel_type_id.id + if linea.reservation_id.channel_type_id.id + else 0 + ) + + cliente = ( + linea.reservation_id.agency_id.id + if linea.reservation_id.agency_id.id + else 0 + ) + + dic_reservas.append( + { + "ID_Reserva": linea.reservation_id.folio_id.id, + "ID_Hotel": prop.id, + "ID_EstadoReserva": estado_array.index( + linea.reservation_id.state + ), + "FechaVenta": linea.reservation_id.create_date.strftime( + "%Y-%m-%d" + ), + "ID_Segmento": id_segmen, + "ID_Cliente": cliente, + "ID_Canal": canal, + "FechaExtraccion": date.today().strftime("%Y-%m-%d"), + "Entrada": linea.date.strftime("%Y-%m-%d"), + "Salida": (linea.date + timedelta(days=1)).strftime("%Y-%m-%d"), + "Noches": 1, + "ID_TipoHabitacion": linea.reservation_id.room_type_id.id, + "ID_HabitacionDuerme": linea.room_id.room_type_id.id, + "ID_Regimen": regimen, + "Adultos": linea.reservation_id.adults, + "Menores": linea.reservation_id.children, + "Cunas": cuna, + "PrecioDiario": linea.price, + "PrecioDto": linea.discount * (linea.price / 100), + "PrecioComision": linea.reservation_id.commission_amount + / len(linea.reservation_id.reservation_line_ids), + "PrecioIva": linea.reservation_id.sale_line_ids.tax_ids.amount + * linea.price + / 100, + "ID_Tarifa": linea.reservation_id.pricelist_id.id, + "ID_Pais": self.data_bi_get_codeine(linea), + "ID_Room": linea.room_id.id, + "FechaCancelacion": "NONE", + "ID_Folio": linea.reservation_id.folio_id.name, + } + ) + + if linea.reservation_id.state == "cancelled": + dic_reservas[-1][ + "FechaCancelacion" + ] = linea.reservation_id.write_date.strftime("%Y-%m-%d") + + # ID_Reserva numérico Código único de la reserva + # ID_Hotel numérico Código del Hotel + # ID_EstadoReserva numérico Código del estado de la reserva + # FechaVenta fecha Fecha de la venta de la reserva + # ID_Segmento numérico Código del Segmento de la reserva + # ID_Cliente Numérico Código del Cliente de la reserva + # ID_Canal numérico Código del Canal + # FechaExtraccion fecha Fecha de la extracción de los datos (Foto) + # Entrada fecha Fecha de entrada + # Salida fecha Fecha de salida + # Noches numérico Nro. de noches de la reserva + # ID_TipoHabitacion numérico Código del Tipo de Habitación + # ID_Regimen numérico Código del Tipo de Régimen + # Adultos numérico Nro. de adultos + # Menores numérico Nro. de menores + # Cunas numérico Nro. de cunas + # PrecioDiario numérico con 2 decimales Precio por noche de la reserva + # ID_Tarifa numérico Código de la tarifa aplicada a la reserva + # ID_Pais alfanumérico Código del país + + return dic_reservas + + @api.model + def data_bi_get_codeine(self, reserva): + response = "NONE" + if reserva.reservation_id.partner_id.code_ine_id: + response = reserva.reservation_id.partner_id.code_ine_id.code + else: + for partner in reserva.reservation_id.folio_id.checkin_partner_ids: + if partner.partner_id.code_ine_id.code: + response = partner.partner_id.code_ine_id.code + return response diff --git a/pms_data_bi/models/inherit_pms_property.py b/pms_data_bi/models/inherit_pms_property.py new file mode 100644 index 00000000..74fad2f2 --- /dev/null +++ b/pms_data_bi/models/inherit_pms_property.py @@ -0,0 +1,18 @@ +# Copyright 2019-2021 Jose Luis Algara (Alda hotels) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class InheritResCompany(models.Model): + _inherit = "pms.property" + + expedia_rate = fields.Integer( + "Expedia Rate DataBI", + default=18, + required=True, + digits=2, + help="It is the commission percentage negotiated with the \ + Expedia company, expressed with two digits. \ + Example: 18 = 18% commission.", + ) diff --git a/pms_data_bi/models/inherit_res_users.py b/pms_data_bi/models/inherit_res_users.py new file mode 100644 index 00000000..6731668d --- /dev/null +++ b/pms_data_bi/models/inherit_res_users.py @@ -0,0 +1,12 @@ +# Copyright 2019 Pablo Quesada +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + # Fields declaration + data_bi_days = fields.Integer( + string="Days to download data", required=False, default=60 + ) diff --git a/pms_data_bi/security/data_bi.xml b/pms_data_bi/security/data_bi.xml new file mode 100644 index 00000000..d911c6e5 --- /dev/null +++ b/pms_data_bi/security/data_bi.xml @@ -0,0 +1,9 @@ + + + + + + Property Management / Export data BI + + + diff --git a/pms_data_bi/security/ir.model.access.csv b/pms_data_bi/security/ir.model.access.csv new file mode 100644 index 00000000..6e2b2b5f --- /dev/null +++ b/pms_data_bi/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +export_access_pms_budget,pms.budget.export,model_pms_budget,group_pms_export_data,1,1,1,1 +manager_access_pms_budget,pms.budget.manager,model_pms_budget,pms.group_pms_manager,1,1,1,1 diff --git a/pms_data_bi/static/description/icon.png b/pms_data_bi/static/description/icon.png new file mode 100644 index 00000000..0ad91d0d Binary files /dev/null and b/pms_data_bi/static/description/icon.png differ diff --git a/pms_data_bi/views/budget.xml b/pms_data_bi/views/budget.xml new file mode 100644 index 00000000..c8a8d3f1 --- /dev/null +++ b/pms_data_bi/views/budget.xml @@ -0,0 +1,94 @@ + + + + + + + + + + budget.form (in hotel_data_bi) + pms.budget + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + budget.tree (in hotel_data_bi) + pms.budget + + + + + + + + + + + + + + pms.budget + + + + + + + + + + + + + + + + diff --git a/pms_data_bi/views/inherit_pms_property.xml b/pms_data_bi/views/inherit_pms_property.xml new file mode 100644 index 00000000..c0986d8b --- /dev/null +++ b/pms_data_bi/views/inherit_pms_property.xml @@ -0,0 +1,23 @@ + + + + + + + + inherit_pms_property_form + pms.property + + + + + + + + + + + + + + diff --git a/pms_data_bi/views/inherit_res_users.xml b/pms_data_bi/views/inherit_res_users.xml new file mode 100644 index 00000000..05e3251c --- /dev/null +++ b/pms_data_bi/views/inherit_res_users.xml @@ -0,0 +1,17 @@ + + + + res.users + + + + + + + + + + diff --git a/pms_l10n_es/__manifest__.py b/pms_l10n_es/__manifest__.py index fe28af85..a1028fdf 100644 --- a/pms_l10n_es/__manifest__.py +++ b/pms_l10n_es/__manifest__.py @@ -4,7 +4,7 @@ { "name": "PMS Spanish Adaptation", "version": "14.0.1.0.0", - "author": "CommitSun, " "Odoo Community Association (OCA)", + "author": "CommitSun, " "Odoo Community Association (OCA), " "Jose Luis Algara", "license": "AGPL-3", "application": True, "category": "Localization", @@ -17,8 +17,11 @@ "partner_contact_birthdate", ], "data": [ + "data/code.ine.csv", "views/pms_checkin_partner_views.xml", "views/res_partner_views.xml", + "views/code_ine.xml", + "security/ir.model.access.csv", ], "installable": True, } diff --git a/pms_l10n_es/data/code.ine.csv b/pms_l10n_es/data/code.ine.csv new file mode 100644 index 00000000..29f4a84a --- /dev/null +++ b/pms_l10n_es/data/code.ine.csv @@ -0,0 +1,309 @@ +"id","code","name" +"__export__.code_ine_1","AFG","Afganistán" +"__export__.code_ine_2","ALB","Albania" +"__export__.code_ine_3","DEU","Alemania" +"__export__.code_ine_4","AND","Andorra" +"__export__.code_ine_5","AGO","Angola" +"__export__.code_ine_6","AIA","Anguila" +"__export__.code_ine_7","ATG","Antigua y Barbuda" +"__export__.code_ine_8","ANT","Antillas Neerlandesas" +"__export__.code_ine_9","ATA","Antártida" +"__export__.code_ine_10","SAU","Arabia Saudita" +"__export__.code_ine_11","DZA","Argelia" +"__export__.code_ine_12","ARG","Argentina" +"__export__.code_ine_13","ARM","Armenia" +"__export__.code_ine_14","ABW","Aruba" +"__export__.code_ine_15","AUS","Australia" +"__export__.code_ine_16","AUT","Austria" +"__export__.code_ine_17","AZE","Azerbaiyán" +"__export__.code_ine_18","BHS","Bahamas" +"__export__.code_ine_19","BHR","Bahrein" +"__export__.code_ine_20","BGD","Bangladesh" +"__export__.code_ine_21","BRB","Barbados" +"__export__.code_ine_22","BLZ","Belice" +"__export__.code_ine_23","BEN","Benin" +"__export__.code_ine_24","BMU","Bermudas" +"__export__.code_ine_25","BTN","Bhután" +"__export__.code_ine_26","BLR","Bielorrusia" +"__export__.code_ine_27","BOL","Bolivia" +"__export__.code_ine_28","BIH","Bosnia-Herzegovina" +"__export__.code_ine_29","BWA","Botswana" +"__export__.code_ine_30","BRA","Brasil" +"__export__.code_ine_31","BRN","Brunéi" +"__export__.code_ine_32","BGR","Bulgaria" +"__export__.code_ine_33","BFA","Burkina Fasso" +"__export__.code_ine_34","BDI","Burundi" +"__export__.code_ine_35","BEL","Bélgica" +"__export__.code_ine_36","CPV","Cabo Verde" +"__export__.code_ine_37","KHM","Camboya" +"__export__.code_ine_38","CMR","Camerún" +"__export__.code_ine_39","CAN","Canadá" +"__export__.code_ine_40","TCD","Chad" +"__export__.code_ine_41","CHL","Chile" +"__export__.code_ine_42","CHN","China" +"__export__.code_ine_43","CYP","Chipre" +"__export__.code_ine_44","COL","Colombia" +"__export__.code_ine_45","COM","Comoras" +"__export__.code_ine_46","COG","Congo, República del" +"__export__.code_ine_47","COD","Congo, República Democrática del" +"__export__.code_ine_48","PRK","Corea, Rep. Popular Democrática" +"__export__.code_ine_49","KOR","Corea, República de" +"__export__.code_ine_50","CIV","Costa de Marfil" +"__export__.code_ine_51","CRI","Costa Rica" +"__export__.code_ine_52","HRV","Croacia" +"__export__.code_ine_53","CUB","Cuba" +"__export__.code_ine_54","DNK","Dinamarca" +"__export__.code_ine_55","DMA","Dominica" +"__export__.code_ine_56","ECU","Ecuador" +"__export__.code_ine_57","EGY","Egipto" +"__export__.code_ine_58","SLV","El Salvador" +"__export__.code_ine_59","ARE","Emiratos Arabes Unidos" +"__export__.code_ine_60","ERI","Eritrea" +"__export__.code_ine_61","SVK","Eslovaquia" +"__export__.code_ine_62","SVN","Eslovenia" +"__export__.code_ine_63","USA","Estados Unidos de América" +"__export__.code_ine_64","EST","Estonia" +"__export__.code_ine_65","ETH","Etiopía" +"__export__.code_ine_66","PHL","Filipinas" +"__export__.code_ine_67","FIN","Finlandia" +"__export__.code_ine_68","FRA","Francia" +"__export__.code_ine_69","GAB","Gabón" +"__export__.code_ine_70","GMB","Gambia" +"__export__.code_ine_71","GEO","Georgia" +"__export__.code_ine_72","GHA","Ghana" +"__export__.code_ine_73","GIB","Gibraltar" +"__export__.code_ine_74","GRD","Granada" +"__export__.code_ine_75","GRC","Grecia" +"__export__.code_ine_76","GRL","Groenlandia" +"__export__.code_ine_77","GLP","Guadalupe" +"__export__.code_ine_78","GUM","Guam" +"__export__.code_ine_79","GTM","Guatemala" +"__export__.code_ine_80","GUF","Guayana Francesa" +"__export__.code_ine_81","GIN","Guinea" +"__export__.code_ine_82","GNQ","Guinea Ecuatorial" +"__export__.code_ine_83","GNB","Guinea-Bissau" +"__export__.code_ine_84","GUY","Guyana" +"__export__.code_ine_85","HTI","Haití" +"__export__.code_ine_86","HND","Honduras" +"__export__.code_ine_87","HKG","Hong-Kong" +"__export__.code_ine_88","HUN","Hungría" +"__export__.code_ine_89","IND","India" +"__export__.code_ine_90","IDN","Indonesia" +"__export__.code_ine_91","IRQ","Irak" +"__export__.code_ine_92","IRL","Irlanda" +"__export__.code_ine_93","IRN","Irán" +"__export__.code_ine_94","BVT","Isla Bouvert" +"__export__.code_ine_95","GGY","Isla de Guernesey" +"__export__.code_ine_96","JEY","Isla de Jersey" +"__export__.code_ine_97","IMN","Isla de Man" +"__export__.code_ine_98","CXR","Isla de Navidad" +"__export__.code_ine_99","ISL","Islandia" +"__export__.code_ine_100","CYM","Islas Caimán" +"__export__.code_ine_101","CCK","Islas Cocos" +"__export__.code_ine_102","COK","Islas Cook" +"__export__.code_ine_103","FLK","Islas Falkland (Malvinas)" +"__export__.code_ine_104","FRO","Islas Feroé" +"__export__.code_ine_105","FJI","Islas Fidji" +"__export__.code_ine_106","SGS","Islas Georgias del Sur y Sandwich" +"__export__.code_ine_107","HMD","Islas Heard e Mcdonald" +"__export__.code_ine_108","MNP","Islas Marianas del Norte" +"__export__.code_ine_109","MHL","Islas Marshall" +"__export__.code_ine_110","UMI","Islas Menores de EEUU" +"__export__.code_ine_111","NFK","Islas Norfolk" +"__export__.code_ine_112","PCN","Islas Pitcairn" +"__export__.code_ine_113","SLB","Islas Salomón" +"__export__.code_ine_114","TCA","Islas Turcas y Caicos" +"__export__.code_ine_115","VGB","Islas Vírgenes Británicas" +"__export__.code_ine_116","VIR","Islas Vírgenes de los EEUU" +"__export__.code_ine_117","WLF","Islas Wallis y Futura" +"__export__.code_ine_118","ALA","Islas Åland" +"__export__.code_ine_119","ISR","Israel" +"__export__.code_ine_120","ITA","Italia" +"__export__.code_ine_121","JAM","Jamaica" +"__export__.code_ine_122","JPN","Japón" +"__export__.code_ine_123","JOR","Jordania" +"__export__.code_ine_124","KAZ","Kazajstán" +"__export__.code_ine_125","KEN","Kenia" +"__export__.code_ine_126","KGZ","Kirguistán" +"__export__.code_ine_127","KIR","Kiribati" +"__export__.code_ine_128","KWT","Kuwait" +"__export__.code_ine_129","LAO","Laos" +"__export__.code_ine_130","LSO","Lesotho" +"__export__.code_ine_131","LVA","Letonia" +"__export__.code_ine_132","LBY","Libia" +"__export__.code_ine_133","LBR","Libéria" +"__export__.code_ine_134","LIE","Liechtenstein" +"__export__.code_ine_135","LTU","Lituania" +"__export__.code_ine_136","LUX","Luxemburgo" +"__export__.code_ine_137","LBN","Líbano" +"__export__.code_ine_138","MAC","Macao" +"__export__.code_ine_139","MKD","Macedonia, ARY" +"__export__.code_ine_140","MDG","Madagascar" +"__export__.code_ine_141","MYS","Malasia" +"__export__.code_ine_142","MWI","Malawi" +"__export__.code_ine_143","MDV","Maldivas" +"__export__.code_ine_144","MLT","Malta" +"__export__.code_ine_145","MLI","Malí" +"__export__.code_ine_146","MAR","Marruecos" +"__export__.code_ine_147","MTQ","Martinica" +"__export__.code_ine_148","MUS","Mauricio" +"__export__.code_ine_149","MRT","Mauritania" +"__export__.code_ine_150","MYT","Mayotte" +"__export__.code_ine_151","FSM","Micronesia" +"__export__.code_ine_152","MDA","Moldavia" +"__export__.code_ine_153","MNG","Mongolia" +"__export__.code_ine_154","MNE","Montenegro" +"__export__.code_ine_155","MSR","Montserrat" +"__export__.code_ine_156","MOZ","Mozambique" +"__export__.code_ine_157","MMR","Myanmar" +"__export__.code_ine_158","MEX","México" +"__export__.code_ine_159","MCO","Mónaco" +"__export__.code_ine_160","NAM","Namibia" +"__export__.code_ine_161","NRU","Naurú" +"__export__.code_ine_162","NPL","Nepal" +"__export__.code_ine_163","NIC","Nicaragua" +"__export__.code_ine_164","NGA","Nigeria" +"__export__.code_ine_165","NIU","Niue" +"__export__.code_ine_166","NOR","Noruega" +"__export__.code_ine_167","NCL","Nueva Caledonia" +"__export__.code_ine_168","NZL","Nueva Zelanda" +"__export__.code_ine_169","NER","Níger" +"__export__.code_ine_170","OMN","Omán" +"__export__.code_ine_171","PAK","Pakistán" +"__export__.code_ine_172","PLW","Palau" +"__export__.code_ine_173","PSE","Palestina, Territorio ocupado" +"__export__.code_ine_174","PAN","Panamá" +"__export__.code_ine_175","PNG","Papua Nueva Guinea" +"__export__.code_ine_176","PRY","Paraguay" +"__export__.code_ine_177","NLD","Países Bajos" +"__export__.code_ine_178","PER","Perú" +"__export__.code_ine_179","PYF","Polinesia Francesa" +"__export__.code_ine_180","POL","Polonia" +"__export__.code_ine_181","PRT","Portugal" +"__export__.code_ine_182","PRI","Puerto Rico" +"__export__.code_ine_183","QAT","Qatar" +"__export__.code_ine_184","GBR","Reino Unido" +"__export__.code_ine_185","CAF","República Centroafricana" +"__export__.code_ine_186","CZE","República Checa" +"__export__.code_ine_187","DOM","República Dominicana" +"__export__.code_ine_188","REU","Reunión" +"__export__.code_ine_189","ROU","Rumania" +"__export__.code_ine_190","RUS","Rusia" +"__export__.code_ine_191","RWA","Rwanda" +"__export__.code_ine_192","ESH","Sahara Occidental" +"__export__.code_ine_193","KNA","Saint Kitts y Nevis" +"__export__.code_ine_194","WSM","Samoa" +"__export__.code_ine_195","ASM","Samoa Americana" +"__export__.code_ine_196","BLM","San Bartolomé" +"__export__.code_ine_197","SMR","San Marino" +"__export__.code_ine_198","MAF","San Martín" +"__export__.code_ine_199","SPM","San Pedro y Miquelón" +"__export__.code_ine_200","VCT","San Vicente y las Granadinas" +"__export__.code_ine_201","SHN","Santa Elena" +"__export__.code_ine_202","LCA","Santa Lucía" +"__export__.code_ine_203","STP","Santo Tomé y Príncipe" +"__export__.code_ine_204","SEN","Senegal" +"__export__.code_ine_205","SRB","Serbia" +"__export__.code_ine_206","SYC","Seychelles" +"__export__.code_ine_207","SLE","Sierra Leona" +"__export__.code_ine_208","SGP","Singapur" +"__export__.code_ine_209","SYR","Siria" +"__export__.code_ine_210","SOM","Somalia" +"__export__.code_ine_211","LKA","Sri Lanka" +"__export__.code_ine_212","SWZ","Suazilandia" +"__export__.code_ine_213","ZAF","Sudáfrica" +"__export__.code_ine_214","SDN","Sudán" +"__export__.code_ine_215","SWE","Suecia" +"__export__.code_ine_216","CHE","Suiza" +"__export__.code_ine_217","SUR","Suriname" +"__export__.code_ine_218","SJM","Svalbard e Islas de Jan Mayen" +"__export__.code_ine_219","THA","Tailandia" +"__export__.code_ine_220","TWN","Taiwán" +"__export__.code_ine_221","TZA","Tanzania" +"__export__.code_ine_222","TJK","Tayikistan" +"__export__.code_ine_223","IOT","Terr. Británico del Oc. Indico" +"__export__.code_ine_224","ATF","Tierras Australes Francesas" +"__export__.code_ine_225","TLS","Timor Oriental" +"__export__.code_ine_226","TGO","Togo" +"__export__.code_ine_227","TKL","Tokelau" +"__export__.code_ine_228","TON","Tonga" +"__export__.code_ine_229","TTO","Trinidad y Tobago" +"__export__.code_ine_230","TKM","Turkmenistán" +"__export__.code_ine_231","TUR","Turquía" +"__export__.code_ine_232","TUV","Tuvalu" +"__export__.code_ine_233","TUN","Túnez" +"__export__.code_ine_234","UKR","Ucrania" +"__export__.code_ine_235","UGA","Uganda" +"__export__.code_ine_236","URY","Uruguay" +"__export__.code_ine_237","UZB","Uzbekistán" +"__export__.code_ine_238","VUT","Vanuatu" +"__export__.code_ine_239","VAT","Vaticano, Santa Sede" +"__export__.code_ine_240","VEN","Venezuela" +"__export__.code_ine_241","VNM","Vietnam" +"__export__.code_ine_242","YEM","Yemen" +"__export__.code_ine_243","DJI","Yibuti" +"__export__.code_ine_244","ZMB","Zambia" +"__export__.code_ine_245","ZWE","Zimbabwe" +"__export__.code_ine_246","KOS","Kosovo" +"__export__.code_ine_247","ES111","A Coruña" +"__export__.code_ine_248","ES112","Lugo" +"__export__.code_ine_249","ES113","Ourense" +"__export__.code_ine_250","ES114","Pontevedra" +"__export__.code_ine_251","ES120","Asturias" +"__export__.code_ine_252","ES130","Cantabria" +"__export__.code_ine_253","ES211","Araba/Álava" +"__export__.code_ine_254","ES212","Gipuzkoa" +"__export__.code_ine_255","ES213","Bizkaia" +"__export__.code_ine_256","ES220","Navarra" +"__export__.code_ine_257","ES230","La Rioja" +"__export__.code_ine_258","ES241","Huesca" +"__export__.code_ine_259","ES242","Teruel" +"__export__.code_ine_260","ES243","Zaragoza" +"__export__.code_ine_261","ES300","Madrid" +"__export__.code_ine_262","ES411","Ávila" +"__export__.code_ine_263","ES412","Burgos" +"__export__.code_ine_264","ES413","León" +"__export__.code_ine_265","ES414","Palencia" +"__export__.code_ine_266","ES415","Salamanca" +"__export__.code_ine_267","ES416","Segovia" +"__export__.code_ine_268","ES417","Soria" +"__export__.code_ine_269","ES418","Valladolid" +"__export__.code_ine_270","ES419","Zamora" +"__export__.code_ine_271","ES421","Albacete" +"__export__.code_ine_272","ES422","Ciudad Real" +"__export__.code_ine_273","ES423","Cuenca" +"__export__.code_ine_274","ES424","Guadalajara" +"__export__.code_ine_275","ES425","Toledo" +"__export__.code_ine_276","ES431","Badajoz" +"__export__.code_ine_277","ES432","Cáceres" +"__export__.code_ine_278","ES511","Barcelona" +"__export__.code_ine_279","ES512","Girona" +"__export__.code_ine_280","ES513","Lleida" +"__export__.code_ine_281","ES514","Tarragona" +"__export__.code_ine_282","ES521","Alicante / Alacant" +"__export__.code_ine_283","ES522","Castellón / Castelló" +"__export__.code_ine_284","ES523","Valencia / València" +"__export__.code_ine_285","ES530","Illes Balears" +"__export__.code_ine_286","ES531","Eivissa y Formentera" +"__export__.code_ine_287","ES532","Mallorca" +"__export__.code_ine_288","ES533","Menorca" +"__export__.code_ine_289","ES611","Almería" +"__export__.code_ine_290","ES612","Cádiz" +"__export__.code_ine_291","ES613","Córdoba" +"__export__.code_ine_292","ES614","Granada" +"__export__.code_ine_293","ES615","Huelva" +"__export__.code_ine_294","ES616","Jaén" +"__export__.code_ine_295","ES617","Málaga" +"__export__.code_ine_296","ES618","Sevilla" +"__export__.code_ine_297","ES620","Murcia" +"__export__.code_ine_298","ES630","Ceuta" +"__export__.code_ine_299","ES640","Melilla" +"__export__.code_ine_300","ES701","Las Palmas" +"__export__.code_ine_301","ES702","Santa Cruz de Tenerife" +"__export__.code_ine_302","ES703","El Hierro" +"__export__.code_ine_303","ES704","Fuerteventura" +"__export__.code_ine_304","ES705","Gran Canaria" +"__export__.code_ine_305","ES706","La Gomera" +"__export__.code_ine_306","ES707","La Palma" +"__export__.code_ine_307","ES708","Lanzarote" +"__export__.code_ine_308","ES709","Tenerife" diff --git a/pms_l10n_es/models/__init__.py b/pms_l10n_es/models/__init__.py index 4354d949..9a9a96fe 100644 --- a/pms_l10n_es/models/__init__.py +++ b/pms_l10n_es/models/__init__.py @@ -1,2 +1,3 @@ from . import res_partner from . import pms_checkin_partner +from . import code_ine diff --git a/pms_l10n_es/models/code_ine.py b/pms_l10n_es/models/code_ine.py new file mode 100644 index 00000000..7cc9ef0a --- /dev/null +++ b/pms_l10n_es/models/code_ine.py @@ -0,0 +1,40 @@ +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2017 2021 Alda Hotels +# Jose Luis Algara +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +from odoo import fields, models + + +class CodeIne(models.Model): + _name = "code.ine" + + name = fields.Char("Place", required=True) + code = fields.Char("Code", required=True) + state_id = fields.Many2one("res.country.state", string="State", ondelete="restrict") + + def name_get(self): + data = [] + for record in self: + subcode = record.code + if len(record.code) > 3: + subcode = "ESP" + display_value = record.name + " (" + subcode + ")" + data.append((record.id, display_value)) + return data diff --git a/pms_l10n_es/models/pms_checkin_partner.py b/pms_l10n_es/models/pms_checkin_partner.py index 81fd7be2..ab275381 100644 --- a/pms_l10n_es/models/pms_checkin_partner.py +++ b/pms_l10n_es/models/pms_checkin_partner.py @@ -63,6 +63,20 @@ class PmsCheckinPartner(models.Model): readonly=False, ) + code_ine_id = fields.Many2one( + comodel_name="code.ine", + string="Code in INE", + compute="_compute_code_ine", + store=True, + readonly=False, + ) + + @api.depends("partner_id", "partner_id.code_ine_id") + def _compute_code_ine(self): + for record in self: + if not record.code_ine_id: + record.code_ine_id = record.partner_id.code_ine_id + @api.depends("partner_id", "partner_id.lastname") def _compute_lastname(self): for record in self: @@ -126,6 +140,7 @@ def _checkin_mandatory_fields(self, depends=False): "document_type", "document_expedition_date", "gender", + "code_ine_id", ] ) return mandatory_fields diff --git a/pms_l10n_es/models/res_partner.py b/pms_l10n_es/models/res_partner.py index 4dfe8fad..ada18656 100644 --- a/pms_l10n_es/models/res_partner.py +++ b/pms_l10n_es/models/res_partner.py @@ -20,6 +20,11 @@ class ResPartner(models.Model): string="Document number", ) document_expedition_date = fields.Date(string="Document expedition date") + code_ine_id = fields.Many2one( + comodel_name="code.ine", + string="Code in INE", + required=False, + ) @api.constrains("document_number", "document_type") def _check_document(self): diff --git a/pms_l10n_es/security/ir.model.access.csv b/pms_l10n_es/security/ir.model.access.csv new file mode 100644 index 00000000..02dca922 --- /dev/null +++ b/pms_l10n_es/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +user_access_code_ine,user_access_code_ine,model_code_ine,pms.group_pms_user,1,0,0,0 diff --git a/pms_l10n_es/tests/test_partner.py b/pms_l10n_es/tests/test_partner.py index 3c17d603..d138cdfa 100644 --- a/pms_l10n_es/tests/test_partner.py +++ b/pms_l10n_es/tests/test_partner.py @@ -32,6 +32,7 @@ def test_check_precheckin_state(self): "gender": "male", "document_type": "D", "document_number": "30065089H", + "code_ine_id": "266", } ) reservation_vals = { @@ -99,6 +100,7 @@ def test_right_action_on_board(self): "gender": "male", "document_type": "D", "document_number": "30065089H", + "code_ine_id": "266", } ) reservation_vals = { diff --git a/pms_l10n_es/views/code_ine.xml b/pms_l10n_es/views/code_ine.xml new file mode 100644 index 00000000..a850f16c --- /dev/null +++ b/pms_l10n_es/views/code_ine.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + code.ine.view.form + code.ine + +
+ + + + + + + + + + + + + +
+
+
+ + + code.ine.view.tree + code.ine + + + + + + + + +
diff --git a/pms_l10n_es/views/pms_checkin_partner_views.xml b/pms_l10n_es/views/pms_checkin_partner_views.xml index 8eefdeef..2cb2cc76 100644 --- a/pms_l10n_es/views/pms_checkin_partner_views.xml +++ b/pms_l10n_es/views/pms_checkin_partner_views.xml @@ -13,6 +13,7 @@ + @@ -32,6 +33,7 @@ + @@ -51,6 +53,7 @@ + @@ -70,6 +73,7 @@ + @@ -89,6 +93,7 @@ + diff --git a/pms_l10n_es/views/res_partner_views.xml b/pms_l10n_es/views/res_partner_views.xml index 2f2c7577..c0c3c131 100644 --- a/pms_l10n_es/views/res_partner_views.xml +++ b/pms_l10n_es/views/res_partner_views.xml @@ -12,6 +12,7 @@ +