From 6d0007aa7303babc71ef9654d472e8b34d3e1b75 Mon Sep 17 00:00:00 2001 From: Sylvain Van Hoof Date: Mon, 20 May 2019 17:31:54 +0200 Subject: [PATCH] [MIG] contract_sale_generation: Migraiton to 11.0 --- contract_sale_generation/README.rst | 71 ++- contract_sale_generation/__init__.py | 1 - contract_sale_generation/__manifest__.py | 5 +- .../data/contract_cron.xml | 9 +- contract_sale_generation/models/__init__.py | 2 +- .../models/account_analytic_account.py | 58 ++- .../models/account_analytic_contract.py | 1 - contract_sale_generation/models/sale_order.py | 14 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 2 + contract_sale_generation/readme/USAGE.rst | 12 + .../static/description/index.html | 438 ++++++++++++++++++ contract_sale_generation/tests/__init__.py | 1 - .../tests/test_contract_sale.py | 22 +- .../views/account_analytic_account_view.xml | 4 +- contract_sale_generation/views/sale_view.xml | 29 +- 16 files changed, 611 insertions(+), 61 deletions(-) create mode 100644 contract_sale_generation/models/sale_order.py create mode 100644 contract_sale_generation/readme/CONTRIBUTORS.rst create mode 100644 contract_sale_generation/readme/DESCRIPTION.rst create mode 100644 contract_sale_generation/readme/USAGE.rst create mode 100644 contract_sale_generation/static/description/index.html diff --git a/contract_sale_generation/README.rst b/contract_sale_generation/README.rst index e7ccfec9..3f4cf00a 100644 --- a/contract_sale_generation/README.rst +++ b/contract_sale_generation/README.rst @@ -1,13 +1,37 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg +====================================== +Contracts Management - Recurring Sales +====================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |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-OCA%2Fcontract-lightgray.png?logo=github + :target: https://github.com/OCA/contract/tree/11.0/contract_sale_generation + :alt: OCA/contract +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/contract-11-0/contract-11-0-contract_sale_generation + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/110/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends functionality of contracts to be able to generate sales +orders instead of invoices. -============================= -Contracts for recurrent sales -============================= +**Table of contents** -This module extends functionality of contracts to be able to generate sales -orders instead of invoices. +.. contents:: + :local: Usage ===== @@ -21,38 +45,45 @@ To use this module, you need to: * Type defines document that contract will generate, can be "Sales" or "Invoices" * Sale Autoconfirm, validate Sales Orders if type is "Sales" -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/110/10.0 - Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. 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 feedback. +Bugs are tracked on `GitHub Issues `_. +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 +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* PESOL +* Okia + Contributors ------------- +~~~~~~~~~~~~ * Angel Moya * Florent THOMAS +* Sylvain Van Hoof -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/contract `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/contract_sale_generation/__init__.py b/contract_sale_generation/__init__.py index a0fdc10f..0650744f 100644 --- a/contract_sale_generation/__init__.py +++ b/contract_sale_generation/__init__.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- from . import models diff --git a/contract_sale_generation/__manifest__.py b/contract_sale_generation/__manifest__.py index f20c1a7a..eb8d409e 100644 --- a/contract_sale_generation/__manifest__.py +++ b/contract_sale_generation/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Pesol () # Copyright 2017 Angel Moya # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) @@ -6,10 +5,10 @@ { 'name': 'Contracts Management - Recurring Sales', - 'version': '10.0.3.0.0', + 'version': '11.0.1.0.0', 'category': 'Contract Management', 'license': 'AGPL-3', - 'author': "PESOL, " + 'author': "PESOL, Okia, " "Odoo Community Association (OCA)", 'website': 'https://github.com/oca/contract', 'depends': ['contract', 'sale'], diff --git a/contract_sale_generation/data/contract_cron.xml b/contract_sale_generation/data/contract_cron.xml index d4d6f8fd..d7fe5b40 100644 --- a/contract_sale_generation/data/contract_cron.xml +++ b/contract_sale_generation/data/contract_cron.xml @@ -1,14 +1,15 @@ - + Generate Recurring sales from Contracts 1 days -1 - - - + + code + + model.cron_recurring_create_sale() diff --git a/contract_sale_generation/models/__init__.py b/contract_sale_generation/models/__init__.py index a3782ea7..b7b95b21 100644 --- a/contract_sale_generation/models/__init__.py +++ b/contract_sale_generation/models/__init__.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import account_analytic_contract from . import account_analytic_account +from . import sale_order diff --git a/contract_sale_generation/models/account_analytic_account.py b/contract_sale_generation/models/account_analytic_account.py index 79405fd7..b1bc6891 100644 --- a/contract_sale_generation/models/account_analytic_account.py +++ b/contract_sale_generation/models/account_analytic_account.py @@ -1,12 +1,12 @@ -# -*- coding: utf-8 -*- -# © 2004-2010 OpenERP SA -# © 2014 Angel Moya -# © 2015 Pedro M. Baeza -# © 2016 Carlos Dauden +# Copyright 2004-2010 OpenERP SA +# Copyright 2014 Angel Moya +# Copyright 2015 Pedro M. Baeza +# Copyright 2016 Carlos Dauden # Copyright 2016-2017 LasLabs Inc. # Copyright 2017 Pesol () # Copyright 2017 Angel Moya # Copyright 2018 Therp BV . +# Copyright 2019 Sylvain Van Hoof # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import api, models, fields @@ -30,7 +30,12 @@ class AccountAnalyticAccount(models.Model): sale_line.product_id_change() sale_line_vals = sale_line._convert_to_write(sale_line._cache) # Insert markers - name = self._insert_markers(line.name) + contract = line.analytic_account_id + lang_obj = self.env['res.lang'] + lang = lang_obj.search( + [('code', '=', contract.partner_id.lang)]) + date_format = lang.date_format or '%m/%d/%Y' + name = self._insert_markers(line, date_format) sale_line_vals.update({ 'name': name, 'discount': line.discount, @@ -51,14 +56,14 @@ class AccountAnalyticAccount(models.Model): 'origin': self.name, 'company_id': self.company_id.id, 'user_id': self.partner_id.user_id.id, - 'project_id': self.id + 'contract_id': self.id }) # Get other invoice values from partner onchange sale.onchange_partner_id() return sale._convert_to_write(sale._cache) @api.multi - def _create_invoice(self): + def _create_invoice(self, invoice=False): """ Create invoices @param self: single record of account.invoice @@ -66,7 +71,8 @@ class AccountAnalyticAccount(models.Model): """ self.ensure_one() if self.type == 'invoice': - return super(AccountAnalyticAccount, self)._create_invoice() + return super(AccountAnalyticAccount, self).\ + _create_invoice(invoice=invoice) else: return self.env['account.invoice'] @@ -92,28 +98,46 @@ class AccountAnalyticAccount(models.Model): @api.multi def recurring_create_sale(self): - """ - Create sales from contracts + """Create sales from contracts + + :param int limit: + Max of sales to create. :return: sales created """ sales = self.env['sale.order'] for contract in self: - if not contract.check_dates_valid(): - continue - # Re-read contract with correct company - ctx = contract.get_invoice_context() + ref_date = contract.recurring_next_date or fields.Date.today() + if (contract.date_start > ref_date or + contract.date_end and contract.date_end < ref_date): + if self.env.context.get('cron'): + continue # Don't fail on cron jobs + raise ValidationError( + _("You must review start and end dates!\n%s") % + contract.name + ) + old_date = fields.Date.from_string(ref_date) + new_date = old_date + self.get_relative_delta( + contract.recurring_rule_type, contract.recurring_interval) + ctx = self.env.context.copy() + ctx.update({ + 'old_date': old_date, + 'next_date': new_date, + # Force company for correct evaluation of domain access rules + 'force_company': contract.company_id.id, + }) sales |= contract.with_context(ctx)._create_sale() contract.write({ - 'recurring_next_date': fields.Date.to_string(ctx['next_date']) + 'recurring_next_date': fields.Date.to_string(new_date) }) return sales @api.model def cron_recurring_create_sale(self): today = fields.Date.today() - contracts = self.search([ + contracts = self.with_context(cron=True).search([ ('recurring_invoices', '=', True), ('recurring_next_date', '<=', today), + ('type', '=', 'sale'), '|', ('date_end', '=', False), ('date_end', '>=', today), diff --git a/contract_sale_generation/models/account_analytic_contract.py b/contract_sale_generation/models/account_analytic_contract.py index 2db200da..d65dfa16 100644 --- a/contract_sale_generation/models/account_analytic_contract.py +++ b/contract_sale_generation/models/account_analytic_contract.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Pesol () # Copyright 2017 Angel Moya # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/contract_sale_generation/models/sale_order.py b/contract_sale_generation/models/sale_order.py new file mode 100644 index 00000000..3b366852 --- /dev/null +++ b/contract_sale_generation/models/sale_order.py @@ -0,0 +1,14 @@ +# Copyright 2019 Sylvain Van Hoof +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + contract_id = fields.Many2one( + 'account.analytic.account', + string='Contract', + readonly=True + ) diff --git a/contract_sale_generation/readme/CONTRIBUTORS.rst b/contract_sale_generation/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..3f3f376b --- /dev/null +++ b/contract_sale_generation/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Angel Moya +* Florent THOMAS +* Sylvain Van Hoof \ No newline at end of file diff --git a/contract_sale_generation/readme/DESCRIPTION.rst b/contract_sale_generation/readme/DESCRIPTION.rst new file mode 100644 index 00000000..634a175c --- /dev/null +++ b/contract_sale_generation/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module extends functionality of contracts to be able to generate sales +orders instead of invoices. \ No newline at end of file diff --git a/contract_sale_generation/readme/USAGE.rst b/contract_sale_generation/readme/USAGE.rst new file mode 100644 index 00000000..4c884d80 --- /dev/null +++ b/contract_sale_generation/readme/USAGE.rst @@ -0,0 +1,12 @@ +To use this module, you need to: + +#. Go to Accounting -> Contracts and select or create a new contract. +#. Check *Generate recurring invoices automatically*. +#. Fill fields for selecting the recurrency and invoice parameters: + + * Type defines document that contract will generate, can be "Sales" or "Invoices" + * Sale Autoconfirm, validate Sales Orders if type is "Sales" + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/110/10.0 \ No newline at end of file diff --git a/contract_sale_generation/static/description/index.html b/contract_sale_generation/static/description/index.html new file mode 100644 index 00000000..71d23771 --- /dev/null +++ b/contract_sale_generation/static/description/index.html @@ -0,0 +1,438 @@ + + + + + + +Contracts Management - Recurring Sales + + + +
+

