Browse Source

Merge pull request #116 from coopiteasy/12.0-emca-mark-invoice-paid

[12.0] emc_api: mark invoice as paid
pull/117/head 12.0-2020-08-19.00
Robin Keunen 4 years ago
committed by GitHub
parent
commit
48f2a754d8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .pre-commit-config.yaml
  2. 4
      README.md
  3. 20
      easy_my_coop/README.rst
  4. 4
      easy_my_coop/__manifest__.py
  5. 30
      easy_my_coop/demo/coop.xml
  6. 1
      easy_my_coop/readme/INSTALL.rst
  7. 37
      easy_my_coop/static/description/index.html
  8. 161
      easy_my_coop/tests/test_base.py
  9. 2
      easy_my_coop_api/__manifest__.py
  10. 19
      easy_my_coop_api/demo/demo.xml
  11. 1
      easy_my_coop_api/models/__init__.py
  12. 81
      easy_my_coop_api/models/external_id_mixin.py
  13. 3
      easy_my_coop_api/services/__init__.py
  14. 21
      easy_my_coop_api/services/abstract_emc_service.py
  15. 78
      easy_my_coop_api/services/account_invoice_service.py
  16. 92
      easy_my_coop_api/services/account_payment_service.py
  17. 3
      easy_my_coop_api/services/ping_service.py
  18. 81
      easy_my_coop_api/services/schemas.py
  19. 81
      easy_my_coop_api/services/subscription_request_service.py
  20. 3
      easy_my_coop_api/tests/__init__.py
  21. 206
      easy_my_coop_api/tests/common.py
  22. 101
      easy_my_coop_api/tests/test_account_invoice.py
  23. 69
      easy_my_coop_api/tests/test_account_payment.py
  24. 83
      easy_my_coop_api/tests/test_external_id_mixin.py
  25. 4
      easy_my_coop_api/tests/test_registry.py
  26. 88
      easy_my_coop_api/tests/test_subscription_requests.py
  27. 1
      easy_my_coop_be/README.rst
  28. 11
      easy_my_coop_ch/README.rst
  29. 3
      easy_my_coop_ch/__manifest__.py
  30. 5
      easy_my_coop_ch/static/description/index.html
  31. 5
      easy_my_coop_dividend/__manifest__.py
  32. 21
      easy_my_coop_es/__manifest__.py
  33. 12
      easy_my_coop_es/models/coop.py
  34. 3
      easy_my_coop_fr/README.rst
  35. 2
      easy_my_coop_fr/static/description/index.html
  36. 1
      easy_my_coop_loan/README.rst
  37. 1
      easy_my_coop_loan_website/README.rst
  38. 4
      easy_my_coop_taxshelter_report/README.rst
  39. 2
      easy_my_coop_taxshelter_report/static/description/index.html
  40. 1
      easy_my_coop_website/README.rst
  41. 6
      easy_my_coop_website/controllers/main.py
  42. 12
      easy_my_coop_website/models/company.py
  43. 1
      easy_my_coop_website/views/res_company_view.xml
  44. 1
      easy_my_coop_website_portal/README.rst
  45. 2
      easy_my_coop_website_portal/controllers/main.py
  46. 3
      partner_age/README.rst
  47. 2
      partner_age/__manifest__.py
  48. 2
      partner_age/static/description/index.html
  49. 8
      theme_light/README.rst
  50. 2
      theme_light/static/description/index.html
  51. 2
      website_recaptcha_reloaded/README.rst
  52. 10
      website_recaptcha_reloaded/__manifest__.py

2
.pre-commit-config.yaml

@ -33,7 +33,7 @@ repos:
- id: check-executables-have-shebangs - id: check-executables-have-shebangs
- id: check-merge-conflict - id: check-merge-conflict
- id: check-symlinks - id: check-symlinks
# - id: check-xml
- id: check-xml
- id: mixed-line-ending - id: mixed-line-ending
args: ["--fix=lf"] args: ["--fix=lf"]
- repo: https://github.com/pre-commit/mirrors-pylint - repo: https://github.com/pre-commit/mirrors-pylint

4
README.md

@ -19,13 +19,15 @@ Available addons
addon | version | summary addon | version | summary
--- | --- | --- --- | --- | ---
[easy_my_coop](easy_my_coop/) | 12.0.3.0.1 | Manage your cooperative shares [easy_my_coop](easy_my_coop/) | 12.0.3.0.1 | Manage your cooperative shares
[easy_my_coop_api](easy_my_coop_api/) | 12.0.0.0.1 | Open Easy My Coop to the world: RESTful API.
[easy_my_coop_be](easy_my_coop_be/) | 12.0.1.2.0 | Easy My Coop Belgium Localization [easy_my_coop_be](easy_my_coop_be/) | 12.0.1.2.0 | Easy My Coop Belgium Localization
[easy_my_coop_ch](easy_my_coop_ch/) | 12.0.1.0.2 | Easy My Coop Switzerland localization [easy_my_coop_ch](easy_my_coop_ch/) | 12.0.1.0.2 | Easy My Coop Switzerland localization
[easy_my_coop_es](easy_my_coop_es/) | 12.0.0.0.13 | Easy My Coop Spain
[easy_my_coop_fr](easy_my_coop_fr/) | 12.0.1.0.1 | This is the french localization for the easy my coop module [easy_my_coop_fr](easy_my_coop_fr/) | 12.0.1.0.1 | This is the french localization for the easy my coop module
[easy_my_coop_loan](easy_my_coop_loan/) | 12.0.1.0.1 | This module allows to manage the bonds and subordinated loans subscription life cycle. [easy_my_coop_loan](easy_my_coop_loan/) | 12.0.1.0.1 | This module allows to manage the bonds and subordinated loans subscription life cycle.
[easy_my_coop_loan_website](easy_my_coop_loan_website/) | 12.0.1.0.1 | This module implements the subscription page for bonds and subordinated loans. [easy_my_coop_loan_website](easy_my_coop_loan_website/) | 12.0.1.0.1 | This module implements the subscription page for bonds and subordinated loans.
[easy_my_coop_taxshelter_report](easy_my_coop_taxshelter_report/) | 12.0.1.0.1 | This module allows you to create a fiscal declaration year and to print tax shelter declaration for each cooperator. [easy_my_coop_taxshelter_report](easy_my_coop_taxshelter_report/) | 12.0.1.0.1 | This module allows you to create a fiscal declaration year and to print tax shelter declaration for each cooperator.
[easy_my_coop_website](easy_my_coop_website/) | 12.0.1.0.0 | This module adds the cooperator subscription form allowing to subscribe for shares online.
[easy_my_coop_website](easy_my_coop_website/) | 12.0.1.0.3 | This module adds the cooperator subscription form allowing to subscribe for shares online.
[easy_my_coop_website_portal](easy_my_coop_website_portal/) | 12.0.1.0.0 | Show cooperator information in the website portal. [easy_my_coop_website_portal](easy_my_coop_website_portal/) | 12.0.1.0.0 | Show cooperator information in the website portal.
[partner_age](partner_age/) | 12.0.2.0.0 | This module computes the age of the partner. [partner_age](partner_age/) | 12.0.2.0.0 | This module computes the age of the partner.
[theme_light](theme_light/) | 12.0.1.0.0 | extract of the theme zen [theme_light](theme_light/) | 12.0.1.0.0 | extract of the theme zen

