From f050f7f932d38f6b7c8a00f13db50eba1243b869 Mon Sep 17 00:00:00 2001 From: braisab Date: Thu, 7 Oct 2021 11:52:14 +0200 Subject: [PATCH] [WIP]pms: changes in pms portal --- pms/__manifest__.py | 1 + pms/controllers/pms_portal.py | 288 ++++---- .../precheckin_invitation_email_template.xml | 44 ++ pms/models/pms_checkin_partner.py | 51 ++ pms/security/ir.model.access.csv | 1 + pms/security/pms_security.xml | 7 + pms/static/src/js/send_invitation_data.js | 68 ++ pms/views/assets.xml | 10 + pms/views/precheckin_portal_templates.xml | 657 +++++++++++------- 9 files changed, 748 insertions(+), 379 deletions(-) create mode 100644 pms/data/precheckin_invitation_email_template.xml create mode 100644 pms/static/src/js/send_invitation_data.js create mode 100644 pms/views/assets.xml diff --git a/pms/__manifest__.py b/pms/__manifest__.py index a3b39364e..54732196d 100644 --- a/pms/__manifest__.py +++ b/pms/__manifest__.py @@ -81,6 +81,7 @@ "views/reservation_portal_templates.xml", "views/res_company_views.xml", "views/traveller_report_template.xml", + "views/assets.xml", "wizards/wizard_split_join_swap_reservation.xml", "views/pms_automated_mails_views.xml", "views/precheckin_portal_templates.xml", diff --git a/pms/controllers/pms_portal.py b/pms/controllers/pms_portal.py index a6ed83d39..1164e6dd6 100644 --- a/pms/controllers/pms_portal.py +++ b/pms/controllers/pms_portal.py @@ -128,6 +128,16 @@ class PortalFolio(CustomerPortal): return request.redirect("/my") values.update(self._folio_get_page_view_values(folio_sudo, access_token, **kw)) values.update({"no_breadcrumbs": True, "error": {}}) + country_ids = request.env['res.country'].search([]) + state_ids = request.env['res.country.state'].search([]) + doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) + values.update( + { + "country_ids": country_ids, + "state_ids": state_ids, + "doc_type_ids": doc_type_ids, + } + ) return request.render("pms.portal_my_folio_precheckin", values) @@ -261,21 +271,6 @@ class PortalReservation(CustomerPortal): class PortalPrecheckin(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"].search( - [("partner_id", "=", partner.id)] - ) - if "checkin_count" in counters: - checkin_partner_count = len(Reservation.checkin_partner_ids) - values["checkin_count"] = ( - checkin_partner_count - if Reservation.check_access_rights("read", raise_exception=False) - else 0 - ) - return values - def _precheckin_get_page_view_values(self, checkin_partner, access_token, **kwargs): values = {"checkin_partner": checkin_partner, "token": access_token} return self._get_page_view_values( @@ -303,77 +298,95 @@ class PortalPrecheckin(CustomerPortal): except (AccessError, MissingError): return request.redirect("/my") values = self._precheckin_get_page_view_values(checkin_sudo, access_token, **kw) - values.update({"no_breadcrumbs": True, "error": {}}) + country_ids = request.env['res.country'].search([]) + state_ids = request.env['res.country.state'].search([]) + doc_type_ids = request.env['res.partner.id_category'].sudo().search([]) + values.update( + { + "doc_type_ids": doc_type_ids, + "country_ids": country_ids, + "state_ids": state_ids, + "no_breadcrumbs": True, + "error": {} + } + ) return request.render("pms.portal_my_precheckin_detail", values) @http.route(["/my/precheckin"], type="http", auth="user", website=True, csrf=False) def portal_precheckin_submit(self, access_token=None, **kw): - values = dict() + checkin_partner = request.env["pms.checkin.partner"].browse( + int(kw.get("id")) + ) values.update( { + "checkin_partner": checkin_partner, "error": {}, - "error_message": [], + "error_message": {}, } ) + country_ids = request.env['res.country'].search([]) + state_ids = request.env['res.country.state'].search([]) + doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) if kw: error, error_message = self.form_validate(kw, None) values.update( { + "no_breadcrumbs": True, "error": error, "error_message": error_message, + "country_ids": country_ids, + "state_ids": state_ids, + "doc_type_ids": doc_type_ids, } ) - if not error: - values = kw - checkin_partner = request.env["pms.checkin.partner"].browse( - int(kw.get("id")) - ) - if not values.get("birthdate_date"): - values.update({"birthdate_date": False}) - if not values.get("document_expedition_date"): - values.update({"document_expedition_date": False}) - lastname = True if values.get("lastname") else False - firstname = True if values.get("firstname") else False - lastname2 = True if values.get("lastname2") else False - if not checkin_partner.partner_id and ( - lastname or firstname or lastname2 - ): - ResPartner = request.env["res.partner"] - res_partner = ResPartner.create(values) + if error: + + return request.render("pms.portal_my_precheckin_detail", values) + else: + try: + values = kw + if values.get("document_type"): + doc_type = request.env["res.partner.id_category"].sudo().search([("name", "=", values.get("document_type"))]) + values.update( + { + "document_type": doc_type, + } + ) + request.env["pms.checkin.partner"].sudo()._save_data_from_portal(values) + doc_type_ids = request.env['res.partner.id_category'].sudo().search([]) values.update( { - "partner_id": res_partner.id, + "doc_type_ids": doc_type_ids, } ) - elif checkin_partner.partner_id: - res_partner = checkin_partner.partner_id - res_partner.write(values) - - checkin_partner.write(values) - values1 = dict() - values1.update( - { - "success": True, - "checkin_partner": checkin_partner, - "no_breadcrumbs": True, - "error": {}, - } - ) - return request.render("pms.portal_my_precheckin_detail", values1) - try: - checkin_partner = request.env["pms.checkin.partner"].browse( - int(kw.get("id")) - ) - values.update( - { - "checkin_partner": checkin_partner, - "no_breadcrumbs": True, - } - ) - return request.render("pms.portal_my_precheckin_detail", values) - except (AccessError, MissingError): - return request.redirect("/my") + # if values.get("document_type"): + # doc_type_id = values.get("document_type") + # doc_type = request.env["res.partner.id_category"].sudo().search([("id", "=", doc_type_id)]) + # values.update( + # { + # "document_type": doc_type, + # } + # ) + country_ids = request.env['res.country'].search([]) + state_ids = request.env['res.country.state'].search([]) + values.update( + { + "country_ids": country_ids, + "state_ids": state_ids, + } + ) + values.update( + { + "success": True, + "checkin_partner": checkin_partner, + "no_breadcrumbs": True, + "error": {}, + } + ) + return request.render("pms.portal_my_precheckin_detail", values) + except (AccessError, MissingError): + return request.redirect("/my") @http.route( ["/my/precheckin/folio_reservation"], @@ -384,7 +397,7 @@ class PortalPrecheckin(CustomerPortal): ) def portal_precheckin_folio_submit(self, **kw): errors = {} - e_messages = [] + e_messages = {} counter = 1 has_error = False checkin_partners = False @@ -396,47 +409,51 @@ class PortalPrecheckin(CustomerPortal): int(kw.get("reservation_id")) ) checkin_partners = reservation.checkin_partner_ids + country_ids = request.env['res.country'].search([]) + state_ids = request.env['res.country.state'].search([]) + doc_type_ids = request.env["res.partner.id_category"].sudo().search([]) + values = { + "no_breadcrumbs": True, + "country_ids": country_ids, + "state_ids": state_ids, + "doc_type_ids": doc_type_ids, + } for checkin in checkin_partners: - values = { - "firstname": kw.get("firstname-" + str(counter)), - "lastname": kw.get("lastname-" + str(counter)), - "lastname2": kw.get("lastname2-" + str(counter)), - "gender": kw.get("gender-" + str(counter)), - "birthdate_date": kw.get("birthdate_date-" + str(counter)) - if kw.get("birthdate_date-" + str(counter)) - else False, - "document_type": kw.get("document_type-" + str(counter)), - "document_number": kw.get("document_number-" + str(counter)), - "document_expedition_date": kw.get( - "document_expedition_date-" + str(counter) + values.update( + { + "id": kw.get("id-" + str(counter)), + "firstname": kw.get("firstname-" + str(counter)), + "lastname": kw.get("lastname-" + str(counter)), + "lastname2": kw.get("lastname2-" + str(counter)), + "gender": kw.get("gender-" + str(counter)), + "birthdate_date": kw.get("birthdate_date-" + str(counter)) + if kw.get("birthdate_date-" + str(counter)) + else False, + "document_type": kw.get("document_type-" + str(counter)), + "document_number": kw.get("document_number-" + str(counter)), + "document_expedition_date": kw.get( + "document_expedition_date-" + str(counter) + ) + if kw.get("document_expedition_date-" + str(counter)) + else False, + "mobile": kw.get("mobile-" + str(counter)), + "email": kw.get("email-" + str(counter)), + } + ) + if values.get("document_type"): + doc_type_code = values.get("document_type") + doc_type = request.env["res.partner.id_category"].sudo().search([("code", "=", doc_type_code)]) + values.update( + { + "document_type": doc_type, + } ) - if kw.get("document_expedition_date-" + str(counter)) - else False, - "mobile": kw.get("mobile-" + str(counter)), - "email": kw.get("email-" + str(counter)), - } error, error_message = self.form_validate(kw, counter) errors.update(error) if error_message: - for e in error_message: - e_messages.append(e) has_error = True else: - lastname = True if kw.get("lastname-" + str(counter)) else False - firstname = True if kw.get("firstname-" + str(counter)) else False - lastname2 = True if kw.get("lastname2-" + str(counter)) else False - if not checkin.partner_id and (lastname or firstname or lastname2): - ResPartner = request.env["res.partner"] - res_partner = ResPartner.create(values) - values.update( - { - "partner_id": res_partner.id, - } - ) - elif checkin.partner_id: - res_partner = checkin.partner_id - res_partner.write(values) - checkin.write(values) + checkin.sudo()._save_data_from_portal(values) counter = counter + 1 values = {"no_breadcrumbs": True} @@ -480,7 +497,7 @@ class PortalPrecheckin(CustomerPortal): data[mobile], ): error[mobile] = "error" - error_message.append("Invalid phone") + error_message[mobile] = "Invalid phone" birthdate_date = ( "birthdate_date" if "birthdate_date" in keys @@ -488,32 +505,22 @@ class PortalPrecheckin(CustomerPortal): ) if data[birthdate_date] and data[birthdate_date] > str(fields.Datetime.today()): error[birthdate_date] = "error" - error_message.append("Birthdate must be less than today") - document_expedition_date = ( - "document_expedition_date" - if "document_expedition_date" in keys - else "document_expedition_date-" + str(counter) - ) - if data[document_expedition_date] and data[document_expedition_date] > str( - fields.Datetime.today() - ): - error[document_expedition_date] = "error" - error_message.append("Expedition Date must be less than today") + error_message[birthdate_date] = "Birthdate must be less than today" email = "email" if "email" in keys else "email-" + str(counter) if data[email] and not tools.single_email_re.match(data[email]): error[email] = "error" - error_message.append("Email format is wrong") + error_message[email] = "Email format is wrong" firstname = "firstname" if "firstname" in keys else "firstname-" + str(counter) lastname = "lastname" if "lastname" in keys else "lastname-" + str(counter) lastname2 = "lastname2" if "lastname2" in keys else "lastname2-" + str(counter) if not data[firstname] and not data[lastname] and not data[lastname2]: error[firstname] = "error" - error_message.append("Firstname or any lastname are not included") + error_message[firstname] = "Firstname or any lastname are not included" return error, error_message def form_document_validate(self, data, counter): error = dict() - error_message = [] + error_message = {} keys = data.keys() document_number = ( "document_number" @@ -525,28 +532,23 @@ class PortalPrecheckin(CustomerPortal): if "document_type" in keys else "document_type-" + str(counter) ) - checkin_partner_id = "id" if "id" in keys else "id-" + str(counter) - checkin_partner = request.env["pms.checkin.partner"].search( - [("id", "=", data[checkin_partner_id])] + document_expedition_date = ( + "document_expedition_date" + if "document_expedition_date" in keys + else "document_expedition_date-" + str(counter) ) - partner_id = checkin_partner.partner_id.id - if partner_id: - partners = request.env["res.partner"].search( - [("id", "!=", str(partner_id))] - ) + if data[document_expedition_date] and not data[document_number]: + error[document_expedition_date] = "error" + error_message[document_expedition_date] = "Document Number not entered and Document Type is not selected" if data[document_number]: - for partner in partners: - if data[document_number] == partner.document_number: - error[document_number] = "error" - error_message.append("Document Number already exists") if not data[document_type]: error[document_type] = "error" - error_message.append("Document Type is not selected") + error_message[document_type] ="Document Type is not selected" if data[document_type] == "D": if len(data[document_number]) == 9 or len(data[document_number]) == 10: if not re.match(r"^\d{8}[ -]?[a-zA-Z]$", data[document_number]): error[document_number] = "error" - error_message.append("The DNI format is wrong") + error_message[document_number] = "The DNI format is wrong" letters = { 0: "T", 1: "R", @@ -574,30 +576,44 @@ class PortalPrecheckin(CustomerPortal): } dni_number = data[document_number][0:8] dni_letter = data[document_number][ - len(data[document_number]) - 1 : len(data[document_number]) - ] + len(data[document_number]) - 1 : len(data[document_number]) + ] if letters.get(int(dni_number) % 23) != dni_letter.upper(): error[document_number] = "error" - error_message.append("DNI is invalid") + error_message[document_number] = "DNI format is invalid" else: error[document_number] = "error" - error_message.append("DNI is invalid") + error_message[document_number] = "DNI is invalid" if data[document_type] == "C" and not re.match( r"^\d{8}[ -]?[a-zA-Z]$", data[document_number] ): error[document_number] = "error" - error_message.append("The Driving License format is wrong") + error_message[document_number] = "The Driving License format is wrong" if data[document_type] == "N" and not re.match( r"^[X|Y]{1}[ -]?\d{7,8}[ -]?[a-zA-Z]$", data[document_number] ): error[document_number] = "error" - error_message.append("The Spanish Residence Permit format is wrong") + error_message[document_number] = "The Spanish Residence Permit format is wrong" if data[document_type] == "X" and not re.match( r"^[X|Y]{1}[ -]?\d{7,8}[ -]?[a-zA-Z]$", data[document_number] ): error[document_number] = "error" - error_message.append("The European Residence Permit format is wrong") + error_message[document_number] = "The European Residence Permit format is wrong" elif data[document_type]: error[document_number] = "error" - error_message.append("Document Number not entered") + error_message[document_number] = "Document Number not entered" return error, error_message + + + @http.route( + ["/my/precheckin/send_invitation"], + auth="user", + website=True, + csrf=False, + ) + def portal_precheckin_folio_send_invitation(self, **kw): + print(kw) + # checkin_partner_id = kw.get("checkin_partner_id") + # checkin_partner = request.env["pms.checkin.partner"].search([("id", "=", checkin_partner_id)]) + # print(checkin_partner) + return request.redirect("/my") diff --git a/pms/data/precheckin_invitation_email_template.xml b/pms/data/precheckin_invitation_email_template.xml new file mode 100644 index 000000000..3575837cb --- /dev/null +++ b/pms/data/precheckin_invitation_email_template.xml @@ -0,0 +1,44 @@ + + + + + + Precheckin + + ${object.company_id.name} has confirmed your reservation in ${object.pms_property_id.name} + ${object.pms_property_id.partner_id.email | safe} + ${(object.email and '"%s" <%s>' % (object.name, object.email) or object.partner_id.email_formatted or '') | safe} + +

__

+ Make your check-in now and save time +
+ Access ourquick registration system. In a few steps you will be able to register your data in an agile, simple and secure way,avoiding queues at reception. + If you register your data in our system, your passage through reception will be much faster, being able to enjoy the comfort of your room right away. + + + + +
+ + + + +
+

+ +

+
Hacer check-in
+

+
+
+
+
+
+
diff --git a/pms/models/pms_checkin_partner.py b/pms/models/pms_checkin_partner.py index 7603a2575..5ffecca6e 100644 --- a/pms/models/pms_checkin_partner.py +++ b/pms/models/pms_checkin_partner.py @@ -7,6 +7,9 @@ import json from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError from odoo.tools.safe_eval import safe_eval +from datetime import datetime +from dateutil.relativedelta import relativedelta +from odoo.tools import DEFAULT_SERVER_DATE_FORMAT class PmsCheckinPartner(models.Model): @@ -670,6 +673,26 @@ class PmsCheckinPartner(models.Model): checkin_vals[key] = value checkin.write(checkin_vals) + @api.model + def calculate_doc_type_expedition_date_from_validity_date(self, doc_type, doc_date, birthdate): + today = fields.datetime.today() + datetime_doc_date = datetime.strptime(doc_date, DEFAULT_SERVER_DATE_FORMAT) + if datetime_doc_date < today: + return datetime_doc_date + datetime_birthdate = datetime.strptime(birthdate, DEFAULT_SERVER_DATE_FORMAT) + age = today.year - datetime_birthdate.year + document_type = self.env["res.partner.id_category"].search([("id", "=", doc_type)]) + document_expedition_date = False + if document_type.code == "D" or document_type.code == "P": + if age < 30: + document_expedition_date = datetime_doc_date - relativedelta(years=5) + else: + document_expedition_date = datetime_doc_date - relativedelta(years=10) + if document_type.code == "C": + if age < 70: + document_expedition_date = datetime_doc_date - relativedelta(years=10) + return document_expedition_date + def action_on_board(self): for record in self: if record.reservation_id.checkin > fields.Date.today(): @@ -725,3 +748,31 @@ class PmsCheckinPartner(models.Model): "type": "ir.actions.act_window", "context": ctx, } + def _save_data_from_portal(self, values): + checkin_partner = self.env["pms.checkin.partner"].browse(int(values.get("id"))) + if values.get("nationality_id"): + nationality_id = self.env['res.country'].search([("id", "=", values.get("nationality_id"))]) + values.update({"nationality_id": nationality_id.id}) + else: + values.update({"nationality_id": False}) + if not values.get("document_type"): + values.update({"document_type": False}) + # else: + # doc_type_id = values.get("document_type") + # document_type = self.env["res.partner.id_category"].search([("id", "=", doc_type_id)]) + # values.update({"document_type": document_type.id}) + if values.get("state"): + state_id = self.env["res.country.state"].search([("id", "=", values.get("state"))]) + values.update( + { + "state_id": state_id + } + ) + values.pop("state") + if values.get("document_expedition_date"): + doc_type = values.get("document_type") + doc_date = values.get("document_expedition_date") + birthdate = values.get("birthdate_date") + document_expedition_date = self.calculate_doc_type_expedition_date_from_validity_date(doc_type, doc_date, birthdate) + values.update({"document_expedition_date": document_expedition_date}) + checkin_partner.sudo().write(values) diff --git a/pms/security/ir.model.access.csv b/pms/security/ir.model.access.csv index 0f7d27ad6..a587d4c21 100644 --- a/pms/security/ir.model.access.csv +++ b/pms/security/ir.model.access.csv @@ -64,3 +64,4 @@ user_access_pms_automated_mails,user_access_pms_automated_mails,model_pms_automa access_pms_several_partners_wizard,access_pms_several_partners_wizard,model_pms_several_partners_wizard,base.group_user,1,1,1,1 user_access_pms_precheckin_portal,user_access_pms_precheckin_portal,model_pms_checkin_partner,base.group_portal,1,0,0,0 user_access_res_partner_portal,user_access_res_partner_portal,model_res_partner,base.group_portal,1,1,1,1 +user_access_pms_precheckin_portal,user_access_pms_precheckin_portal,model_pms_checkin_partner,base.group_portal,1,1,1,1 diff --git a/pms/security/pms_security.xml b/pms/security/pms_security.xml index 25b4edf9e..a47fff764 100644 --- a/pms/security/pms_security.xml +++ b/pms/security/pms_security.xml @@ -251,5 +251,12 @@ + + Portal Checkin Partner Rule + + [] + + + diff --git a/pms/static/src/js/send_invitation_data.js b/pms/static/src/js/send_invitation_data.js new file mode 100644 index 000000000..8fdd1ab99 --- /dev/null +++ b/pms/static/src/js/send_invitation_data.js @@ -0,0 +1,68 @@ +odoo.define('pms', function (require) { +'use strict'; + +var core = require('web.core'); +var _t = core._t; +var utils = require('web.utils'); +var publicWidget = require('web.public.widget'); + +publicWidget.registry.SendInvitationData = publicWidget.Widget.extend({ + selector: '.o_send_invitation_js', + events: { + 'click': '_onReminderToggleClick', + }, + + /** + * @override + */ +// init: function () { +// this._super.apply(this, arguments); +// this._onReminderToggleClick = _.debounce(this._onReminderToggleClick, 500, true); +// }, + + //-------------------------------------------------------------------------- + // Handlers + //------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + _onReminderToggleClick: function (ev) { +// var self = this; +// var $checkinPartner = $(ev.currentTarget).find('i'); + + this._rpc({ + route: '/my/precheckin/send_invitation', + params: { + checkin_partner_id: $checkinPartner.data('checkin_partner_id'), + }, + })/*.then(function (result) {*/ +// if (result.error && result.error === 'ignored') { +// self.displayNotification({ +// type: 'info', +// title: _t('Error'), +// message: _.str.sprintf(_t('Talk already in your Favorites')), +// }); +// } else { +// self.reminderOn = reminderOnValue; +// var reminderText = self.reminderOn ? _t('Favorite On') : _t('Set Favorite'); +// self.$('.o_wetrack_js_reminder_text').text(reminderText); +// self._updateDisplay(); +// var message = self.reminderOn ? _t('Talk added to your Favorites') : _t('Talk removed from your Favorites'); +// self.displayNotification({ +// type: 'info', +// title: message +// }); +// } +// if (result.visitor_uuid) { +// utils.set_cookie('visitor_uuid', result.visitor_uuid); +// } +// }); + }, + + +}); +return publicWidget.registry.SendInvitationData; + +}); diff --git a/pms/views/assets.xml b/pms/views/assets.xml new file mode 100644 index 000000000..a24bf9b72 --- /dev/null +++ b/pms/views/assets.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/pms/views/precheckin_portal_templates.xml b/pms/views/precheckin_portal_templates.xml index 6b7892acc..d0c80c607 100644 --- a/pms/views/precheckin_portal_templates.xml +++ b/pms/views/precheckin_portal_templates.xml @@ -4,9 +4,9 @@ Contact Details
- + + + @@ -22,7 +22,7 @@
-
+
-
+
-
+
-
+
+ + + + + +
+
+ + + + + +
+
+ + + + + + +
+
-
- -

- -
-
- -

- -
-
- - -
-
- - -
-
+
-
+
+ + + +
+
+ +

+ +
+
+ + +
+
+ +
-
+
+ + @@ -519,6 +606,10 @@ + +

-
- + - Reservation: + + + Reservation: + + - - Checkin - - - - + + + Host + + + + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + + + + + + +
Gender

+ class="gender_class" + t-att-id="'genderId'+str(count)" + >

- - - - - - - - + class="doc_type_class" + t-att-id="'docTypeId'+str(count)" + >

+ + + + + + +
+
+ + +
+
+ + +
@@ -779,6 +949,7 @@ t-att-value="id or checkin_partner.id" />
+
@@ -814,31 +985,31 @@