[IMP] pms: precheckin portal

This commit is contained in:
Sara Lago
2022-12-02 19:31:31 +01:00
committed by Darío Lodeiros
parent ea832ba9bc
commit 825e5c3678
3 changed files with 576 additions and 39 deletions

View File

@@ -368,6 +368,55 @@ class PortalPrecheckin(CustomerPortal):
return request.render("pms.portal_not_checkin", values)
return request.render("pms.portal_my_reservation_precheckin", values)
@http.route(
["/my/folios/<int:folio_id>/reservations"],
type="http",
auth="public",
website=True,
csrf=False,
)
def portal_precheckin_folio(self, folio_id, **kw):
folio = request.env["pms.folio"].sudo().browse(folio_id)
values = {}
values.update({"folio": folio})
return request.render("pms.portal_my_prechekin_folio", values)
@http.route(
["/my/folios/<int:folio_id>/reservations/<int:reservation_id>/checkins"],
type="http",
auth="public",
website=True,
csrf=False,
)
def portal_precheckin_reservation(self, folio_id, reservation_id, **kw):
folio = request.env["pms.folio"].sudo().browse(folio_id)
reservation = request.env["pms.reservation"].sudo().browse(reservation_id)
values = {}
values.update({"folio": folio})
values.update({"reservation": reservation})
return request.render("pms.portal_my_prechekin_reservation", values)
@http.route(
[
"/my/folios/<int:folio_id>/reservations/<int:reservation_id>/checkins/<int:checkin_partner_id>"
],
type="http",
auth="public",
website=True,
csrf=False,
)
def portal_precheckin(self, folio_id, reservation_id, checkin_partner_id, **kw):
folio = request.env["pms.folio"].sudo().browse(folio_id)
reservation = request.env["pms.reservation"].sudo().browse(reservation_id)
checkin_partner = (
request.env["pms.checkin.partner"].sudo().browse(checkin_partner_id)
)
values = {}
values.update({"folio": folio})
values.update({"reservation": reservation})
values.update({"checkin_partner": checkin_partner})
return request.render("pms.portal_my_precheckin_detail", values)
@http.route(
["/my/precheckin/<int:folio_id>/checkin/<int:checkin_partner_id>"],
type="http",
@@ -494,7 +543,7 @@ class PortalPrecheckin(CustomerPortal):
error_message[firstname] = "Firstname or any lastname are not included"
if not data.get("gender"):
error["gender"] = "error"
error_message["gender"] = "Gender is mandatory"
error_message["gender"] = _("Gender is mandatory")
if not data.get("document_number"):
error["document_number"] = "error"
error_message["document_number"] = "Document number is mandatory"

View File

@@ -1,6 +1,499 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!--folio template -->
<template id="portal_my_prechekin_folio" name="My precheckin in folio">
<t t-call="portal.portal_layout">
<t t-foreach="folio.reservation_ids" t-as="reservation">
<t t-set="reservation" t-value="reservation" />
<form
t-att-action="'/my/folios/'+str(folio.id)+'/reservations/'+str(reservation.id)+'/checkins'"
method="post"
>
<div class="reservation-card">
<span t-field="reservation.name" />
<button type="submit" class="btn btn-primary float-right">
Show details
</button>
</div>
</form>
</t>
</t>
<script />
<style>
.reservation-card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
width: 60%;
height:36px;
border-radius: 5px;
}
.reservation-card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
</style>
</template>
<!-- reservation template -->
<template id="portal_my_prechekin_reservation" name="My precheckin in folio">
<t t-call="portal.portal_layout">
<t t-foreach="reservation.checkin_partner_ids" t-as="checkin_partner">
<form
t-att-action="'/my/folios/'+str(folio.id)+'/reservations/'+str(reservation.id)+'/checkins/'+str(checkin_partner.id)"
method="post"
>
<div class="checkin-card">
<span t-field="checkin_partner.id" />
<button type="submit" class="btn btn-primary float-right">
Complete partner data
</button>
</div>
</form>
</t>
</t>
<script />
<style>
.checkin-card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
width: 60%;
height:36px;
border-radius: 5px;
},
.checkin-card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
</style>
</template>
<!-- checkin form without error handling-->
<template id="portal_my_precheckin_detail" name="My Precheckin">
<t t-call="portal.portal_layout">
<form t-att-action="checkin_partner.get_portal_url()" method="post">
<div class="row o_portal_details">
<div id="title" class="form-group col-xl-12">
<center>
<h4 class="font-weight-bold">PreCheckin in <span
t-field="folio.pms_property_id.name"
/></h4>
</center>
</div>
<div class="row justify-content-center">
<div t-attf-class="form-group col-12 col-md-6">
<label class="col-form-label" for="firstname">Name<small
>*</small></label>
<input
type="text"
name="firstname"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
class="col-form-label"
for="lastname"
>Lastname</label>
<input
type="text"
name="lastname"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6 pb-md-5">
<label
class="col-form-label"
for="lastname2"
> Second Lastname (Optional)</label>
<input
type="text"
name="lastname2"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6 pb-5">
<label
class="col-form-label"
for="gender"
>Gender</label>
<div class="d-none"><p id="genderId"><t
t-esc="gender"
/></p></div>
<select
class="form-control"
name="gender"
t-attf-class="form-control"
>
<option value="">Select an option</option>
<option
value="female"
t-att-selected="'female' == gender"
>
Female
</option>
<option
value="male"
t-att-selected="'male' == gender"
>
Male
</option>
<option
value="other"
t-att-selected="'other' == gender"
>
Other
</option>
</select>
</div>
<div
name="document_type_div"
t-attf-class="form-group col-12 col-md-6"
>
<label
class="col-form-label"
for="document_type"
>Doc. Type</label>
<div class="d-none"><p id="docTypeId"><t
t-esc="document_type"
/></p></div>
<select
class="form-control"
name='document_type'
id="doc_type"
>
<option value="">Select an option</option>
<t t-foreach="doc_type_ids" t-as='doc_type'>
<option
t-att-value="doc_type.name"
t-att-selected="doc_type.name == document_type"
>
<t t-esc='doc_type.name' />
</option>
</t>
</select>
</div>
<div
name="document_number_div"
t-attf-class="form-group col-12 col-md-6"
>
<label
class="col-form-label"
for="document_number"
>Doc. Number</label>
<input
type="text"
name="document_number"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
class="col-form-label"
for="document_expedition_date"
>Doc. Expedition Date/Doc. Validity Date</label>
<span
class="fa fa-question-circle fa-lg ml-4"
data-toggle="tooltip"
title="If you enter the validity date of the document, the expedition date will be automatically calculated and entered depending on the document type."
/>
<input
type="date"
name="document_expedition_date"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
class="col-form-label"
for="birthdate_date"
> Birth Date</label>
<input
type="date"
name="birthdate_date"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
class="col-form-label"
for="nationality_id"
>Nationality</label>
<select
t-attf-class="form-control"
id="country"
name='nationality_id'
>
<option value="">Select an option</option>
<t t-foreach="country_ids" t-as='country_id'>
<option
t-att-value="country_id.id"
t-att-selected="str(country_id.id) == nationality_id"
>
<t t-esc='country_id.name' />
</option>
</t>
</select>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
id="label_mobile"
class="col-form-label"
for="mobile"
>Mobile (Optional)</label>
<input
type="phone"
name="mobile"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
id="label_phone"
class="col-form-label"
for="phone"
>Phone (Optional)</label>
<input
type="phone"
name="phone"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-12 col-md-6">
<label
id="label_email"
class="col-form-label"
for="email"
>Email (Optional)</label>
<input
type="email"
name="email"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-md-12 pt-md-5">
<label
class="col-form-label"
for="residence_street"
>Residence Address</label>
<input
type="text"
placeholder="Street"
name="residence_street"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-md-12">
<input
type="text"
placeholder="Second Street (Optional)"
name="residence_street2"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-md-4">
<input
type="text"
placeholder="City"
name="residence_city"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-md-4">
<input
type="text"
placeholder="Zip"
name="residence_zip"
t-attf-class="form-control"
/>
</div>
<div t-attf-class="form-group col-md-4">
<select
t-attf-class="form-control"
id="residence-country"
name='residence_country_id'
onclick="changeCountryFormClass()"
>
<option
id="country_placeholder"
hidden="1"
value="placeholder"
>Country</option>
<t t-foreach="country_ids" t-as='country_id'>
<option
t-att-value="country_id.id"
t-att-selected="str(country_id.id) == residence_country_id if residence_country_id and error else placeholder"
>
<t t-esc='country_id.name' />
</option>
</t>
</select>
</div>
<div t-attf-class="form-group col-md-12 pb-md-3">
<select
t-attf-class="form-control"
id="residence-state"
name='residence_state_id'
onclick="changeFormClass()"
>
<option
id="placeholder"
hidden="1"
value="placeholder"
>State</option>
<t t-foreach="state_ids" t-as='state'>
<option
t-att-value="state.id"
t-att-country_id="state.country_id.id"
t-att-selected="str(state.id) == residence_state_id if residence_state_id and error else placeholder"
>
<t t-esc="state.name" />
</option>
</t>
</select>
</div>
</div>
</div>
</form>
</t>
<style>
#snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #6c757d;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 50%;
top: 100px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@-webkit-keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 100px; opacity: 1;}
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 100px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {top: 100px; opacity: 1;}
to {top: 0; opacity: 0;}
}
@keyframes fadeout {
from {top: 100px; opacity: 1;}
to {top: 0; opacity: 0;}
}
.placeholder-class{
display: block;
width: 100%;
height: calc(1.5em + 0.75rem + 2px);
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
font-weight: 400;
line-height: 1.5;
color: grey;
background-color: #FFFFFF;
background-clip: padding-box;
border: 1px solid #CED4DA;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
</style>
<script>
var placeholder_country = document.getElementById("country_placeholder")
function changeCountryFormClass() {
let select_value = placeholder_country.parentNode.value
if (placeholder_country.parentNode.value == 'placeholder'){
placeholder_country.parentNode.classList.add('placeholder-class')
}else{
placeholder_country.parentNode.classList.remove('placeholder-class')
}
};
this.changeCountryFormClass()
var placeholder = document.getElementById("placeholder")
function changeFormClass() {
let select_value = placeholder.parentNode.value
if (placeholder.parentNode.value == 'placeholder'){
placeholder.parentNode.classList.remove('form-control')
placeholder.parentNode.classList.add('placeholder-class')
}else{
placeholder.parentNode.classList.remove('placeholder-class')
placeholder.parentNode.classList.add('form-control')
}
};
this.changeFormClass()
let select_residence_country = document.getElementById('residence-country')
select_residence_country.addEventListener("change", () => {
let country_value = select_residence_country.value
Array.from(document.getElementById('residence-state').options).forEach(element => {
if (element.getAttribute('country_id') == country_value) {
element.style="";
} else {
element.style="display:none";
}
});
});
var select_doc_type = document.getElementById("doc_type")
var document_type_value = document.getElementById("docTypeId").textContent
for (let i=0;i&lt;select_doc_type.length;i++){
if (select_doc_type[i].value == document_type_value){
select_doc_type[i].setAttribute("selected","True")
}
}
var folio_id = document.getElementById("folio").value
var checkin_partner_id = document.getElementById("checkin").value
var access_token = document.getElementById("input_access_token").value
var checkin_pos = document.getElementById("input_checkin_pos").value;
window.history.pushState(null, '', '/my/precheckin/'+folio_id+'/checkin/'+checkin_partner_id +'?access_token='+ access_token);
function launchSnackBar(element) {
var x = document.getElementById("snackbar");
if (checkin_pos == -1){
x.className = "show";
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
}
}
var select_doc_type = document.getElementById("doc_type")
var document_type_value = document.getElementById("docTypeId").textContent
for (let i=0;i&lt;select_doc_type.length;i++){
if (select_doc_type[i].value == document_type_value){
select_doc_type[i].setAttribute("selected","True")
}
}
</script>
</template>
<!-- checkin form-->
<template id="portal_my_precheckin_detail2" name="My Precheckin">
<t t-call="portal.portal_layout">
<form t-att-action="checkin_partner_id.get_portal_url()" method="post">
<div class="row o_portal_details">
@@ -575,6 +1068,7 @@
</script>
</template>
<!-- precheckin buttons and send invitations -->
<template id="portal_my_reservation_precheckin" name="Precheckin Reservation">
<t t-call="portal.portal_layout">
<wrap>
@@ -635,9 +1129,9 @@
<form
class="col-6 float-right"
style="margin-bottom:50px"
t-att-action="'/my/precheckin/'+str(folio.id)+'/checkin/'+str(checkin_partner_id.id)"
t-att-action="'/my/folios/'+str(folio.id)+'/reservations'"
method="post"
>
> <!--t-att-action="'/my/precheckin/'+str(folio.id)+'/checkin/'+str(checkin_partner_id.id)"-->
<input
type="text"
name="access_token"
@@ -671,27 +1165,27 @@
</button>
</form>
</div>
<!-- <center>-->
<!-- <t t-if="len(folio.checkin_partner_ids) &gt; 1">-->
<!-- <div>-->
<!-- If you wish, you can share with the rest of the guests the access to their check-in so that they can fill it out.-->
<!-- <a-->
<!-- role="button"-->
<!-- t-att-href="folio.get_portal_url(suffix='/invitations')"-->
<!-- >-->
<!-- <button-->
<!-- type="submit"-->
<!-- class="btn btn-primary"-->
<!-- style="margin-top:40px;"-->
<!-- >-->
<!-- <span class="fa fa-share-square" />-->
<!-- Send Invitations-->
<!-- </button>-->
<!-- </a>-->
<!-- </div>-->
<!-- </t>-->
<center>
<t t-if="len(folio.checkin_partner_ids) &gt; 1">
<div>
If you wish, you can share with the rest of the guests the access to their check-in so that they can fill it out.
<a
role="button"
t-att-href="folio.get_portal_url(suffix='/invitations')"
>
<button
type="submit"
class="btn btn-primary"
style="margin-top:40px;"
>
<span class="fa fa-share-square" />
Send Invitations
</button>
</a>
</div>
</t>
<!-- </center>-->
</center>
<div
class="oe_structure"
id="oe_structure_website_form_reservation_precheckin_2"
@@ -702,6 +1196,7 @@
</style>
</template>
<!-- invitations -->
<template id="portal_my_folio_invitations" name="Precheckin Folio">
<t t-call="portal.portal_layout">
<t t-if="not folio.reservation_ids">
@@ -977,6 +1472,7 @@
}
</script>
</template>
<!--thanks for complete precheckin-->
<template id="portal_my_precheckin_end" name="Precheckin End">
<t t-call="portal.portal_layout">
<wrap>
@@ -1033,6 +1529,7 @@
</t>
<style />
</template>
<!-- checkin not available -->
<template id="portal_not_checkin" name="Not Checkin">
<wrap>
<div class="oe_structure" id="oe_structure_website_form_no_precheckin_1" />