20
easy_my_coop/README.rst

@ -32,6 +32,26 @@ Please don't hesitate to suggest one of your modules to this project.
.. contents:: .. contents::
:local: :local:
Installation
============
## Deploying with pip
We used [odoo setup tools](https://pypi.org/project/setuptools-odoo/#packaging-a-single-addon) to generate the pypi files from the odoo manifests. To deploy any packaged module, so that odoo can later install them,
you can create a venv with this name (it's git-ignored)
```shell
python -m venv venv
```
And then pip-install them [from pypi](https://pypi.org/user/coopdevs/).
### Example
For instance, for the addon `easy_my_coop_website_portal`
```shell
pip install odoo12-addon-easy-my-coop-website-portal==12.0.1.0.0.99.dev9
```
Beware that for word separation, pypi uses dashes `-` and odoo underscores `_`.
Bug Tracker Bug Tracker
=========== ===========

4
easy_my_coop/__manifest__.py

@ -25,10 +25,6 @@
"category": "Cooperative management", "category": "Cooperative management",
"website": "https://www.coopiteasy.be", "website": "https://www.coopiteasy.be",
"license": "AGPL-3", "license": "AGPL-3",
"description": """
This module allows to manage the cooperator subscription and all the
cooperative business processes.
""",
"data": [ "data": [
"data/easy_my_coop_data.xml", "data/easy_my_coop_data.xml",
"data/paperformat.xml", "data/paperformat.xml",

30
easy_my_coop/demo/coop.xml

@ -76,8 +76,11 @@
<field name="reconcile" eval="True"/> <field name="reconcile" eval="True"/>
</record> </record>
<record id="base.main_company" model="res.company">
<field name="property_cooperator_account" ref="account_cooperator_demo"/>
<record id="account_equity_demo" model="account.account">
<field name="name">Equity</field>
<field name="code">100910</field>
<field eval="True" name="reconcile"/>
<field name="user_type_id" ref="account.data_account_type_equity"/>
</record> </record>
<record id="base.main_company" model="res.company"> <record id="base.main_company" model="res.company">
@ -85,6 +88,11 @@
ref="account_cooperator_demo"/> ref="account_cooperator_demo"/>
</record> </record>
<record id="subscription_journal" model="account.journal">
<field name="default_credit_account_id" ref="account_equity_demo"/>
<field name="default_debit_account_id" ref="account_equity_demo"/>
</record>
<record id="product_template_share_type_1_demo" model="product.template"> <record id="product_template_share_type_1_demo" model="product.template">
<field name="name">Part A - Founder</field> <field name="name">Part A - Founder</field>
<field name="short_name">Part A</field> <field name="short_name">Part A</field>
@ -127,6 +135,23 @@
<field name="skip_control_ng" eval="True"/> <field name="skip_control_ng" eval="True"/>
</record> </record>
<record id="subscription_request_waiting_demo" model="subscription.request">
<field name="name">Catherine des Champs</field>
<field name="email">catherine@demo.net</field>
<field name="address">Chemin des bois fleuris</field>
<field name="zip_code">1000</field>
<field name="city">Brussels</field>
<field name="country_id" ref="base.be"/>
<field name="date" eval="datetime.now() - timedelta(days=60)"/>
<field name="source">manual</field>
<field name="ordered_parts">4</field>
<field name="share_product_id" model="product.template"
eval="obj(ref('product_template_share_type_1_demo')).product_variant_id.id"/>
<field name="lang">en_US</field>
<field name="skip_control_ng" eval="True"/>
<field name="state">waiting</field>
</record>
<record id="share_line_1_demo" model="share.line"> <record id="share_line_1_demo" model="share.line">
<field name="share_product_id" model="product.template" <field name="share_product_id" model="product.template"
eval="obj(ref('product_template_share_type_1_demo')).product_variant_id.id"/> eval="obj(ref('product_template_share_type_1_demo')).product_variant_id.id"/>
@ -146,4 +171,5 @@
<field name="effective_date" <field name="effective_date"
eval="datetime.now() - timedelta(days=120)"/> eval="datetime.now() - timedelta(days=120)"/>
</record> </record>
</odoo> </odoo>

1
easy_my_coop/description.rst → easy_my_coop/readme/INSTALL.rst

@ -14,4 +14,3 @@ For instance, for the addon `easy_my_coop_website_portal`
pip install odoo12-addon-easy-my-coop-website-portal==12.0.1.0.0.99.dev9 pip install odoo12-addon-easy-my-coop-website-portal==12.0.1.0.0.99.dev9
``` ```
Beware that for word separation, pypi uses dashes `-` and odoo underscores `_`. Beware that for word separation, pypi uses dashes `-` and odoo underscores `_`.

37
easy_my_coop/static/description/index.html

@ -380,17 +380,34 @@ ul.auto-toc {
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
<li><a class="reference internal" href="#installation" id="id1">Installation</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="installation">
<h1><a class="toc-backref" href="#id1">Installation</a></h1>
<p>## Deploying with pip</p>
<p>We used [odoo setup tools](<a class="reference external" href="https://pypi.org/project/setuptools-odoo/#packaging-a-single-addon">https://pypi.org/project/setuptools-odoo/#packaging-a-single-addon</a>) to generate the pypi files from the odoo manifests. To deploy any packaged module, so that odoo can later install them,
you can create a venv with this name (it’s git-ignored)
<tt class="docutils literal">`shell
python <span class="pre">-m</span> venv venv
`</tt>
And then pip-install them [from pypi](<a class="reference external" href="https://pypi.org/user/coopdevs/">https://pypi.org/user/coopdevs/</a>).</p>
<p>### Example</p>
<p>For instance, for the addon <cite>easy_my_coop_website_portal</cite>
<tt class="docutils literal">`shell
pip install <span class="pre">odoo12-addon-easy-my-coop-website-portal==12.0.1.0.0.99.dev9</span>
`</tt>
Beware that for word separation, pypi uses dashes <cite>-</cite> and odoo underscores <cite>_</cite>.</p>
</div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
@ -398,21 +415,21 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id2">Credits</a></h1>
<h1><a class="toc-backref" href="#id3">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
<h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Coop IT Easy SCRLfs</li> <li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<h2><a class="toc-backref" href="#id5">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Coop IT Easy SCRLfs</li> <li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id5">Maintainers</a></h2>
<h2><a class="toc-backref" href="#id6">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop">coopiteasy/vertical-cooperative</a> project on GitHub.</p> <p>This module is part of the <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop">coopiteasy/vertical-cooperative</a> project on GitHub.</p>
<p>You are welcome to contribute.</p> <p>You are welcome to contribute.</p>
</div> </div>

161
easy_my_coop/tests/test_base.py

@ -6,12 +6,165 @@ import odoo.tests.common as common
class EMCBaseCase(common.TransactionCase): class EMCBaseCase(common.TransactionCase):
@classmethod
def setUpClass(cls, *args, **kwargs):
super().setUpClass(*args, **kwargs)
def _chart_template_create(self):
transfer_account_id = self.env["account.account.template"].create(
{
"code": "000",
"name": "Liquidity Transfers",
"reconcile": True,
"user_type_id": self.env.ref(
"account.data_account_type_current_assets"
).id,
}
)
self.chart = self.env["account.chart.template"].create(
{
"name": "Test COA",
"code_digits": 4,
"bank_account_code_prefix": 1014,
"cash_account_code_prefix": 1014,
"currency_id": self.env.ref("base.USD").id,
"transfer_account_code_prefix": "000",
}
)
transfer_account_id.update({"chart_template_id": self.chart.id})
self.env["ir.model.data"].create(
{
"res_id": transfer_account_id.id,
"model": transfer_account_id._name,
"name": "Liquidity Transfers",
}
)
act = self.env["account.account.template"].create(
{
"code": "001",
"name": "Expenses",
"user_type_id": self.env.ref(
"account.data_account_type_expenses"
).id,
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "expenses"}
)
act = self.env["account.account.template"].create(
{
"code": "002",
"name": "Product Sales",
"user_type_id": self.env.ref(
"account.data_account_type_revenue"
).id,
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "sales"}
)
act = self.env["account.account.template"].create(
{
"code": "003",
"name": "Account Receivable",
"user_type_id": self.env.ref(
"account.data_account_type_receivable"
).id,
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "receivable"}
)
act = self.env["account.account.template"].create(
{
"code": "004",
"name": "Account Payable",
"user_type_id": self.env.ref(
"account.data_account_type_payable"
).id,
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "payable"}
)
def _add_chart_of_accounts(self):
self.company = self.env.user.company_id
self.chart.try_loading_for_current_company()
self.revenue = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_revenue").id,
)
],
limit=1,
)
self.expense = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_expenses").id,
)
],
limit=1,
)
self.receivable = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_receivable").id,
)
],
limit=1,
)
self.payable = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_payable").id,
)
],
limit=1,
)
self.equity_account = self.env.ref("easy_my_coop.account_equity_demo")
self.cooperator_account = self.env.ref(
"easy_my_coop.account_cooperator_demo"
)
return True
def _journals_setup(self):
self.subscription_journal = self.env.ref(
"easy_my_coop.subscription_journal"
)
self.subscription_journal.write(
{
"default_debit_account_id": self.equity_account.id,
"default_credit_account_id": self.equity_account.id,
}
)
self.bank_journal = self.env["account.journal"].search(
[("type", "=", "bank")], limit=1
)
return True
def setUp(self): def setUp(self):
super(EMCBaseCase, self).setUp() super(EMCBaseCase, self).setUp()
# todo set from demo data
user = self.env["res.users"].browse(self.uid)
cooperator_account = self.ref("easy_my_coop.account_cooperator_demo")
user.company_id.property_cooperator_account = cooperator_account
self._chart_template_create()
self._add_chart_of_accounts()
self._journals_setup()
def as_user(self): def as_user(self):
self.uid = self.ref("base.user_demo") self.uid = self.ref("base.user_demo")

