mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
@@ -1 +1,2 @@
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -15,10 +15,23 @@
|
||||
"partner_second_lastname",
|
||||
"partner_contact_gender",
|
||||
"partner_contact_birthdate",
|
||||
"partner_contact_nationality",
|
||||
"queue_job",
|
||||
],
|
||||
"external_dependencies": {
|
||||
"python": [
|
||||
"bs4",
|
||||
],
|
||||
},
|
||||
"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_property_views.xml",
|
||||
"views/res_partner_views.xml",
|
||||
"wizards/traveller_report.xml",
|
||||
],
|
||||
"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 pms_checkin_partner
|
||||
from . import pms_property
|
||||
|
||||
@@ -62,12 +62,13 @@ class PmsCheckinPartner(models.Model):
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@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
|
||||
nationality_id = fields.Many2one(
|
||||
string="Nationality ID",
|
||||
compute="_compute_nationality",
|
||||
comodel_name="res.country",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@api.depends("partner_id", "partner_id.firstname")
|
||||
def _compute_firstname(self):
|
||||
@@ -75,6 +76,12 @@ class PmsCheckinPartner(models.Model):
|
||||
if not record.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")
|
||||
def _compute_lastname2(self):
|
||||
for record in self:
|
||||
@@ -113,6 +120,12 @@ class PmsCheckinPartner(models.Model):
|
||||
if not record.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
|
||||
def _checkin_mandatory_fields(self, depends=False):
|
||||
mandatory_fields = super(PmsCheckinPartner, self)._checkin_mandatory_fields(
|
||||
@@ -120,7 +133,6 @@ class PmsCheckinPartner(models.Model):
|
||||
)
|
||||
mandatory_fields.extend(
|
||||
[
|
||||
"lastname2",
|
||||
"birthdate_date",
|
||||
"document_number",
|
||||
"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">
|
||||
<data>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="lastname" />
|
||||
<field name="lastname2" />
|
||||
<field name="gender" />
|
||||
<field name="birthdate_date" />
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
@@ -32,6 +34,7 @@
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
@@ -51,6 +54,7 @@
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
@@ -70,11 +74,11 @@
|
||||
<field name="document_type" />
|
||||
<field name="document_number" />
|
||||
<field name="document_expedition_date" />
|
||||
<field name="nationality_id" />
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pms_checkin_partner_view_search" model="ir.ui.view">
|
||||
<field name="name">Checkin partner view tree Spain</field>
|
||||
<field name="model">pms.checkin.partner</field>
|
||||
@@ -93,6 +97,4 @@
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</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>
|
||||
Reference in New Issue
Block a user