View File

@@ -7,13 +7,9 @@
<div t-attf-class="form-group col-md-6">
<label class="col-form-label" for="document_type">Doc. Type</label>
<div class="d-none"><p id="docTypeId"><t
t-esc="checkin_partner_id.document_type"
t-esc="checkin_partner.document_type"
/></p></div>
<select
class="form-control #{error.get('document_type') and 'is-invalid' or ''}"
name='document_type'
id="doc_type"
>
<select class="form-control" name='document_type' id="doc_type">
<option value="">Select an option</option>
<t t-foreach="doc_type_ids" t-as='doc_type'>
<option
@@ -24,29 +20,24 @@
</option>
</t>
</select>
<t t-if="error_message">
<!--<t t-if="error_message">
<span
class="text-danger"
t-esc="error_message.get('document_type')"
/>
</t>
</t>-->
</div>
</xpath>
<xpath expr="//div[@name='document_number_div']" position="replace">
<div t-attf-class="col-12 col-md-6">
<label class="col-form-label" for="document_number">Doc. Number</label>
<input
type="text"
name="document_number"
t-attf-class="form-control #{error.get('document_number') and 'is-invalid' or ''}"
t-att-value="document_number if document_number and error else ''"
/>
<t t-if="error_message">
<input type="text" name="document_number" t-attf-class="form-control" />
<!--<t t-if="error_message">
<span
class="text-danger"
t-esc="error_message.get('document_number')"
/>
</t>
</t>-->
</div>
</xpath>
</template>