2
easy_my_coop_api/__manifest__.py

@ -18,7 +18,7 @@
Open Easy My Coop to the world: RESTful API. Open Easy My Coop to the world: RESTful API.
""", """,
"data": [], "data": [],
"demo": [],
"demo": ["demo/demo.xml"],
"installable": True, "installable": True,
"application": False, "application": False,
} }

19
easy_my_coop_api/demo/demo.xml

@ -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
easy_my_coop_api/models/__init__.py

@ -1 +1,2 @@
from . import auth_api_key from . import auth_api_key
from . import external_id_mixin

81
easy_my_coop_api/models/external_id_mixin.py

@ -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"]

3
easy_my_coop_api/services/__init__.py

@ -1,2 +1,5 @@
from . import abstract_emc_service
from . import ping_service from . import ping_service
from . import subscription_request_service from . import subscription_request_service
from . import account_invoice_service
from . import account_payment_service

21
easy_my_coop_api/services/abstract_emc_service.py

@ -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 {}

78
easy_my_coop_api/services/account_invoice_service.py

@ -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

92
easy_my_coop_api/services/account_payment_service.py

@ -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

3
easy_my_coop_api/services/ping_service.py

@ -10,10 +10,9 @@ from odoo.addons.component.core import Component
class PingService(Component): class PingService(Component):
_inherit = "base.rest.service"
_inherit = "emc.rest.service"
_name = "emc.services" _name = "emc.services"
_usage = "ping" # service_name _usage = "ping" # service_name
_collection = "emc.services"
_description = """ _description = """
Ping services (test the api) Ping services (test the api)
""" """

81
easy_my_coop_api/services/schemas.py

