mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-27 16:51:59 +02:00
19.0 vanilla
This commit is contained in:
parent
79f83631d5
commit
73afc09215
6267 changed files with 1534193 additions and 1130106 deletions
|
|
@ -0,0 +1,4 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_reinvoice
|
||||
from . import test_sale_project_stock_profitability
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.stock.tests.common import TestStockCommon
|
||||
|
||||
|
||||
class TestReInvoice(TestStockCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.partner = cls.env['res.partner'].create({'name': 'Test Partner'})
|
||||
cls.sale_order = cls.env['sale.order'].create({
|
||||
'partner_id': cls.partner.id,
|
||||
'partner_invoice_id': cls.partner.id,
|
||||
'partner_shipping_id': cls.partner.id,
|
||||
})
|
||||
cls.project = cls.env['project.project'].create({
|
||||
'name': 'Project',
|
||||
'reinvoiced_sale_order_id': cls.sale_order.id,
|
||||
})
|
||||
cls.picking_out = cls.PickingObj.create({
|
||||
'picking_type_id': cls.picking_type_out.id,
|
||||
'location_id': cls.stock_location.id,
|
||||
'location_dest_id': cls.customer_location.id,
|
||||
'project_id': cls.project.id,
|
||||
})
|
||||
cls.picking_out.picking_type_id.analytic_costs = True
|
||||
cls.reinvoicable_product_at_cost, cls.reinvoicable_product_sales_price = cls.env['product.product'].create([
|
||||
{
|
||||
'name': 'product_order_cost',
|
||||
'standard_price': 100.0,
|
||||
'expense_policy': 'cost',
|
||||
},
|
||||
{
|
||||
'name': 'product_order_cost',
|
||||
'list_price': 500.0,
|
||||
'expense_policy': 'sales_price',
|
||||
},
|
||||
])
|
||||
cls.sale_order.action_confirm()
|
||||
|
||||
def test_picking_reinvoicing(self):
|
||||
move_values = {
|
||||
'product_uom': self.uom_unit.id,
|
||||
'picking_id': self.picking_out.id,
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
}
|
||||
self.MoveObj.create([
|
||||
{
|
||||
**move_values,
|
||||
'product_id': self.reinvoicable_product_at_cost.id,
|
||||
'product_uom_qty': 3,
|
||||
},
|
||||
{
|
||||
**move_values,
|
||||
'product_id': self.reinvoicable_product_sales_price.id,
|
||||
'product_uom_qty': 5,
|
||||
},
|
||||
])
|
||||
self.picking_out.with_user(self.user_stock_user).action_confirm()
|
||||
self.picking_out.with_user(self.user_stock_user).button_validate()
|
||||
|
||||
self.assertEqual(len(self.sale_order.order_line), 2, 'There should be 2 lines on the SO')
|
||||
new_sale_order_line1 = self.sale_order.order_line.filtered(lambda sol: sol.product_id == self.reinvoicable_product_at_cost)
|
||||
self.assertTrue(new_sale_order_line1, 'A new sale line should have been created with the reinvoicable product at cost')
|
||||
self.assertEqual(
|
||||
(new_sale_order_line1.price_unit, new_sale_order_line1.qty_delivered, new_sale_order_line1.product_uom_qty, new_sale_order_line1.qty_invoiced),
|
||||
(self.reinvoicable_product_at_cost.standard_price, 3, 3, 0),
|
||||
'Sale line is wrong after confirming the picking',
|
||||
)
|
||||
self.assertEqual(new_sale_order_line1.qty_delivered_method, 'stock_move', 'Delivered quantity of SO line should be computed by stock move')
|
||||
|
||||
new_sale_order_line2 = self.sale_order.order_line.filtered(lambda sol: sol.product_id == self.reinvoicable_product_sales_price)
|
||||
self.assertTrue(new_sale_order_line2, 'A new sale line should have been created with the reinvoicable product at sales price')
|
||||
self.assertEqual(
|
||||
(new_sale_order_line2.price_unit, new_sale_order_line2.qty_delivered, new_sale_order_line2.product_uom_qty, new_sale_order_line2.qty_invoiced),
|
||||
(self.reinvoicable_product_sales_price.list_price, 5, 5, 0),
|
||||
'Sale line is wrong after confirming the picking',
|
||||
)
|
||||
self.assertEqual(new_sale_order_line2.qty_delivered_method, 'stock_move', 'Delivered quantity of SO line should be computed by stock move')
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import Command, fields
|
||||
from odoo.addons.sale_project.tests.test_project_profitability import TestProjectProfitabilityCommon
|
||||
from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestSaleProjectStockProfitability(TestProjectProfitabilityCommon, ValuationReconciliationTestCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
project_template = cls.env['project.project'].create({
|
||||
'name': 'sale_project_stock project template',
|
||||
'account_id': cls.analytic_account.id,
|
||||
})
|
||||
cls.cogs_account = cls.env['account.account'].search([
|
||||
('name', '=', 'Cost of Goods Sold'),
|
||||
('company_ids', 'in', cls.env.company.id),
|
||||
], limit=1)
|
||||
cls.auto_valuated_product = cls.env['product.product'].create({
|
||||
'name': 'auto valuated product',
|
||||
'is_storable': True,
|
||||
'categ_id': cls.stock_account_product_categ.id,
|
||||
'standard_price': 12.0,
|
||||
'list_price': 24.0,
|
||||
})
|
||||
cls.product_superb_service = cls.env['product.product'].create({
|
||||
'name': 'product that creates project on order',
|
||||
'type': 'service',
|
||||
'standard_price': 10.0,
|
||||
'list_price': 20.0,
|
||||
'service_tracking': 'project_only',
|
||||
'project_template_id': project_template.id,
|
||||
})
|
||||
|
||||
def test_report_invoice_items_anglo_saxon_automatic_valuation(self):
|
||||
""" An invoice can have some lines which should be classified/displayed under the 'Costs'
|
||||
section of a project's profitability report (specifically, COGS lines).
|
||||
"""
|
||||
self.env.company.anglo_saxon_accounting = True
|
||||
self.stock_account_product_categ.write({
|
||||
'property_account_expense_categ_id': self.cogs_account.id,
|
||||
'property_cost_method': 'average',
|
||||
})
|
||||
service_product = self.product_superb_service
|
||||
avco_product = self.auto_valuated_product
|
||||
other_avco_product = self.env['product.product'].create({
|
||||
'name': 'other avco product',
|
||||
'is_storable': True,
|
||||
'categ_id': avco_product.categ_id.id,
|
||||
'standard_price': 16.0,
|
||||
'list_price': 32.0,
|
||||
})
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner.id,
|
||||
'order_line': [Command.create({
|
||||
'product_id': service_product.id,
|
||||
'product_uom_qty': 10,
|
||||
}), Command.create({
|
||||
'product_id': avco_product.id,
|
||||
'product_uom_qty': 10,
|
||||
}), Command.create({
|
||||
'product_id': other_avco_product.id,
|
||||
'product_uom_qty': 10,
|
||||
})],
|
||||
})
|
||||
sale_order.action_confirm()
|
||||
delivery = sale_order.picking_ids
|
||||
delivery.move_ids.quantity = 10
|
||||
delivery.button_validate()
|
||||
sale_order._create_invoices()
|
||||
invoice = sale_order.invoice_ids[0]
|
||||
invoice.invoice_date = fields.Date.today()
|
||||
invoice.action_post()
|
||||
panel_data = sale_order.project_ids.get_panel_data()
|
||||
self.assertEqual(
|
||||
panel_data['profitability_items']['costs'],
|
||||
{
|
||||
'data': [{
|
||||
'action': {
|
||||
'args': f'["cost_of_goods_sold", [["id", "in", [{invoice.id}]]], {invoice.id}]',
|
||||
'name': 'action_profitability_items',
|
||||
'type': 'object',
|
||||
},
|
||||
'id': 'cost_of_goods_sold',
|
||||
'billed': -280.0,
|
||||
'sequence': 21,
|
||||
'to_bill': 0.0,
|
||||
}],
|
||||
'total': {
|
||||
'billed': -280.0,
|
||||
'to_bill': 0.0,
|
||||
}
|
||||
}
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue