Browse Source

[UPG] Contract for 10.0

pull/40/head
Stefan Rijnhart 8 years ago
parent
commit
6292accd47
  1. 9
      contract/README.rst
  2. 6
      contract/__manifest__.py
  3. 24
      contract/data/contract_cron.xml
  4. 17
      contract/models/contract.py
  5. 2
      contract/models/invoice.py
  6. 4
      contract/security/ir.model.access.csv
  7. 7
      contract/tests/test_contract.py
  8. 28
      contract/views/account_invoice_view.xml
  9. 208
      contract/views/contract.xml

9
contract/README.rst

@ -6,8 +6,9 @@
Contracts for recurrent invoicing Contracts for recurrent invoicing
================================= =================================
This module forward-port to v9 the contracts management with recurring
invoicing functions.
This module forward-port to v10 the contracts management with recurring
invoicing functions. In upstream Odoo, this functionality was moved into the
Enterprise edition.
Configuration Configuration
============= =============
@ -19,7 +20,7 @@ Usage
To use this module, you need to: To use this module, you need to:
#. Go to Sales -> Contracts and select or create a new contract.
#. Go to Accounting -> Contracts and select or create a new contract.
#. Check *Generate recurring invoices automatically*. #. Check *Generate recurring invoices automatically*.
#. Fill fields for selecting the recurrency and invoice parameters: #. Fill fields for selecting the recurrency and invoice parameters:
* Journal * Journal
@ -41,7 +42,7 @@ To use this module, you need to:
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/110/9.0
:target: https://runbot.odoo-community.org/runbot/110/10.0
Known issues / Roadmap Known issues / Roadmap
====================== ======================

6
contract/__manifest__.py

@ -5,13 +5,13 @@
{ {
'name': 'Contracts Management recurring', 'name': 'Contracts Management recurring',
'version': '9.0.1.1.0',
'version': '10.0.1.0.0',
'category': 'Contract Management', 'category': 'Contract Management',
'license': 'AGPL-3', 'license': 'AGPL-3',
'author': "OpenERP SA," 'author': "OpenERP SA,"
"Tecnativa," "Tecnativa,"
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
'website': 'http://openerp.com',
'website': 'https://github.com/oca/contract',
'depends': ['base', 'account', 'analytic'], 'depends': ['base', 'account', 'analytic'],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
@ -19,5 +19,5 @@
'views/contract.xml', 'views/contract.xml',
'views/account_invoice_view.xml', 'views/account_invoice_view.xml',
], ],
'installable': False,
'installable': True,
} }

24
contract/data/contract_cron.xml

@ -1,16 +1,14 @@
<?xml version="1.0" encoding='UTF-8'?> <?xml version="1.0" encoding='UTF-8'?>
<openerp>
<data>
<odoo>
<record model="ir.cron" id="account_analytic_cron_for_invoice">
<field name="name">Generate Recurring Invoices from Contracts</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="model" eval="'account.analytic.account'"/>
<field name="function" eval="'cron_recurring_create_invoice'"/>
<field name="args" eval="'()'"/>
</record>
<record model="ir.cron" id="account_analytic_cron_for_invoice">
<field name="name">Generate Recurring Invoices from Contracts</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="model" eval="'account.analytic.account'"/>
<field name="function" eval="'cron_recurring_create_invoice'"/>
<field name="args" eval="'()'"/>
</record>
</data>
</openerp>
</odoo>

17
contract/models/contract.py