@ -9,12 +9,20 @@ from odoo.fields import Date
def date_validator(field, value, error): def date_validator(field, value, error):
try: try:
Date.from_string(value) Date.from_string(value)
except ValueError as e:
except ValueError:
return error( return error(
field, _("{} does not match format '%Y-%m-%d'".format(value)) field, _("{} does not match format '%Y-%m-%d'".format(value))
) )
S_MANY_2_ONE = {
"type": "dict",
"schema": {
"id": {"type": "integer", "required": True},
"name": {"type": "string", "required": True, "empty": False},
},
}
S_SUBSCRIPTION_REQUEST_GET = {"_id": {"type": "integer"}} S_SUBSCRIPTION_REQUEST_GET = {"_id": {"type": "integer"}}
S_SUBSCRIPTION_REQUEST_RETURN_GET = { S_SUBSCRIPTION_REQUEST_RETURN_GET = {
@ -24,13 +32,7 @@ S_SUBSCRIPTION_REQUEST_RETURN_GET = {
"date": {"type": "string", "required": True, "empty": False}, "date": {"type": "string", "required": True, "empty": False},
"state": {"type": "string", "required": True, "empty": False}, "state": {"type": "string", "required": True, "empty": False},
"ordered_parts": {"type": "integer", "required": True}, "ordered_parts": {"type": "integer", "required": True},
"share_product": {
"type": "dict",
"schema": {
"id": {"type": "integer", "required": True},
"name": {"type": "string", "required": True, "empty": False},
},
},
"share_product": S_MANY_2_ONE,
"address": { "address": {
"type": "dict", "type": "dict",
"schema": { "schema": {
@ -41,6 +43,12 @@ S_SUBSCRIPTION_REQUEST_RETURN_GET = {
}, },
}, },
"lang": {"type": "string", "required": True, "empty": False}, "lang": {"type": "string", "required": True, "empty": False},
"capital_release_request": {
"type": "list",
"schema": {"type": "integer"},
"required": True,
"empty": True,
},
} }
S_SUBSCRIPTION_REQUEST_SEARCH = { S_SUBSCRIPTION_REQUEST_SEARCH = {
@ -93,3 +101,60 @@ S_SUBSCRIPTION_REQUEST_UPDATE = {
"lang": {"type": "string"}, "lang": {"type": "string"},
"share_product": {"type": "integer"}, "share_product": {"type": "integer"},
} }
S_SUBSCRIPTION_REQUEST_VALIDATE = {"_id": {"type": "integer"}}
S_INVOICE_GET = {"_id": {"type": "integer"}}
S_INVOICE_LINE_RETURN_GET = {
"type": "list",
"schema": {
"type": "dict",
"schema": {
"name": {"type": "string", "required": True},
"account": S_MANY_2_ONE,
"product": S_MANY_2_ONE,
"quantity": {"type": "float", "required": True},
"price_unit": {"type": "float", "required": True},
},
},
"required": True,
"empty": True,
}
S_INVOICE_RETURN_GET = {
"id": {"type": "integer", "required": True},
"name": {"type": "string", "required": True, "empty": False},
"state": {"type": "string", "required": True, "empty": False},
"type": {"type": "string", "required": True, "empty": False},
"date": {"type": "string", "required": True, "empty": False},
"date_due": {"type": "string", "required": True, "empty": False},
"date_invoice": {"type": "string", "required": True, "empty": False},
"partner": S_MANY_2_ONE,
"journal": S_MANY_2_ONE,
"account": S_MANY_2_ONE,
"subscription_request": {
"type": "dict",
"schema": {"id": {"type": "integer"}, "name": {"type": "string"}},
},
"invoice_lines": S_INVOICE_LINE_RETURN_GET,
}
S_PAYMENT_RETURN_GET = {
"id": {"type": "integer", "required": True},
"journal": S_MANY_2_ONE,
"invoice": S_MANY_2_ONE,
"payment_date": {"type": "string", "check_with": date_validator},
"amount": {"type": "float", "required": True},
"communication": {"type": "string", "required": True},
}
S_PAYMENT_CREATE = {
"journal": {"type": "integer", "required": True},
"invoice": {"type": "integer", "required": True},
"payment_date": {"type": "string", "check_with": date_validator},
"amount": {"type": "float", "required": True},
"communication": {"type": "string", "required": True},
"payment_type": {"type": "string", "required": True},
"payment_method": {"type": "string", "required": True},
}

81
easy_my_coop_api/services/subscription_request_service.py

@ -19,16 +19,17 @@ _logger = logging.getLogger(__name__)
class SubscriptionRequestService(Component): class SubscriptionRequestService(Component):
_inherit = "base.rest.service"
_inherit = "emc.rest.service"
_name = "subscription.request.services" _name = "subscription.request.services"
_usage = "subscription-request" _usage = "subscription-request"
_collection = "emc.services"
_description = """ _description = """
Subscription requests
Subscription Request Services
""" """
def get(self, _id): def get(self, _id):
sr = self.env["subscription.request"].browse(_id)
sr = self.env["subscription.request"].search(
[("_api_external_id", "=", _id)]
)
if sr: if sr:
return self._to_dict(sr) return self._to_dict(sr)
else: else:
@ -63,7 +64,9 @@ class SubscriptionRequestService(Component):
def update(self, _id, **params): def update(self, _id, **params):
params = self._prepare_update(params) params = self._prepare_update(params)
sr = self.env["subscription.request"].browse(_id)
sr = self.env["subscription.request"].search(
[("_api_external_id", "=", _id)]
)
if not sr: if not sr:
raise wrapJsonException( raise wrapJsonException(
NotFound(_("No subscription request for id %s") % _id) NotFound(_("No subscription request for id %s") % _id)
@ -71,19 +74,43 @@ class SubscriptionRequestService(Component):
sr.write(params) sr.write(params)
return self._to_dict(sr) return self._to_dict(sr)
def validate(self, _id, **params):
sr = self.env["subscription.request"].search(
[("_api_external_id", "=", _id)]
)
if not sr:
raise wrapJsonException(
NotFound(_("No subscription request for id %s") % _id)
)
if sr.state != "draft":
raise wrapJsonException(
BadRequest(
_("Subscription request %s is not in draft state") % _id
)
)
sr.validate_subscription_request()
return self._to_dict(sr)
def _to_dict(self, sr): def _to_dict(self, sr):
sr.ensure_one() sr.ensure_one()
if sr.capital_release_request:
invoice_ids = [
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 { return {
"id": sr.id,
"id": sr.get_api_external_id(),
"name": sr.name, "name": sr.name,
"email": sr.email, "email": sr.email,
"state": sr.state, "state": sr.state,
"date": Date.to_string(sr.date), "date": Date.to_string(sr.date),
"ordered_parts": sr.ordered_parts, "ordered_parts": sr.ordered_parts,
"share_product": {
"id": sr.share_product_id.id,
"name": sr.share_product_id.name,
},
"share_product": self._one_to_many_to_dict(share_product),
"address": { "address": {
"street": sr.address, "street": sr.address,
"zip_code": sr.zip_code, "zip_code": sr.zip_code,
@ -91,6 +118,7 @@ class SubscriptionRequestService(Component):
"country": sr.country_id.code, "country": sr.country_id.code,
}, },
"lang": sr.lang, "lang": sr.lang,
"capital_release_request": invoice_ids,
} }
def _get_country(self, code): def _get_country(self, code):
@ -102,15 +130,29 @@ class SubscriptionRequestService(Component):
BadRequest(_("No country for isocode %s") % code) BadRequest(_("No country for isocode %s") % code)
) )
def _get_share_product(self, template_id):
product = self.env["product.product"].search(
[("product_tmpl_id", "=", template_id)]
)
if product:
return product
else:
raise wrapJsonException(
BadRequest(_("No share for id %s") % template_id)
)
def _prepare_create(self, params): def _prepare_create(self, params):
"""Prepare a writable dictionary of values"""
address = params["address"] address = params["address"]
country = self._get_country(address["country"]) country = self._get_country(address["country"])
share_product_id = self._get_share_product(params["share_product"])
return { return {
"name": params["name"], "name": params["name"],
"email": params["email"], "email": params["email"],
"ordered_parts": params["ordered_parts"], "ordered_parts": params["ordered_parts"],
"share_product_id": params["share_product"],
"share_product_id": share_product_id.id,
"address": address["street"], "address": address["street"],
"zip_code": address["zip_code"], "zip_code": address["zip_code"],
"city": address["city"], "city": address["city"],
@ -123,16 +165,23 @@ class SubscriptionRequestService(Component):
address = params["address"] address = params["address"]
if "country" in address: if "country" in address:
country = self._get_country(address["country"]).id country = self._get_country(address["country"]).id
address["country"] = country
address["country"] = country.id
else: else:
address = {} address = {}
if "share_product" in params:
share_product_id = self._get_share_product(
params["share_product"]
).id
else:
share_product_id = None
params = { params = {
"name": params.get("name"), "name": params.get("name"),
"email": params.get("email"), "email": params.get("email"),
"state": params.get("state"), "state": params.get("state"),
"ordered_parts": params.get("ordered_parts"), "ordered_parts": params.get("ordered_parts"),
"share_product_id": params.get("share_product"),
"share_product_id": share_product_id,
"address": address.get("street"), "address": address.get("street"),
"zip_code": address.get("zip_code"), "zip_code": address.get("zip_code"),
"city": address.get("city"), "city": address.get("city"),
@ -165,3 +214,9 @@ class SubscriptionRequestService(Component):
def _validator_return_update(self): def _validator_return_update(self):
return schemas.S_SUBSCRIPTION_REQUEST_RETURN_GET return schemas.S_SUBSCRIPTION_REQUEST_RETURN_GET
def _validator_validate(self):
return schemas.S_SUBSCRIPTION_REQUEST_VALIDATE
def _validator_return_validate(self):
return schemas.S_SUBSCRIPTION_REQUEST_RETURN_GET

3
easy_my_coop_api/tests/__init__.py

@ -1,3 +1,6 @@
from . import test_ping from . import test_ping
from . import test_registry from . import test_registry
from . import test_external_id_mixin
from . import test_subscription_requests from . import test_subscription_requests
from . import test_account_invoice
from . import test_account_payment

206
easy_my_coop_api/tests/common.py

@ -9,7 +9,6 @@ import requests
from lxml import html from lxml import html
import odoo import odoo
from odoo.fields import Date
from odoo.addons.base_rest.tests.common import BaseRestCase from odoo.addons.base_rest.tests.common import BaseRestCase
@ -17,56 +16,185 @@ HOST = "127.0.0.1"
PORT = odoo.tools.config["http_port"] PORT = odoo.tools.config["http_port"]
def _add_api_key(headers):
key_dict = {"API-KEY": "api-key"}
if headers:
headers.update(key_dict)
else:
headers = key_dict
return headers
class BaseEMCRestCase(BaseRestCase): class BaseEMCRestCase(BaseRestCase):
@classmethod @classmethod
def setUpClass(cls, *args, **kwargs): def setUpClass(cls, *args, **kwargs):
super().setUpClass(*args, **kwargs) super().setUpClass(*args, **kwargs)
cls.AuthApiKey = cls.env["auth.api.key"] cls.AuthApiKey = cls.env["auth.api.key"]
emc_manager = cls.env.ref("easy_my_coop.res_users_manager_emc_demo")
cls.api_key_test = cls.AuthApiKey.create(
{"name": "test-key", "key": "api-key", "user_id": emc_manager.id}
cls.api_key_test = cls.env.ref(
"easy_my_coop_api.auth_api_key_manager_emc_demo"
) )
cls._chart_template_create()
cls._add_chart_of_accounts()
cls._journals_setup()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.session = requests.Session() self.session = requests.Session()
self.demo_request_1 = self.browse_ref(
"easy_my_coop.subscription_request_1_demo"
)
self.demo_share_product = self.demo_request_1.share_product_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",
@classmethod
def _chart_template_create(cls):
transfer_account_id = cls.env["account.account.template"].create(
{
"code": "000",
"name": "Liquidity Transfers",
"reconcile": True,
"user_type_id": cls.env.ref(
"account.data_account_type_current_assets"
).id,
}
)
cls.chart = cls.env["account.chart.template"].create(
{
"name": "Test COA",
"code_digits": 4,
"bank_account_code_prefix": 1014,
"cash_account_code_prefix": 1014,
"currency_id": cls.env.ref("base.USD").id,
"transfer_account_code_prefix": "000",
}
)
transfer_account_id.update({"chart_template_id": cls.chart.id})
cls.env["ir.model.data"].create(
{
"res_id": transfer_account_id.id,
"model": transfer_account_id._name,
"name": "Liquidity Transfers",
} }
)
act = cls.env["account.account.template"].create(
{
"code": "001",
"name": "Expenses",
"user_type_id": cls.env.ref(
"account.data_account_type_expenses"
).id,
"chart_template_id": cls.chart.id,
"reconcile": True,
}
)
cls.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "expenses"}
)
act = cls.env["account.account.template"].create(
{
"code": "002",
"name": "Product Sales",
"user_type_id": cls.env.ref(
"account.data_account_type_revenue"
).id,
"chart_template_id": cls.chart.id,
"reconcile": True,
}
)
cls.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "sales"}
)
act = cls.env["account.account.template"].create(
{
"code": "003",
"name": "Account Receivable",
"user_type_id": cls.env.ref(
"account.data_account_type_receivable"
).id,
"chart_template_id": cls.chart.id,
"reconcile": True,
}
)
cls.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "receivable"}
)
act = cls.env["account.account.template"].create(
{
"code": "004",
"name": "Account Payable",
"user_type_id": cls.env.ref(
"account.data_account_type_payable"
).id,
"chart_template_id": cls.chart.id,
"reconcile": True,
}
)
cls.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "payable"}
)
@classmethod
def _add_chart_of_accounts(cls):
cls.company = cls.env.user.company_id
cls.chart.try_loading_for_current_company()
cls.revenue = cls.env["account.account"].search(
[
(
"user_type_id",
"=",
cls.env.ref("account.data_account_type_revenue").id,
)
],
limit=1,
)
cls.expense = cls.env["account.account"].search(
[
(
"user_type_id",
"=",
cls.env.ref("account.data_account_type_expenses").id,
)
],
limit=1,
)
cls.receivable = cls.env["account.account"].search(
[
(
"user_type_id",
"=",
cls.env.ref("account.data_account_type_receivable").id,
)
],
limit=1,
)
cls.payable = cls.env["account.account"].search(
[
(
"user_type_id",
"=",
cls.env.ref("account.data_account_type_payable").id,
)
],
limit=1,
)
cls.equity_account = cls.env.ref("easy_my_coop.account_equity_demo")
cls.cooperator_account = cls.env.ref(
"easy_my_coop.account_cooperator_demo"
)
return True
@classmethod
def _journals_setup(cls):
cls.subscription_journal = cls.env.ref(
"easy_my_coop.subscription_journal"
)
cls.subscription_journal.write(
{
"default_debit_account_id": cls.equity_account.id,
"default_credit_account_id": cls.equity_account.id,
}
)
cls.bank_journal = cls.env["account.journal"].search(
[("type", "=", "bank")], limit=1
)
return True
def _add_api_key(self, headers):
key_dict = {"API-KEY": self.api_key_test.key}
if headers:
headers.update(key_dict)
else:
headers = key_dict
return headers
def http_get(self, url, headers=None): def http_get(self, url, headers=None):
headers = _add_api_key(headers)
headers = self._add_api_key(headers)
if url.startswith("/"): if url.startswith("/"):
url = "http://{}:{}{}".format(HOST, PORT, url) url = "http://{}:{}{}".format(HOST, PORT, url)
@ -79,7 +207,7 @@ class BaseEMCRestCase(BaseRestCase):
return json.loads(content) return json.loads(content)
def http_post(self, url, data, headers=None): def http_post(self, url, data, headers=None):
headers = _add_api_key(headers)
headers = self._add_api_key(headers)
if url.startswith("/"): if url.startswith("/"):
url = "http://{}:{}{}".format(HOST, PORT, url) url = "http://{}:{}{}".format(HOST, PORT, url)

