mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
@@ -1,2 +1,3 @@
|
|||||||
partner-contact
|
partner-contact
|
||||||
reporting-engine
|
reporting-engine
|
||||||
|
queue
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
from . import models
|
from . import models
|
||||||
|
from . import wizards
|
||||||
|
|||||||
@@ -15,10 +15,23 @@
|
|||||||
"partner_second_lastname",
|
"partner_second_lastname",
|
||||||
"partner_contact_gender",
|
"partner_contact_gender",
|
||||||
"partner_contact_birthdate",
|
"partner_contact_birthdate",
|
||||||
|
"partner_contact_nationality",
|
||||||
|
"queue_job",
|
||||||
],
|
],
|
||||||
|
"external_dependencies": {
|
||||||
|
"python": [
|
||||||
|
"bs4",
|
||||||
|
],
|
||||||
|
},
|
||||||
"data": [
|
"data": [
|
||||||
|
"data/cron_jobs.xml",
|
||||||
|
"data/queue_data.xml",
|
||||||
|
"data/queue_job_function_data.xml",
|
||||||
|
"security/ir.model.access.csv",
|
||||||
"views/pms_checkin_partner_views.xml",
|
"views/pms_checkin_partner_views.xml",
|
||||||
|
"views/pms_property_views.xml",
|
||||||
"views/res_partner_views.xml",
|
"views/res_partner_views.xml",
|
||||||
|
"wizards/traveller_report.xml",
|
||||||
],
|
],
|
||||||
"installable": True,
|
"installable": True,
|
||||||
}
|
}
|
||||||
|
|||||||
21
pms_l10n_es/data/cron_jobs.xml
Normal file
21
pms_l10n_es/data/cron_jobs.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
<record model="ir.cron" id="autosend_traveller_report">
|
||||||
|
<field name="name">Automatic Send Traveller Report</field>
|
||||||
|
<field name="active" eval="True" />
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="user_id" ref="base.user_root" />
|
||||||
|
<field name="interval_type">days</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field name="doall" eval="False" />
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="model_id" ref="model_traveller_report_wizard" />
|
||||||
|
<field
|
||||||
|
name="nextcall"
|
||||||
|
eval="datetime.now(pytz.timezone('UTC')).strftime('%Y-%m-%d 03:00:00')"
|
||||||
|
/>
|
||||||
|
<field name="code">model.send_file_gc_async()</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
9
pms_l10n_es/data/queue_data.xml
Normal file
9
pms_l10n_es/data/queue_data.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="channel_gc_file_send" model="queue.job.channel">
|
||||||
|
<field name="name">gc_file_send</field>
|
||||||
|
<field name="parent_id" ref="queue_job.channel_root" />
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
12
pms_l10n_es/data/queue_job_function_data.xml
Normal file
12
pms_l10n_es/data/queue_job_function_data.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo noupdate="1">
|
||||||
|
<record
|
||||||
|
id="traveller_report_send_file_async_job_function"
|
||||||
|
model="queue.job.function"
|
||||||
|
>
|
||||||
|
<field name="model_id" ref="pms_l10n_es.model_traveller_report_wizard" />
|
||||||
|
<field name="method">send_file_async</field>
|
||||||
|
<field name="channel_id" ref="pms_l10n_es.channel_gc_file_send" />
|
||||||
|
<field name="retry_pattern" eval="{1: 10, 5: 30, 10: 60, 15: 300}" />
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
from . import res_partner
|
from . import res_partner
|
||||||
from . import pms_checkin_partner
|
from . import pms_checkin_partner
|
||||||
|
from . import pms_property
|
||||||
|
|||||||
@@ -62,12 +62,13 @@ class PmsCheckinPartner(models.Model):
|
|||||||
store=True,
|
store=True,
|
||||||
readonly=False,
|
readonly=False,
|
||||||
)
|
)
|
||||||
|
nationality_id = fields.Many2one(
|
||||||
@api.depends("partner_id", "partner_id.lastname")
|
string="Nationality ID",
|
||||||
def _compute_lastname(self):
|
compute="_compute_nationality",
|
||||||
for record in self:
|
comodel_name="res.country",
|
||||||
if not record.lastname:
|
store=True,
|
||||||
record.lastname = record.partner_id.lastname
|
readonly=False,
|
||||||
|
)
|
||||||
|
|
||||||
@api.depends("partner_id", "partner_id.firstname")
|
@api.depends("partner_id", "partner_id.firstname")
|
||||||
def _compute_firstname(self):
|
def _compute_firstname(self):
|
||||||
@@ -75,6 +76,12 @@ class PmsCheckinPartner(models.Model):
|
|||||||
if not record.firstname:
|
if not record.firstname:
|
||||||
record.firstname = record.partner_id.firstname
|
record.firstname = record.partner_id.firstname
|
||||||
|
|
||||||
|
@api.depends("partner_id", "partner_id.lastname")
|
||||||
|
def _compute_lastname(self):
|
||||||
|
for record in self:
|
||||||
|
if not record.lastname:
|
||||||
|
record.lastname = record.partner_id.lastname
|
||||||
|
|
||||||
@api.depends("partner_id", "partner_id.lastname2")
|
@api.depends("partner_id", "partner_id.lastname2")
|
||||||
def _compute_lastname2(self):
|
def _compute_lastname2(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
@@ -113,6 +120,12 @@ class PmsCheckinPartner(models.Model):
|
|||||||
if not record.gender:
|
if not record.gender:
|
||||||
record.gender = record.partner_id.gender
|
record.gender = record.partner_id.gender
|
||||||
|
|
||||||
|
@api.depends("partner_id", "partner_id.lastname")
|
||||||
|
def _compute_nationality(self):
|
||||||
|
for record in self:
|
||||||
|
if not record.nationality_id:
|
||||||
|
record.nationality_id = record.partner_id.nationality_id
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _checkin_mandatory_fields(self, depends=False):
|
def _checkin_mandatory_fields(self, depends=False):
|
||||||
mandatory_fields = super(PmsCheckinPartner, self)._checkin_mandatory_fields(
|
mandatory_fields = super(PmsCheckinPartner, self)._checkin_mandatory_fields(
|
||||||
@@ -120,7 +133,6 @@ class PmsCheckinPartner(models.Model):
|
|||||||
)
|
)
|
||||||
mandatory_fields.extend(
|
mandatory_fields.extend(
|
||||||
[
|
[
|
||||||
"lastname2",
|
|
||||||
"birthdate_date",
|
"birthdate_date",
|
||||||
"document_number",
|
"document_number",
|
||||||
"document_type",
|
"document_type",
|
||||||
|
|||||||
98
pms_l10n_es/models/pms_property.py
Normal file
98
pms_l10n_es/models/pms_property.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup as bs
|
||||||
|
|
||||||
|
from odoo import _, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from odoo.modules import get_module_resource
|
||||||
|
|
||||||
|
|
||||||
|
class PmsProperty(models.Model):
|
||||||
|
_inherit = "pms.property"
|
||||||
|
|
||||||
|
institution = fields.Selection(
|
||||||
|
[
|
||||||
|
("guardia_civil", "Guardia Civil"),
|
||||||
|
("policia_nacional", "Policía Nacional (soon)"),
|
||||||
|
("ertxaintxa", "Ertxaintxa (soon)"),
|
||||||
|
("mossos", "Mossos_d'esquadra (soon)"),
|
||||||
|
],
|
||||||
|
string="Institution",
|
||||||
|
default="guardia_civil",
|
||||||
|
help="Institution to send daily guest data.",
|
||||||
|
)
|
||||||
|
institution_property_id = fields.Char(
|
||||||
|
string="Institution property id",
|
||||||
|
size=10,
|
||||||
|
help="Id provided by institution to send data from property.",
|
||||||
|
)
|
||||||
|
institution_user = fields.Char(
|
||||||
|
string="Institution user", help="User provided by institution to send the data."
|
||||||
|
)
|
||||||
|
institution_password = fields.Char(
|
||||||
|
string="Institution password",
|
||||||
|
help="Password provided by institution to send the data.",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_gc_connection(self):
|
||||||
|
for pms_property in self:
|
||||||
|
if (
|
||||||
|
pms_property.institution == "guardia_civil"
|
||||||
|
and pms_property.institution_property_id
|
||||||
|
and pms_property.institution_user
|
||||||
|
and pms_property.institution_password
|
||||||
|
):
|
||||||
|
|
||||||
|
url = "https://hospederias.guardiacivil.es/"
|
||||||
|
login_route = "/hospederias/login.do"
|
||||||
|
logout_route = "/hospederias/logout.do"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 "
|
||||||
|
"Build/MRA58N) AppleWebKit/537.36 (KHTML, like "
|
||||||
|
"Gecko) Chrome/90.0.4430.93 Mobile Safari/537.36",
|
||||||
|
}
|
||||||
|
session = requests.session()
|
||||||
|
login_payload = {
|
||||||
|
"usuario": pms_property.institution_user,
|
||||||
|
"pswd": pms_property.institution_password,
|
||||||
|
}
|
||||||
|
|
||||||
|
# login
|
||||||
|
response_login = session.post(
|
||||||
|
url + login_route,
|
||||||
|
headers=headers,
|
||||||
|
data=login_payload,
|
||||||
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
|
)
|
||||||
|
time.sleep(1)
|
||||||
|
# logout
|
||||||
|
session.get(
|
||||||
|
url + logout_route,
|
||||||
|
headers=headers,
|
||||||
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
|
)
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
# check if authentication was successful / unsuccessful or the
|
||||||
|
# resource cannot be accessed
|
||||||
|
soup = bs(response_login.text, "html.parser")
|
||||||
|
errors = soup.select("#txterror > ul > li")
|
||||||
|
if errors:
|
||||||
|
raise ValidationError(errors[0].text)
|
||||||
|
else:
|
||||||
|
login_correct = soup.select(".cabecera2")
|
||||||
|
if login_correct:
|
||||||
|
message = {
|
||||||
|
"type": "ir.actions.client",
|
||||||
|
"tag": "display_notification",
|
||||||
|
"params": {
|
||||||
|
"title": _("Connection Established!"),
|
||||||
|
"message": _("Connection established succesfully"),
|
||||||
|
"sticky": False,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
else:
|
||||||
|
raise ValidationError(_("Connection could not be established"))
|
||||||
2
pms_l10n_es/security/ir.model.access.csv
Normal file
2
pms_l10n_es/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
user_access_traveller_report_wizard,user_access_traveller_report_wizard,model_traveller_report_wizard,pms.group_pms_user,1,1,1,1
|
||||||
|
104
pms_l10n_es/static/cert.pem
Normal file
104
pms_l10n_es/static/cert.pem
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIIwDCCB6igAwIBAgIQGBMhPyx6Rolez7EMhDFA1jANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG
|
||||||
|
EwJFUzERMA8GA1UECgwIRk5NVC1SQ00xJTAjBgNVBAsMHEFDIENvbXBvbmVudGVzIEluZm9ybcOh
|
||||||
|
dGljb3MwHhcNMjAwNTI4MTIzOTQwWhcNMjIwNTI4MTIzOTM5WjCBmDELMAkGA1UEBhMCRVMxDzAN
|
||||||
|
BgNVBAcMBk1BRFJJRDEuMCwGA1UECgwlRElSRUNDSU9OIEdFTkVSQUwgREUgTEEgR1VBUkRJQSBD
|
||||||
|
SVZJTDESMBAGA1UEBRMJUzI4MTYwMDNEMRgwFgYDVQRhDA9WQVRFUy1TMjgxNjAwM0QxGjAYBgNV
|
||||||
|
BAMMESouZ3VhcmRpYWNpdmlsLmVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApA++
|
||||||
|
/lNaimrEGvflr1eNHDDLmEZF/FKIA9Bd9YJnieciGg+3ZJ9/Kd99eV1V9zIgfdSLLDucMeflp6s6
|
||||||
|
8v563u4+zX7AgREB539rKAaCUwtqVcutZROL+NIjkoHHtMHgMlCbbQaKC32n8awaB0YRNGI+eLMJ
|
||||||
|
4u7X2iBR1OohEjGFa1xfDS2UHOeWsxW5eDPGhK3iaDSHmcy1jtIGVmas4YtcNFRf/8y2v2I2QqHY
|
||||||
|
2l7IbiDMAdSW2nPme/5HZXvIlkDdD4SG17xhIAe1uPEBKd0g6lt89OLCFetNwcRaqjFtA5DrpmiQ
|
||||||
|
0hqHQTk8AST6ibpRvAZCKvln+uXNWcDDywIDAQABo4IFVDCCBVAwDAYDVR0TAQH/BAIwADCBgQYI
|
||||||
|
KwYBBQUHAQEEdTBzMDsGCCsGAQUFBzABhi9odHRwOi8vb2NzcGNvbXAuY2VydC5mbm10LmVzL29j
|
||||||
|
c3AvT2NzcFJlc3BvbmRlcjA0BggrBgEFBQcwAoYoaHR0cDovL3d3dy5jZXJ0LmZubXQuZXMvY2Vy
|
||||||
|
dHMvQUNDT01QLmNydDCCASgGA1UdIASCAR8wggEbMIIBDQYKKwYBBAGsZgMJETCB/jApBggrBgEF
|
||||||
|
BQcCARYdaHR0cDovL3d3dy5jZXJ0LmZubXQuZXMvZHBjcy8wgdAGCCsGAQUFBwICMIHDDIHAQ2Vy
|
||||||
|
dGlmaWNhZG8gd2lsZGNhcmQgZGUgYXV0ZW50aWNhY2nDs24gZGUgc2l0aW8gd2ViIHNlZ8O6biBy
|
||||||
|
ZWdsYW1lbnRvIGV1cm9wZW8gZUlEQVMuIFN1amV0byBhIGNvbmRpY2lvbmVzIGRlIHVzbyBzZWfD
|
||||||
|
um4gRFBDIGRlIEZOTVQtUkNNLCBOSUY6IFEyODI2MDA0LUogKEMvSm9yZ2UgSnVhbiAxMDYtMjgw
|
||||||
|
MDktTWFkcmlkLUVzcGHDsWEpMAgGBgQAj3oBBzAcBgNVHREEFTATghEqLmd1YXJkaWFjaXZpbC5l
|
||||||
|
czATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFEMrHDu3J/7S
|
||||||
|
OVend+G0LsfbflPRMIGmBggrBgEFBQcBAwSBmTCBljALBgYEAI5GAQMCAQ8wEwYGBACORgEGMAkG
|
||||||
|
BwQAjkYBBgMwcgYGBACORgEFMGgwMhYsaHR0cHM6Ly93d3cuY2VydC5mbm10LmVzL3Bkcy9QRFNf
|
||||||
|
Q09NUF9lcy5wZGYTAmVzMDIWLGh0dHBzOi8vd3d3LmNlcnQuZm5tdC5lcy9wZHMvUERTX0NPTVBf
|
||||||
|
ZW4ucGRmEwJlbjAfBgNVHSMEGDAWgBQZ+FgvFNamzJsEmAgNTNerAKeDZTCB4AYDVR0fBIHYMIHV
|
||||||
|
MIHSoIHPoIHMhoGebGRhcDovL2xkYXBjb21wLmNlcnQuZm5tdC5lcy9DTj1DUkwxLE9VPUFDJTIw
|
||||||
|
Q29tcG9uZW50ZXMlMjBJbmZvcm1hdGljb3MsTz1GTk1ULVJDTSxDPUVTP2NlcnRpZmljYXRlUmV2
|
||||||
|
b2NhdGlvbkxpc3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Y2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSG
|
||||||
|
KWh0dHA6Ly93d3cuY2VydC5mbm10LmVzL2NybHNjb21wL0NSTDEuY3JsMIIBfwYKKwYBBAHWeQIE
|
||||||
|
AgSCAW8EggFrAWkAdwApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAAAXJbS5kkAAAE
|
||||||
|
AwBIMEYCIQDxUFJkb+yYGmvDckxbKLZvcycZmEvAX6g8GH3jqr7RjAIhAOshzUdC84VntNxq56Dx
|
||||||
|
160eCj65UVL9A64z7hnXnUKBAHYARqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUcAAAFy
|
||||||
|
W0ua9gAABAMARzBFAiEAj3S5/JDapowZIsHUOFXQuxxb26oIhOy/YfNLZI01pQMCIEN8b4AxHp9Z
|
||||||
|
mj8StFvP4/YLqvYgQbhgewCvFExlsRtVAHYAQcjKsd8iRkoQxqE6CUKHXk4xixsD6+tLx2jwkGKW
|
||||||
|
BvYAAAFyW0ucLAAABAMARzBFAiEAt+XKebp1KrEamXlKU2VkKt6lsRiylbNFTCTpGm5GAP8CIEUT
|
||||||
|
WXZee7o83zyXQ9nBy0t8TcRtI70vuheLQ909va6dMA0GCSqGSIb3DQEBCwUAA4IBAQBJAplPXRRv
|
||||||
|
b4nLZFqQvQjHlr0TSKTiC21vAzXe/1iiuPOPZF3AE1ZcOMEqiPWTN6GOR3UYksZE2Cfm0xqNOytr
|
||||||
|
bj/INmu5tX5U7yvGQxiB8EdHaTdQQknAi/IBEx0KJE+EAT+upOPYbne5km1lffN19WwQ2f3ybAbj
|
||||||
|
l5ZpWR6lSuV3JStUllHAS/0HjwBbqHhxJZ2BTG4Ca5SkHnbK/K1mfwLe2VGVYp7WWUzKkSQQ8Hs0
|
||||||
|
RuY9EZ0sovRH7lL/EIf7uV/5d1V4kW1h7F38jEPDH4UVTHDMMaR9NV/4pES0zQnI6y5NJCiRP39k
|
||||||
|
GFyKTE/4x7pFeIFnXXIwswUWFA9h
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIG1jCCBL6gAwIBAgIQNMarBE42mRJRyCULbJTWwDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQG
|
||||||
|
EwJFUzERMA8GA1UECgwIRk5NVC1SQ00xGTAXBgNVBAsMEEFDIFJBSVogRk5NVC1SQ00wHhcNMTMw
|
||||||
|
NjI0MTA1MjU5WhcNMjgwNjI0MTA1MjU5WjBHMQswCQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1S
|
||||||
|
Q00xJTAjBgNVBAsMHEFDIENvbXBvbmVudGVzIEluZm9ybcOhdGljb3MwggEiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4IBDwAwggEKAoIBAQCXVx8rdbF7/xY44CaSqzzGo5BhvzA8knxC/3KJYVzTf+CkOvMxMUDu
|
||||||
|
b8b0h38MDujm/RKZhBNOWbKhxF3U61ZVhcR9xOCciuS/soT80m3BByxAKcZsNka0jCA4XRkglDaA
|
||||||
|
FxCHEZ06MOnvXsSOZDfPYahbQ3VFCVycJuhlHdAwSpmceQwcRYkR6YgXwTiyzCNGivMKAmRS3dIt
|
||||||
|
qDOmDW/nxiDFq/Jd8VWY7GFkwbbAeqYId8FjN8zfvafunsB9SLFkUjPPMeqfmC7Bdh7HMxLpaOXR
|
||||||
|
OwH201cmlebiPkn0xSFxXFqwhhr6yN8UQYZ3O/+xdHLrS6DS9+CJUF6d09ijAgMBAAGjggLIMIIC
|
||||||
|
xDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUGfhYLxTWpsyb
|
||||||
|
BJgIDUzXqwCng2UwgZgGCCsGAQUFBwEBBIGLMIGIMEkGCCsGAQUFBzABhj1odHRwOi8vb2NzcGZu
|
||||||
|
bXRyY21jYS5jZXJ0LmZubXQuZXMvb2NzcGZubXRyY21jYS9PY3NwUmVzcG9uZGVyMDsGCCsGAQUF
|
||||||
|
BzAChi9odHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9jZXJ0cy9BQ1JBSVpGTk1UUkNNLmNydDAfBgNV
|
||||||
|
HSMEGDAWgBT3fcX9xOiaG3dkp/UdoMy/h2CabTCB6wYDVR0gBIHjMIHgMIHdBgRVHSAAMIHUMCkG
|
||||||
|
CCsGAQUFBwIBFh1odHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzCBpgYIKwYBBQUHAgIwgZkM
|
||||||
|
gZZTdWpldG8gYSBsYXMgY29uZGljaW9uZXMgZGUgdXNvIGV4cHVlc3RhcyBlbiBsYSBEZWNsYXJh
|
||||||
|
Y2nDs24gZGUgUHLDoWN0aWNhcyBkZSBDZXJ0aWZpY2FjacOzbiBkZSBsYSBGTk1ULVJDTSAoIEMv
|
||||||
|
IEpvcmdlIEp1YW4sIDEwNi0yODAwOS1NYWRyaWQtRXNwYcOxYSkwgdQGA1UdHwSBzDCByTCBxqCB
|
||||||
|
w6CBwIaBkGxkYXA6Ly9sZGFwZm5tdC5jZXJ0LmZubXQuZXMvQ049Q1JMLE9VPUFDJTIwUkFJWiUy
|
||||||
|
MEZOTVQtUkNNLE89Rk5NVC1SQ00sQz1FUz9hdXRob3JpdHlSZXZvY2F0aW9uTGlzdDtiaW5hcnk/
|
||||||
|
YmFzZT9vYmplY3RjbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludIYraHR0cDovL3d3dy5jZXJ0LmZu
|
||||||
|
bXQuZXMvY3Jscy9BUkxGTk1UUkNNLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAo2bsQ2xLDcyodieq
|
||||||
|
jd+uy/lfxDw/MbrAq/ZaNFkIlcypUYamOM4vrm5rz8oLjPCoLkJ48P+nP08Gkcl5Q6q6VFcZLia+
|
||||||
|
U3gfHXrkyqToQlrtViGCGH3xA4u56XtMHGXSdk9vQ0yDnW5f7bUEkp+uvcKewrOvNcpbIAgD4eU7
|
||||||
|
gdOS0w7BagcFRBgTKBw2s3z73fRZtouJg/atmWYtXbBsfNjph+pCh+h5sbSyZUVzO5AemyjpYYYN
|
||||||
|
MWDQrTXq+7O8zIPuPaNESjEexuzn+VjHG90RlUK1LygARi+Ir0opD2w6erb/hK8Eea7MFdKQ2ASq
|
||||||
|
NBGJggNo5vfPVvjHiL+Antmh7mQSKL+4YwFU64d4KK9k0C1mbJethDQFKcjTK1vMvnXFiupsIuyT
|
||||||
|
qwKauo7u2zMKzY4r3VYOW9TpMyLPFIY8pII5GyNzXlL0F4nscOvduTEPEYqxeNJfpDDPY/DO8Wfx
|
||||||
|
gdRTy2W3D/UoAulb+Y+nuzGGCtFQrsSMQX487R+aY0nWot/hajef6BcPuxhDfQrg5IafrISVmcJA
|
||||||
|
plb3tXhh0sz7RbYz6jf1bke4eU5fnrTMtGlVteUL2vjrfUPHW07kBJuaQ7sxORNV3bpHisOnHj+A
|
||||||
|
riQzCn5vINpSHW6hTm7IfRkbltu/aQrsMuUhP7HE/v+uXe5CuboV5ubZhHU=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -7,12 +7,14 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="//field[@name='partner_id']" position="after">
|
<xpath expr="//field[@name='partner_id']" position="after">
|
||||||
|
<field name="lastname" />
|
||||||
<field name="lastname2" />
|
<field name="lastname2" />
|
||||||
<field name="gender" />
|
<field name="gender" />
|
||||||
<field name="birthdate_date" />
|
<field name="birthdate_date" />
|
||||||
<field name="document_type" />
|
<field name="document_type" />
|
||||||
<field name="document_number" />
|
<field name="document_number" />
|
||||||
<field name="document_expedition_date" />
|
<field name="document_expedition_date" />
|
||||||
|
<field name="nationality_id" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
<field name="document_type" />
|
<field name="document_type" />
|
||||||
<field name="document_number" />
|
<field name="document_number" />
|
||||||
<field name="document_expedition_date" />
|
<field name="document_expedition_date" />
|
||||||
|
<field name="nationality_id" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
@@ -51,6 +54,7 @@
|
|||||||
<field name="document_type" />
|
<field name="document_type" />
|
||||||
<field name="document_number" />
|
<field name="document_number" />
|
||||||
<field name="document_expedition_date" />
|
<field name="document_expedition_date" />
|
||||||
|
<field name="nationality_id" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
@@ -70,11 +74,11 @@
|
|||||||
<field name="document_type" />
|
<field name="document_type" />
|
||||||
<field name="document_number" />
|
<field name="document_number" />
|
||||||
<field name="document_expedition_date" />
|
<field name="document_expedition_date" />
|
||||||
|
<field name="nationality_id" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="pms_checkin_partner_view_search" model="ir.ui.view">
|
<record id="pms_checkin_partner_view_search" model="ir.ui.view">
|
||||||
<field name="name">Checkin partner view tree Spain</field>
|
<field name="name">Checkin partner view tree Spain</field>
|
||||||
<field name="model">pms.checkin.partner</field>
|
<field name="model">pms.checkin.partner</field>
|
||||||
@@ -93,6 +97,4 @@
|
|||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
40
pms_l10n_es/views/pms_property_views.xml
Normal file
40
pms_l10n_es/views/pms_property_views.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<!-- Hotel Settings -->
|
||||||
|
<record id="view_property_form_pms_l10n_es" model="ir.ui.view">
|
||||||
|
<field name="name">Property Form l10n_es</field>
|
||||||
|
<field name="model">pms.property</field>
|
||||||
|
<field name="inherit_id" ref="pms.pms_property_views_form" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//page[@name='property_settings']" position="inside">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="o_horizontal_separator">
|
||||||
|
Guest information sending settings
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<group name="property_data">
|
||||||
|
<field name="institution" />
|
||||||
|
<field name="institution_property_id" />
|
||||||
|
</group>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 px-0">
|
||||||
|
<group name="property_data">
|
||||||
|
<field name="institution_user" />
|
||||||
|
<field name="institution_password" password="True" />
|
||||||
|
</group>
|
||||||
|
<button
|
||||||
|
name="test_gc_connection"
|
||||||
|
class="btn btn-primary btn-sm"
|
||||||
|
type="object"
|
||||||
|
string="Test user/password"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
1
pms_l10n_es/wizards/__init__.py
Normal file
1
pms_l10n_es/wizards/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import traveller_report
|
||||||
237
pms_l10n_es/wizards/traveller_report.py
Normal file
237
pms_l10n_es/wizards/traveller_report.py
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
import base64
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup as bs
|
||||||
|
|
||||||
|
from odoo import _, api, fields, models
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from odoo.modules.module import get_module_resource
|
||||||
|
|
||||||
|
|
||||||
|
class TravellerReport(models.TransientModel):
|
||||||
|
_name = "traveller.report.wizard"
|
||||||
|
_description = "Traveller Report"
|
||||||
|
|
||||||
|
txt_filename = fields.Text()
|
||||||
|
txt_binary = fields.Binary(string="File Download")
|
||||||
|
txt_message = fields.Char(string="File Preview")
|
||||||
|
|
||||||
|
def generate_file(self):
|
||||||
|
|
||||||
|
# get the active property
|
||||||
|
pms_property = self.env["pms.property"].search(
|
||||||
|
[("id", "=", self.env.user.get_active_property_ids()[0])]
|
||||||
|
)
|
||||||
|
|
||||||
|
# build content
|
||||||
|
content = self.generate_checkin_list(pms_property.id)
|
||||||
|
|
||||||
|
if not pms_property.institution_property_id:
|
||||||
|
raise ValidationError(
|
||||||
|
_("The guest information sending settings is not property updated.")
|
||||||
|
)
|
||||||
|
elif not content:
|
||||||
|
raise ValidationError(_("There is no guest information to send."))
|
||||||
|
else:
|
||||||
|
# file creation
|
||||||
|
txt_binary = self.env["traveller.report.wizard"].create(
|
||||||
|
{
|
||||||
|
"txt_filename": pms_property.institution_property_id + ".999",
|
||||||
|
"txt_binary": base64.b64encode(str.encode(content)),
|
||||||
|
"txt_message": content,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"name": _("Traveller Report"),
|
||||||
|
"res_id": txt_binary.id,
|
||||||
|
"res_model": "traveller.report.wizard",
|
||||||
|
"target": "new",
|
||||||
|
"type": "ir.actions.act_window",
|
||||||
|
"view_id": self.env.ref("pms_l10n_es.traveller_report_wizard").id,
|
||||||
|
"view_mode": "form",
|
||||||
|
"view_type": "form",
|
||||||
|
}
|
||||||
|
|
||||||
|
def generate_checkin_list(self, property_id):
|
||||||
|
|
||||||
|
# check if there's guests info pending to send
|
||||||
|
if self.env["pms.checkin.partner"].search_count(
|
||||||
|
[
|
||||||
|
("state", "=", "onboard"),
|
||||||
|
("arrival", ">=", str(date.today()) + " 0:00:00"),
|
||||||
|
("arrival", "<=", str(date.today()) + " 23:59:59"),
|
||||||
|
]
|
||||||
|
):
|
||||||
|
|
||||||
|
# get the active property
|
||||||
|
pms_property = self.env["pms.property"].search([("id", "=", property_id)])
|
||||||
|
|
||||||
|
# check if the GC configuration info is properly set
|
||||||
|
if not (
|
||||||
|
pms_property.name
|
||||||
|
and pms_property.institution_property_id
|
||||||
|
and pms_property.institution_user
|
||||||
|
and pms_property.institution_password
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
_("Check the GC configuration to send the guests info")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# get checkin partners info to send
|
||||||
|
lines = self.env["pms.checkin.partner"].search(
|
||||||
|
[
|
||||||
|
("state", "=", "onboard"),
|
||||||
|
("arrival", ">=", str(date.today()) + " 0:00:00"),
|
||||||
|
("arrival", "<=", str(date.today()) + " 23:59:59"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# build the property info record
|
||||||
|
# 1 | property id | property name | date | nº of checkin partners
|
||||||
|
|
||||||
|
content = (
|
||||||
|
"1|"
|
||||||
|
+ pms_property.institution_property_id.upper()
|
||||||
|
+ "|"
|
||||||
|
+ pms_property.name.upper()
|
||||||
|
+ "|"
|
||||||
|
+ datetime.datetime.now().strftime("%Y%m%d|%H%M")
|
||||||
|
+ "|"
|
||||||
|
+ str(len(lines))
|
||||||
|
+ "\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
# build each checkin partner line's record
|
||||||
|
# 2|DNI nº|Doc.number|doc.type|exp.date|lastname|lastname2|name|...
|
||||||
|
# ...gender|birthdate|nation.|checkin
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
content += "2"
|
||||||
|
# [P|N|..]
|
||||||
|
if line.document_type != "D":
|
||||||
|
content += "||" + line.document_number.upper() + "|"
|
||||||
|
else:
|
||||||
|
content += "|" + line.document_number.upper() + "||"
|
||||||
|
content += line.document_type + "|"
|
||||||
|
content += line.document_expedition_date.strftime("%Y%m%d") + "|"
|
||||||
|
content += line.lastname.upper() + "|"
|
||||||
|
if line.lastname2:
|
||||||
|
content += line.lastname2.upper()
|
||||||
|
content += "|" + line.firstname.upper() + "|"
|
||||||
|
if line.gender == "female":
|
||||||
|
content += "F|"
|
||||||
|
else:
|
||||||
|
content += "M|"
|
||||||
|
content += line.birthdate_date.strftime("%Y%m%d") + "|"
|
||||||
|
content += line.nationality_id.name.upper() + "|"
|
||||||
|
content += line.arrival.strftime("%Y%m%d") + "\n"
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def send_file_gc(self, pms_property=False):
|
||||||
|
url = "https://hospederias.guardiacivil.es/"
|
||||||
|
login_route = "/hospederias/login.do"
|
||||||
|
upload_file_route = "/hospederias/cargaFichero.do"
|
||||||
|
logout_route = "/hospederias/logout.do"
|
||||||
|
called_from_user = False
|
||||||
|
if not pms_property:
|
||||||
|
called_from_user = True
|
||||||
|
# get the active property
|
||||||
|
pms_property = self.env["pms.property"].search(
|
||||||
|
[("id", "=", self.env.user.get_active_property_ids()[0])]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not (
|
||||||
|
pms_property
|
||||||
|
and pms_property.institution_property_id
|
||||||
|
and pms_property.institution_user
|
||||||
|
and pms_property.institution_password
|
||||||
|
):
|
||||||
|
raise ValidationError(
|
||||||
|
_("The guest information sending settings is not complete.")
|
||||||
|
)
|
||||||
|
|
||||||
|
content = self.generate_checkin_list(pms_property.id)
|
||||||
|
|
||||||
|
if content:
|
||||||
|
headers = {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 "
|
||||||
|
"Build/MRA58N) AppleWebKit/537.36 (KHTML, like "
|
||||||
|
"Gecko) Chrome/90.0.4430.93 Mobile Safari/537.36",
|
||||||
|
}
|
||||||
|
session = requests.session()
|
||||||
|
login_payload = {
|
||||||
|
"usuario": pms_property.institution_user,
|
||||||
|
"pswd": pms_property.institution_password,
|
||||||
|
}
|
||||||
|
|
||||||
|
# login
|
||||||
|
response_login = session.post(
|
||||||
|
url + login_route,
|
||||||
|
headers=headers,
|
||||||
|
data=login_payload,
|
||||||
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# check if authentication was successful / unsuccessful or the
|
||||||
|
# resource cannot be accessed
|
||||||
|
soup = bs(response_login.text, "html.parser")
|
||||||
|
errors_login = soup.select("#txterror > ul > li")
|
||||||
|
if errors_login:
|
||||||
|
raise ValidationError(errors_login[0].text)
|
||||||
|
else:
|
||||||
|
login_correct = soup.select(".cabecera2")
|
||||||
|
if not login_correct:
|
||||||
|
session.close()
|
||||||
|
raise ValidationError(_("Connection could not be established"))
|
||||||
|
|
||||||
|
# build the file to send
|
||||||
|
files = {"fichero": (pms_property.institution_user + ".999", content)}
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# send file
|
||||||
|
response_file_sent = session.post(
|
||||||
|
url + upload_file_route,
|
||||||
|
data={"autoSeq": "on"},
|
||||||
|
files=files,
|
||||||
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
# logout & close connection
|
||||||
|
session.get(
|
||||||
|
url + logout_route,
|
||||||
|
headers=headers,
|
||||||
|
verify=get_module_resource("pms_l10n_es", "static", "cert.pem"),
|
||||||
|
)
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
# check if the file send has been correct
|
||||||
|
soup = bs(response_file_sent.text, "html.parser")
|
||||||
|
errors = soup.select("#errores > tbody > tr")
|
||||||
|
if errors:
|
||||||
|
msg = "Errores en el fichero:\n"
|
||||||
|
for e in errors:
|
||||||
|
msg += "Error en línea " + e.select("a")[0].text + ": "
|
||||||
|
msg += e.select("a")[2].text + "\n"
|
||||||
|
raise ValidationError(msg)
|
||||||
|
else:
|
||||||
|
if called_from_user:
|
||||||
|
message = {
|
||||||
|
"type": "ir.actions.client",
|
||||||
|
"tag": "display_notification",
|
||||||
|
"params": {
|
||||||
|
"title": _("Sent succesfully!"),
|
||||||
|
"message": _("Successful file sending"),
|
||||||
|
"sticky": False,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def send_file_gc_async(self):
|
||||||
|
for prop in self.env["pms.property"].search([]):
|
||||||
|
self.with_delay().send_file_gc(prop)
|
||||||
62
pms_l10n_es/wizards/traveller_report.xml
Normal file
62
pms_l10n_es/wizards/traveller_report.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="traveller_report_wizard" model="ir.ui.view">
|
||||||
|
<field name="name">Traveller Report</field>
|
||||||
|
<field name="model">traveller.report.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<field name="txt_filename" invisible="1" />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<group attrs="{'invisible': [('txt_message','=',False)]}">
|
||||||
|
<field name="txt_message" readonly="1" />
|
||||||
|
</group>
|
||||||
|
<group attrs="{'invisible': [('txt_message','=',False)]}">
|
||||||
|
<field
|
||||||
|
name="txt_binary"
|
||||||
|
filename="txt_filename"
|
||||||
|
readonly="1"
|
||||||
|
/>
|
||||||
|
</group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row ">
|
||||||
|
<div class="col-3">
|
||||||
|
<button
|
||||||
|
name="generate_file"
|
||||||
|
class="btn btn-primary btn-sm"
|
||||||
|
type="object"
|
||||||
|
string="Preview file"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<button
|
||||||
|
name="send_file_gc"
|
||||||
|
class="btn btn-primary btn-sm"
|
||||||
|
type="object"
|
||||||
|
string="Send file"
|
||||||
|
attrs="{'invisible': [('txt_message','=',False)]}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer />
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="action_traveller_report" model="ir.actions.act_window">
|
||||||
|
<field name="name">Traveller Report</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">traveller.report.wizard</field>
|
||||||
|
<field name="view_id" ref="traveller_report_wizard" />
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
id="menu_traveller_report"
|
||||||
|
name="Traveller Report"
|
||||||
|
sequence="30"
|
||||||
|
parent="pms.pms_configuration_menu"
|
||||||
|
action="action_traveller_report"
|
||||||
|
/>
|
||||||
|
</odoo>
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
# generated from manifests external_dependencies
|
# generated from manifests external_dependencies
|
||||||
|
bs4
|
||||||
xlrd
|
xlrd
|
||||||
|
|||||||
Reference in New Issue
Block a user