Contracts Management - Recurring Sales

+ + +

Beta License: AGPL-3 OCA/contract Translate me on Weblate Try me on Runbot

+

This module extends functionality of contracts to be able to generate sales +orders instead of invoices.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to Accounting -> Contracts and select or create a new contract.
  2. +
  3. Check Generate recurring invoices automatically.
  4. +
  5. Fill fields for selecting the recurrency and invoice parameters:
      +
    • Type defines document that contract will generate, can be “Sales” or “Invoices”
    • +
    • Sale Autoconfirm, validate Sales Orders if type is “Sales”
    • +
    +
  6. +
+Try me on Runbot +
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +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 +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • PESOL
  • +
  • Okia
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/contract project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/contract_sale_generation/tests/__init__.py b/contract_sale_generation/tests/__init__.py index a76c76cb..87f76cff 100644 --- a/contract_sale_generation/tests/__init__.py +++ b/contract_sale_generation/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import test_contract_sale diff --git a/contract_sale_generation/tests/test_contract_sale.py b/contract_sale_generation/tests/test_contract_sale.py index 035ca8b9..c4fe689e 100644 --- a/contract_sale_generation/tests/test_contract_sale.py +++ b/contract_sale_generation/tests/test_contract_sale.py @@ -1,7 +1,7 @@ -# -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # Copyright 2017 Pesol () # Copyright 2017 Angel Moya +# Copyright 2019 Sylvain Van Hoof # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.exceptions import ValidationError @@ -59,14 +59,14 @@ class TestContractSale(TransactionCase): self.contract_line.price_unit = 100.0 self.contract.recurring_create_sale() self.sale_monthly = self.env['sale.order'].search( - [('project_id', '=', self.contract.id), + [('contract_id', '=', self.contract.id), ('state', '=', 'draft')]) self.assertTrue(self.sale_monthly) self.assertEqual(self.contract.recurring_next_date, '2017-02-28') self.sale_line = self.sale_monthly.order_line[0] self.assertAlmostEqual(self.sale_line.price_subtotal, 50.0) - self.assertEqual(self.contract.partner_id.user_id, - self.sale_monthly.user_id) + self.assertEqual(self.contract.partner_id.user_id.id or self.env.uid, + self.sale_monthly.user_id.id) def test_contract_autoconfirm(self): self.contract.sale_autoconfirm = True @@ -76,15 +76,15 @@ class TestContractSale(TransactionCase): self.contract_line.price_unit = 100.0 self.contract.recurring_create_sale() self.sale_monthly = self.env['sale.order'].search( - [('project_id', '=', self.contract.id), + [('contract_id', '=', self.contract.id), ('state', '=', 'sale')]) self.assertTrue(self.sale_monthly) self.assertEqual(self.contract.recurring_next_date, '2017-02-28') self.sale_line = self.sale_monthly.order_line[0] self.assertAlmostEqual(self.sale_line.price_subtotal, 50.0) - self.assertEqual(self.contract.partner_id.user_id, - self.sale_monthly.user_id) + self.assertEqual(self.contract.partner_id.user_id.id or self.env.uid, + self.sale_monthly.user_id.id) def test_onchange_contract_template_id(self): """ It should change the contract values to match the template. """ @@ -106,3 +106,9 @@ class TestContractSale(TransactionCase): sale_orders = self.contract.with_context( cron=True).recurring_create_sale() self.assertFalse(sale_orders) + + def test_create_invoice(self): + """ The method _create_invoice should never + create an invoice from a sale contract """ + + self.assertFalse(self.contract._create_invoice()) diff --git a/contract_sale_generation/views/account_analytic_account_view.xml b/contract_sale_generation/views/account_analytic_account_view.xml index 47a4ccec..73419189 100644 --- a/contract_sale_generation/views/account_analytic_account_view.xml +++ b/contract_sale_generation/views/account_analytic_account_view.xml @@ -1,7 +1,7 @@ - + account.analytic.account.invoice.recurring.sale.form account.analytic.account @@ -26,7 +26,7 @@ {'invisible': ['|',('recurring_invoices','!=',True),('type','!=','invoice')]} -