101
easy_my_coop_api/tests/test_account_invoice.py

@ -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)

69
easy_my_coop_api/tests/test_account_payment.py

@ -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)

83
easy_my_coop_api/tests/test_external_id_mixin.py

@ -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())

4
easy_my_coop_api/tests/test_registry.py

@ -3,16 +3,12 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import odoo
from odoo.http import controllers_per_module from odoo.http import controllers_per_module
from odoo.addons.base_rest.tests.common import BaseRestCase from odoo.addons.base_rest.tests.common import BaseRestCase
from ..controllers.controllers import UserController from ..controllers.controllers import UserController
HOST = "127.0.0.1"
PORT = odoo.tools.config["http_port"]
class TestControllerRegistry(BaseRestCase): class TestControllerRegistry(BaseRestCase):
def test_controller_registry(self): def test_controller_registry(self):

88
easy_my_coop_api/tests/test_subscription_requests.py

@ -5,6 +5,8 @@
import json import json
from datetime import timedelta from datetime import timedelta
from werkzeug.exceptions import BadRequest
import odoo import odoo
from odoo.fields import Date from odoo.fields import Date
@ -22,36 +24,71 @@ class TestSRController(BaseEMCRestCase):
model_name="rest.service.registration", collection=collection model_name="rest.service.registration", collection=collection
) )
self.service = emc_services_env.component(usage="subscription-request")
self.sr_service = emc_services_env.component(
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): def test_service(self):
# kept as example # kept as example
# useful if you need to change data in database and check db type # useful if you need to change data in database and check db type
result = self.service.get(self.demo_request_1.id)
result = self.sr_service.get(self.demo_request_1.get_api_external_id())
self.assertEquals(self.demo_request_1_dict, result) self.assertEquals(self.demo_request_1_dict, result)
all_sr = self.service.search()
all_sr = self.sr_service.search()
self.assertTrue(all_sr) self.assertTrue(all_sr)
sr_date = self.demo_request_1.date sr_date = self.demo_request_1.date
date_from = Date.to_string(sr_date - timedelta(days=1)) date_from = Date.to_string(sr_date - timedelta(days=1))
date_to = Date.to_string(sr_date + timedelta(days=1)) date_to = Date.to_string(sr_date + timedelta(days=1))
date_sr = self.service.search(date_from=date_from, date_to=date_to)
date_sr = self.sr_service.search(date_from=date_from, date_to=date_to)
self.assertTrue(date_sr) self.assertTrue(date_sr)
def test_route_get(self): def test_route_get(self):
id_ = self.demo_request_1.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) content = self.http_get_content(route)
self.assertEquals(self.demo_request_1_dict, content) self.assertEquals(self.demo_request_1_dict, content)
@odoo.tools.mute_logger("odoo.addons.base_rest.http")
def test_route_get_returns_not_found(self):
route = "/api/subscription-request/%s" % "99999"
response = self.http_get(route)
self.assertEquals(response.status_code, 404)
# fixme works locally, not on travis: check later and move on
# @odoo.tools.mute_logger("odoo.addons.base_rest.http")
# def test_route_get_returns_not_found(self):
# route = "/api/subscription-request/%s" % "99999"
# response = self.http_get(route)
# self.assertEquals(response.status_code, 404)
def test_route_get_string_returns_method_not_allowed(self): def test_route_get_string_returns_method_not_allowed(self):
route = "/api/subscription-request/%s" % "abc" route = "/api/subscription-request/%s" % "abc"
@ -123,15 +160,19 @@ class TestSRController(BaseEMCRestCase):
"date": Date.to_string(Date.today()), "date": Date.to_string(Date.today()),
"state": "draft", "state": "draft",
"share_product": { "share_product": {
"id": self.demo_share_product.id,
"id": self.demo_share_product.get_api_external_id(),
"name": self.demo_share_product.name, "name": self.demo_share_product.name,
}, },
"capital_release_request": [],
}, },
} }
self.assertEquals(expected, content) self.assertEquals(expected, content)
def test_route_update(self): def test_route_update(self):
url = "/api/subscription-request/%s" % self.demo_request_1.id
url = (
"/api/subscription-request/%s"
% self.demo_request_1.get_api_external_id()
)
data = {"state": "done"} data = {"state": "done"}
response = self.http_post(url, data=data) response = self.http_post(url, data=data)
@ -141,3 +182,24 @@ class TestSRController(BaseEMCRestCase):
expected = self.demo_request_1_dict expected = self.demo_request_1_dict
expected["state"] = "done" expected["state"] = "done"
self.assertEquals(expected, content) self.assertEquals(expected, content)
def test_route_validate(self):
url = (
"/api/subscription-request/%s/validate"
% self.demo_request_1.get_api_external_id()
)
response = self.http_post(url, data={})
self.assertEquals(response.status_code, 200)
content = json.loads(response.content.decode("utf-8"))
state = content.get("state")
self.assertEquals(state, "done")
def test_service_validate_draft_request(self):
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.get_api_external_id())

