diff --git a/easy_my_coop/demo/coop.xml b/easy_my_coop/demo/coop.xml index 7573fb7..9179c16 100644 --- a/easy_my_coop/demo/coop.xml +++ b/easy_my_coop/demo/coop.xml @@ -135,7 +135,6 @@ - Catherine des Champs catherine@demo.net @@ -153,20 +152,6 @@ waiting - - Catherine des Champs - - - catherine@demo.net - Chemin des bois fleuris, 2 - Brussels - 1000 - - - - - - @@ -186,4 +171,5 @@ + diff --git a/easy_my_coop_api/__manifest__.py b/easy_my_coop_api/__manifest__.py index a7f8cd9..7aa896a 100644 --- a/easy_my_coop_api/__manifest__.py +++ b/easy_my_coop_api/__manifest__.py @@ -17,7 +17,7 @@ "summary": """ Open Easy My Coop to the world: RESTful API. """, - "data": ["data/sequences.xml"], + "data": [], "demo": ["demo/demo.xml"], "installable": True, "application": False, diff --git a/easy_my_coop_api/data/sequences.xml b/easy_my_coop_api/data/sequences.xml deleted file mode 100644 index 4d03a8a..0000000 --- a/easy_my_coop_api/data/sequences.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - Subscritpion Request External ID sequence - subscription.request.external.id - 3 - - - Subscritpion Request External ID sequence - account.invoice.external.id - 3 - - - diff --git a/easy_my_coop_api/demo/demo.xml b/easy_my_coop_api/demo/demo.xml index 57f3a58..72d2102 100644 --- a/easy_my_coop_api/demo/demo.xml +++ b/easy_my_coop_api/demo/demo.xml @@ -9,10 +9,11 @@ cbd07f57-c903-43b4-b668-436b3bec5f15 - - - - - - + + 1 + + + + 2 + diff --git a/easy_my_coop_api/models/__init__.py b/easy_my_coop_api/models/__init__.py index b951867..6740752 100644 --- a/easy_my_coop_api/models/__init__.py +++ b/easy_my_coop_api/models/__init__.py @@ -1,3 +1,2 @@ from . import auth_api_key -from . import subscription_request -from . import account_invoice +from . import external_id_mixin diff --git a/easy_my_coop_api/models/account_invoice.py b/easy_my_coop_api/models/account_invoice.py deleted file mode 100644 index ae3c520..0000000 --- a/easy_my_coop_api/models/account_invoice.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2020 Coop IT Easy SCRL fs -# Robin Keunen -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - -from odoo import api, fields, models - - -class AccountInvoice(models.Model): - _inherit = "account.invoice" - - external_id = fields.Integer( - string="External ID", index=True, required=False - ) - - @api.multi - def get_external_id(self): - self.ensure_one() - if not self.external_id: - self.external_id = self.env["ir.sequence"].next_by_code( - "account.invoice.external.id" - ) - return self.external_id diff --git a/easy_my_coop_api/models/external_id_mixin.py b/easy_my_coop_api/models/external_id_mixin.py new file mode 100644 index 0000000..c2ebbc3 --- /dev/null +++ b/easy_my_coop_api/models/external_id_mixin.py @@ -0,0 +1,76 @@ +# Copyright 2020 Coop IT Easy SCRL fs +# Robin Keunen +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ExternalIdMixin(models.AbstractModel): + _name = "external.id.mixin" + _description = "External ID Mixin" + + # do not access directly, always use get_api_external_id method + _api_external_id = fields.Integer( + string="External ID", index=True, required=False + ) + external_id_sequence_id = fields.Many2one( + comodel_name="ir.sequence", + string="External ID Sequence", + required=False, + ) + + @api.multi + def set_external_sequence(self): + self.ensure_one() + code = "%s.external.id" % self._name + Sequence = self.env["ir.sequence"] + # check if code was created for that model + sequence = Sequence.search([("code", "=", code)]) + if not sequence: + sequence = Sequence.sudo().create( + {"name": code, "code": code, "number_next": 1} + ) + + self.sudo().write({"external_id_sequence_id": sequence.id}) + return True + + @api.multi + def get_api_external_id(self): + self.ensure_one() + if not self.external_id_sequence_id: + self.set_external_sequence() + if not self._api_external_id: + self.sudo().write( + {"_api_external_id": self.external_id_sequence_id._next()} + ) + return self._api_external_id + + +class ResPartner(models.Model): + _name = "res.partner" + _inherit = ["res.partner", "external.id.mixin"] + + +class SubscriptionRequest(models.Model): + _name = "subscription.request" + _inherit = ["subscription.request", "external.id.mixin"] + + +class AccountAccount(models.Model): + _name = "account.account" + _inherit = ["account.account", "external.id.mixin"] + + +class AccountJournal(models.Model): + _name = "account.journal" + _inherit = ["account.journal", "external.id.mixin"] + + +class AccountInvoice(models.Model): + _name = "account.invoice" + _inherit = ["account.invoice", "external.id.mixin"] + + +class ProductTemplate(models.Model): + _name = "product.template" + _inherit = ["product.template", "external.id.mixin"] diff --git a/easy_my_coop_api/models/subscription_request.py b/easy_my_coop_api/models/subscription_request.py deleted file mode 100644 index 717c072..0000000 --- a/easy_my_coop_api/models/subscription_request.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2020 Coop IT Easy SCRL fs -# Robin Keunen -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - -from os.path import join - -from odoo import api, fields, models - - -class SubscriptionRequest(models.Model): - _inherit = "subscription.request" - - external_id = fields.Integer( - string="External ID", index=True, required=False - ) - - @api.multi - def get_external_id(self): - self.ensure_one() - if not self.external_id: - self.external_id = self.env["ir.sequence"].next_by_code( - "subscription.request.external.id" - ) - return self.external_id diff --git a/easy_my_coop_api/services/subscription_request_service.py b/easy_my_coop_api/services/subscription_request_service.py index c962690..a56d68a 100644 --- a/easy_my_coop_api/services/subscription_request_service.py +++ b/easy_my_coop_api/services/subscription_request_service.py @@ -24,12 +24,12 @@ class SubscriptionRequestService(Component): _usage = "subscription-request" _collection = "emc.services" _description = """ - Subscription requests + Subscription Request Services """ def get(self, _id): sr = self.env["subscription.request"].search( - [("external_id", "=", _id)] + [("_api_external_id", "=", _id)] ) if sr: return self._to_dict(sr) @@ -66,7 +66,7 @@ class SubscriptionRequestService(Component): def update(self, _id, **params): params = self._prepare_update(params) sr = self.env["subscription.request"].search( - [("external_id", "=", _id)] + [("_api_external_id", "=", _id)] ) if not sr: raise wrapJsonException( @@ -77,7 +77,7 @@ class SubscriptionRequestService(Component): def validate(self, _id, **params): sr = self.env["subscription.request"].search( - [("external_id", "=", _id)] + [("_api_external_id", "=", _id)] ) if not sr: raise wrapJsonException( @@ -97,22 +97,23 @@ class SubscriptionRequestService(Component): if sr.capital_release_request: invoice_ids = [ - invoice.get_external_id() + invoice.get_api_external_id() for invoice in sr.capital_release_request ] else: invoice_ids = [] + share_product = sr.share_product_id.product_tmpl_id return { - "id": sr.get_external_id(), + "id": sr.get_api_external_id(), "name": sr.name, "email": sr.email, "state": sr.state, "date": Date.to_string(sr.date), "ordered_parts": sr.ordered_parts, "share_product": { - "id": sr.share_product_id.product_tmpl_id.id, - "name": sr.share_product_id.product_tmpl_id.name, + "id": share_product.get_api_external_id(), + "name": share_product.name, }, "address": { "street": sr.address, diff --git a/easy_my_coop_api/tests/__init__.py b/easy_my_coop_api/tests/__init__.py index f831997..a7be43d 100644 --- a/easy_my_coop_api/tests/__init__.py +++ b/easy_my_coop_api/tests/__init__.py @@ -1,3 +1,4 @@ from . import test_ping from . import test_registry +from . import test_external_id_mixin from . import test_subscription_requests diff --git a/easy_my_coop_api/tests/common.py b/easy_my_coop_api/tests/common.py index 5c91962..d959400 100644 --- a/easy_my_coop_api/tests/common.py +++ b/easy_my_coop_api/tests/common.py @@ -9,7 +9,6 @@ import requests from lxml import html import odoo -from odoo.fields import Date from odoo.addons.base_rest.tests.common import BaseRestCase @@ -37,37 +36,6 @@ class BaseEMCRestCase(BaseRestCase): def setUp(self): super().setUp() self.session = requests.Session() - self.demo_request_1 = self.browse_ref( - "easy_my_coop.subscription_request_1_demo" - ) - self.demo_request_2 = self.browse_ref( - "easy_my_coop.subscription_request_2_demo" - ) - self.demo_share_product = ( - self.demo_request_1.share_product_id.product_tmpl_id - ) - - date = Date.to_string(self.demo_request_1.date) - self.demo_request_1_dict = { - "id": self.demo_request_1.id, - "name": "Manuel Dublues", - "email": "manuel@demo.net", - "date": date, - "state": "draft", - "ordered_parts": 3, - "share_product": { - "id": self.demo_share_product.id, - "name": self.demo_share_product.name, - }, - "address": { - "street": "schaerbeekstraat", - "zip_code": "1111", - "city": "Brussels", - "country": "BE", - }, - "lang": "en_US", - "capital_release_request": [], - } def http_get(self, url, headers=None): headers = self._add_api_key(headers) diff --git a/easy_my_coop_api/tests/test_external_id_mixin.py b/easy_my_coop_api/tests/test_external_id_mixin.py new file mode 100644 index 0000000..0f7f0a3 --- /dev/null +++ b/easy_my_coop_api/tests/test_external_id_mixin.py @@ -0,0 +1,83 @@ +# Copyright 2020 Coop IT Easy SCRL fs +# Robin Keunen +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.fields import Date +from odoo.tests import TransactionCase + + +class TestExternalIdMixin(TransactionCase): + def test_res_partner_api_external_id(self): + partner = self.env["res.partner"].create({"name": "Test Partner"}) + self.assertFalse(partner._api_external_id) + self.assertFalse(partner.external_id_sequence_id) + + external_id = partner.get_api_external_id() + self.assertTrue(bool(partner._api_external_id)) + self.assertTrue(bool(partner.external_id_sequence_id)) + + self.assertEquals(external_id, partner.get_api_external_id()) + + def test_subscription_request_api_external_id(self): + share_type = self.browse_ref( + "easy_my_coop.product_template_share_type_2_demo" + ).product_variant_id + sr = self.env["subscription.request"].create( + { + "name": "test create request", + "email": "test@demo.net", + "address": "schaerbeekstraat", + "zip_code": "1111", + "city": "Brussels", + "country_id": self.ref("base.be"), + "date": Date.today(), + "source": "manual", + "ordered_parts": 3, + "share_product_id": share_type.id, + "lang": "en_US", + } + ) + self.assertFalse(sr._api_external_id) + self.assertFalse(sr.external_id_sequence_id) + + external_id = sr.get_api_external_id() + self.assertTrue(bool(sr._api_external_id)) + self.assertTrue(bool(sr.external_id_sequence_id)) + + self.assertEquals(external_id, sr.get_api_external_id()) + + def test_account_journal_api_external_id(self): + bank = self.env["res.partner.bank"].create( + { + "acc_number": "test", + "partner_id": self.env.user.company_id.partner_id.id, + } + ) + journal = self.env["account.journal"].create( + { + "name": "test journal", + "code": "123", + "type": "bank", + "company_id": self.env.ref("base.main_company").id, + "bank_account_id": bank.id, + } + ) + self.assertFalse(journal._api_external_id) + self.assertFalse(journal.external_id_sequence_id) + + external_id = journal.get_api_external_id() + self.assertTrue(bool(journal._api_external_id)) + self.assertTrue(bool(journal.external_id_sequence_id)) + + self.assertEquals(external_id, journal.get_api_external_id()) + + def test_account_invoice_api_external_id(self): + invoice = self.env["account.invoice"].create({"name": "create passes"}) + self.assertFalse(invoice._api_external_id) + self.assertFalse(invoice.external_id_sequence_id) + + external_id = invoice.get_api_external_id() + self.assertTrue(bool(invoice._api_external_id)) + self.assertTrue(bool(invoice.external_id_sequence_id)) + + self.assertEquals(external_id, invoice.get_api_external_id()) diff --git a/easy_my_coop_api/tests/test_registry.py b/easy_my_coop_api/tests/test_registry.py index b420eff..adef8e3 100644 --- a/easy_my_coop_api/tests/test_registry.py +++ b/easy_my_coop_api/tests/test_registry.py @@ -10,9 +10,6 @@ from odoo.addons.base_rest.tests.common import BaseRestCase from ..controllers.controllers import UserController -HOST = "127.0.0.1" -PORT = odoo.tools.config["http_port"] - class TestControllerRegistry(BaseRestCase): def test_controller_registry(self): diff --git a/easy_my_coop_api/tests/test_subscription_requests.py b/easy_my_coop_api/tests/test_subscription_requests.py index 36764da..73e66e2 100644 --- a/easy_my_coop_api/tests/test_subscription_requests.py +++ b/easy_my_coop_api/tests/test_subscription_requests.py @@ -28,11 +28,43 @@ class TestSRController(BaseEMCRestCase): usage="subscription-request" ) + self.demo_request_1 = self.browse_ref( + "easy_my_coop.subscription_request_1_demo" + ) + self.demo_request_2 = self.browse_ref( + "easy_my_coop.subscription_request_waiting_demo" + ) + self.demo_share_product = ( + self.demo_request_1.share_product_id.product_tmpl_id + ) + + date = Date.to_string(self.demo_request_1.date) + self.demo_request_1_dict = { + "id": self.demo_request_1.get_api_external_id(), + "name": "Manuel Dublues", + "email": "manuel@demo.net", + "date": date, + "state": "draft", + "ordered_parts": 3, + "share_product": { + "id": self.demo_share_product.get_api_external_id(), + "name": self.demo_share_product.name, + }, + "address": { + "street": "schaerbeekstraat", + "zip_code": "1111", + "city": "Brussels", + "country": "BE", + }, + "lang": "en_US", + "capital_release_request": [], + } + def test_service(self): # kept as example # useful if you need to change data in database and check db type - result = self.sr_service.get(self.demo_request_1.external_id) + result = self.sr_service.get(self.demo_request_1.get_api_external_id()) self.assertEquals(self.demo_request_1_dict, result) all_sr = self.sr_service.search() @@ -46,8 +78,8 @@ class TestSRController(BaseEMCRestCase): self.assertTrue(date_sr) def test_route_get(self): - id_ = self.demo_request_1.external_id - route = "/api/subscription-request/%s" % id_ + external_id = self.demo_request_1.get_api_external_id() + route = "/api/subscription-request/%s" % external_id content = self.http_get_content(route) self.assertEquals(self.demo_request_1_dict, content) @@ -127,7 +159,7 @@ class TestSRController(BaseEMCRestCase): "date": Date.to_string(Date.today()), "state": "draft", "share_product": { - "id": self.demo_share_product.id, + "id": self.demo_share_product.get_api_external_id(), "name": self.demo_share_product.name, }, "capital_release_request": [], @@ -136,7 +168,10 @@ class TestSRController(BaseEMCRestCase): self.assertEquals(expected, content) def test_route_update(self): - url = "/api/subscription-request/%s" % self.demo_request_1.external_id + url = ( + "/api/subscription-request/%s" + % self.demo_request_1.get_api_external_id() + ) data = {"state": "done"} response = self.http_post(url, data=data) @@ -150,7 +185,7 @@ class TestSRController(BaseEMCRestCase): def test_route_validate(self): url = ( "/api/subscription-request/%s/validate" - % self.demo_request_1.external_id + % self.demo_request_1.get_api_external_id() ) response = self.http_post(url, data={}) self.assertEquals(response.status_code, 200) @@ -160,10 +195,10 @@ class TestSRController(BaseEMCRestCase): self.assertEquals(state, "done") def test_service_validate_draft_request(self): - self.sr_service.validate(self.demo_request_1.external_id) + self.sr_service.validate(self.demo_request_1.get_api_external_id()) self.assertEquals(self.demo_request_1.state, "done") self.assertTrue(len(self.demo_request_1.capital_release_request) > 0) def test_service_validate_done_request(self): with self.assertRaises(BadRequest): - self.sr_service.validate(self.demo_request_2.external_id) + self.sr_service.validate(self.demo_request_2.get_api_external_id())