Browse Source

[ADD] emcc: send validate request to platform

pull/115/head
robin.keunen 5 years ago
parent
commit
b2af3a22b0
  1. 6
      easy_my_coop_connector/demo/demo.xml
  2. 1
      easy_my_coop_connector/models/__init__.py
  3. 20
      easy_my_coop_connector/models/account_invoice.py
  4. 44
      easy_my_coop_connector/models/emc_backend.py
  5. 11
      easy_my_coop_connector/models/emc_bindings.py
  6. 53
      easy_my_coop_connector/models/subscription_request.py
  7. 19
      easy_my_coop_connector/models/subscription_request_adapter.py
  8. 1
      easy_my_coop_connector/security/ir.model.access.csv
  9. 48
      easy_my_coop_connector/tests/test_subscription_request.py
  10. 6
      easy_my_coop_connector/views/actions.xml
  11. 28
      easy_my_coop_connector/views/emc_bindings.xml
  12. 9
      easy_my_coop_connector/views/menus.xml

6
easy_my_coop_connector/demo/demo.xml

@ -21,4 +21,10 @@
<field name="internal_id" ref="easy_my_coop.product_template_share_type_2_demo"/> <field name="internal_id" ref="easy_my_coop.product_template_share_type_2_demo"/>
<field name="external_id">31</field> <field name="external_id">31</field>
</record> </record>
<record id="easy_my_coop.subscription_request_1_demo" model="subscription.request">
<field name="source">emc_api</field>
</record>
</odoo> </odoo>

1
easy_my_coop_connector/models/__init__.py

@ -1,3 +1,4 @@
from . import emc_backend from . import emc_backend
from . import emc_bindings from . import emc_bindings
from . import account_invoice
from . import subscription_request from . import subscription_request

20
easy_my_coop_connector/models/account_invoice.py

@ -0,0 +1,20 @@
# Copyright 2020 Coop IT Easy SCRL fs
# Robin Keunen <robin@coopiteasy.be>
# 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,
)

44
easy_my_coop_connector/models/emc_backend.py

@ -6,15 +6,10 @@ import json
import logging import logging
import requests import requests
from werkzeug.exceptions import (
InternalServerError,
NotFound,
)
from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
from odoo import _, api, fields, models from odoo import _, api, fields, models
from odoo.exceptions import (
AccessDenied,
)
from odoo.exceptions import AccessDenied
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -38,16 +33,22 @@ class EMCBackend(models.Model):
return requests.get(url, params=params, headers=headers) 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: if response.status_code == 200:
content = response.content.decode("utf-8") content = response.content.decode("utf-8")
return json.loads(content) 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: 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: elif response.status_code == 404:
raise NotFound( raise NotFound(
_("Resource not found %s on server" % response.status_code) _("Resource not found %s on server" % response.status_code)
@ -55,10 +56,18 @@ class EMCBackend(models.Model):
else: # 500 et al. else: # 500 et al.
content = response.content.decode("utf-8") content = response.content.decode("utf-8")
raise InternalServerError( 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 @api.multi
def http_post(self, url, data, headers=None): def http_post(self, url, data, headers=None):
self.ensure_one() self.ensure_one()
@ -68,6 +77,11 @@ class EMCBackend(models.Model):
return requests.post(url, json=data, headers=headers) 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 @api.multi
def _add_api_key(self, headers): def _add_api_key(self, headers):
self.ensure_one() self.ensure_one()

11
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" comodel_name="emc.backend", string="EMC Backend", ondelete="restrict"
) )
external_id = fields.Integer(string="ID in Platform", index=True) 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 @api.model
def search_binding(self, backend, external_id): def search_binding(self, backend, external_id):
@ -46,3 +46,12 @@ class ProductTemplateBinding(models.Model):
domain="[('is_share', '=', True)]", domain="[('is_share', '=', True)]",
required=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
)

53
easy_my_coop_connector/models/subscription_request.py