1
easy_my_coop_be/README.rst

@ -49,7 +49,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

11
easy_my_coop_ch/README.rst

@ -10,11 +10,14 @@ Easy My Coop Switzerland
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status :target: https://odoo-community.org/page/development-status
:alt: Beta :alt: Beta
.. |badge2| image:: https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github
:target: https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop_ch :target: https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop_ch
:alt: coopiteasy/vertical-cooperative :alt: coopiteasy/vertical-cooperative
|badge1| |badge2|
|badge1| |badge2| |badge3|
This is the swiss localization for the easy my coop module This is the swiss localization for the easy my coop module
@ -39,13 +42,13 @@ Credits
Authors Authors
~~~~~~~ ~~~~~~~
* Houssine BAKKALI <houssine@coopiteasy.be>
* Coop IT Easy SCRLfs
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
* Houssine BAKKALI <houssine@coopiteasy.be>
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

3
easy_my_coop_ch/__manifest__.py

@ -11,9 +11,6 @@
"author": "Coop IT Easy SCRLfs", "author": "Coop IT Easy SCRLfs",
"category": "Cooperative management", "category": "Cooperative management",
"website": "https://www.coopiteasy.be", "website": "https://www.coopiteasy.be",
"description": """
This is the swiss localization for the easy my coop module
""",
"data": [ "data": [
"views/subscription_template.xml", "views/subscription_template.xml",
# "views/subscription_request_view.xml", # "views/subscription_request_view.xml",

5
easy_my_coop_ch/static/description/index.html

@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop_ch"><img alt="coopiteasy/vertical-cooperative" src="https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/easy_my_coop_ch"><img alt="coopiteasy/vertical-cooperative" src="https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github" /></a></p>
<p>This is the swiss localization for the easy my coop module</p> <p>This is the swiss localization for the easy my coop module</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
@ -394,13 +394,14 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2> <h2><a class="toc-backref" href="#id3">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Houssine BAKKALI &lt;<a class="reference external" href="mailto:houssine&#64;coopiteasy.be">houssine&#64;coopiteasy.be</a>&gt;</li>
<li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2> <h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Coop IT Easy SCRLfs</li> <li>Coop IT Easy SCRLfs</li>
<li>Houssine BAKKALI &lt;<a class="reference external" href="mailto:houssine&#64;coopiteasy.be">houssine&#64;coopiteasy.be</a>&gt;</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">

5
easy_my_coop_dividend/__manifest__.py

@ -22,11 +22,6 @@
"summary": """ "summary": """
Manage the dividend computation for a fiscal year. Manage the dividend computation for a fiscal year.
""", """,
'description': """
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.
""",
"author": "Houssine BAKKALI, <houssine@coopiteasy.be>", "author": "Houssine BAKKALI, <houssine@coopiteasy.be>",
"license": "AGPL-3", "license": "AGPL-3",
"version": "12.0.0.0.1", "version": "12.0.0.0.1",

21
easy_my_coop_es/__manifest__.py

@ -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 Easy My Coop localization for Spain
""", """,
"license": "AGPL-3", "license": "AGPL-3",
'data': [
"views/subscription_request_view.xml",
],
'installable': True,
"data": ["views/subscription_request_view.xml"],
"installable": True,
} }

12
easy_my_coop_es/models/coop.py

@ -2,22 +2,22 @@ from odoo import fields, models
class SubscriptionRequest(models.Model): class SubscriptionRequest(models.Model):
_inherit = 'subscription.request'
_inherit = "subscription.request"
vat = fields.Char( vat = fields.Char(
string='Tax ID',
string="Tax ID",
help=""" help="""
The Tax Identification Number. Complete it if the contact is subjected to The Tax Identification Number. Complete it if the contact is subjected to
government taxes. Used in some legal statements." government taxes. Used in some legal statements."
"""
""",
) )
voluntary_contribution = fields.Monetary( voluntary_contribution = fields.Monetary(
string='Voluntary contribution',
string="Voluntary contribution",
currency_field="company_currency_id", currency_field="company_currency_id",
help="Voluntary contribution made by the cooperator while buying a share."
help="Voluntary contribution made by the cooperator while buying a share.",
) )
def get_partner_vals(self): def get_partner_vals(self):
vals = super(SubscriptionRequest, self).get_partner_vals() vals = super(SubscriptionRequest, self).get_partner_vals()
vals['vat'] = self.vat
vals["vat"] = self.vat
return vals return vals

3
easy_my_coop_fr/README.rst

@ -42,14 +42,13 @@ Credits
Authors Authors
~~~~~~~ ~~~~~~~
* Houssine BAKKALI <houssine@coopiteasy.be>
* Coop IT Easy SCRLfs
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

2
easy_my_coop_fr/static/description/index.html

@ -394,7 +394,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2> <h2><a class="toc-backref" href="#id3">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Houssine BAKKALI &lt;<a class="reference external" href="mailto:houssine&#64;coopiteasy.be">houssine&#64;coopiteasy.be</a>&gt;</li>
<li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">

1
easy_my_coop_loan/README.rst

@ -49,7 +49,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

1
easy_my_coop_loan_website/README.rst

@ -49,7 +49,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

4
easy_my_coop_taxshelter_report/README.rst

@ -33,7 +33,6 @@ Development
Do not implement tests before fixing the direct use of self.env.cr.commit() Do not implement tests before fixing the direct use of self.env.cr.commit()
in models.tax_shelter_declaration in models.tax_shelter_declaration
Bug Tracker Bug Tracker
=========== ===========
@ -50,14 +49,13 @@ Credits
Authors Authors
~~~~~~~ ~~~~~~~
* Houssine BAKKALI <houssine@coopiteasy.be>
* Coop IT Easy SCRLfs
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

2
easy_my_coop_taxshelter_report/static/description/index.html

