odoo-addon-ebill-postfinance 16.0.1.0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. odoo/addons/ebill_postfinance/README.rst +130 -0
  2. odoo/addons/ebill_postfinance/__init__.py +1 -0
  3. odoo/addons/ebill_postfinance/__manifest__.py +35 -0
  4. odoo/addons/ebill_postfinance/data/ir_cron.xml +14 -0
  5. odoo/addons/ebill_postfinance/data/mail_activity_type.xml +10 -0
  6. odoo/addons/ebill_postfinance/data/transmit.method.xml +10 -0
  7. odoo/addons/ebill_postfinance/i18n/ebill_postfinance.pot +533 -0
  8. odoo/addons/ebill_postfinance/messages/invoice-2003A.jinja +238 -0
  9. odoo/addons/ebill_postfinance/messages/invoice-yellowbill.jinja +227 -0
  10. odoo/addons/ebill_postfinance/messages/ybInvoice_V2.0.4.xsd +1395 -0
  11. odoo/addons/ebill_postfinance/models/__init__.py +5 -0
  12. odoo/addons/ebill_postfinance/models/account_move.py +140 -0
  13. odoo/addons/ebill_postfinance/models/ebill_payment_contract.py +73 -0
  14. odoo/addons/ebill_postfinance/models/ebill_postfinance_invoice_message.py +404 -0
  15. odoo/addons/ebill_postfinance/models/ebill_postfinance_service.py +154 -0
  16. odoo/addons/ebill_postfinance/models/sale_order.py +19 -0
  17. odoo/addons/ebill_postfinance/readme/CONFIGURE.rst +13 -0
  18. odoo/addons/ebill_postfinance/readme/CONTRIBUTORS.rst +1 -0
  19. odoo/addons/ebill_postfinance/readme/DESCRIPTION.rst +1 -0
  20. odoo/addons/ebill_postfinance/readme/INSTALL.rst +2 -0
  21. odoo/addons/ebill_postfinance/readme/ROADMAP.rst +10 -0
  22. odoo/addons/ebill_postfinance/readme/USAGE.rst +5 -0
  23. odoo/addons/ebill_postfinance/security/ir.model.access.csv +5 -0
  24. odoo/addons/ebill_postfinance/static/description/icon.png +0 -0
  25. odoo/addons/ebill_postfinance/static/description/index.html +470 -0
  26. odoo/addons/ebill_postfinance/tests/__init__.py +3 -0
  27. odoo/addons/ebill_postfinance/tests/common.py +194 -0
  28. odoo/addons/ebill_postfinance/tests/examples/credit_note_yb.xml +176 -0
  29. odoo/addons/ebill_postfinance/tests/examples/invoice_qr_yb.xml +182 -0
  30. odoo/addons/ebill_postfinance/tests/examples/yellowbill_qr_iban.xml +178 -0
  31. odoo/addons/ebill_postfinance/tests/fixtures/cassettes/test_ping_service.yaml +1057 -0
  32. odoo/addons/ebill_postfinance/tests/fixtures/cassettes/test_search_invoices.yaml +564 -0
  33. odoo/addons/ebill_postfinance/tests/fixtures/cassettes/test_upload_file.yaml +561 -0
  34. odoo/addons/ebill_postfinance/tests/test_ebill_postfinance.py +50 -0
  35. odoo/addons/ebill_postfinance/tests/test_ebill_postfinance_message_yb.py +65 -0
  36. odoo/addons/ebill_postfinance/tests/test_ebill_postfinance_message_yb_creditnote.py +67 -0
  37. odoo/addons/ebill_postfinance/views/ebill_payment_contract.xml +56 -0
  38. odoo/addons/ebill_postfinance/views/ebill_postfinance_invoice_message.xml +81 -0
  39. odoo/addons/ebill_postfinance/views/ebill_postfinance_service.xml +136 -0
  40. odoo/addons/ebill_postfinance/views/message_template.xml +8 -0
  41. odoo_addon_ebill_postfinance-16.0.1.0.0.3.dist-info/METADATA +149 -0
  42. odoo_addon_ebill_postfinance-16.0.1.0.0.3.dist-info/RECORD +44 -0
  43. odoo_addon_ebill_postfinance-16.0.1.0.0.3.dist-info/WHEEL +5 -0
  44. odoo_addon_ebill_postfinance-16.0.1.0.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,154 @@
