Browse Source
Merge pull request #116 from coopiteasy/12.0-emca-mark-invoice-paid
Merge pull request #116 from coopiteasy/12.0-emca-mark-invoice-paid
[12.0] emc_api: mark invoice as paidpull/117/head 12.0-2020-08-19.00
Robin Keunen
4 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 1242 additions and 192 deletions
-
2.pre-commit-config.yaml
-
4README.md
-
20easy_my_coop/README.rst
-
4easy_my_coop/__manifest__.py
-
30easy_my_coop/demo/coop.xml
-
1easy_my_coop/readme/INSTALL.rst
-
37easy_my_coop/static/description/index.html
-
161easy_my_coop/tests/test_base.py
-
2easy_my_coop_api/__manifest__.py
-
19easy_my_coop_api/demo/demo.xml
-
1easy_my_coop_api/models/__init__.py
-
81easy_my_coop_api/models/external_id_mixin.py
-
3easy_my_coop_api/services/__init__.py
-
21easy_my_coop_api/services/abstract_emc_service.py
-
78easy_my_coop_api/services/account_invoice_service.py
-
92easy_my_coop_api/services/account_payment_service.py
-
3easy_my_coop_api/services/ping_service.py
-
81easy_my_coop_api/services/schemas.py
-
81easy_my_coop_api/services/subscription_request_service.py
-
3easy_my_coop_api/tests/__init__.py
-
206easy_my_coop_api/tests/common.py
-
101easy_my_coop_api/tests/test_account_invoice.py
-
69easy_my_coop_api/tests/test_account_payment.py
-
83easy_my_coop_api/tests/test_external_id_mixin.py
-
4easy_my_coop_api/tests/test_registry.py
-
88easy_my_coop_api/tests/test_subscription_requests.py
-
1easy_my_coop_be/README.rst
-
11easy_my_coop_ch/README.rst
-
3easy_my_coop_ch/__manifest__.py
-
5easy_my_coop_ch/static/description/index.html
-
5easy_my_coop_dividend/__manifest__.py
-
6easy_my_coop_dividend/readme/DESCRIPTION.rst
-
21easy_my_coop_es/__manifest__.py
-
12easy_my_coop_es/models/coop.py
-
3easy_my_coop_fr/README.rst
-
2easy_my_coop_fr/static/description/index.html
-
1easy_my_coop_loan/README.rst
-
1easy_my_coop_loan_website/README.rst
-
4easy_my_coop_taxshelter_report/README.rst
-
2easy_my_coop_taxshelter_report/static/description/index.html
-
1easy_my_coop_website/README.rst
-
6easy_my_coop_website/controllers/main.py
-
12easy_my_coop_website/models/company.py
-
1easy_my_coop_website/views/res_company_view.xml
-
1easy_my_coop_website_portal/README.rst
-
2easy_my_coop_website_portal/controllers/main.py
-
3partner_age/README.rst
-
2partner_age/__manifest__.py
-
2partner_age/static/description/index.html
-
8theme_light/README.rst
-
2theme_light/static/description/index.html
-
2website_recaptcha_reloaded/README.rst
-
10website_recaptcha_reloaded/__manifest__.py
@ -0,0 +1,19 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
Copyright 2020 Coop IT Easy |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
--> |
|||
<odoo> |
|||
<record id="auth_api_key_manager_emc_demo" model="auth.api.key"> |
|||
<field name="user_id" ref="easy_my_coop.res_users_manager_emc_demo"/> |
|||
<field name="key">cbd07f57-c903-43b4-b668-436b3bec5f15</field> |
|||
</record> |
|||
|
|||
<record id="easy_my_coop.subscription_request_1_demo" model="subscription.request"> |
|||
<field name="_api_external_id">1</field> |
|||
</record> |
|||
|
|||
<record id="easy_my_coop.subscription_request_waiting_demo" model="subscription.request"> |
|||
<field name="_api_external_id">2</field> |
|||
</record> |
|||
</odoo> |
@ -1 +1,2 @@ |
|||
from . import auth_api_key |
|||
from . import external_id_mixin |
@ -0,0 +1,81 @@ |
|||
# 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). |
|||
|
|||
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 AccountPayment(models.Model): |
|||
_name = "account.payment" |
|||
_inherit = ["account.payment", "external.id.mixin"] |
|||
|
|||
|
|||
class ProductTemplate(models.Model): |
|||
_name = "product.template" |
|||
_inherit = ["product.template", "external.id.mixin"] |
@ -1,2 +1,5 @@ |
|||
from . import abstract_emc_service |
|||
from . import ping_service |
|||
from . import subscription_request_service |
|||
from . import account_invoice_service |
|||
from . import account_payment_service |
@ -0,0 +1,21 @@ |
|||
# Copyright 2019 Coop IT Easy SCRL fs |
|||
# Robin Keunen <robin@coopiteasy.be> |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|||
# pylint: disable=consider-merging-classes-inherited |
|||
|
|||
from odoo.addons.component.core import AbstractComponent |
|||
|
|||
|
|||
class BaseRestService(AbstractComponent): |
|||
_name = "emc.rest.service" |
|||
_inherit = "base.rest.service" |
|||
_collection = "emc.services" |
|||
_description = """ |
|||
Base Rest Services |
|||
""" |
|||
|
|||
def _one_to_many_to_dict(self, record): |
|||
if record: |
|||
return {"id": record.get_api_external_id(), "name": record.name} |
|||
else: |
|||
return {} |
@ -0,0 +1,78 @@ |
|||
# Copyright 2019 Coop IT Easy SCRL fs |
|||
# Robin Keunen <robin@coopiteasy.be> |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|||
# pylint: disable=consider-merging-classes-inherited |
|||
|
|||
import logging |
|||
|
|||
from werkzeug.exceptions import NotFound |
|||
|
|||
from odoo import _ |
|||
from odoo.fields import Date |
|||
|
|||
from odoo.addons.base_rest.http import wrapJsonException |
|||
from odoo.addons.component.core import Component |
|||
|
|||
from . import schemas |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class AccountInvoiceService(Component): |
|||
_name = "account.invoice.service" |
|||
_inherit = "emc.rest.service" |
|||
_usage = "invoice" |
|||
_description = """ |
|||
Account Invoice Services |
|||
""" |
|||
|
|||
def get(self, _id): |
|||
sr = self.env["account.invoice"].search( |
|||
[("_api_external_id", "=", _id)] |
|||
) |
|||
if sr: |
|||
return self._to_dict(sr) |
|||
else: |
|||
raise wrapJsonException( |
|||
NotFound(_("No invoice found for id %s") % _id) |
|||
) |
|||
|
|||
def _to_dict(self, invoice): |
|||
invoice.ensure_one() |
|||
|
|||
data = { |
|||
"id": invoice.get_api_external_id(), |
|||
"name": invoice.name, |
|||
"state": invoice.state, |
|||
"type": invoice.type, |
|||
"date": Date.to_string(invoice.date), |
|||
"date_due": Date.to_string(invoice.date_due), |
|||
"date_invoice": Date.to_string(invoice.date_invoice), |
|||
"partner": self._one_to_many_to_dict(invoice.partner_id), |
|||
"journal": self._one_to_many_to_dict(invoice.journal_id), |
|||
"account": self._one_to_many_to_dict(invoice.account_id), |
|||
"subscription_request": self._one_to_many_to_dict( |
|||
invoice.subscription_request |
|||
), |
|||
"invoice_lines": [ |
|||
self._line_to_dict(line) for line in invoice.invoice_line_ids |
|||
], |
|||
} |
|||
return data |
|||
|
|||
def _line_to_dict(self, line): |
|||
return { |
|||
"name": line.name, |
|||
"account": self._one_to_many_to_dict(line.account_id), |
|||
"product": self._one_to_many_to_dict( |
|||
line.product_id.product_tmpl_id |
|||
), |
|||
"quantity": line.quantity, |
|||
"price_unit": line.price_unit, |
|||
} |
|||
|
|||
def _validator_get(self): |
|||
return schemas.S_INVOICE_GET |
|||
|
|||
def _validator_return_get(self): |
|||
return schemas.S_INVOICE_RETURN_GET |
@ -0,0 +1,92 @@ |
|||
# Copyright 2019 Coop IT Easy SCRL fs |
|||
# Robin Keunen <robin@coopiteasy.be> |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|||
# pylint: disable=consider-merging-classes-inherited |
|||
|
|||
import logging |
|||
|
|||
from werkzeug.exceptions import NotFound |
|||
|
|||
from odoo import _ |
|||
from odoo.fields import Date |
|||
|
|||
from odoo.addons.base_rest.http import wrapJsonException |
|||
from odoo.addons.component.core import Component |
|||
|
|||
from . import schemas |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class AccountPaymentService(Component): |
|||
_name = "account.payment.service" |
|||
_inherit = "emc.rest.service" |
|||
_usage = "payment" |
|||
_description = """ |
|||
Account Payment Services |
|||
""" |
|||
|
|||
def create(self, **params): # pylint: disable=method-required-super |
|||
params = self._prepare_create(params) |
|||
payment = self.env["account.payment"].create(params) |
|||
payment.post() |
|||
return self._to_dict(payment) |
|||
|
|||
def _prepare_create(self, params): |
|||
"""Prepare a writable dictionary of values""" |
|||
journal = self.env["account.journal"].search( |
|||
[("_api_external_id", "=", params["journal"])] |
|||
) |
|||
if not journal: |
|||
raise wrapJsonException( |
|||
NotFound(_("No journal %s on platform") % params["journal"]) |
|||
) |
|||
|
|||
invoice = self.env["account.invoice"].search( |
|||
[("_api_external_id", "=", params["invoice"])] |
|||
) |
|||
if not invoice: |
|||
raise wrapJsonException( |
|||
NotFound(_("No invoice %s on platform") % params["invoice"]) |
|||
) |
|||
|
|||
payment_method_id = self.env["account.payment.method"].search( |
|||
[ |
|||
("code", "=", params["payment_method"]), |
|||
("payment_type", "=", params["payment_type"]), |
|||
] |
|||
) |
|||
if not payment_method_id: |
|||
codes = ( |
|||
self.env["account.payment.method"].search([]).mapped("code") |
|||
) |
|||
raise wrapJsonException( |
|||
NotFound(_("Payment method must be one of %s") % codes) |
|||
) |
|||
|
|||
return { |
|||
"payment_date": params["payment_date"], |
|||
"amount": params["amount"], |
|||
"payment_type": params["payment_type"], |
|||
"communication": params["communication"], |
|||
"invoice_ids": [(4, invoice.id, False)], |
|||
"payment_method_id": payment_method_id.id, |
|||
"journal_id": journal.id, |
|||
"partner_type": "customer", |
|||
} |
|||
|
|||
def _to_dict(self, payment): |
|||
return { |
|||
"id": payment.get_api_external_id(), |
|||
"journal": self._one_to_many_to_dict(payment.journal_id), |
|||
"invoice": self._one_to_many_to_dict(payment.invoice_ids), |
|||
"payment_date": Date.to_string(payment.payment_date), |
|||
"amount": payment.amount, |
|||
"communication": payment.communication, |
|||
} |
|||
|
|||
def _validator_create(self): |
|||
return schemas.S_PAYMENT_CREATE |
|||
|
|||
def _validator_return_create(self): |
|||
return schemas.S_PAYMENT_RETURN_GET |
@ -1,3 +1,6 @@ |
|||
from . import test_ping |
|||
from . import test_registry |
|||
from . import test_external_id_mixin |
|||
from . import test_subscription_requests |
|||
from . import test_account_invoice |
|||
from . import test_account_payment |
@ -0,0 +1,101 @@ |
|||
# 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). |
|||
|
|||
from odoo.fields import Date |
|||
|
|||
from odoo.addons.base_rest.controllers.main import _PseudoCollection |
|||
from odoo.addons.component.core import WorkContext |
|||
|
|||
from .common import BaseEMCRestCase |
|||
|
|||
|
|||
class TestAccountInvoiceController(BaseEMCRestCase): |
|||
@classmethod |
|||
def setUpClass(cls, *args, **kwargs): |
|||
super().setUpClass(*args, **kwargs) |
|||
|
|||
def setUp(self): |
|||
res = super().setUp() |
|||
collection = _PseudoCollection("emc.services", self.env) |
|||
emc_services_env = WorkContext( |
|||
model_name="rest.service.registration", collection=collection |
|||
) |
|||
self.ai_service = emc_services_env.component(usage="invoice") |
|||
|
|||
self.share_type_A = self.browse_ref( |
|||
"easy_my_coop.product_template_share_type_1_demo" |
|||
) |
|||
self._capital_release_create() |
|||
|
|||
today = Date.to_string(Date.today()) |
|||
self.demo_invoice_dict = { |
|||
"id": 1, |
|||
"name": "Capital Release Example", |
|||
"partner": {"id": 1, "name": "Catherine des Champs"}, |
|||
"account": {"id": 1, "name": "Cooperators"}, |
|||
"journal": {"id": 1, "name": "Subscription Journal"}, |
|||
"subscription_request": {}, |
|||
"state": "open", |
|||
"date": today, |
|||
"date_invoice": today, |
|||
"date_due": today, |
|||
"type": "out_invoice", |
|||
"invoice_lines": [ |
|||
{ |
|||
"name": "Share Type A", |
|||
"product": {"id": 1, "name": "Part A - Founder"}, |
|||
"price_unit": 100.0, |
|||
"quantity": 2.0, |
|||
"account": {"id": 2, "name": "Equity"}, |
|||
} |
|||
], |
|||
} |
|||
return res |
|||
|
|||
def _capital_release_create(self): |
|||
self.coop_candidate = self.env["res.partner"].create( |
|||
{ |
|||
"name": "Catherine des Champs", |
|||
"company_id": self.company.id, |
|||
"property_account_receivable_id": self.receivable.id, |
|||
"property_account_payable_id": self.payable.id, |
|||
} |
|||
) |
|||
|
|||
capital_release_line = [ |
|||
( |
|||
0, |
|||
False, |
|||
{ |
|||
"name": "Share Type A", |
|||
"account_id": self.equity_account.id, |
|||
"quantity": 2.0, |
|||
"price_unit": 100.0, |
|||
"product_id": self.share_type_A.product_variant_id.id, |
|||
}, |
|||
) |
|||
] |
|||
|
|||
self.capital_release = self.env["account.invoice"].create( |
|||
{ |
|||
"name": "Capital Release Example", |
|||
"partner_id": self.coop_candidate.id, |
|||
"type": "out_invoice", |
|||
"invoice_line_ids": capital_release_line, |
|||
"account_id": self.cooperator_account.id, |
|||
"journal_id": self.subscription_journal.id, |
|||
} |
|||
) |
|||
self.capital_release.action_invoice_open() |
|||
|
|||
def test_service_get(self): |
|||
external_id = self.capital_release.get_api_external_id() |
|||
result = self.ai_service.get(external_id) |
|||
self.assertEquals(self.demo_invoice_dict, result) |
|||
|
|||
def test_route_get(self): |
|||
external_id = self.capital_release.get_api_external_id() |
|||
route = "/api/invoice/%s" % external_id |
|||
content = self.http_get_content(route) |
|||
self.assertEquals(self.demo_invoice_dict, content) |
@ -0,0 +1,69 @@ |
|||
# 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). |
|||
|
|||
from odoo.fields import Date |
|||
|
|||
from odoo.addons.base_rest.controllers.main import _PseudoCollection |
|||
from odoo.addons.component.core import WorkContext |
|||
|
|||
from .common import BaseEMCRestCase |
|||
|
|||
|
|||
class TestAccountPaymentController(BaseEMCRestCase): |
|||
@classmethod |
|||
def setUpClass(cls, *args, **kwargs): |
|||
super().setUpClass(*args, **kwargs) |
|||
|
|||
def setUp(self): |
|||
res = super().setUp() |
|||
collection = _PseudoCollection("emc.services", self.env) |
|||
emc_services_env = WorkContext( |
|||
model_name="rest.service.registration", collection=collection |
|||
) |
|||
self.ap_service = emc_services_env.component(usage="payment") |
|||
self.ai_service = emc_services_env.component(usage="invoice") |
|||
self.demo_request_1 = self.browse_ref( |
|||
"easy_my_coop.subscription_request_1_demo" |
|||
) |
|||
return res |
|||
|
|||
def test_service_create(self): |
|||
self.demo_request_1.validate_subscription_request() |
|||
invoice = self.demo_request_1.capital_release_request |
|||
journal = self.bank_journal |
|||
|
|||
result = self.ap_service.create( |
|||
payment_date=Date.to_string(Date.today()), |
|||
amount=self.demo_request_1.subscription_amount, |
|||
payment_type="inbound", |
|||
payment_method="manual", |
|||
communication=invoice.reference, |
|||
invoice=invoice.get_api_external_id(), |
|||
journal=journal.get_api_external_id(), |
|||
) |
|||
|
|||
demo_payment_dict = { |
|||
"id": result["id"], |
|||
"communication": invoice.reference, |
|||
"invoice": { |
|||
"id": invoice.get_api_external_id(), |
|||
"name": invoice.name, |
|||
}, |
|||
"amount": self.demo_request_1.subscription_amount, |
|||
"payment_date": Date.to_string(Date.today()), |
|||
"journal": { |
|||
"id": self.bank_journal.get_api_external_id(), |
|||
"name": self.bank_journal.name, |
|||
}, |
|||
} |
|||
self.assertEquals(demo_payment_dict, result) |
|||
|
|||
invoice = self.ai_service.get(invoice.get_api_external_id()) |
|||
self.assertEquals("paid", invoice["state"]) |
|||
|
|||
# def test_route_create(self): # todo |
|||
# external_id = self.capital_release.get_api_external_id() |
|||
# route = "/api/payment/%s" % external_id |
|||
# content = self.http_get_content(route) |
|||
# self.assertEquals(self.demo_payment_dict, content) |
@ -0,0 +1,83 @@ |
|||
# 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). |
|||
|
|||
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()) |
@ -1,3 +1,3 @@ |
|||
This module allows to calculate the dividend to give to a cooperator base |
|||
on the amount of his shares, the percentage allocated and for how long the |
|||
shares have been owned on prorata temporis calculation. |
|||
This module allows to calculate the dividend to give to a cooperator base |
|||
on the amount of his shares, the percentage allocated and for how long the |
|||
shares have been owned on prorata temporis calculation. |
@ -1,17 +1,14 @@ |
|||
{ |
|||
'name': "Easy My Coop Spain", |
|||
'version': '12.0.0.0.13', |
|||
'depends': ['easy_my_coop'], |
|||
'author': "Coop IT Easy SCRLfs, " |
|||
"Coopdevs Treball SCCL", |
|||
'mantainer': "Coopdevs Treball SCCL", |
|||
'category': "Cooperative management", |
|||
'description': """ |
|||
"name": "Easy My Coop Spain", |
|||
"version": "12.0.0.0.13", |
|||
"depends": ["easy_my_coop"], |
|||
"author": "Coop IT Easy SCRLfs, " "Coopdevs Treball SCCL", |
|||
"mantainer": "Coopdevs Treball SCCL", |
|||
"category": "Cooperative management", |
|||
"summary": """ |
|||
Easy My Coop localization for Spain |
|||
""", |
|||
"license": "AGPL-3", |
|||
'data': [ |
|||
"views/subscription_request_view.xml", |
|||
], |
|||
'installable': True, |
|||
"data": ["views/subscription_request_view.xml"], |
|||
"installable": True, |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue