Browse Source
[ADD] Module add to make the #START# and #END# date on the time markers configurable.
pull/174/head
[ADD] Module add to make the #START# and #END# date on the time markers configurable.
pull/174/head
Roel Adriaans
6 years ago
11 changed files with 230 additions and 0 deletions
-
21contract_time_markers/README.rst
-
1contract_time_markers/__init__.py
-
18contract_time_markers/__manifest__.py
-
3contract_time_markers/models/__init__.py
-
49contract_time_markers/models/account_analytic_account.py
-
1contract_time_markers/readme/CONTRIBUTORS.rst
-
1contract_time_markers/readme/DESCRIPTION.rst
-
18contract_time_markers/readme/USAGE.rst
-
4contract_time_markers/tests/__init__.py
-
87contract_time_markers/tests/test_contract.py
-
27contract_time_markers/views/account_analytic_account_view.xml
@ -0,0 +1,21 @@ |
|||
**This file is going to be generated by oca-gen-addon-readme.** |
|||
|
|||
*Manual changes will be overwritten.* |
|||
|
|||
Please provide content in the ``readme`` directory: |
|||
|
|||
* **DESCRIPTION.rst** (required) |
|||
* INSTALL.rst (optional) |
|||
* CONFIGURE.rst (optional) |
|||
* **USAGE.rst** (optional, highly recommended) |
|||
* DEVELOP.rst (optional) |
|||
* ROADMAP.rst (optional) |
|||
* HISTORY.rst (optional, recommended) |
|||
* **CONTRIBUTORS.rst** (optional, highly recommended) |
|||
* CREDITS.rst (optional) |
|||
|
|||
Content of this README will also be drawn from the addon manifest, |
|||
from keys such as name, authors, maintainers, development_status, |
|||
and license. |
|||
|
|||
A good, one sentence summary in the manifest is also highly recommended. |
@ -0,0 +1 @@ |
|||
from . import models |
@ -0,0 +1,18 @@ |
|||
# Copyright 2018 Road-Support - Roel Adriaans |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
{ |
|||
'name': 'Contracts Management - Configure time markers', |
|||
'version': '11.0.1.0.0', |
|||
'category': 'Contract Management', |
|||
'license': 'AGPL-3', |
|||
'author': "Road-Support, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/oca/contract', |
|||
'depends': ['contract'], |
|||
'data': [ |
|||
'views/account_analytic_account_view.xml', |
|||
], |
|||
'development_status': 'alpha', |
|||
'installable': True, |
|||
} |
@ -0,0 +1,3 @@ |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import account_analytic_account |
@ -0,0 +1,49 @@ |
|||
# Copyright 2018 Road-Support - Roel Adriaans |
|||
|
|||
import re |
|||
|
|||
from odoo import api, fields, models |
|||
from odoo.tools.misc import format_date |
|||
|
|||
|
|||
class AccountAnalyticAccount(models.Model): |
|||
_inherit = 'account.analytic.account' |
|||
|
|||
def _format_date(self, date, partner_lang, parse): |
|||
try: |
|||
res = format_date(self.env, date, partner_lang, parse) |
|||
return res |
|||
except (AttributeError, ValueError) as e: |
|||
# At the moment we catch exceptions silent, and return |
|||
# an empty string. |
|||
# Should we raise an error, or create a new mail.activity? |
|||
return "" |
|||
|
|||
@api.model |
|||
def _insert_markers(self, line, date_format): |
|||
date_from = fields.Date.from_string(line.date_from) |
|||
date_to = fields.Date.from_string(line.date_to) |
|||
from_regex = r"#START\((.*?)\)#" |
|||
to_regex = r"#END\((.*?)\)#" |
|||
name = line.name |
|||
|
|||
from_result = re.findall(from_regex, name) |
|||
to_result = re.findall(to_regex, name) |
|||
|
|||
partner_lang = line.analytic_account_id.partner_id.lang |
|||
|
|||
if from_result and len(from_result[0]) > 1: |
|||
from_string = self._format_date(date_from, partner_lang, from_result[0]) |
|||
name = re.sub(from_regex, from_string, name) |
|||
else: |
|||
# Original behaviour |
|||
name = name.replace('#START#', date_from.strftime(date_format)) |
|||
|
|||
if to_result and len(to_result[0]) > 1: |
|||
to_string = self._format_date(date_to, partner_lang, to_result[0]) |
|||
name = re.sub(to_regex, to_string, name) |
|||
else: |
|||
# Original behaviour |
|||
name = name.replace('#END#', date_to.strftime(date_format)) |
|||
|
|||
return name |
@ -0,0 +1 @@ |
|||
* Roel Adriaans <roel@road-support.nl> |
@ -0,0 +1 @@ |
|||
Make the #START# and #END# date on the time markers configurable. |
@ -0,0 +1,18 @@ |
|||
To use this module, you need to: |
|||
|
|||
#. Install the contract module |
|||
#. Use the markers #START# or #END#. |
|||
#. With this module installed |
|||
it is possible to configure the date format using the LDML |
|||
format. See http://babel.pocoo.org/en/latest/dates.html#date-fields |
|||
|
|||
Only date fields are supported. |
|||
|
|||
Examples for 1 September 2018 |
|||
|
|||
- #START(MMMM yyyy)# -- September 2018 |
|||
- #START(d MMMM yy)# -- 1 September 18 |
|||
- #END(dd MMMM yyy)# -- 01 September 2018 |
|||
- #END(EEEE dd MMMM yyy)# -- Sunday 01 September 2018 |
|||
- #START(dd/MM/yyyy) -- 30/09/2018 |
|||
- #END# -- Default behaviour - Date format on based on partner language |
@ -0,0 +1,4 @@ |
|||
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from . import test_contract |
@ -0,0 +1,87 @@ |
|||
# Copyright 2016 Tecnativa - Carlos Dauden |
|||
# Copyright 2017 Tecnativa - Pedro M. Baeza |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from odoo import fields |
|||
from odoo.exceptions import ValidationError |
|||
from odoo.tests import common |
|||
|
|||
|
|||
class TestContractBase(common.SavepointCase): |
|||
@classmethod |
|||
def setUpClass(cls): |
|||
super(TestContractBase, cls).setUpClass() |
|||
cls.partner = cls.env.ref('base.res_partner_2') |
|||
cls.product = cls.env.ref('product.product_product_2') |
|||
cls.product.taxes_id += cls.env['account.tax'].search( |
|||
[('type_tax_use', '=', 'sale')], limit=1) |
|||
cls.product.description_sale = 'Test description sale' |
|||
cls.template_vals = { |
|||
'recurring_rule_type': 'yearly', |
|||
'recurring_interval': 12345, |
|||
'name': 'Test Contract Template', |
|||
} |
|||
cls.template = cls.env['account.analytic.contract'].create( |
|||
cls.template_vals, |
|||
) |
|||
cls.contract = cls.env['account.analytic.account'].create({ |
|||
'name': 'Test Contract', |
|||
'partner_id': cls.partner.id, |
|||
'pricelist_id': cls.partner.property_product_pricelist.id, |
|||
'recurring_invoices': True, |
|||
'date_start': '2016-02-15', |
|||
'recurring_next_date': '2016-02-29', |
|||
}) |
|||
cls.line_vals = { |
|||
'analytic_account_id': cls.contract.id, |
|||
'product_id': cls.product.id, |
|||
'name': 'Services from #START# to #END#', |
|||
'quantity': 1, |
|||
'uom_id': cls.product.uom_id.id, |
|||
'price_unit': 100, |
|||
'discount': 50, |
|||
} |
|||
cls.acct_line = cls.env['account.analytic.invoice.line'].create( |
|||
cls.line_vals, |
|||
) |
|||
|
|||
|
|||
class TestContract(TestContractBase): |
|||
def test_contract_default_name(self): |
|||
""" Create invoice, based on default values. |
|||
Should have a valid name""" |
|||
self.contract.cron_recurring_create_invoice() |
|||
invoice_id = self.env['account.invoice'].search( |
|||
[('contract_id', '=', self.contract.id)]) |
|||
self.assertEqual(invoice_id.invoice_line_ids.name, |
|||
'Services from 02/29/2016 to 03/28/2016') |
|||
|
|||
def test_contract_computed_name(self): |
|||
""" Create invoice, based on computed values. |
|||
Should have these computed values in invoice line.""" |
|||
self.acct_line.unlink() |
|||
self.line_vals['name'] = "Services from #START(dd/MM/yyyy)# " \ |
|||
"to #END(d MMMM yy)#" |
|||
self.acct_line = self.env['account.analytic.invoice.line'].create( |
|||
self.line_vals, |
|||
) |
|||
self.contract.cron_recurring_create_invoice() |
|||
invoice_id = self.env['account.invoice'].search( |
|||
[('contract_id', '=', self.contract.id)]) |
|||
self.assertEqual(invoice_id.invoice_line_ids.name, |
|||
'Services from 29/02/2016 to 28 March 16') |
|||
|
|||
def test_contract_computed_broken_name(self): |
|||
""" Broken date format. Should not give an error, but empty |
|||
test in the invoice line.""" |
|||
self.acct_line.unlink() |
|||
self.line_vals['name'] = "Services from #START(Invalid)# " \ |
|||
"to #END(EEEE dd MMMM yyy)#" |
|||
self.acct_line = self.env['account.analytic.invoice.line'].create( |
|||
self.line_vals, |
|||
) |
|||
self.contract.cron_recurring_create_invoice() |
|||
invoice_id = self.env['account.invoice'].search( |
|||
[('contract_id', '=', self.contract.id)]) |
|||
self.assertEqual(invoice_id.invoice_line_ids.name, |
|||
'Services from to Monday 28 March 2016') |
@ -0,0 +1,27 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
|
|||
<record id="account_analytic_account_timeformat_form" model="ir.ui.view"> |
|||
<field name="name">Contract form</field> |
|||
<field name="model">account.analytic.account</field> |
|||
<field name="inherit_id" ref="contract.account_analytic_account_recurring_form_form"/> |
|||
<field name="arch" type="xml"> |
|||
<group name="group_legend" position="inside"> |
|||
<p colspan="2"><strong>#START(FORMATTING)# and #END(FORMATTING)</strong>: Format the date according to |
|||
the LDML |
|||
format. Examples: for 1 September 2018 |
|||
</p> |
|||
<p> |
|||
<ul> |
|||
<li>#START(MMMM yyyy)# : September 2018</li> |
|||
<li>#START(d MMMM yy)# : 1 September 18</li> |
|||
<li>#END(dd MMMM yyy)# : 01 September 2018</li> |
|||
<li>#END(EEEE dd MMMM yyy)# : Sunday 01 September 2018</li> |
|||
<li>#START(dd/MM/yyyy) : 30/09/2018</li> |
|||
<li>#END# : Default behaviour - Date format on based on partner language</li> |
|||
</ul> |
|||
</p> |
|||
</group> |
|||
</field> |
|||
</record> |
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue