[IMP] sale_timesheet: class tests
This commit adds tests for reinvoicing flow, to check reinvoice service does not generate task/project and delivered quantity still depends only on analytic entries and not timesheet. This commit also unify tests in sale_timesheet, by making them extend the sale common class. They are now launched at module installation.
This commit is contained in:
@@ -5,3 +5,4 @@ from . import common
|
||||
from . import test_sale_timesheet
|
||||
from . import test_sale_service
|
||||
from . import test_timesheet_revenue
|
||||
from . import test_reinvoice
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.addons.sale.tests.test_sale_common import TestCommonSaleNoChart
|
||||
|
||||
|
||||
class CommonTest(common.SavepointCase):
|
||||
class TestCommonSaleTimesheetNoChart(TestCommonSaleNoChart):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CommonTest, cls).setUpClass()
|
||||
def setUpEmployees(cls):
|
||||
# Create employees
|
||||
cls.employee_user = cls.env['hr.employee'].create({
|
||||
'name': 'Employee User',
|
||||
'timesheet_cost': 15,
|
||||
})
|
||||
cls.employee_manager = cls.env['hr.employee'].create({
|
||||
'name': 'Employee Manager',
|
||||
'timesheet_cost': 45,
|
||||
})
|
||||
|
||||
# Create accounts
|
||||
cls.account_debit = cls.env['account.account'].create({
|
||||
'code': 'X1012',
|
||||
'name': 'Debtors - (test)',
|
||||
'reconcile': True,
|
||||
'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
|
||||
})
|
||||
cls.account_credit = cls.env['account.account'].create({
|
||||
'code': 'X1111',
|
||||
'name': 'Creditors - (test)',
|
||||
'reconcile': True,
|
||||
'user_type_id': cls.env.ref('account.data_account_type_payable').id,
|
||||
})
|
||||
@classmethod
|
||||
def setUpServiceProducts(cls):
|
||||
""" Create Service product for all kind, with each tracking policy. """
|
||||
# Account and project
|
||||
cls.account_sale = cls.env['account.account'].create({
|
||||
'code': 'X2020',
|
||||
'code': 'SERV-2020',
|
||||
'name': 'Product Sales - (test)',
|
||||
'reconcile': True,
|
||||
'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
|
||||
})
|
||||
|
||||
# Create project
|
||||
cls.project_global = cls.env['project.project'].create({
|
||||
'name': 'Project for selling timesheets',
|
||||
'allow_timesheets': True,
|
||||
})
|
||||
|
||||
# Create service products
|
||||
uom_hour = cls.env.ref('product.product_uom_hour')
|
||||
|
||||
# -- ordered quantities (ordered, timesheet)
|
||||
cls.product_order_timesheet1 = cls.env['product.product'].create({
|
||||
@@ -45,8 +44,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 13,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'order',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-ORDERED1',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'no',
|
||||
@@ -60,8 +59,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 90,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'order',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-ORDERED2',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'task_global_project',
|
||||
@@ -75,8 +74,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 20,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'order',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-ORDERED3',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'task_new_project',
|
||||
@@ -90,8 +89,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 30,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'order',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-ORDERED4',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'project_only',
|
||||
@@ -107,8 +106,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 13,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI1',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'no',
|
||||
@@ -122,8 +121,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 90,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI2',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'task_global_project',
|
||||
@@ -137,8 +136,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 20,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI3',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'task_new_project',
|
||||
@@ -152,8 +151,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 30,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI4',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'project_only',
|
||||
@@ -162,15 +161,15 @@ class CommonTest(common.SavepointCase):
|
||||
'property_account_income_id': cls.account_sale.id,
|
||||
})
|
||||
|
||||
# -- milestons (delivered, manual)
|
||||
# -- milestones (delivered, manual)
|
||||
cls.product_delivery_manual1 = cls.env['product.product'].create({
|
||||
'name': "Service delivered, create no task",
|
||||
'standard_price': 11,
|
||||
'list_price': 13,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI1',
|
||||
'service_type': 'manual',
|
||||
'service_tracking': 'no',
|
||||
@@ -184,8 +183,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 90,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI2',
|
||||
'service_type': 'manual',
|
||||
'service_tracking': 'task_global_project',
|
||||
@@ -199,8 +198,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 20,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI3',
|
||||
'service_type': 'manual',
|
||||
'service_tracking': 'task_new_project',
|
||||
@@ -214,8 +213,8 @@ class CommonTest(common.SavepointCase):
|
||||
'list_price': 30,
|
||||
'type': 'service',
|
||||
'invoice_policy': 'delivery',
|
||||
'uom_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_po_id': cls.env.ref('product.product_uom_hour').id,
|
||||
'uom_id': uom_hour.id,
|
||||
'uom_po_id': uom_hour.id,
|
||||
'default_code': 'SERV-DELI4',
|
||||
'service_type': 'manual',
|
||||
'service_tracking': 'project_only',
|
||||
@@ -223,58 +222,3 @@ class CommonTest(common.SavepointCase):
|
||||
'taxes_id': False,
|
||||
'property_account_income_id': cls.account_sale.id,
|
||||
})
|
||||
|
||||
# Create pricelists
|
||||
cls.pricelist_usd = cls.env['product.pricelist'].create({
|
||||
'name': 'USD pricelist',
|
||||
'active': True,
|
||||
'currency_id': cls.env.ref('base.USD').id,
|
||||
'company_id': cls.env.user.company_id.id,
|
||||
})
|
||||
|
||||
cls.bank_journal_euro = cls.env['account.journal'].create({
|
||||
'name': 'Sale Journal - Test',
|
||||
'type': 'sale',
|
||||
'code': 'SJT',
|
||||
'currency_id': cls.env.ref('base.EUR').id,
|
||||
})
|
||||
|
||||
cls.bank_journal_usd = cls.env['account.journal'].create({
|
||||
'name': 'Sale Journal - Test US',
|
||||
'type': 'sale',
|
||||
'code': 'SJTU',
|
||||
'currency_id': cls.env.ref('base.USD').id,
|
||||
})
|
||||
|
||||
cls.pricelist_eur = cls.env['product.pricelist'].create({
|
||||
'name': 'EUR pricelist',
|
||||
'active': True,
|
||||
'currency_id': cls.env.ref('base.EUR').id,
|
||||
'company_id': cls.env.user.company_id.id,
|
||||
})
|
||||
|
||||
# Create partners
|
||||
cls.partner_usd = cls.env['res.partner'].create({
|
||||
'name': 'Cool Partner in USD',
|
||||
'email': 'partner.usd@test.com',
|
||||
'property_product_pricelist': cls.pricelist_usd.id,
|
||||
'property_account_payable_id': cls.account_credit.id,
|
||||
'property_account_receivable_id': cls.account_debit.id,
|
||||
})
|
||||
cls.partner_eur = cls.env['res.partner'].create({
|
||||
'name': 'Cool partner in EUR',
|
||||
'email': 'partner.eur@test.com',
|
||||
'property_product_pricelist': cls.pricelist_eur.id,
|
||||
'property_account_payable_id': cls.account_credit.id,
|
||||
'property_account_receivable_id': cls.account_debit.id,
|
||||
})
|
||||
|
||||
# Create employees
|
||||
cls.employee_user = cls.env['hr.employee'].create({
|
||||
'name': 'Employee User',
|
||||
'timesheet_cost': 15,
|
||||
})
|
||||
cls.employee_manager = cls.env['hr.employee'].create({
|
||||
'name': 'Employee Manager',
|
||||
'timesheet_cost': 45,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart
|
||||
|
||||
|
||||
class TestReInvoice(TestCommonSaleTimesheetNoChart):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestReInvoice, cls).setUpClass()
|
||||
|
||||
cls.setUpEmployees()
|
||||
cls.setUpExpenseProducts()
|
||||
cls.setUpAdditionalAccounts()
|
||||
cls.setUpAccountJournal()
|
||||
|
||||
# patch expense products to make them services creating task/project
|
||||
service_values = {
|
||||
'type': 'service',
|
||||
'service_type': 'timesheet',
|
||||
'service_tracking': 'task_new_project'
|
||||
}
|
||||
cls.product_ordered_cost.write(service_values)
|
||||
cls.product_deliver_cost.write(service_values)
|
||||
cls.product_order_sales_price.write(service_values)
|
||||
cls.product_deliver_sales_price.write(service_values)
|
||||
cls.product_no_expense.write(service_values)
|
||||
|
||||
# create AA, SO and invoices
|
||||
cls.analytic_account = cls.env['account.analytic.account'].create({
|
||||
'name': 'Test AA',
|
||||
'code': 'TESTSALE_TIMESHEET_REINVOICE',
|
||||
'company_id': cls.partner_customer_usd.company_id.id,
|
||||
'partner_id': cls.partner_customer_usd.id
|
||||
})
|
||||
|
||||
cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({
|
||||
'partner_id': cls.partner_customer_usd.id,
|
||||
'partner_invoice_id': cls.partner_customer_usd.id,
|
||||
'partner_shipping_id': cls.partner_customer_usd.id,
|
||||
'analytic_account_id': cls.analytic_account.id,
|
||||
})
|
||||
|
||||
Invoice = cls.env['account.invoice'].with_context(mail_notrack=True, mail_create_nolog=True)
|
||||
cls.invoiceA = Invoice.create({
|
||||
'name': 'Test Invoice',
|
||||
'type': 'in_invoice',
|
||||
'partner_id': cls.partner_customer_usd.id,
|
||||
'account_id': cls.account_payable.id,
|
||||
'journal_id': cls.journal_purchase.id,
|
||||
'currency_id': cls.env.user.company_id.currency_id.id,
|
||||
})
|
||||
cls.invoiceB = Invoice.create({
|
||||
'name': 'Test Invoice 2',
|
||||
'type': 'in_invoice',
|
||||
'partner_id': cls.partner_customer_usd.id,
|
||||
'account_id': cls.account_payable.id,
|
||||
'journal_id': cls.journal_purchase.id,
|
||||
'currency_id': cls.env.user.company_id.currency_id.id,
|
||||
})
|
||||
|
||||
def test_at_cost(self):
|
||||
""" Test vendor bill at cost for product based on ordered and delivered quantities. """
|
||||
# create SO line and confirm SO (with only one line)
|
||||
sale_order_line1 = self.env['sale.order.line'].create({
|
||||
'name': self.product_ordered_cost.name,
|
||||
'product_id': self.product_ordered_cost.id,
|
||||
'product_uom_qty': 2,
|
||||
'product_uom': self.product_ordered_cost.uom_id.id,
|
||||
'price_unit': self.product_ordered_cost.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line1.product_id_change()
|
||||
sale_order_line2 = self.env['sale.order.line'].create({
|
||||
'name': self.product_deliver_cost.name,
|
||||
'product_id': self.product_deliver_cost.id,
|
||||
'product_uom_qty': 4,
|
||||
'product_uom': self.product_deliver_cost.uom_id.id,
|
||||
'price_unit': self.product_deliver_cost.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line2.product_id_change()
|
||||
|
||||
self.sale_order.onchange_partner_id()
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
self.assertEquals(sale_order_line1.qty_delivered_method, 'timesheet', "Delivered quantity of 'service' SO line should be computed by timesheet amount")
|
||||
self.assertEquals(sale_order_line2.qty_delivered_method, 'timesheet', "Delivered quantity of 'service' SO line should be computed by timesheet amount")
|
||||
|
||||
# let's log some timesheets (on the project created by sale_order_line1)
|
||||
task_sol1 = sale_order_line1.task_id
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': task_sol1.project_id.id,
|
||||
'task_id': task_sol1.id,
|
||||
'unit_amount': 1,
|
||||
'employee_id': self.employee_user.id,
|
||||
})
|
||||
|
||||
# create invoice lines and validate it
|
||||
invoice_lineA1 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_ordered_cost.name,
|
||||
'product_id': self.product_ordered_cost.id,
|
||||
'quantity': 3,
|
||||
'uom_id': self.product_ordered_cost.uom_id.id,
|
||||
'price_unit': self.product_ordered_cost.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceA.id,
|
||||
})
|
||||
invoice_lineA2 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_deliver_cost.name,
|
||||
'product_id': self.product_deliver_cost.id,
|
||||
'quantity': 3,
|
||||
'uom_id': self.product_deliver_cost.uom_id.id,
|
||||
'price_unit': self.product_deliver_cost.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceA.id,
|
||||
})
|
||||
self.invoiceA.action_invoice_open()
|
||||
|
||||
sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_ordered_cost)
|
||||
sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_deliver_cost)
|
||||
|
||||
self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product")
|
||||
self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product")
|
||||
self.assertEquals(len(self.sale_order.order_line), 4, "There should be 4 lines on the SO (2 vendor bill lines created)")
|
||||
self.assertEquals(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 2, "There should be 4 lines on the SO (2 vendor bill lines created)")
|
||||
|
||||
self.assertEquals(sale_order_line1.qty_delivered, 1, "Exising SO line 1 should not be impacted by reinvoicing product at cost")
|
||||
self.assertEquals(sale_order_line2.qty_delivered, 0, "Exising SO line 2 should not be impacted by reinvoicing product at cost")
|
||||
|
||||
self.assertFalse(sale_order_line3.task_id, "Adding a new expense SO line should not create a task (sol3)")
|
||||
self.assertFalse(sale_order_line4.task_id, "Adding a new expense SO line should not create a task (sol4)")
|
||||
self.assertEquals(len(self.sale_order.project_ids), 1, "SO create only one project with its service line. Adding new expense SO line should not impact that")
|
||||
|
||||
self.assertEquals((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_ordered_cost.standard_price, invoice_lineA1.quantity, 0, 0), 'Sale line is wrong after confirming vendor invoice')
|
||||
self.assertEquals((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_deliver_cost.standard_price, invoice_lineA2.quantity, 0, 0), 'Sale line is wrong after confirming vendor invoice')
|
||||
|
||||
self.assertEquals(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount")
|
||||
self.assertEquals(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount")
|
||||
|
||||
# create second invoice lines and validate it
|
||||
invoice_lineB1 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_ordered_cost.name,
|
||||
'product_id': self.product_ordered_cost.id,
|
||||
'quantity': 2,
|
||||
'uom_id': self.product_ordered_cost.uom_id.id,
|
||||
'price_unit': self.product_ordered_cost.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceB.id,
|
||||
})
|
||||
invoice_lineB2 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_deliver_cost.name,
|
||||
'product_id': self.product_deliver_cost.id,
|
||||
'quantity': 2,
|
||||
'uom_id': self.product_deliver_cost.uom_id.id,
|
||||
'price_unit': self.product_deliver_cost.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceB.id,
|
||||
})
|
||||
self.invoiceB.action_invoice_open()
|
||||
|
||||
sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_ordered_cost)
|
||||
sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_deliver_cost)
|
||||
|
||||
self.assertTrue(sale_order_line5, "A new sale line should have been created with ordered product")
|
||||
self.assertTrue(sale_order_line6, "A new sale line should have been created with delivered product")
|
||||
|
||||
self.assertEquals(len(self.sale_order.order_line), 6, "There should be still 4 lines on the SO, no new created")
|
||||
self.assertEquals(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 4, "There should be still 2 expenses lines on the SO")
|
||||
|
||||
self.assertEquals((sale_order_line5.price_unit, sale_order_line5.qty_delivered, sale_order_line5.product_uom_qty, sale_order_line5.qty_invoiced), (self.product_ordered_cost.standard_price, invoice_lineB1.quantity, 0, 0), 'Sale line 5 is wrong after confirming 2e vendor invoice')
|
||||
self.assertEquals((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line6.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_deliver_cost.standard_price, invoice_lineB2.quantity, 0, 0), 'Sale line 6 is wrong after confirming 2e vendor invoice')
|
||||
|
||||
def test_sales_price(self):
|
||||
""" Test invoicing vendor bill at sales price for products based on delivered and ordered quantities. Check no existing SO line is incremented, but when invoicing a
|
||||
second time, increment only the delivered so line.
|
||||
"""
|
||||
# create SO line and confirm SO (with only one line)
|
||||
sale_order_line1 = self.env['sale.order.line'].create({
|
||||
'name': self.product_deliver_sales_price.name,
|
||||
'product_id': self.product_deliver_sales_price.id,
|
||||
'product_uom_qty': 2,
|
||||
'qty_delivered': 1,
|
||||
'product_uom': self.product_deliver_sales_price.uom_id.id,
|
||||
'price_unit': self.product_deliver_sales_price.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line1.product_id_change()
|
||||
sale_order_line2 = self.env['sale.order.line'].create({
|
||||
'name': self.product_order_sales_price.name,
|
||||
'product_id': self.product_order_sales_price.id,
|
||||
'product_uom_qty': 3,
|
||||
'qty_delivered': 1,
|
||||
'product_uom': self.product_order_sales_price.uom_id.id,
|
||||
'price_unit': self.product_order_sales_price.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
sale_order_line2.product_id_change()
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
# let's log some timesheets (on the project created by sale_order_line1)
|
||||
task_sol1 = sale_order_line1.task_id
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': task_sol1.project_id.id,
|
||||
'task_id': task_sol1.id,
|
||||
'unit_amount': 1,
|
||||
'employee_id': self.employee_user.id,
|
||||
})
|
||||
|
||||
# create invoice lines and validate it
|
||||
invoice_lineA1 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_deliver_sales_price.name,
|
||||
'product_id': self.product_deliver_sales_price.id,
|
||||
'quantity': 3,
|
||||
'uom_id': self.product_deliver_sales_price.uom_id.id,
|
||||
'price_unit': self.product_deliver_sales_price.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceA.id,
|
||||
})
|
||||
invoice_lineA2 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_order_sales_price.name,
|
||||
'product_id': self.product_order_sales_price.id,
|
||||
'quantity': 3,
|
||||
'uom_id': self.product_order_sales_price.uom_id.id,
|
||||
'price_unit': self.product_order_sales_price.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceA.id,
|
||||
})
|
||||
self.invoiceA.action_invoice_open()
|
||||
|
||||
sale_order_line3 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol.product_id == self.product_deliver_sales_price)
|
||||
sale_order_line4 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol.product_id == self.product_order_sales_price)
|
||||
|
||||
self.assertTrue(sale_order_line3, "A new sale line should have been created with ordered product")
|
||||
self.assertTrue(sale_order_line4, "A new sale line should have been created with delivered product")
|
||||
self.assertEquals(len(self.sale_order.order_line), 4, "There should be 4 lines on the SO (2 vendor bill lines created)")
|
||||
self.assertEquals(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 2, "There should be 4 lines on the SO (2 vendor bill lines created)")
|
||||
|
||||
self.assertEquals(sale_order_line1.qty_delivered, 1, "Exising SO line 1 should not be impacted by reinvoicing product at cost")
|
||||
self.assertEquals(sale_order_line2.qty_delivered, 0, "Exising SO line 2 should not be impacted by reinvoicing product at cost")
|
||||
|
||||
self.assertFalse(sale_order_line3.task_id, "Adding a new expense SO line should not create a task (sol3)")
|
||||
self.assertFalse(sale_order_line4.task_id, "Adding a new expense SO line should not create a task (sol4)")
|
||||
self.assertEquals(len(self.sale_order.project_ids), 1, "SO create only one project with its service line. Adding new expense SO line should not impact that")
|
||||
|
||||
self.assertEquals((sale_order_line3.price_unit, sale_order_line3.qty_delivered, sale_order_line3.product_uom_qty, sale_order_line3.qty_invoiced), (self.product_deliver_sales_price.list_price, invoice_lineA1.quantity, 0, 0), 'Sale line is wrong after confirming vendor invoice')
|
||||
self.assertEquals((sale_order_line4.price_unit, sale_order_line4.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line4.qty_invoiced), (self.product_order_sales_price.list_price, invoice_lineA2.quantity, 0, 0), 'Sale line is wrong after confirming vendor invoice')
|
||||
|
||||
self.assertEquals(sale_order_line3.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 3 should be computed by analytic amount")
|
||||
self.assertEquals(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 4 should be computed by analytic amount")
|
||||
|
||||
# create second invoice lines and validate it
|
||||
invoice_lineB1 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_deliver_sales_price.name,
|
||||
'product_id': self.product_deliver_sales_price.id,
|
||||
'quantity': 2,
|
||||
'uom_id': self.product_deliver_sales_price.uom_id.id,
|
||||
'price_unit': self.product_deliver_sales_price.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceB.id,
|
||||
})
|
||||
invoice_lineB2 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_order_sales_price.name,
|
||||
'product_id': self.product_order_sales_price.id,
|
||||
'quantity': 2,
|
||||
'uom_id': self.product_order_sales_price.uom_id.id,
|
||||
'price_unit': self.product_order_sales_price.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceB.id,
|
||||
})
|
||||
self.invoiceB.action_invoice_open()
|
||||
|
||||
sale_order_line5 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line1 and sol != sale_order_line3 and sol.product_id == self.product_deliver_sales_price)
|
||||
sale_order_line6 = self.sale_order.order_line.filtered(lambda sol: sol != sale_order_line2 and sol != sale_order_line4 and sol.product_id == self.product_order_sales_price)
|
||||
|
||||
self.assertFalse(sale_order_line5, "No new sale line should have been created with delivered product !!")
|
||||
self.assertTrue(sale_order_line6, "A new sale line should have been created with ordered product")
|
||||
|
||||
self.assertEquals(len(self.sale_order.order_line), 5, "There should be 5 lines on the SO, 1 new created and 1 incremented")
|
||||
self.assertEquals(len(self.sale_order.order_line.filtered(lambda sol: sol.is_expense)), 3, "There should be 3 expenses lines on the SO")
|
||||
|
||||
self.assertEquals((sale_order_line6.price_unit, sale_order_line6.qty_delivered, sale_order_line4.product_uom_qty, sale_order_line6.qty_invoiced), (self.product_order_sales_price.list_price, invoice_lineB2.quantity, 0, 0), 'Sale line is wrong after confirming 2e vendor invoice')
|
||||
|
||||
def test_no_expense(self):
|
||||
""" Test invoicing vendor bill with no policy. Check nothing happen. """
|
||||
# confirm SO
|
||||
sale_order_line = self.env['sale.order.line'].create({
|
||||
'name': self.product_no_expense.name,
|
||||
'product_id': self.product_no_expense.id,
|
||||
'product_uom_qty': 2,
|
||||
'qty_delivered': 1,
|
||||
'product_uom': self.product_no_expense.uom_id.id,
|
||||
'price_unit': self.product_no_expense.list_price,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
self.sale_order._compute_tax_id()
|
||||
self.sale_order.action_confirm()
|
||||
|
||||
# create invoice lines and validate it
|
||||
invoice_lineA1 = self.env['account.invoice.line'].create({
|
||||
'name': self.product_no_expense.name,
|
||||
'product_id': self.product_no_expense.id,
|
||||
'quantity': 3,
|
||||
'uom_id': self.product_no_expense.uom_id.id,
|
||||
'price_unit': self.product_no_expense.standard_price,
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'account_id': self.account_income.id,
|
||||
'invoice_id': self.invoiceA.id,
|
||||
})
|
||||
self.invoiceA.action_invoice_open()
|
||||
|
||||
# let's log some timesheets (on the project created by sale_order_line1)
|
||||
task_sol1 = sale_order_line.task_id
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': task_sol1.project_id.id,
|
||||
'task_id': task_sol1.id,
|
||||
'unit_amount': 1,
|
||||
'employee_id': self.employee_user.id,
|
||||
})
|
||||
|
||||
self.assertEquals(len(self.sale_order.order_line), 1, "No SO line should have been created (or removed) when validating vendor bill")
|
||||
self.assertEquals(sale_order_line.qty_delivered, 1, "The delivered quantity of SO line should not have been incremented")
|
||||
self.assertTrue(invoice_lineA1.invoice_id.move_id.mapped('line_ids.analytic_line_ids'), "Analytic lines should be generated")
|
||||
@@ -1,43 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.sale_timesheet.tests.common import CommonTest
|
||||
from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class TestSaleService(CommonTest):
|
||||
class TestSaleService(TestCommonSaleTimesheetNoChart):
|
||||
""" This test suite provide checks for miscellaneous small things. """
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSaleService, cls).setUpClass()
|
||||
# set up
|
||||
cls.setUpEmployees()
|
||||
cls.setUpServiceProducts()
|
||||
|
||||
cls.sale_order = cls.env['sale.order'].with_context(mail_notrack=True, mail_create_nolog=True).create({
|
||||
'partner_id': cls.partner_customer_usd.id,
|
||||
'partner_invoice_id': cls.partner_customer_usd.id,
|
||||
'partner_shipping_id': cls.partner_customer_usd.id,
|
||||
})
|
||||
|
||||
def test_sale_service(self):
|
||||
""" Test task creation when confirming a sale_order with the corresponding product """
|
||||
sale_order_vals = {
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'order_line': [(0, 0, {
|
||||
'name': self.product_delivery_timesheet2.name,
|
||||
'product_id': self.product_delivery_timesheet2.id,
|
||||
'product_uom_qty': 50,
|
||||
'product_uom': self.product_delivery_timesheet2.uom_id.id,
|
||||
'price_unit': self.product_delivery_timesheet2.list_price
|
||||
})],
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
}
|
||||
sale_order = self.env['sale.order'].create(sale_order_vals)
|
||||
sale_order.order_line._compute_product_updatable()
|
||||
self.assertTrue(sale_order.order_line[0].product_updatable)
|
||||
sale_order.action_confirm()
|
||||
sale_order.order_line._compute_product_updatable()
|
||||
self.assertFalse(sale_order.order_line[0].product_updatable)
|
||||
self.assertEqual(sale_order.invoice_status, 'no', 'Sale Service: there should be nothing to invoice after validation')
|
||||
sale_order_line = self.env['sale.order.line'].create({
|
||||
'order_id': self.sale_order.id,
|
||||
'name': self.product_delivery_timesheet2.name,
|
||||
'product_id': self.product_delivery_timesheet2.id,
|
||||
'product_uom_qty': 50,
|
||||
'product_uom': self.product_delivery_timesheet2.uom_id.id,
|
||||
'price_unit': self.product_delivery_timesheet2.list_price
|
||||
})
|
||||
|
||||
self.sale_order.order_line._compute_product_updatable()
|
||||
self.assertTrue(sale_order_line.product_updatable)
|
||||
self.sale_order.action_confirm()
|
||||
self.sale_order.order_line._compute_product_updatable()
|
||||
|
||||
self.assertFalse(sale_order_line.product_updatable)
|
||||
self.assertEqual(self.sale_order.invoice_status, 'no', 'Sale Service: there should be nothing to invoice after validation')
|
||||
|
||||
# check task creation
|
||||
project = self.project_global
|
||||
task = project.task_ids.filtered(lambda t: t.name == '%s:%s' % (sale_order.name, self.product_delivery_timesheet2.name))
|
||||
task = project.task_ids.filtered(lambda t: t.name == '%s:%s' % (self.sale_order.name, self.product_delivery_timesheet2.name))
|
||||
self.assertTrue(task, 'Sale Service: task is not created')
|
||||
self.assertEqual(task.partner_id, sale_order.partner_id, 'Sale Service: customer should be the same on task and on SO')
|
||||
self.assertEqual(task.email_from, sale_order.partner_id.email, 'Sale Service: Task Email should be the same as the SO customer Email')
|
||||
# register timesheet on task
|
||||
self.assertEqual(task.partner_id, self.sale_order.partner_id, 'Sale Service: customer should be the same on task and on SO')
|
||||
self.assertEqual(task.email_from, self.sale_order.partner_id.email, 'Sale Service: Task Email should be the same as the SO customer Email')
|
||||
|
||||
# log timesheet on task
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': project.id,
|
||||
@@ -45,12 +55,12 @@ class TestSaleService(CommonTest):
|
||||
'unit_amount': 50,
|
||||
'employee_id': self.employee_manager.id,
|
||||
})
|
||||
self.assertEqual(sale_order.invoice_status, 'to invoice', 'Sale Service: there should be sale_ordermething to invoice after registering timesheets')
|
||||
sale_order.action_invoice_create()
|
||||
line = sale_order.order_line
|
||||
self.assertTrue(line.product_uom_qty == line.qty_delivered == line.qty_invoiced, 'Sale Service: line should be invoiced completely')
|
||||
self.assertEqual(sale_order.invoice_status, 'invoiced', 'Sale Service: SO should be invoiced')
|
||||
self.assertEqual(sale_order.tasks_count, 1, "A task should have been created on SO confirmation.")
|
||||
self.assertEqual(self.sale_order.invoice_status, 'to invoice', 'Sale Service: there should be sale_ordermething to invoice after registering timesheets')
|
||||
self.sale_order.action_invoice_create()
|
||||
|
||||
self.assertTrue(sale_order_line.product_uom_qty == sale_order_line.qty_delivered == sale_order_line.qty_invoiced, 'Sale Service: line should be invoiced completely')
|
||||
self.assertEqual(self.sale_order.invoice_status, 'invoiced', 'Sale Service: SO should be invoiced')
|
||||
self.assertEqual(self.sale_order.tasks_count, 1, "A task should have been created on SO confirmation.")
|
||||
|
||||
# Add a line on the confirmed SO, and it should generate a new task directly
|
||||
product_service_task = self.env['product.product'].create({
|
||||
@@ -73,71 +83,58 @@ class TestSaleService(CommonTest):
|
||||
'product_uom_qty': 10,
|
||||
'product_uom': product_service_task.uom_id.id,
|
||||
'price_unit': product_service_task.list_price,
|
||||
'order_id': sale_order.id,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
|
||||
self.assertEqual(sale_order.tasks_count, 2, "Adding a new service line on a confirmer SO should create a new task.")
|
||||
self.assertEqual(self.sale_order.tasks_count, 2, "Adding a new service line on a confirmer SO should create a new task.")
|
||||
|
||||
def test_timesheet_uom(self):
|
||||
""" Test timesheet invoicing and uom conversion """
|
||||
# create SO and confirm it
|
||||
uom_days = self.env.ref('product.product_uom_day')
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'name': self.product_delivery_timesheet3.name,
|
||||
'product_id': self.product_delivery_timesheet3.id,
|
||||
'product_uom_qty': 5,
|
||||
'product_uom': uom_days.id,
|
||||
'price_unit': self.product_delivery_timesheet3.list_price
|
||||
})
|
||||
],
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
sale_order_line = self.env['sale.order.line'].create({
|
||||
'order_id': self.sale_order.id,
|
||||
'name': self.product_delivery_timesheet3.name,
|
||||
'product_id': self.product_delivery_timesheet3.id,
|
||||
'product_uom_qty': 5,
|
||||
'product_uom': uom_days.id,
|
||||
'price_unit': self.product_delivery_timesheet3.list_price
|
||||
})
|
||||
sale_order.action_confirm()
|
||||
task = self.env['project.task'].search([('sale_line_id', '=', sale_order.order_line.id)])
|
||||
self.sale_order.action_confirm()
|
||||
task = self.env['project.task'].search([('sale_line_id', '=', sale_order_line.id)])
|
||||
|
||||
# let's log some timesheets
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': sale_order.project_project_id.id,
|
||||
'project_id': self.sale_order.project_project_id.id,
|
||||
'task_id': task.id,
|
||||
'unit_amount': 16,
|
||||
'employee_id': self.employee_manager.id,
|
||||
})
|
||||
self.assertEqual(sale_order.order_line.qty_delivered, 2, 'Sale: uom conversion of timesheets is wrong')
|
||||
self.assertEqual(self.sale_order.order_line.qty_delivered, 2, 'Sale: uom conversion of timesheets is wrong')
|
||||
|
||||
self.env['account.analytic.line'].create({
|
||||
'name': 'Test Line',
|
||||
'project_id': sale_order.project_project_id.id,
|
||||
'project_id': self.sale_order.project_project_id.id,
|
||||
'task_id': task.id,
|
||||
'unit_amount': 24,
|
||||
'employee_id': self.employee_user.id,
|
||||
})
|
||||
sale_order.action_invoice_create()
|
||||
self.assertEqual(sale_order.invoice_status, 'invoiced', 'Sale Timesheet: "invoice on delivery" timesheets should not modify the invoice_status of the so')
|
||||
self.sale_order.action_invoice_create()
|
||||
self.assertEqual(self.sale_order.invoice_status, 'invoiced', 'Sale Timesheet: "invoice on delivery" timesheets should not modify the invoice_status of the so')
|
||||
|
||||
def test_task_so_line_assignation(self):
|
||||
# create SO and confirm it
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
})
|
||||
so_line_deliver_global_project = self.env['sale.order.line'].create({
|
||||
'name': self.product_delivery_timesheet2.name,
|
||||
'product_id': self.product_delivery_timesheet2.id,
|
||||
'product_uom_qty': 10,
|
||||
'product_uom': self.product_delivery_timesheet2.uom_id.id,
|
||||
'price_unit': self.product_delivery_timesheet2.list_price,
|
||||
'order_id': sale_order.id,
|
||||
'order_id': self.sale_order.id,
|
||||
})
|
||||
so_line_deliver_global_project.product_id_change()
|
||||
sale_order.action_confirm()
|
||||
self.sale_order.action_confirm()
|
||||
task_serv2 = self.env['project.task'].search([('sale_line_id', '=', so_line_deliver_global_project.id)])
|
||||
|
||||
# let's log some timesheets (on the project created by so_line_ordered_project_only)
|
||||
@@ -168,7 +165,7 @@ class TestSaleService(CommonTest):
|
||||
self.assertTrue(all([billing_type == 'billable_time' for billing_type in timesheets.mapped('timesheet_invoice_type')]), "Timesheet to a billable time task should be billable")
|
||||
|
||||
# invoice SO, and validate invoice
|
||||
invoice_id = sale_order.action_invoice_create()[0]
|
||||
invoice_id = self.sale_order.action_invoice_create()[0]
|
||||
invoice = self.env['account.invoice'].browse(invoice_id)
|
||||
invoice.action_invoice_open()
|
||||
|
||||
@@ -179,9 +176,9 @@ class TestSaleService(CommonTest):
|
||||
def test_delivered_quantity(self):
|
||||
# create SO and confirm it
|
||||
sale_order = self.env['sale.order'].with_context(tracking_disable=True).create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'partner_id': self.partner_customer_usd.id,
|
||||
'partner_invoice_id': self.partner_customer_usd.id,
|
||||
'partner_shipping_id': self.partner_customer_usd.id,
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
})
|
||||
so_line_deliver_new_task_project = self.env['sale.order.line'].create({
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tools import float_is_zero, float_compare
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
from odoo.addons.sale_timesheet.tests.common import CommonTest
|
||||
from odoo.addons.sale_timesheet.tests.common import TestCommonSaleTimesheetNoChart
|
||||
|
||||
|
||||
class TestSaleTimesheet(CommonTest):
|
||||
class TestSaleTimesheet(TestCommonSaleTimesheetNoChart):
|
||||
""" This test suite provide tests for the 3 main flows of selling services:
|
||||
- Selling services based on ordered quantities
|
||||
- Selling timesheet based on delivered quantities
|
||||
@@ -14,6 +14,13 @@ class TestSaleTimesheet(CommonTest):
|
||||
quantities changes, ...
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSaleTimesheet, cls).setUpClass()
|
||||
# set up
|
||||
cls.setUpEmployees()
|
||||
cls.setUpServiceProducts()
|
||||
|
||||
def test_timesheet_order(self):
|
||||
""" Test timesheet invoicing with 'invoice on order' timetracked products
|
||||
1. create SO with 2 ordered product and confirm
|
||||
@@ -24,9 +31,9 @@ class TestSaleTimesheet(CommonTest):
|
||||
"""
|
||||
# create SO and confirm it
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'partner_id': self.partner_customer_usd.id,
|
||||
'partner_invoice_id': self.partner_customer_usd.id,
|
||||
'partner_shipping_id': self.partner_customer_usd.id,
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
})
|
||||
so_line_ordered_project_only = self.env['sale.order.line'].create({
|
||||
@@ -126,9 +133,9 @@ class TestSaleTimesheet(CommonTest):
|
||||
"""
|
||||
# create SO and confirm it
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'partner_id': self.partner_customer_usd.id,
|
||||
'partner_invoice_id': self.partner_customer_usd.id,
|
||||
'partner_shipping_id': self.partner_customer_usd.id,
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
})
|
||||
so_line_deliver_global_project = self.env['sale.order.line'].create({
|
||||
@@ -222,9 +229,9 @@ class TestSaleTimesheet(CommonTest):
|
||||
"""
|
||||
# create SO and confirm it
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_usd.id,
|
||||
'partner_invoice_id': self.partner_usd.id,
|
||||
'partner_shipping_id': self.partner_usd.id,
|
||||
'partner_id': self.partner_customer_usd.id,
|
||||
'partner_invoice_id': self.partner_customer_usd.id,
|
||||
'partner_shipping_id': self.partner_customer_usd.id,
|
||||
'pricelist_id': self.pricelist_usd.id,
|
||||
})
|
||||
so_line_manual_global_project = self.env['sale.order.line'].create({
|
||||
|
||||
Reference in New Issue
Block a user