@ -23,13 +23,24 @@ class SubscriptionRequest(models.Model):
required=False, 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 @api.model
def fetch_subscription_requests(self, date_from=None, date_to=None): def fetch_subscription_requests(self, date_from=None, date_to=None):
SRBinding = self.env["emc.binding.subscription.request"] 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) adapter = SubscriptionRequestAdapter(backend=backend)
requests_dict = adapter.search(date_from=date_from, date_to=date_to) requests_dict = adapter.search(date_from=date_from, date_to=date_to)
for request_dict in requests_dict["rows"]: for request_dict in requests_dict["rows"]:
@ -62,8 +73,7 @@ class SubscriptionRequest(models.Model):
def backend_read(self, external_id): def backend_read(self, external_id):
SRBinding = self.env["emc.binding.subscription.request"] 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) adapter = SubscriptionRequestAdapter(backend)
sr_data = adapter.read(external_id) sr_data = adapter.read(external_id)
@ -87,15 +97,7 @@ class SubscriptionRequest(models.Model):
@api.model @api.model
def fetch_subscription_requests_cron(self): 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_to = date.today()
date_from = date_to - timedelta(days=1) 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) self.fetch_subscription_requests(date_from=date_from, date_to=date_to)
_logger.info("fetch done.") _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

19
easy_my_coop_connector/models/subscription_request_adapter.py

@ -4,8 +4,10 @@
from os.path import join from os.path import join
from werkzeug.exceptions import BadRequest
from odoo import _ from odoo import _
from odoo.exceptions import UserError
from odoo.exceptions import UserError, ValidationError
from odoo.fields import Date from odoo.fields import Date
@ -50,6 +52,21 @@ class SubscriptionRequestAdapter:
def delete(self): def delete(self):
raise NotImplementedError 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): def to_write_values(self, request):
""" """
:return a writable dictionary of values from the dictionary :return a writable dictionary of values from the dictionary

1
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_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_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_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

48
easy_my_coop_connector/tests/test_subscription_request.py

@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
import requests 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} NOT_FOUND_ERROR = {"name": "Not Found", "code": 404}
FORBIDDEN_ERROR = {"name": "Forbidden", "code": 403} FORBIDDEN_ERROR = {"name": "Forbidden", "code": 403}
@ -53,12 +53,35 @@ GET_RESULT = {
"state": "draft", "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): def dict_to_dump(content):
return json.dumps(content).encode("utf-8") return json.dumps(content).encode("utf-8")
class TestCase(TransactionCase):
class EMCConnectorCase(EMCBaseCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.backend = self.browse_ref( self.backend = self.browse_ref(
@ -109,3 +132,24 @@ class TestCase(TransactionCase):
SubscriptionRequest.backend_read(external_id) SubscriptionRequest.backend_read(external_id)
self.assertEquals(srequest.name, "Robin Des Bois") 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

6
easy_my_coop_connector/views/actions.xml

@ -22,4 +22,10 @@
<field name="res_model">emc.binding.product.template</field> <field name="res_model">emc.binding.product.template</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
</record> </record>
<record id="emc_binding_account_invoice_action" model="ir.actions.act_window">
<field name="name">Invoice Bindings</field>
<field name="res_model">emc.binding.account.invoice</field>
<field name="view_mode">tree,form</field>
</record>
</odoo> </odoo>

28
easy_my_coop_connector/views/emc_bindings.xml

@ -59,4 +59,32 @@
</tree> </tree>
</field> </field>
</record> </record>
<record id="emc_binding_account_invoice_view_form" model="ir.ui.view">
<field name="name">emc_binding_account_invoice_view_form</field>
<field name="model">emc.binding.account.invoice</field>
<field name="arch" type="xml">
<form string="emc_binding_account_invoice_form">
<sheet>
<group>
<field name="backend_id"/>
<field name="internal_id"/>
<field name="external_id"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="emc_binding_account_invoice_view_tree" model="ir.ui.view">
<field name="name">emc_binding_account_invoice_view_tree</field>
<field name="model">emc.binding.account.invoice</field>
<field name="arch" type="xml">
<tree string="emc_binding_account_invoice_tree">
<field name="backend_id"/>
<field name="internal_id"/>
<field name="external_id"/>
</tree>
</field>
</record>
</odoo> </odoo>

9
easy_my_coop_connector/views/menus.xml

@ -33,10 +33,17 @@
groups="base.group_user" groups="base.group_user"
sequence="1030"/> sequence="1030"/>
<menuitem id="emc_binding_account_invoice_action_menu"
name="Invoice Bindings"
parent="emc_connector_menu_menu"
action="emc_binding_account_invoice_action"
groups="base.group_user"
sequence="1040"/>
<menuitem id="emc_history_import_action_menu" <menuitem id="emc_history_import_action_menu"
name="Import Subscription Request History" name="Import Subscription Request History"
parent="emc_connector_menu_menu" parent="emc_connector_menu_menu"
action="emc_history_import_action" action="emc_history_import_action"
groups="base.group_user" groups="base.group_user"
sequence="1050"/>
sequence="1100"/>
</odoo> </odoo>
Loading…
Cancel
Save