1
+ # Copyright 2022 Camptocamp SA
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
+
4
+ import logging
5
+ import logging.config
6
+
7
+ from ebilling_postfinance import ebilling_postfinance
8
+
9
+ from odoo import api, fields, models
10
+ from odoo.exceptions import UserError
11
+
12
+ _logger = logging.getLogger(__name__)
13
+
14
+
15
+ class EbillPostfinanceService(models.Model):
16
+ _name = "ebill.postfinance.service"
17
+ _description = "Postfinance eBill service configuration"
18
+
19
+ name = fields.Char(required=True)
20
+ username = fields.Char()
21
+ password = fields.Char()
22
+ biller_id = fields.Char(string="Biller ID", size=17, required=True)
23
+ use_test_service = fields.Boolean(string="Testing", help="Target the test service")
24
+ partner_bank_id = fields.Many2one(
25
+ comodel_name="res.partner.bank", string="Bank account", ondelete="restrict"
26
+ )
27
+ invoice_message_ids = fields.One2many(
28
+ comodel_name="ebill.postfinance.invoice.message",
29
+ inverse_name="service_id",
30
+ string="Invoice Messages",
31
+ readonly=True,
32
+ )
33
+ ebill_payment_contract_ids = fields.One2many(
34
+ comodel_name="ebill.payment.contract",
35
+ inverse_name="postfinance_service_id",
36
+ string="Contracts",
37
+ readonly=True,
38
+ )
39
+ active = fields.Boolean(default=True)
40
+ file_type_to_use = fields.Selection(
41
+ string="Invoice Format",
42
+ default="XML",
43
+ required=True,
44
+ selection=[
45
+ ("XML", "XML Yellow Bill"),
46
+ ("EAI.XML", "Custom XML (SAPiDoc)"),
47
+ # ("eai.edi", "Custom EDIFACT"),
48
+ ("struct.pdf", "Factur X"),
49
+ ],
50
+ )
51
+ use_file_type_xml_paynet = fields.Boolean(
52
+ string="Use Paynet/SIX format",
53
+ help="Enable use of legacy SIX/Paynet invoice format.",
54
+ )
55
+ operation_timeout = fields.Integer(
56
+ string="HTTP Timeout",
57
+ default="600",
58
+ help="Timeout for each HTTP (GET, POST) request in seconds.",
59
+ )
60
+
61
+ def _get_service(self):
62
+ return ebilling_postfinance.WebService(
63
+ self.use_test_service,
64
+ self.username,
65
+ self.password,
66
+ self.biller_id,
67
+ self.operation_timeout,
68
+ )
69
+
70
+ def test_ping(self):
71
+ """Test the service from the UI."""
72
+ self.ensure_one()
73
+ msg = ["Test connection to service"]
74
+ res = self.ping_service()
75
+ if res:
76
+ msg.append("Success pinging service \n Receive :{}".format(res))
77
+ else:
78
+ msg.append(" - Failed pinging service")
79
+ raise UserError("\n".join(msg))
80
+
81
+ def ping_service(self, test_error=False, test_exception=False):
82
+ """Ping the service, uses the authentication.
83
+
84
+ test_error: will create an unhandled error in the repsonse
85
+ test_exception: will create a FaultException
86
+
87
+ """
88
+ service = self._get_service()
89
+ return service.ping()
90
+
91
+ def search_invoice(self, transaction_id=None):
92
+ """Get invoice status from the server.
93
+
94
+ transaction_id:
95
+ """
96
+ service = self._get_service()
97
+ res = service.search_invoices(transaction_id)
98
+ if res.InvoiceCount == 0:
99
+ _logger.info("Search invoice returned no invoice")
100
+ return res
101
+ if res.InvoiceCount < res.TotalInvoiceCount:
102
+ # TODO handle the case where there is more to download ?
103
+ _logger.info("Search invoice has more to download")
104
+ for message in res.InvoiceList.SearchInvoice:
105
+ _logger.info(f"Found record for message {message}")
106
+ record = self.invoice_message_ids.search(
107
+ [("transaction_id", "=", message.TransactionId)],
108
+ limit=1,
109
+ order="create_date desc",
110
+ )
111
+ if record:
112
+ record.update_message_from_server_data(message)
113
+ else:
114
+ _logger.warning(f"Could not find record for message {message}")
115
+ return res
116
+
117
+ def upload_file(self, transaction_id, file_type, data):
118
+ service = self._get_service()
119
+ res = service.upload_files(transaction_id, file_type, data)
120
+ return res
121
+
122
+ def get_invoice_list(self, archive_data=False):
123
+ service = self._get_service()
124
+ res = service.get_invoice_list(archive_data)
125
+ return res
126
+
127
+ def get_process_protocol_list(self, archive_data=False):
128
+ # Is this the processing result of an invoice ?
129
+ service = self._get_service()
130
+ res = service.get_process_protocol_list(archive_data)
131
+ return res
132
+
133
+ def get_ebill_recipient_subscription_status(self, recipient_id):
134
+ service = self._get_service()
135
+ res = service.get_ebill_recipient_subscription_status(recipient_id)
136
+ return res
137
+
138
+ def get_registration_protocol_list(self, archive_data=False):
139
+ service = self._get_service()
140
+ res = service.get_registration_protocol_list(archive_data)
141
+ for registration_protocol in res or {}:
142
+ self.get_registration_protocol(registration_protocol.CreateDate)
143
+ return res
144
+
145
+ def get_registration_protocol(self, create_date, archive_data=False):
146
+ service = self._get_service()
147
+ res = service.get_registration_protocol(create_date, archive_data)
148
+ return res
149
+
150
+ @api.model
151
+ def cron_update_invoices(self):
152
+ services = self.search([])
153
+ for service in services:
154
+ service.search_invoice()
@@ -0,0 +1,19 @@
1
+ # Copyright 2021 Camptocamp SA
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
+
4
+ from odoo import api, fields, models
5
+
6
+
7
+ class SaleOrder(models.Model):
8
+
9
+ _inherit = "sale.order"
10
+
11
+ postfinance_ebill_client_order_ref = fields.Char(
12
+ compute="_compute_postfinance_ebill_client_order_ref"
13
+ )
14
+
15
+ @api.depends("client_order_ref")
16
+ def _compute_postfinance_ebill_client_order_ref(self):
17
+ """Compute the customer reference order to allow for glue module."""
18
+ for order in self:
19
+ order.postfinance_ebill_client_order_ref = order.client_order_ref
@@ -0,0 +1,13 @@
1
+ Create a service
2
+ ================
3
+
4
+ First you need to be registred on 'Postfinance eBill service <https://www.postfinance.ch/en/business/products/accounts-receivable-solutions/e-bill-invoice-issuer.html>'
5
+ To create a service go to `Accounting - Configuration - Payments - Postfinance eBill Service`
6
+
7
+ Configure a customer and create his contract
8
+ ============================================
9
+
10
+ The contracts specific to Postfinance e-billing are located in `Accounting - Customers - eBill Postfinance Contract`
11
+ Create a contract for a customer with his PayerId and make sure that the contract is active by being in `Open` state with valid start/end dates.
12
+
13
+ Set `Customer Invoice Transmission Method` on the customer to Postfinance.
@@ -0,0 +1 @@
1
+ * Thierry Ducrest <thierry.ducrest@camptocamp.com>
@@ -0,0 +1 @@
1
+ This module implements the exchange of electronic invoices with the Postfinance web service.
@@ -0,0 +1,2 @@
1
+ This module needs the Python library `ebilling_postfiance` which can be installed from Pypi.
2
+ More information can be found at `<repository https://github.com/camptocamp/ebilling-postfinance>`_.
@@ -0,0 +1,10 @@
1
+ ToDo
2
+
3
+ * Add option to import the contract subscription (csv)
4
+ * Add the download of this csv from web service, but what is the endpoint ?
5
+
6
+
7
+ Nice to have
8
+
9
+ * Add a link to the failed job in the chatter message.
10
+ * Add an action on partner to create a ebilling contract.
@@ -0,0 +1,5 @@
1
+ To use this module, you need to:
2
+
3
+ #. Configure the service, customers and contracts as described in the CONFIGURATION section.
4
+ #. Create an invoice for a customer with an open Postfinance contract.
5
+ #. Validate the invoice, and click the Send eBill button.
@@ -0,0 +1,5 @@
1
+ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2
+ access_ebill_postfinance_service_user,access.ebill.postfinance.service.user,model_ebill_postfinance_service,base.group_user,1,0,0,0
3
+ access_ebill_postfinance_service_manager,access.postfinance.service.manager,model_ebill_postfinance_service,account.group_account_manager,1,1,1,1
4
+ access_ebill_postfinance_invoice_message_user,access.ebill.postfinance.invoice.message.user,model_ebill_postfinance_invoice_message,base.group_user,1,0,0,0
5
+ access_ebill_postfinance_invoice_message_manager,access.ebill.postfinance.invoice.message.manager,model_ebill_postfinance_invoice_message,account.group_account_manager,1,1,1,1