[14.0][FIX] Travis

This commit is contained in:
Freni-OSI
2021-04-07 16:41:41 +05:30
committed by ntsirintanis
parent bd851a4b06
commit 5f6e948cad
11 changed files with 232 additions and 214 deletions

View File

@@ -1,2 +1 @@
from . import models from . import models

View File

@@ -4,18 +4,17 @@
{ {
'name': 'Contracts Management - Recurring Sales', "name": "Contracts Management - Recurring Sales",
'version': '12.0.1.0.2', "version": "14.0.1.0.0",
'category': 'Contract Management', "category": "Contract Management",
'license': 'AGPL-3', "license": "AGPL-3",
'author': "PESOL, " "author": "PESOL, " "Odoo Community Association (OCA)",
"Odoo Community Association (OCA)", "website": "https://github.com/OCA/contract",
'website': 'https://github.com/oca/contract', "depends": ["contract", "sale"],
'depends': ['contract', 'sale'], "data": [
'data': [ "data/contract_cron.xml",
'data/contract_cron.xml', "views/contract.xml",
'views/contract.xml', "views/contract_template.xml",
'views/contract_template.xml',
], ],
'installable': True, "installable": True,
} }

View File

@@ -1,8 +1,7 @@
<odoo> <odoo>
<record id="contract_cron_for_sale" model="ir.cron">
<record id="contract_cron_for_sale" model="ir.cron">
<field name="name">Generate Recurring sales from Contracts</field> <field name="name">Generate Recurring sales from Contracts</field>
<field name="model_id" ref="model_contract_contract"/> <field name="model_id" ref="model_contract_contract" />
<field name="state">code</field> <field name="state">code</field>
<field name="code">model.cron_recurring_create_sale()</field> <field name="code">model.cron_recurring_create_sale()</field>
<field name="user_id" ref="base.user_root" /> <field name="user_id" ref="base.user_root" />
@@ -11,5 +10,4 @@
<field name="numbercall">-1</field> <field name="numbercall">-1</field>
<field eval="False" name="doall" /> <field eval="False" name="doall" />
</record> </record>
</odoo> </odoo>

View File

@@ -6,14 +6,12 @@ from odoo import fields, models
class ContractAbstractContract(models.AbstractModel): class ContractAbstractContract(models.AbstractModel):
_inherit = 'contract.abstract.contract' _inherit = "contract.abstract.contract"
type = fields.Selection( type = fields.Selection(
[('invoice', 'Invoice'), [("invoice", "Invoice"), ("sale", "Sale")],
('sale', 'Sale')], string="Type",
string='Type', default="invoice",
default='invoice',
required=True, required=True,
) )
sale_autoconfirm = fields.Boolean( sale_autoconfirm = fields.Boolean(string="Sale Autoconfirm")
string='Sale Autoconfirm')

View File

@@ -8,24 +8,26 @@
# Copyright 2018 Therp BV <https://therp.nl>. # Copyright 2018 Therp BV <https://therp.nl>.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _ from odoo import _, api, fields, models
class ContractContract(models.Model): class ContractContract(models.Model):
_inherit = 'contract.contract' _inherit = "contract.contract"
sale_count = fields.Integer(compute="_compute_sale_count") sale_count = fields.Integer(compute="_compute_sale_count")
@api.multi @api.multi
def _prepare_sale(self, date_ref): def _prepare_sale(self, date_ref):
self.ensure_one() self.ensure_one()
sale = self.env['sale.order'].new({ sale = self.env["sale.order"].new(
'partner_id': self.partner_id, {
'date_order': fields.Date.to_string(date_ref), "partner_id": self.partner_id,
'origin': self.name, "date_order": fields.Date.to_string(date_ref),
'company_id': self.company_id.id, "origin": self.name,
'user_id': self.partner_id.user_id.id, "company_id": self.company_id.id,
}) "user_id": self.partner_id.user_id.id,
}
)
if self.payment_term_id: if self.payment_term_id:
sale.payment_term_id = self.payment_term_id.id sale.payment_term_id = self.payment_term_id.id
if self.fiscal_position_id: if self.fiscal_position_id:
@@ -37,10 +39,11 @@ class ContractContract(models.Model):
@api.multi @api.multi
def _get_related_sales(self): def _get_related_sales(self):
self.ensure_one() self.ensure_one()
sales = (self.env['sale.order.line'] sales = (
.search([('contract_line_id', 'in', self.env["sale.order.line"]
self.contract_line_ids.ids) .search([("contract_line_id", "in", self.contract_line_ids.ids)])
]).mapped('order_id')) .mapped("order_id")
)
return sales return sales
@api.multi @api.multi
@@ -51,20 +54,18 @@ class ContractContract(models.Model):
@api.multi @api.multi
def action_show_sales(self): def action_show_sales(self):
self.ensure_one() self.ensure_one()
tree_view = self.env.ref('sale.view_order_tree', tree_view = self.env.ref("sale.view_order_tree", raise_if_not_found=False)
raise_if_not_found=False) form_view = self.env.ref("sale.view_order_form", raise_if_not_found=False)
form_view = self.env.ref('sale.view_order_form',
raise_if_not_found=False)
action = { action = {
'type': 'ir.actions.act_window', "type": "ir.actions.act_window",
'name': 'Sales Orders', "name": "Sales Orders",
'res_model': 'sale.order', "res_model": "sale.order",
'view_type': 'form', "view_type": "form",
'view_mode': 'tree,kanban,form,calendar,pivot,graph,activity', "view_mode": "tree,kanban,form,calendar,pivot,graph,activity",
'domain': [('id', 'in', self._get_related_sales().ids)], "domain": [("id", "in", self._get_related_sales().ids)],
} }
if tree_view and form_view: if tree_view and form_view:
action['views'] = [(tree_view.id, 'tree'), (form_view.id, 'form')] action["views"] = [(tree_view.id, "tree"), (form_view.id, "form")]
return action return action
@api.multi @api.multi
@@ -77,10 +78,10 @@ class ContractContract(models.Model):
for sale_rec in sales: for sale_rec in sales:
self.message_post( self.message_post(
body=_( body=_(
'Contract manually sale order: ' "Contract manually sale order: "
'<a href="#" data-oe-model="%s" data-oe-id="%s">' '<a href="#" data-oe-model="%s" data-oe-id="%s">'
'Sale Order' "Sale Order"
'</a>' "</a>"
) )
% (sale_rec._name, sale_rec.id) % (sale_rec._name, sale_rec.id)
) )
@@ -107,14 +108,12 @@ class ContractContract(models.Model):
continue continue
sale_values = contract._prepare_sale(date_ref) sale_values = contract._prepare_sale(date_ref)
for line in contract_lines: for line in contract_lines:
sale_values.setdefault('order_line', []) sale_values.setdefault("order_line", [])
invoice_line_values = line._prepare_sale_line( invoice_line_values = line._prepare_sale_line(
sale_values=sale_values, sale_values=sale_values,
) )
if invoice_line_values: if invoice_line_values:
sale_values['order_line'].append( sale_values["order_line"].append((0, 0, invoice_line_values))
(0, 0, invoice_line_values)
)
sales_values.append(sale_values) sales_values.append(sale_values)
contract_lines._update_recurring_next_date() contract_lines._update_recurring_next_date()
return sales_values return sales_values
@@ -123,7 +122,7 @@ class ContractContract(models.Model):
def _recurring_create_sale(self, date_ref=False): def _recurring_create_sale(self, date_ref=False):
sales_values = self._prepare_recurring_sales_values(date_ref) sales_values = self._prepare_recurring_sales_values(date_ref)
so_rec = self.env["sale.order"].create(sales_values) so_rec = self.env["sale.order"].create(sales_values)
for rec in self.filtered(lambda c: c.sale_autoconfirm): for _rec in self.filtered(lambda c: c.sale_autoconfirm):
so_rec.action_confirm() so_rec.action_confirm()
return so_rec return so_rec
@@ -132,11 +131,10 @@ class ContractContract(models.Model):
if not date_ref: if not date_ref:
date_ref = fields.Date.context_today(self) date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref) domain = self._get_contracts_to_invoice_domain(date_ref)
domain.extend([('type', '=', 'sale')]) domain.extend([("type", "=", "sale")])
sales = self.env["sale.order"] sales = self.env["sale.order"]
# Sales by companies, so assignation emails get correct context # Sales by companies, so assignation emails get correct context
companies_to_sale = self.read_group( companies_to_sale = self.read_group(domain, ["company_id"], ["company_id"])
domain, ["company_id"], ["company_id"])
for row in companies_to_sale: for row in companies_to_sale:
contracts_to_sale = self.search(row["__domain"]).with_context( contracts_to_sale = self.search(row["__domain"]).with_context(
allowed_company_ids=[row["company_id"][0]] allowed_company_ids=[row["company_id"][0]]
@@ -149,15 +147,13 @@ class ContractContract(models.Model):
if not date_ref: if not date_ref:
date_ref = fields.Date.context_today(self) date_ref = fields.Date.context_today(self)
domain = self._get_contracts_to_invoice_domain(date_ref) domain = self._get_contracts_to_invoice_domain(date_ref)
domain.extend([('type', '=', 'invoice')]) domain.extend([("type", "=", "invoice")])
invoices = self.env["account.invoice"] invoices = self.env["account.invoice"]
# Invoice by companies, so assignation emails get correct context # Invoice by companies, so assignation emails get correct context
companies_to_invoice = self.read_group( companies_to_invoice = self.read_group(domain, ["company_id"], ["company_id"])
domain, ["company_id"], ["company_id"])
for row in companies_to_invoice: for row in companies_to_invoice:
contracts_to_invoice = self.search(row["__domain"]).with_context( contracts_to_invoice = self.search(row["__domain"]).with_context(
allowed_company_ids=[row["company_id"][0]] allowed_company_ids=[row["company_id"][0]]
) )
invoices |= contracts_to_invoice._recurring_create_invoice( invoices |= contracts_to_invoice._recurring_create_invoice(date_ref)
date_ref)
return invoices return invoices

View File

@@ -5,7 +5,7 @@ from odoo import api, models
class ContractLine(models.Model): class ContractLine(models.Model):
_inherit = 'contract.line' _inherit = "contract.line"
@api.multi @api.multi
def _prepare_sale_line(self, order_id=False, sale_values=False): def _prepare_sale_line(self, order_id=False, sale_values=False):
@@ -14,22 +14,30 @@ class ContractLine(models.Model):
self.last_date_invoiced, self.recurring_next_date self.last_date_invoiced, self.recurring_next_date
) )
sale_line_vals = { sale_line_vals = {
'product_id': self.product_id.id, "product_id": self.product_id.id,
'product_uom_qty': self._get_quantity_to_invoice(*dates), "product_uom_qty": self._get_quantity_to_invoice(*dates),
'uom_id': self.uom_id.id, "uom_id": self.uom_id.id,
'discount': self.discount, "discount": self.discount,
'contract_line_id': self.id, "contract_line_id": self.id,
'display_type': self.display_type, "display_type": self.display_type,
} }
if order_id: if order_id:
sale_line_vals['order_id'] = order_id.id sale_line_vals["order_id"] = order_id.id
order_line = self.env['sale.order.line'].with_context( order_line = (
force_company=self.contract_id.company_id.id, self.env["sale.order.line"]
).new(sale_line_vals) .with_context(
if sale_values and not order_id:
sale = self.env['sale.order'].with_context(
force_company=self.contract_id.company_id.id, force_company=self.contract_id.company_id.id,
).new(sale_values) )
.new(sale_line_vals)
)
if sale_values and not order_id:
sale = (
self.env["sale.order"]
.with_context(
force_company=self.contract_id.company_id.id,
)
.new(sale_values)
)
order_line.order_id = sale order_line.order_id = sale
# Get other order line values from product onchange # Get other order line values from product onchange
order_line.product_id_change() order_line.product_id_change()
@@ -38,10 +46,10 @@ class ContractLine(models.Model):
name = self._insert_markers(dates[0], dates[1]) name = self._insert_markers(dates[0], dates[1])
sale_line_vals.update( sale_line_vals.update(
{ {
'sequence': self.sequence, "sequence": self.sequence,
'name': name, "name": name,
'analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)], "analytic_tag_ids": [(6, 0, self.analytic_tag_ids.ids)],
'price_unit': self.price_unit, "price_unit": self.price_unit,
} }
) )
return sale_line_vals return sale_line_vals

