[ADD]pms_api_rest: OTA API configurations

This commit is contained in:
Darío Lodeiros
2023-12-31 12:01:53 +01:00
parent b807d75744
commit a07aba7188
9 changed files with 137 additions and 7 deletions

View File

@@ -21,6 +21,7 @@
"python": ["jwt", "simplejson", "marshmallow", "jose"],
},
"data": [
"security/ir.model.access.csv",
"data/sql_reports.xml",
"data/auth_jwt_validator.xml",
"data/pms_app_reset_password_template.xml",

View File

@@ -5,3 +5,4 @@ from . import sql_export
from . import pms_room_type_class
from . import account_bank_statement
from . import product_template
from . import ota_property_settings

View File

@@ -0,0 +1,34 @@
from odoo import fields, models
class OtaPropertySettings(models.Model):
_name = "ota.property.settings"
pms_property_id = fields.Many2one(
string="PMS Property",
help="PMS Property",
comodel_name="pms.property",
default=lambda self: self.env.user.get_active_property_ids()[0],
)
agency_id = fields.Many2one(
string="Partner",
help="Partner",
comodel_name="res.partner",
domain=[("is_agency", "=", True)],
)
pms_api_alowed_payments = fields.Boolean(
string="PMS API Allowed Payments",
help="PMS API Allowed Payments",
)
pms_api_payment_journal_id = fields.Many2one(
string="Payment Journal",
help="Payment Journal",
comodel_name="account.journal",
)
pms_api_payment_identifier = fields.Char(
string="Payment Identifier",
help="""
Text string used by the OTA to identify a prepaid reservation.
The string will be searched within the partnerRequests parameter.
""",
)

View File

@@ -93,3 +93,10 @@ class PmsProperty(models.Model):
string="Hotel image",
store=True,
)
ota_property_settings_ids = fields.One2many(
string="OTA Property Settings",
help="OTA Property Settings",
comodel_name="ota.property.settings",
inverse_name="pms_property_id",
)

View File

@@ -22,6 +22,17 @@ class ResUsers(models.Model):
readonly=False,
)
pms_api_client = fields.Boolean(
string="PMS API Client",
help="PMS API Client",
)
pms_api_payment_journal_id = fields.Many2one(
string="Payment Journal",
help="Payment Journal",
comodel_name="account.journal",
)
def _get_default_avail_rule_fields(self):
default_avail_rule_fields = self.env["ir.model.fields"].search(
[

View File

@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
user_access_ota_property_settings,user_access_ota_property_settings,model_ota_property_settings,pms.group_pms_user,1,0,0,0
manager_access_ota_property_settings,manager_access_ota_property_settings,model_ota_property_settings,pms.group_pms_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 user_access_ota_property_settings user_access_ota_property_settings model_ota_property_settings pms.group_pms_user 1 0 0 0
3 manager_access_ota_property_settings manager_access_ota_property_settings model_ota_property_settings pms.group_pms_manager 1 1 1 1

View File

@@ -772,12 +772,7 @@ class PmsFolioService(Component):
("ref", "ilike", transaction.reference),
]
):
# TODO: Move this to the user API payment configuration
journal = (
self.env["channel.wubook.backend"]
.search([("pms_property_id", "=", folio.pms_property_id.id)])
.wubook_journal_id
)
journal = transaction.journalId
if transaction.transactionType == "inbound":
folio.do_payment(
journal,
@@ -1438,7 +1433,7 @@ class PmsFolioService(Component):
# - Channel Manager
# - Booking Engine
# - ...
if "neobookings" in self.env.user.login:
if self.env.user.pms_api_client:
return "external_app"
return "internal_app"
@@ -1605,6 +1600,8 @@ class PmsFolioService(Component):
skip_compute_service_ids=True,
force_overbooking=True if call_type == "external_app" else False,
).write(folio_vals)
# Compute OTA transactions
pms_folio_info.transactions = self.normalize_payments_structure(pms_folio_info)
if pms_folio_info.transactions:
self.compute_transactions(folio, pms_folio_info.transactions)
# Force update availability
@@ -1618,6 +1615,54 @@ class PmsFolioService(Component):
date_to=date_to,
)
def normalize_payments_structure(self, pms_folio_info):
"""
This method use the OTA payment structure to normalize the structure
and incorporate them in the transactions datamodel param
"""
if pms_folio_info.transactions:
for transaction in pms_folio_info.transactions:
if not transaction.journalId:
ota_conf = self.env["ota.property.settings"].search(
[
("pms_property_id", "=", pms_folio_info.pmsPropertyId),
("agency_id", "=", self.env.user.partner_id.id),
]
)
transaction.journalId = ota_conf.pms_api_payment_journal_id.id
elif pms_folio_info.agencyId:
ota_conf = self.env["ota.property.settings"].search(
[
("pms_property_id", "=", pms_folio_info.pmsPropertyId),
("agency_id", "=", pms_folio_info.agencyId),
]
)
# TODO: Review where to input the data to identify payments,
# as partnerRequest in the reservation doesn't seem like the best location.
if (
ota_conf
and ota_conf.pms_api_alowed_payments
and any(
[
reservation.partnerRequests
and ota_conf.pms_api_payment_identifier
in reservation.partnerRequests
for reservation in pms_folio_info.reservations
]
)
):
journal = ota_conf.pms_api_payment_journal_id
pmsTransactionInfo = self.env.datamodels["pms.transaction.info"]
pms_folio_info.transactions = [
pmsTransactionInfo(
journalId=journal.id,
transactionType="inbound",
amount=pms_folio_info.totalPrice,
date=fields.Date.today().strftime("%Y-%m-%d"),
reference=pms_folio_info.externalReference,
)
]
def wrapper_reservations(self, folio, info_reservations):
"""
This method is used to create or update the reservations in folio

View File

@@ -90,6 +90,22 @@
</group>
</group>
</xpath>
<xpath expr="//field[@name='default_departure_hour']" position="after">
<group string="OTAs API Configuration">
<field name="ota_property_settings_ids">
<tree name="OTAs" editable="bottom">
<field name="pms_property_id" invisible="1" />
<field name="agency_id" options="{'no_create': True}" />
<field name="pms_api_alowed_payments" />
<field
name="pms_api_payment_journal_id"
options="{'no_create': True}"
/>
<field name="pms_api_payment_identifier" />
</tree>
</field>
</group>
</xpath>
</field>
</record>
</odoo>

View File

@@ -17,6 +17,18 @@
options="{'no_create': True}"
domain="['&amp;',('model_id', '=', 'pms.availability.plan.rule'), ('name', 'in', ('min_stay', 'max_stay', 'quota', 'max_stay_arrival', 'closed_arrival', 'closed', 'closed_departure', 'min_stay_arrival', 'max_avail'))]"
/>
<field
name="pms_api_client"
string="PMS API Client"
help="This user is used to PMS API's client (channel managers, precheckin apps, booking engines, etc.)"
/>
<field
name="pms_api_payment_journal_id"
string="PMS API Payment Journal"
domain="[('type', '=', 'bank')]"
help="This journal is used to PMS API's client (channel managers, precheckin apps, booking engines, etc.)"
attrs="{'invisible': [('pms_api_client', '=', False)]}"
/>
</group>
</group>
</xpath>