diff --git a/easy_my_coop_connector/demo/demo.xml b/easy_my_coop_connector/demo/demo.xml
index 5a3a1c7..eae18ae 100644
--- a/easy_my_coop_connector/demo/demo.xml
+++ b/easy_my_coop_connector/demo/demo.xml
@@ -21,4 +21,10 @@
31
+
+
+ emc_api
+
+
+
diff --git a/easy_my_coop_connector/models/__init__.py b/easy_my_coop_connector/models/__init__.py
index f5c72d9..e786407 100644
--- a/easy_my_coop_connector/models/__init__.py
+++ b/easy_my_coop_connector/models/__init__.py
@@ -1,3 +1,4 @@
from . import emc_backend
from . import emc_bindings
+from . import account_invoice
from . import subscription_request
diff --git a/easy_my_coop_connector/models/account_invoice.py b/easy_my_coop_connector/models/account_invoice.py
new file mode 100644
index 0000000..91fa6e7
--- /dev/null
+++ b/easy_my_coop_connector/models/account_invoice.py
@@ -0,0 +1,20 @@
+# Copyright 2020 Coop IT Easy SCRL fs
+# Robin Keunen
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+import logging
+
+from odoo import fields, models
+
+_logger = logging.getLogger(__name__)
+
+
+class AccountInvoice(models.Model):
+ _inherit = "account.invoice"
+
+ binding_id = fields.One2many(
+ comodel_name="emc.binding.account.invoice",
+ inverse_name="internal_id",
+ string="Binding ID",
+ required=False,
+ )
diff --git a/easy_my_coop_connector/models/emc_backend.py b/easy_my_coop_connector/models/emc_backend.py
index 3079df6..61743cb 100644
--- a/easy_my_coop_connector/models/emc_backend.py
+++ b/easy_my_coop_connector/models/emc_backend.py
@@ -6,15 +6,10 @@ import json
import logging
import requests
-from werkzeug.exceptions import (
- InternalServerError,
- NotFound,
-)
+from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
from odoo import _, api, fields, models
-from odoo.exceptions import (
- AccessDenied,
-)
+from odoo.exceptions import AccessDenied
_logger = logging.getLogger(__name__)
@@ -38,16 +33,22 @@ class EMCBackend(models.Model):
return requests.get(url, params=params, headers=headers)
- @api.multi
- def http_get_content(self, url, params=None, headers=None):
- self.ensure_one()
- response = self.http_get(url, params=params, headers=headers)
-
+ def _process_response(self, response):
if response.status_code == 200:
content = response.content.decode("utf-8")
return json.loads(content)
+ elif response.status_code == 400:
+ content = response.content.decode("utf-8")
+ raise BadRequest(
+ _(
+ "request returned status code %s with message %s"
+ % (response.status_code, content)
+ )
+ )
elif response.status_code == 403:
- raise AccessDenied(_("You are not allowed to access this resource"))
+ raise AccessDenied(
+ _("You are not allowed to access this resource")
+ )
elif response.status_code == 404:
raise NotFound(
_("Resource not found %s on server" % response.status_code)
@@ -55,10 +56,18 @@ class EMCBackend(models.Model):
else: # 500 et al.
content = response.content.decode("utf-8")
raise InternalServerError(
- _("request returned status code %s with message %s" % (
- response.status_code, content))
+ _(
+ "request returned status code %s with message %s"
+ % (response.status_code, content)
+ )
)
+ @api.multi
+ def http_get_content(self, url, params=None, headers=None):
+ self.ensure_one()
+ response = self.http_get(url, params=params, headers=headers)
+ return self._process_response(response)
+
@api.multi
def http_post(self, url, data, headers=None):
self.ensure_one()
@@ -68,6 +77,11 @@ class EMCBackend(models.Model):
return requests.post(url, json=data, headers=headers)
+ def http_post_content(self, url, data, headers=None):
+ self.ensure_one()
+ response = self.http_post(url, data, headers=headers)
+ return self._process_response(response)
+
@api.multi
def _add_api_key(self, headers):
self.ensure_one()
diff --git a/easy_my_coop_connector/models/emc_bindings.py b/easy_my_coop_connector/models/emc_bindings.py
index c1e9981..39dec2e 100644
--- a/easy_my_coop_connector/models/emc_bindings.py
+++ b/easy_my_coop_connector/models/emc_bindings.py
@@ -13,7 +13,7 @@ class EMCBinding(models.AbstractModel):
comodel_name="emc.backend", string="EMC Backend", ondelete="restrict"
)
external_id = fields.Integer(string="ID in Platform", index=True)
- # odoo_id = fields.Many2one # implement in concrete class
+ # internal_id = fields.Many2one # implement in concrete class
@api.model
def search_binding(self, backend, external_id):
@@ -46,3 +46,12 @@ class ProductTemplateBinding(models.Model):
domain="[('is_share', '=', True)]",
required=True,
)
+
+
+class AccountInvoiceBinding(models.Model):
+ _name = "emc.binding.account.invoice"
+ _inherit = "emc.binding"
+
+ internal_id = fields.Many2one(
+ comodel_name="account.invoice", string="Internal ID", required=True
+ )
diff --git a/easy_my_coop_connector/models/subscription_request.py b/easy_my_coop_connector/models/subscription_request.py
index b09c22d..2662b9c 100644
--- a/easy_my_coop_connector/models/subscription_request.py
+++ b/easy_my_coop_connector/models/subscription_request.py
@@ -23,13 +23,24 @@ class SubscriptionRequest(models.Model):
required=False,
)
+ @api.model
+ def _get_backend(self):
+ backend = self.env["emc.backend"].search([("active", "=", True)])
+ try:
+ backend.ensure_one()
+ except ValueError as e:
+ _logger.error(
+ "One and only one backend is allowed for the Easy My Coop "
+ "connector."
+ )
+ raise e
+ return backend
+
@api.model
def fetch_subscription_requests(self, date_from=None, date_to=None):
SRBinding = self.env["emc.binding.subscription.request"]
- backend = self.env["emc.backend"].search([("active", "=", True)])
- backend.ensure_one()
-
+ backend = self._get_backend()
adapter = SubscriptionRequestAdapter(backend=backend)
requests_dict = adapter.search(date_from=date_from, date_to=date_to)
for request_dict in requests_dict["rows"]:
@@ -62,8 +73,7 @@ class SubscriptionRequest(models.Model):
def backend_read(self, external_id):
SRBinding = self.env["emc.binding.subscription.request"]
- backend = self.env["emc.backend"].search([("active", "=", True)])
- backend.ensure_one()
+ backend = self._get_backend()
adapter = SubscriptionRequestAdapter(backend)
sr_data = adapter.read(external_id)
@@ -87,15 +97,7 @@ class SubscriptionRequest(models.Model):
@api.model
def fetch_subscription_requests_cron(self):
- backend = self.env["emc.backend"].search([("active", "=", True)])
- try:
- backend.ensure_one()
- except ValueError as e:
- _logger.error(
- "One and only one backend is allowed for the Easy My Coop "
- "connector "
- )
- raise e
+ backend = self._get_backend()
date_to = date.today()
date_from = date_to - timedelta(days=1)
@@ -107,3 +109,26 @@ class SubscriptionRequest(models.Model):
)
self.fetch_subscription_requests(date_from=date_from, date_to=date_to)
_logger.info("fetch done.")
+
+ @api.multi
+ def validate_subscription_request(self):
+ self.ensure_one()
+ invoice = super(
+ SubscriptionRequest, self
+ ).validate_subscription_request()
+
+ if self.source == "emc_api":
+ backend = self._get_backend()
+ sr_adapter = SubscriptionRequestAdapter(backend=backend)
+ invoice_dict = sr_adapter.validate(self.binding_id.external_id)
+
+ InvoiceBinding = self.env["emc.binding.account.invoice"]
+ InvoiceBinding.create(
+ {
+ "backend_id": backend.id,
+ "external_id": invoice_dict["id"],
+ "internal_id": invoice.id,
+ }
+ )
+
+ return invoice
diff --git a/easy_my_coop_connector/models/subscription_request_adapter.py b/easy_my_coop_connector/models/subscription_request_adapter.py
index d28a182..d312563 100644
--- a/easy_my_coop_connector/models/subscription_request_adapter.py
+++ b/easy_my_coop_connector/models/subscription_request_adapter.py
@@ -4,8 +4,10 @@
from os.path import join
+from werkzeug.exceptions import BadRequest
+
from odoo import _
-from odoo.exceptions import UserError
+from odoo.exceptions import UserError, ValidationError
from odoo.fields import Date
@@ -50,6 +52,21 @@ class SubscriptionRequestAdapter:
def delete(self):
raise NotImplementedError
+ def validate(self, id_):
+ url = self.get_url([str(id_), "validate"])
+ data = {}
+ try:
+ invoice_dict = self.backend.http_post_content(url, data)
+ except BadRequest:
+ raise ValidationError(
+ _(
+ "The request was already validated on the "
+ "platform. Please check data consistency "
+ "with your system administrator."
+ )
+ )
+ return invoice_dict
+
def to_write_values(self, request):
"""
:return a writable dictionary of values from the dictionary
diff --git a/easy_my_coop_connector/security/ir.model.access.csv b/easy_my_coop_connector/security/ir.model.access.csv
index 5dc68a2..9ce8ad3 100644
--- a/easy_my_coop_connector/security/ir.model.access.csv
+++ b/easy_my_coop_connector/security/ir.model.access.csv
@@ -2,3 +2,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_emc_backend_administrator,access_emc_backend_administrator,model_emc_backend,base.group_system,1,1,1,1
access_emc_binding_subscription_request_administrator,access_emc_binding_subscription_request_administrator,model_emc_binding_subscription_request,base.group_system,1,1,1,1
access_emc_binding_product_template_administrator,access_emc_binding_product_template_administrator,model_emc_binding_product_template,base.group_system,1,1,1,1
+access_emc_binding_account_invoice_administrator,access_emc_binding_account_invoice_administrator,model_emc_binding_account_invoice,base.group_system,1,1,1,1
diff --git a/easy_my_coop_connector/tests/test_subscription_request.py b/easy_my_coop_connector/tests/test_subscription_request.py
index 65f4931..c13f788 100644
--- a/easy_my_coop_connector/tests/test_subscription_request.py
+++ b/easy_my_coop_connector/tests/test_subscription_request.py
@@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
import requests
-from odoo.tests.common import TransactionCase
+from odoo.addons.easy_my_coop.tests.test_base import EMCBaseCase
NOT_FOUND_ERROR = {"name": "Not Found", "code": 404}
FORBIDDEN_ERROR = {"name": "Forbidden", "code": 403}
@@ -53,12 +53,35 @@ GET_RESULT = {
"state": "draft",
}
+VALIDATE_RESULT = {
+ "id": 9999,
+ "number": "SUBJ/2020/001",
+ "date_due": "2020-08-12",
+ "state": "open",
+ "date_invoice": "2020-08-12",
+ "date": "2020-08-12",
+ "type": "out_invoice",
+ "subscription_request": {"name": "Manuel Dublues", "id": 1},
+ "partner": {"name": "Manuel Dublues", "id": 1},
+ "invoice_lines": [
+ {
+ "price_unit": 25.0,
+ "quantity": 3.0,
+ "account": {"name": "Product Sales", "id": 2},
+ "name": "Part B - Worker",
+ "product": {"name": "Part B - Worker", "id": 2},
+ }
+ ],
+ "journal": {"name": "Subscription Journal", "id": 1},
+ "account": {"name": "Cooperators", "id": 1},
+}
+
def dict_to_dump(content):
return json.dumps(content).encode("utf-8")
-class TestCase(TransactionCase):
+class EMCConnectorCase(EMCBaseCase):
def setUp(self):
super().setUp()
self.backend = self.browse_ref(
@@ -109,3 +132,24 @@ class TestCase(TransactionCase):
SubscriptionRequest.backend_read(external_id)
self.assertEquals(srequest.name, "Robin Des Bois")
+
+ def test_validate_request(self):
+ srequest = self.browse_ref("easy_my_coop.subscription_request_1_demo")
+ with patch.object(requests, "post") as mock_get:
+ mock_get.return_value = mock_response = Mock()
+ mock_response.status_code = 200
+ mock_response.content = dict_to_dump(VALIDATE_RESULT)
+
+ srequest.validate_subscription_request()
+
+ self.assertEquals(srequest.state, "done")
+
+ # local invoice created
+ self.assertTrue(len(srequest.capital_release_request) > 0)
+ # local invoice linked to external invoice
+ self.assertEquals(
+ srequest.capital_release_request.binding_id.external_id,
+ VALIDATE_RESULT["id"],
+ )
+
+ # todo test 400
diff --git a/easy_my_coop_connector/views/actions.xml b/easy_my_coop_connector/views/actions.xml
index 97e2390..6790a5c 100644
--- a/easy_my_coop_connector/views/actions.xml
+++ b/easy_my_coop_connector/views/actions.xml
@@ -22,4 +22,10 @@
emc.binding.product.template
tree,form
+
+
+ Invoice Bindings
+ emc.binding.account.invoice
+ tree,form
+
diff --git a/easy_my_coop_connector/views/emc_bindings.xml b/easy_my_coop_connector/views/emc_bindings.xml
index 7d92357..8d20980 100644
--- a/easy_my_coop_connector/views/emc_bindings.xml
+++ b/easy_my_coop_connector/views/emc_bindings.xml
@@ -59,4 +59,32 @@
+
+
+ emc_binding_account_invoice_view_form
+ emc.binding.account.invoice
+
+
+
+
+
+
+ emc_binding_account_invoice_view_tree
+ emc.binding.account.invoice
+
+
+
+
+
+
+
+
diff --git a/easy_my_coop_connector/views/menus.xml b/easy_my_coop_connector/views/menus.xml
index 47c5a00..caac917 100644
--- a/easy_my_coop_connector/views/menus.xml
+++ b/easy_my_coop_connector/views/menus.xml
@@ -33,10 +33,17 @@
groups="base.group_user"
sequence="1030"/>
+
+
+ sequence="1100"/>