@ -401,7 +401,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id4">Authors</a></h2> <h2><a class="toc-backref" href="#id4">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Houssine BAKKALI &lt;<a class="reference external" href="mailto:houssine&#64;coopiteasy.be">houssine&#64;coopiteasy.be</a>&gt;</li>
<li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">

1
easy_my_coop_website/README.rst

@ -50,7 +50,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

6
easy_my_coop_website/controllers/main.py

@ -242,7 +242,9 @@ class WebsiteSubscription(http.Controller):
product_id = kwargs.get("share_product_id") product_id = kwargs.get("share_product_id")
return prod_obj.sudo().browse(int(product_id)).product_variant_ids[0] return prod_obj.sudo().browse(int(product_id)).product_variant_ids[0]
def validation(self, kwargs, logged, values, post_file):
def validation( # noqa: C901 (method too complex)
self, kwargs, logged, values, post_file
):
user_obj = request.env["res.users"] user_obj = request.env["res.users"]
sub_req_obj = request.env["subscription.request"] sub_req_obj = request.env["subscription.request"]
@ -256,7 +258,7 @@ class WebsiteSubscription(http.Controller):
redirect = "easy_my_coop_website.becomecompanycooperator" redirect = "easy_my_coop_website.becomecompanycooperator"
email = kwargs.get("company_email") email = kwargs.get("company_email")
# TODO: Use a overloaded function with the captcha implementation # TODO: Use a overloaded function with the captcha implementation
if request.website.company_id.captcha_type == 'google':
if request.website.company_id.captcha_type == "google":
if ( if (
"g-recaptcha-response" not in kwargs "g-recaptcha-response" not in kwargs
or kwargs["g-recaptcha-response"] == "" or kwargs["g-recaptcha-response"] == ""

12
easy_my_coop_website/models/company.py

@ -2,8 +2,10 @@ from odoo import fields, models
class ResCompany(models.Model): class ResCompany(models.Model):
_inherit = 'res.company'
captcha_type = fields.Selection([
('none', 'Disabled'),
('google', 'Google Recaptcha'),
], 'Captcha type or disabled', required=True, default='google')
_inherit = "res.company"
captcha_type = fields.Selection(
[("none", "Disabled"), ("google", "Google Recaptcha")],
"Captcha type or disabled",
required=True,
default="google",
)

1
easy_my_coop_website/views/res_company_view.xml

@ -11,4 +11,3 @@
</field> </field>
</record> </record>
</odoo> </odoo>

1
easy_my_coop_website_portal/README.rst

@ -49,7 +49,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

2
easy_my_coop_website_portal/controllers/main.py

@ -192,6 +192,7 @@ class CooperatorPortalAccount(CustomerPortal):
auth="public", auth="public",
website=True, website=True,
) )
# fmt: off
def portal_my_invoice_detail( def portal_my_invoice_detail(
self, self,
invoice_id, invoice_id,
@ -200,6 +201,7 @@ class CooperatorPortalAccount(CustomerPortal):
download=False, download=False,
**kw **kw
): ):
# fmt: on
# override in order to not retrieve release capital request as invoices # override in order to not retrieve release capital request as invoices
try: try:
invoice_sudo = self._document_check_access( invoice_sudo = self._document_check_access(

3
partner_age/README.rst

@ -42,14 +42,13 @@ Credits
Authors Authors
~~~~~~~ ~~~~~~~
* Houssine BAKKALI <houssine.bakkali@gmail.com>
* Coop IT Easy SCRLfs
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

2
partner_age/__manifest__.py

@ -8,7 +8,7 @@
"depends": ["partner_contact_birthdate"], "depends": ["partner_contact_birthdate"],
"author": "Coop IT Easy SCRLfs", "author": "Coop IT Easy SCRLfs",
"category": "Cooperative management", "category": "Cooperative management",
'website': "https://coopiteasy.be",
"website": "https://coopiteasy.be",
"license": "AGPL-3", "license": "AGPL-3",
"summary": "This module computes the age of the partner.", "summary": "This module computes the age of the partner.",
"data": ["view/partner_view.xml"], "data": ["view/partner_view.xml"],

2
partner_age/static/description/index.html

@ -394,7 +394,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2> <h2><a class="toc-backref" href="#id3">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Houssine BAKKALI &lt;<a class="reference external" href="mailto:houssine.bakkali&#64;gmail.com">houssine.bakkali&#64;gmail.com</a>&gt;</li>
<li>Coop IT Easy SCRLfs</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">

8
theme_light/README.rst

@ -10,11 +10,14 @@ Theme light
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status :target: https://odoo-community.org/page/development-status
:alt: Beta :alt: Beta
.. |badge2| image:: https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github
:target: https://github.com/coopiteasy/vertical-cooperative/tree/12.0/theme_light :target: https://github.com/coopiteasy/vertical-cooperative/tree/12.0/theme_light
:alt: coopiteasy/vertical-cooperative :alt: coopiteasy/vertical-cooperative
|badge1| |badge2|
|badge1| |badge2| |badge3|
Extract of the theme zen. Extract of the theme zen.
@ -48,7 +51,6 @@ Contributors
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

2
theme_light/static/description/index.html

@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/theme_light"><img alt="coopiteasy/vertical-cooperative" src="https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/coopiteasy/vertical-cooperative/tree/12.0/theme_light"><img alt="coopiteasy/vertical-cooperative" src="https://img.shields.io/badge/github-coopiteasy%2Fvertical--cooperative-lightgray.png?logo=github" /></a></p>
<p>Extract of the theme zen.</p> <p>Extract of the theme zen.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">

2
website_recaptcha_reloaded/README.rst

@ -48,13 +48,13 @@ Authors
~~~~~~~ ~~~~~~~
* Tech Receptives * Tech Receptives
* Coop IT Easy SCRLfs
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
* Coop IT Easy SCRLfs * Coop IT Easy SCRLfs
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

10
website_recaptcha_reloaded/__manifest__.py

@ -9,16 +9,6 @@
"license": "AGPL-3", "license": "AGPL-3",
"website": "https://www.techreceptives.com", "website": "https://www.techreceptives.com",
"summary": "Add google recaptcha to forms.", "summary": "Add google recaptcha to forms.",
"description": """
Odoo Website reCAPTCHA Reloaded
================================
This modules allows you to integrate Google reCAPTCHA v2.0 to your website
forms. You can configure your Google reCAPTCHA site and public keys
in "Settings" -> "Website Settings"
You will need to install various website_<module>_recaptcha modules
to use it in your various pages.
""",
"data": ["views/website_view.xml", "views/res_config.xml"], "data": ["views/website_view.xml", "views/res_config.xml"],
"installable": True, "installable": True,
} }
Loading…
Cancel
Save