@ -8,10 +8,10 @@
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
import logging import logging
from openerp import api, fields, models
from openerp.addons.decimal_precision import decimal_precision as dp
from openerp.exceptions import ValidationError
from openerp.tools.translate import _
from odoo import api, fields, models
from odoo.addons import decimal_precision as dp
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -30,7 +30,7 @@ class AccountAnalyticInvoiceLine(models.Model):
price_unit = fields.Float('Unit Price', required=True) price_unit = fields.Float('Unit Price', required=True)
price_subtotal = fields.Float( price_subtotal = fields.Float(
compute='_compute_price_subtotal', compute='_compute_price_subtotal',
digits_compute=dp.get_precision('Account'),
digits=dp.get_precision('Account'),
string='Sub Total') string='Sub Total')
discount = fields.Float( discount = fields.Float(
string='Discount (%)', string='Discount (%)',
@ -155,7 +155,7 @@ class AccountAnalyticAccount(models.Model):
self.recurring_next_date = self.date_start self.recurring_next_date = self.date_start
@api.model @api.model
def get_relalive_delta(self, recurring_rule_type, interval):
def get_relative_delta(self, recurring_rule_type, interval):
if recurring_rule_type == 'daily': if recurring_rule_type == 'daily':
return relativedelta(days=interval) return relativedelta(days=interval)
elif recurring_rule_type == 'weekly': elif recurring_rule_type == 'weekly':
@ -175,7 +175,7 @@ class AccountAnalyticAccount(models.Model):
date_to = next_date - relativedelta(days=1) date_to = next_date - relativedelta(days=1)
else: else:
date_from = (date_start - date_from = (date_start -
self.get_relalive_delta(contract.recurring_rule_type,
self.get_relative_delta(contract.recurring_rule_type,
contract.recurring_interval) + contract.recurring_interval) +
relativedelta(days=1)) relativedelta(days=1))
date_to = date_start date_to = date_start
@ -267,7 +267,7 @@ class AccountAnalyticAccount(models.Model):
for contract in self: for contract in self:
old_date = fields.Date.from_string( old_date = fields.Date.from_string(
contract.recurring_next_date or fields.Date.today()) contract.recurring_next_date or fields.Date.today())
new_date = old_date + self.get_relalive_delta(
new_date = old_date + self.get_relative_delta(
contract.recurring_rule_type, contract.recurring_interval) contract.recurring_rule_type, contract.recurring_interval)
ctx = self.env.context.copy() ctx = self.env.context.copy()
ctx.update({ ctx.update({
@ -287,6 +287,5 @@ class AccountAnalyticAccount(models.Model):
def cron_recurring_create_invoice(self): def cron_recurring_create_invoice(self):
contracts = self.search( contracts = self.search(
[('recurring_next_date', '<=', fields.date.today()), [('recurring_next_date', '<=', fields.date.today()),
('account_type', '=', 'normal'),
('recurring_invoices', '=', True)]) ('recurring_invoices', '=', True)])
return contracts.recurring_create_invoice() return contracts.recurring_create_invoice()

2
contract/models/invoice.py

@ -2,7 +2,7 @@
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com> # © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import fields, models
from odoo import fields, models
class AccountInvoice(models.Model): class AccountInvoice(models.Model):

4
contract/security/ir.model.access.csv

@ -1,4 +1,4 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"account_analytic_invoice_line_manager","Recurring manager","model_account_analytic_invoice_line","base.group_sale_manager",1,1,1,1
"account_analytic_invoice_line_user","Recurring user","model_account_analytic_invoice_line","base.group_sale_salesman",1,0,0,0
"account_analytic_invoice_line_manager","Recurring manager","model_account_analytic_invoice_line","account.group_account_manager",1,1,1,1
"account_analytic_invoice_line_user","Recurring user","model_account_analytic_invoice_line","account.group_account_user",1,0,0,0

7
contract/tests/test_contract.py

@ -2,8 +2,8 @@
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com> # © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.exceptions import ValidationError
from openerp.tests.common import TransactionCase
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase
class TestContract(TransactionCase): class TestContract(TransactionCase):
@ -12,6 +12,8 @@ class TestContract(TransactionCase):
super(TestContract, self).setUp() super(TestContract, self).setUp()
self.partner = self.env.ref('base.res_partner_2') self.partner = self.env.ref('base.res_partner_2')
self.product = self.env.ref('product.product_product_2') self.product = self.env.ref('product.product_product_2')
self.product.taxes_id += self.env['account.tax'].search(
[('type_tax_use', '=', 'sale')], limit=1)
self.product.description_sale = 'Test description sale' self.product.description_sale = 'Test description sale'
self.contract = self.env['account.analytic.account'].create({ self.contract = self.env['account.analytic.account'].create({
'name': 'Test Contract', 'name': 'Test Contract',
@ -53,6 +55,7 @@ class TestContract(TransactionCase):
self.assertEqual(self.contract.recurring_next_date, '2016-03-29') self.assertEqual(self.contract.recurring_next_date, '2016-03-29')
self.inv_line = self.invoice_monthly.invoice_line_ids[0] self.inv_line = self.invoice_monthly.invoice_line_ids[0]
self.assertTrue(self.inv_line.invoice_line_tax_ids)
self.assertAlmostEqual(self.inv_line.price_subtotal, 50.0) self.assertAlmostEqual(self.inv_line.price_subtotal, 50.0)
self.assertEqual(self.contract.partner_id.user_id, self.assertEqual(self.contract.partner_id.user_id,
self.invoice_monthly.user_id) self.invoice_monthly.user_id)

28
contract/views/account_invoice_view.xml

@ -1,19 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<!-- Invoice search view with contract -->
<record id="view_account_invoice_filter_contract" model="ir.ui.view">
<field name="name">account.invoice.select.contract</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<field name="date" position="after">
<separator/>
<field name="contract_id"/>
</field>
<!-- Invoice search view with contract -->
<record id="view_account_invoice_filter_contract" model="ir.ui.view">
<field name="name">account.invoice.select.contract</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<field name="date" position="after">
<separator/>
<field name="contract_id"/>
</field> </field>
</record>
</field>
</record>
</data>
</openerp>
</odoo>

208
contract/views/contract.xml

@ -1,116 +1,114 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<record id="act_recurring_invoices" model="ir.actions.act_window">
<field name="context">{'search_default_contract_id':
[active_id],
'default_contract_id': active_id}
</field>
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_id" ref="account.invoice_tree" />
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
</record>
<record id="act_recurring_invoices" model="ir.actions.act_window">
<field name="context">{'search_default_contract_id':
[active_id],
'default_contract_id': active_id}
</field>
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_id" ref="account.invoice_tree" />
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
</record>
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view">
<field name="name">account.analytic.account.invoice.recurring.form.inherit</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="40" name="priority"/>
<field name="arch" type="xml">
<notebook position="before">
<separator string="Recurring Invoices" attrs="{'invisible': [('recurring_invoices','!=',True)]}"/>
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view">
<field name="name">account.analytic.account.invoice.recurring.form.inherit</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field eval="40" name="priority"/>
<field name="arch" type="xml">
<group name="main" position="after">
<separator string="Recurring Invoices" attrs="{'invisible': [('recurring_invoices','!=',True)]}"/>
<div>
<field name="recurring_invoices" class="oe_inline"/>
<label for="recurring_invoices" />
<button name="recurring_create_invoice" type="object"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
string="Create invoices" class="oe_link"
groups="base.group_no_one"/>
<button name="%(contract.act_recurring_invoices)d" type="action"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
string="⇒ Show recurring invoices" class="oe_link"/>
</div>
<group col="4" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<field name="journal_id"/>
<field name="pricelist_id"/>
<label for="recurring_interval"/>
<div> <div>
<field name="recurring_invoices" class="oe_inline"/>
<label for="recurring_invoices" />
<button name="recurring_create_invoice" type="object"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
string="Create invoices" class="oe_link"
groups="base.group_no_one"/>
<button name="%(contract.act_recurring_invoices)d" type="action"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
string="⇒ Show recurring invoices" class="oe_link"/>
</div>
<group col="4" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<field name="journal_id"/>
<field name="pricelist_id"/>
<label for="recurring_interval"/>
<div>
<field name="recurring_interval" class="oe_inline" attrs="{'required': [('recurring_invoices', '=', True)]}"/>
<field name="recurring_rule_type" class="oe_inline" attrs="{'required': [('recurring_invoices', '=', True)]}"/>
</div>
<field name="recurring_invoicing_type"/>
<field name="date_start"/>
<field name="recurring_next_date"/>
</group>
<label for="recurring_invoice_line_ids" attrs="{'invisible': [('recurring_invoices','=',False)]}"/>
<div attrs="{'invisible': [('recurring_invoices','=',False)]}">
<field name="recurring_invoice_line_ids">
<tree string="Account Analytic Lines" editable="bottom">
<field name="product_id"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line" />
<field name="price_subtotal"/>
</tree>
</field>
<field name="recurring_interval" class="oe_inline" attrs="{'required': [('recurring_invoices', '=', True)]}"/>
<field name="recurring_rule_type" class="oe_inline" attrs="{'required': [('recurring_invoices', '=', True)]}"/>
</div> </div>
<group string="Legend (for the markers inside invoice lines description)"
name="group_legend" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<p colspan="2"> <strong>#START#</strong>: Start date of the invoiced period</p>
<p colspan="2"> <strong>#END#</strong>: End date of the invoiced period</p>
</group>
</notebook>
</field>
</record>
<field name="recurring_invoicing_type"/>
<field name="date_start"/>
<field name="recurring_next_date"/>
</group>
<label for="recurring_invoice_line_ids" attrs="{'invisible': [('recurring_invoices','=',False)]}"/>
<div attrs="{'invisible': [('recurring_invoices','=',False)]}">
<field name="recurring_invoice_line_ids">
<tree string="Account Analytic Lines" editable="bottom">
<field name="product_id"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line" />
<field name="price_subtotal"/>
</tree>
</field>
</div>
<group string="Legend (for the markers inside invoice lines description)"
name="group_legend" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<p colspan="2"> <strong>#START#</strong>: Start date of the invoiced period</p>
<p colspan="2"> <strong>#END#</strong>: End date of the invoiced period</p>
</group>
</group>
</field>
</record>
<!-- Inherited Analytic Account list for contracts -->
<record id="view_account_analytic_account_journal_tree" model="ir.ui.view">
<field name="name">account.analytic.account.journal.list</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_list" />
<field name="arch" type="xml">
<field name="partner_id" position="before">
<field name="journal_id" groups="account.group_account_user"/>
</field>
<!-- Inherited Analytic Account list for contracts -->
<record id="view_account_analytic_account_journal_tree" model="ir.ui.view">
<field name="name">account.analytic.account.journal.list</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_list" />
<field name="arch" type="xml">
<field name="partner_id" position="before">
<field name="journal_id" groups="account.group_account_user"/>
</field> </field>
</record>
</field>
</record>
<!-- Analytic Account search view for contract -->
<record id="view_account_analytic_account_contract_search" model="ir.ui.view">
<field name="name">account.analytic.account.contract.search</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_search"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="journal_id"/>
<field name="pricelist_id"/>
<filter name="recurring_invoices" string="Recurring Invoices" domain="[('recurring_invoices','=',True)]"/>
<group expand="0" string="Group By...">
<filter string="Next Invoice" domain="[]" context="{'group_by':'recurring_next_date'}"/>
</group>
</field>
<!-- Analytic Account search view for contract -->
<record id="view_account_analytic_account_contract_search" model="ir.ui.view">
<field name="name">account.analytic.account.contract.search</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_search"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="journal_id"/>
<field name="pricelist_id"/>
<filter name="recurring_invoices" string="Recurring Invoices" domain="[('recurring_invoices','=',True)]"/>
<group expand="0" string="Group By...">
<filter string="Next Invoice" domain="[]" context="{'group_by':'recurring_next_date'}"/>
</group>
</field> </field>
</record>
</field>
</record>
<!-- Action Sales/Sales/Contracts -->
<record id="action_account_analytic_overdue_all" model="ir.actions.act_window">
<field name="name">Contracts</field>
<field name="res_model">account.analytic.account</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_active':1, 'search_default_recurring_invoices':1}</field>
<field name="search_view_id" ref="analytic.view_account_analytic_account_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<menuitem action="action_account_analytic_overdue_all" id="menu_action_account_analytic_overdue_all" sequence="8" parent="base.menu_sales"/>
<!-- Action Sales/Sales/Contracts -->
<record id="action_account_analytic_overdue_all" model="ir.actions.act_window">
<field name="name">Contracts</field>
<field name="res_model">account.analytic.account</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_active':1, 'search_default_recurring_invoices':1}</field>
<field name="search_view_id" ref="analytic.view_account_analytic_account_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<menuitem action="action_account_analytic_overdue_all" id="menu_action_account_analytic_overdue_all" sequence="99" parent="account.menu_finance_receivables"/>
</data>
</openerp>
</odoo>
Loading…
Cancel
Save