View File

@@ -5,8 +5,8 @@ from odoo import fields, models
class SaleOrderLine(models.Model): class SaleOrderLine(models.Model):
_inherit = 'sale.order.line' _inherit = "sale.order.line"
contract_line_id = fields.Many2one( contract_line_id = fields.Many2one(
'contract.line', string='Contract Line', index=True "contract.line", string="Contract Line", index=True
) )

View File

@@ -1,2 +1,2 @@
This module extends functionality of contracts to be able to generate sales This module extends functionality of contracts to be able to generate sales
orders instead of invoices. orders instead of invoices.

View File

@@ -3,8 +3,8 @@
# Copyright 2017 Angel Moya <angel.moya@pesol.es> # Copyright 2017 Angel Moya <angel.moya@pesol.es>
# 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 odoo.exceptions import ValidationError
from odoo import fields from odoo import fields
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
@@ -17,95 +17,95 @@ class TestContractSale(TransactionCase):
def setUp(self): def setUp(self):
super(TestContractSale, self).setUp() super(TestContractSale, self).setUp()
self.pricelist = self.env['product.pricelist'].create({ self.pricelist = self.env["product.pricelist"].create(
'name': 'pricelist for contract test', {
}) "name": "pricelist for contract test",
self.partner = self.env['res.partner'].create({ }
'name': 'partner test contract',
'property_product_pricelist': self.pricelist.id,
})
self.product_1 = self.env.ref('product.product_product_1')
self.product_1.taxes_id += self.env['account.tax'].search(
[('type_tax_use', '=', 'sale')], limit=1
) )
self.product_1.description_sale = 'Test description sale' self.partner = self.env["res.partner"].create(
{
"name": "partner test contract",
"property_product_pricelist": self.pricelist.id,
}
)
self.product_1 = self.env.ref("product.product_product_1")
self.product_1.taxes_id += self.env["account.tax"].search(
[("type_tax_use", "=", "sale")], limit=1
)
self.product_1.description_sale = "Test description sale"
self.line_template_vals = { self.line_template_vals = {
'product_id': self.product_1.id, "product_id": self.product_1.id,
'name': 'Test Contract Template', "name": "Test Contract Template",
'quantity': 1, "quantity": 1,
'uom_id': self.product_1.uom_id.id, "uom_id": self.product_1.uom_id.id,
'price_unit': 100, "price_unit": 100,
'discount': 50, "discount": 50,
'recurring_rule_type': 'yearly', "recurring_rule_type": "yearly",
'recurring_interval': 1, "recurring_interval": 1,
} }
self.template_vals = { self.template_vals = {
'name': 'Test Contract Template', "name": "Test Contract Template",
'contract_line_ids': [ "contract_line_ids": [
(0, 0, self.line_template_vals), (0, 0, self.line_template_vals),
], ],
} }
self.template = self.env['contract.template'].create( self.template = self.env["contract.template"].create(self.template_vals)
self.template_vals
)
# For being sure of the applied price # For being sure of the applied price
self.env['product.pricelist.item'].create( self.env["product.pricelist.item"].create(
{ {
'pricelist_id': self.partner.property_product_pricelist.id, "pricelist_id": self.partner.property_product_pricelist.id,
'product_id': self.product_1.id, "product_id": self.product_1.id,
'compute_price': 'formula', "compute_price": "formula",
'base': 'list_price', "base": "list_price",
} }
) )
self.contract = self.env['contract.contract'].create( self.contract = self.env["contract.contract"].create(
{ {
'name': 'Test Contract', "name": "Test Contract",
'partner_id': self.partner.id, "partner_id": self.partner.id,
'pricelist_id': self.partner.property_product_pricelist.id, "pricelist_id": self.partner.property_product_pricelist.id,
'type': 'sale', "type": "sale",
'sale_autoconfirm': False "sale_autoconfirm": False,
} }
) )
self.line_vals = { self.line_vals = {
'contract_id': self.contract.id, "contract_id": self.contract.id,
'product_id': self.product_1.id, "product_id": self.product_1.id,
'name': 'Services from #START# to #END#', "name": "Services from #START# to #END#",
'quantity': 1, "quantity": 1,
'uom_id': self.product_1.uom_id.id, "uom_id": self.product_1.uom_id.id,
'price_unit': 100, "price_unit": 100,
'discount': 50, "discount": 50,
'recurring_rule_type': 'monthly', "recurring_rule_type": "monthly",
'recurring_interval': 1, "recurring_interval": 1,
'date_start': '2020-01-01', "date_start": "2020-01-01",
'recurring_next_date': '2020-01-15', "recurring_next_date": "2020-01-15",
} }
self.contract.contract_template_id = self.template self.contract.contract_template_id = self.template
self.contract._onchange_contract_template_id() self.contract._onchange_contract_template_id()
self.contract_line = self.env['contract.line'].create( self.contract_line = self.env["contract.line"].create(self.line_vals)
self.line_vals self.contract2 = self.env["contract.contract"].create(
)
self.contract2 = self.env['contract.contract'].create(
{ {
'name': 'Test Contract 2', "name": "Test Contract 2",
'type': 'sale', "type": "sale",
'partner_id': self.partner.id, "partner_id": self.partner.id,
'pricelist_id': self.partner.property_product_pricelist.id, "pricelist_id": self.partner.property_product_pricelist.id,
'contract_type': 'purchase', "contract_type": "purchase",
'contract_line_ids': [ "contract_line_ids": [
( (
0, 0,
0, 0,
{ {
'product_id': self.product_1.id, "product_id": self.product_1.id,
'name': 'Services from #START# to #END#', "name": "Services from #START# to #END#",
'quantity': 1, "quantity": 1,
'uom_id': self.product_1.uom_id.id, "uom_id": self.product_1.uom_id.id,
'price_unit': 100, "price_unit": 100,
'discount': 50, "discount": 50,
'recurring_rule_type': 'monthly', "recurring_rule_type": "monthly",
'recurring_interval': 1, "recurring_interval": 1,
'date_start': '2018-02-15', "date_start": "2018-02-15",
'recurring_next_date': '2018-02-22', "recurring_next_date": "2018-02-22",
}, },
) )
], ],
@@ -114,40 +114,36 @@ class TestContractSale(TransactionCase):
def test_check_discount(self): def test_check_discount(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
self.contract_line.write({'discount': 120}) self.contract_line.write({"discount": 120})
def test_contract(self): def test_contract(self):
recurring_next_date = to_date('2020-02-15') recurring_next_date = to_date("2020-02-15")
self.assertAlmostEqual(self.contract_line.price_subtotal, 50.0) self.assertAlmostEqual(self.contract_line.price_subtotal, 50.0)
res = self.contract_line._onchange_product_id() res = self.contract_line._onchange_product_id()
self.assertIn('uom_id', res['domain']) self.assertIn("uom_id", res["domain"])
self.contract_line.price_unit = 100.0 self.contract_line.price_unit = 100.0
self.contract.partner_id = self.partner.id self.contract.partner_id = self.partner.id
self.contract.recurring_create_sale() self.contract.recurring_create_sale()
self.sale_monthly = self.contract._get_related_sales() self.sale_monthly = self.contract._get_related_sales()
self.assertTrue(self.sale_monthly) self.assertTrue(self.sale_monthly)
self.assertEqual( self.assertEqual(self.contract_line.recurring_next_date, recurring_next_date)
self.contract_line.recurring_next_date, recurring_next_date
)
self.order_line = self.sale_monthly.order_line[0] self.order_line = self.sale_monthly.order_line[0]
self.assertTrue(self.order_line.tax_id) self.assertTrue(self.order_line.tax_id)
self.assertAlmostEqual(self.order_line.price_subtotal, 50.0) self.assertAlmostEqual(self.order_line.price_subtotal, 50.0)
self.assertEqual(self.contract.user_id, self.sale_monthly.user_id) self.assertEqual(self.contract.user_id, self.sale_monthly.user_id)
def test_contract_autoconfirm(self): def test_contract_autoconfirm(self):
recurring_next_date = to_date('2020-02-15') recurring_next_date = to_date("2020-02-15")
self.contract.sale_autoconfirm = True self.contract.sale_autoconfirm = True
self.assertAlmostEqual(self.contract_line.price_subtotal, 50.0) self.assertAlmostEqual(self.contract_line.price_subtotal, 50.0)
res = self.contract_line._onchange_product_id() res = self.contract_line._onchange_product_id()
self.assertIn('uom_id', res['domain']) self.assertIn("uom_id", res["domain"])
self.contract_line.price_unit = 100.0 self.contract_line.price_unit = 100.0
self.contract.partner_id = self.partner.id self.contract.partner_id = self.partner.id
self.contract.recurring_create_sale() self.contract.recurring_create_sale()
self.sale_monthly = self.contract._get_related_sales() self.sale_monthly = self.contract._get_related_sales()
self.assertTrue(self.sale_monthly) self.assertTrue(self.sale_monthly)
self.assertEqual( self.assertEqual(self.contract_line.recurring_next_date, recurring_next_date)
self.contract_line.recurring_next_date, recurring_next_date
)
self.order_line = self.sale_monthly.order_line[0] self.order_line = self.sale_monthly.order_line[0]
self.assertTrue(self.order_line.tax_id) self.assertTrue(self.order_line.tax_id)
self.assertAlmostEqual(self.order_line.price_subtotal, 50.0) self.assertAlmostEqual(self.order_line.price_subtotal, 50.0)
@@ -160,19 +156,24 @@ class TestContractSale(TransactionCase):
self.contract.contract_template_id = self.template self.contract.contract_template_id = self.template
self.contract._onchange_contract_template_id() self.contract._onchange_contract_template_id()
res = { res = {
'contract_line_ids': "contract_line_ids": [
[(0, 0, { (
'product_id': self.product_1.id, 0,
'name': 'Test Contract Template', 0,
'quantity': 1, {
'uom_id': self.product_1.uom_id.id, "product_id": self.product_1.id,
'price_unit': 100, "name": "Test Contract Template",
'discount': 50, "quantity": 1,
'recurring_rule_type': 'yearly', "uom_id": self.product_1.uom_id.id,
'recurring_interval': 1, "price_unit": 100,
})] "discount": 50,
"recurring_rule_type": "yearly",
"recurring_interval": 1,
},
)
]
} }
del self.template_vals['name'] del self.template_vals["name"]
self.assertDictEqual(res, self.template_vals) self.assertDictEqual(res, self.template_vals)
def test_contract_count_sale(self): def test_contract_count_sale(self):
@@ -183,27 +184,26 @@ class TestContractSale(TransactionCase):
self.assertEqual(self.contract.sale_count, 3) self.assertEqual(self.contract.sale_count, 3)
def test_contract_count_sale_2(self): def test_contract_count_sale_2(self):
orders = self.env['sale.order'] orders = self.env["sale.order"]
orders |= self.contract.recurring_create_sale() orders |= self.contract.recurring_create_sale()
orders |= self.contract.recurring_create_sale() orders |= self.contract.recurring_create_sale()
orders |= self.contract.recurring_create_sale() orders |= self.contract.recurring_create_sale()
action = self.contract.action_show_sales() action = self.contract.action_show_sales()
self.assertEqual(set(action['domain'][0][2]), set(orders.ids)) self.assertEqual(set(action["domain"][0][2]), set(orders.ids))
def test_cron_recurring_create_sale(self): def test_cron_recurring_create_sale(self):
self.contract_line.date_start = '2020-01-01' self.contract_line.date_start = "2020-01-01"
self.contract_line.recurring_invoicing_type = 'post-paid' self.contract_line.recurring_invoicing_type = "post-paid"
self.contract_line.date_end = '2020-03-15' self.contract_line.date_end = "2020-03-15"
self.contract_line._onchange_date_start() self.contract_line._onchange_date_start()
contracts = self.contract2 contracts = self.contract2
for _i in range(10): for _i in range(10):
contracts |= self.contract.copy({'type': 'sale'}) contracts |= self.contract.copy({"type": "sale"})
self.env['contract.contract'].cron_recurring_create_sale() self.env["contract.contract"].cron_recurring_create_sale()
order_lines = self.env['sale.order.line'].search( order_lines = self.env["sale.order.line"].search(
[('contract_line_id', 'in', [("contract_line_id", "in", contracts.mapped("contract_line_ids").ids)]
contracts.mapped('contract_line_ids').ids)]
) )
self.assertEqual( self.assertEqual(
len(contracts.mapped('contract_line_ids')), len(contracts.mapped("contract_line_ids")),
len(order_lines), len(order_lines),
) )

View File

@@ -3,38 +3,58 @@
<record id="contract_contract_form_view_recurring_sale_form" model="ir.ui.view"> <record id="contract_contract_form_view_recurring_sale_form" model="ir.ui.view">
<field name="name">contract.contract.form.recurring.sale.form</field> <field name="name">contract.contract.form.recurring.sale.form</field>
<field name="model">contract.contract</field> <field name="model">contract.contract</field>
<field name="inherit_id" ref="contract.contract_contract_form_view"/> <field name="inherit_id" ref="contract.contract_contract_form_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='recurring_invoices']" position="after"> <xpath expr="//group[@name='recurring_invoices']" position="after">
<group name="recurring_sale_or_invoicing" string="Recurring Sales/Invoicing" col="4"> <group
<field name="type"/> name="recurring_sale_or_invoicing"
<field name="sale_autoconfirm" attrs="{'invisible':[('type','!=', 'sale')]}" /> string="Recurring Sales/Invoicing"
col="4"
>
<field name="type" />
<field
name="sale_autoconfirm"
attrs="{'invisible':[('type','!=', 'sale')]}"
/>
</group> </group>
</xpath> </xpath>
<xpath expr="//button[@name='recurring_create_invoice']" position="attributes"> <xpath
<attribute name="attrs">{'invisible': ['|', ('create_invoice_visibility', '=', False),('type','!=','invoice')]}</attribute> expr="//button[@name='recurring_create_invoice']"
</xpath> position="attributes"
<xpath expr="//button[@name='recurring_create_invoice']" position="before"> >
<button name="recurring_create_sale" <attribute
type="object" name="attrs"
attrs="{'invisible': [('type','!=','sale')]}" >{'invisible': ['|', ('create_invoice_visibility', '=', False),('type','!=','invoice')]}</attribute>
string="CREATE SALES" </xpath>
class="oe_link" <xpath expr="//button[@name='recurring_create_invoice']" position="before">
groups="base.group_no_one" <button
/> name="recurring_create_sale"
type="object"
attrs="{'invisible': [('type','!=','sale')]}"
string="CREATE SALES"
class="oe_link"
groups="base.group_no_one"
/>
</xpath>
<xpath
expr="//button[@name='action_show_invoices']"
position="attributes"
>
<attribute
name="attrs"
>{'invisible': [('type','!=','invoice')]}</attribute>
</xpath> </xpath>
<xpath expr="//button[@name='action_show_invoices']" position="attributes">
<attribute name="attrs">{'invisible': [('type','!=','invoice')]}</attribute>
</xpath>
<xpath expr="//button[@name='action_show_invoices']" position="after"> <xpath expr="//button[@name='action_show_invoices']" position="after">
<button name="action_show_sales" <button
type="object" icon="fa-list" name="action_show_sales"
class="oe_stat_button" attrs="{'invisible': [('type','!=','sale')]}"> type="object"
<field string="Sales Order" icon="fa-list"
name="sale_count" class="oe_stat_button"
widget="statinfo"/> attrs="{'invisible': [('type','!=','sale')]}"
>
<field string="Sales Order" name="sale_count" widget="statinfo" />
</button> </button>
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@@ -3,10 +3,10 @@
<record id="contract_template_form_view_inherit_sale" model="ir.ui.view"> <record id="contract_template_form_view_inherit_sale" model="ir.ui.view">
<field name="name">contract.template form view (in contract)</field> <field name="name">contract.template form view (in contract)</field>
<field name="model">contract.template</field> <field name="model">contract.template</field>
<field name="inherit_id" ref="contract.contract_template_form_view"/> <field name="inherit_id" ref="contract.contract_template_form_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='pricelist_id']" position="after"> <xpath expr="//field[@name='pricelist_id']" position="after">
<field name="type"/> <field name="type" />
</xpath> </xpath>
</field> </field>
</record> </record>