Odoo18-Base/addons/mrp_account/tests/test_analytic_account.py
2025-03-10 11:12:23 +07:00

340 lines
15 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import TransactionCase
from odoo.tests import Form
class TestMrpAnalyticAccount(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env.user.write({'groups_id': [(4, cls.env.ref('analytic.group_analytic_accounting').id),]})
cls.analytic_plan = cls.env['account.analytic.plan'].create({
'name': 'Plan',
'company_id': False,
})
cls.analytic_account = cls.env['account.analytic.account'].create({
'name': 'test_analytic_account',
'plan_id': cls.analytic_plan.id,
})
cls.workcenter = cls.env['mrp.workcenter'].create({
'name': 'Workcenter',
'default_capacity': 1,
'time_efficiency': 100,
'costs_hour': 10,
})
cls.product = cls.env['product.product'].create({
'name': 'Product',
'type': 'product',
'standard_price': 233.0,
})
cls.component = cls.env['product.product'].create({
'name': 'Component',
'type': 'product',
'standard_price': 10.0,
})
cls.bom = cls.env['mrp.bom'].create({
'product_id': cls.product.id,
'product_tmpl_id': cls.product.product_tmpl_id.id,
'product_qty': 1.0,
'type': 'normal',
'bom_line_ids': [
(0, 0, {'product_id': cls.component.id, 'product_qty': 1.0}),
],
'operation_ids': [
(0, 0, {'name': 'work work', 'workcenter_id': cls.workcenter.id, 'time_cycle': 15, 'sequence': 1}),
]})
class TestAnalyticAccount(TestMrpAnalyticAccount):
def test_mo_analytic(self):
"""Test the amount on analytic line will change when consumed qty of the
component changed.
"""
# create a mo
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product
mo_form.bom_id = self.bom
mo_form.product_qty = 10.0
mo_form.analytic_account_id = self.analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.state, 'confirmed')
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 0)
# increase qty_producing to 5.0
mo_form = Form(mo)
mo_form.qty_producing = 5.0
mo_form.save()
self.assertEqual(mo.state, 'progress')
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.amount, -50.0)
# increase qty_producing to 10.0
mo_form = Form(mo)
mo_form.qty_producing = 10.0
mo_form.save()
# Hack to bypass test doing strange things
mo._set_qty_producing()
mo.workorder_ids.button_finish()
self.assertEqual(mo.state, 'to_close')
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.amount, -100.0)
# mark as done
mo.button_mark_done()
self.assertEqual(mo.state, 'done')
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.amount, -100.0)
def test_mo_analytic_backorder(self):
"""Test the analytic lines are correctly posted when backorder.
"""
# create a mo
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product
mo_form.bom_id = self.bom
mo_form.product_qty = 10.0
mo_form.analytic_account_id = self.analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.state, 'confirmed')
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 0)
# increase qty_producing to 5.0
mo_form = Form(mo)
mo_form.qty_producing = 5.0
mo_form.save()
self.assertEqual(mo.state, 'progress')
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.amount, -50.0)
backorder_wizard_dict = mo.button_mark_done()
Form(self.env[(backorder_wizard_dict.get('res_model'))].with_context(backorder_wizard_dict['context'])).save().action_backorder()
self.assertEqual(mo.state, 'done')
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.amount, -50.0)
def test_workcenter_same_analytic_account(self):
"""Test when workcenter and MO are using the same analytic account, no
duplicated lines will be post.
"""
# Required for `workorder_ids` to be visible in the view
self.env.user.groups_id += self.env.ref('mrp.group_mrp_routings')
# set wc analytic account to be the same of the one on the bom
self.workcenter.costs_hour_account_id = self.analytic_account
# create a mo
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product
mo_form.bom_id = self.bom
mo_form.product_qty = 10.0
mo_form.analytic_account_id = self.analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(len(mo.workorder_ids.wc_analytic_account_line_id), 0)
# change duration to 60
mo_form = Form(mo)
with mo_form.workorder_ids.edit(0) as line_edit:
line_edit.duration = 60.0
mo_form.save()
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -10.0)
self.assertEqual(len(mo.workorder_ids.wc_analytic_account_line_id), 0)
# change duration to 120
with mo_form.workorder_ids.edit(0) as line_edit:
line_edit.duration = 120.0
mo_form.save()
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -20.0)
self.assertEqual(len(mo.workorder_ids.wc_analytic_account_line_id), 0)
# mark as done
mo_form.qty_producing = 10.0
mo_form.save()
mo.button_mark_done()
self.assertEqual(mo.state, 'done')
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -20.0)
self.assertEqual(len(mo.workorder_ids.wc_analytic_account_line_id), 0)
def test_workcenter_different_analytic_account(self):
"""Test when workcenter and MO are using the same analytic account, no
duplicated lines will be post.
"""
# Required for `workorder_ids` to be visible in the view
self.env.user.groups_id += self.env.ref('mrp.group_mrp_routings')
# set wc analytic account to be different from the one on the bom
analytic_plan = self.env['account.analytic.plan'].create({'name': 'Plan Test', 'company_id': False})
wc_analytic_account = self.env['account.analytic.account'].create({'name': 'wc_analytic_account', 'plan_id': analytic_plan.id})
self.workcenter.costs_hour_account_id = wc_analytic_account
# create a mo
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product
mo_form.bom_id = self.bom
mo_form.product_qty = 10.0
mo_form.analytic_account_id = self.analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(len(mo.workorder_ids.wc_analytic_account_line_id), 0)
# change duration to 60
mo_form = Form(mo)
with mo_form.workorder_ids.edit(0) as line_edit:
line_edit.duration = 60.0
mo_form.save()
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -10.0)
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.account_id, self.analytic_account)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.amount, -10.0)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.account_id, wc_analytic_account)
# change duration to 120
with mo_form.workorder_ids.edit(0) as line_edit:
line_edit.duration = 120.0
mo_form.save()
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -20.0)
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.account_id, self.analytic_account)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.amount, -20.0)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.account_id, wc_analytic_account)
# mark as done
mo_form.qty_producing = 10.0
mo_form.save()
mo.button_mark_done()
self.assertEqual(mo.state, 'done')
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.amount, -20.0)
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.account_id, self.analytic_account)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.amount, -20.0)
self.assertEqual(mo.workorder_ids.wc_analytic_account_line_id.account_id, wc_analytic_account)
def test_changing_mo_analytic_account(self):
""" Check if the MO account analytic lines are correctly updated
after the change of the MO account analytic.
"""
# Required for `workorder_ids` to be visible in the view
self.env.user.groups_id += self.env.ref('mrp.group_mrp_routings')
# create a mo
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product
mo_form.bom_id = self.bom
mo_form.product_qty = 1
mo_form.analytic_account_id = self.analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.state, 'confirmed')
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 0)
self.assertEqual(len(mo.workorder_ids.mo_analytic_account_line_id), 0)
# Change duration to 60
mo_form = Form(mo)
with mo_form.workorder_ids.edit(0) as line_edit:
line_edit.duration = 60.0
mo_form.save()
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.account_id, self.analytic_account)
# Mark as done
wizard_dict = mo.button_mark_done()
Form(self.env[(wizard_dict.get('res_model'))].with_context(wizard_dict['context'])).save().process()
self.assertEqual(mo.state, 'done')
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 1)
# Create a new analytic account
analytic_plan = self.env['account.analytic.plan'].create({'name': 'Plan Test', 'company_id': False})
new_analytic_account = self.env['account.analytic.account'].create({'name': 'test_analytic_account_2', 'plan_id': analytic_plan.id})
# Change the MO analytic account
mo.analytic_account_id = new_analytic_account
self.assertEqual(mo.move_raw_ids.analytic_account_line_id.account_id.id, new_analytic_account.id)
self.assertEqual(mo.workorder_ids.mo_analytic_account_line_id.account_id.id, new_analytic_account.id)
#Get the MO analytic account lines
mo_analytic_account_raw_lines = mo.move_raw_ids.analytic_account_line_id
mo_analytic_account_wc_lines = mo.workorder_ids.mo_analytic_account_line_id
mo.analytic_account_id = False
# Check that the MO analytic account lines are deleted
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 0)
self.assertEqual(len(mo.workorder_ids.mo_analytic_account_line_id), 0)
self.assertFalse(mo_analytic_account_raw_lines.exists())
self.assertFalse(mo_analytic_account_wc_lines.exists())
# Check that the AA lines are recreated correctly if we delete the AA, save the MO, and assign a new one
mo.analytic_account_id = self.analytic_account
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 1)
self.assertEqual(len(mo.workorder_ids.mo_analytic_account_line_id), 1)
def test_add_remove_wo_analytic_no_company(self):
"""Test the addition and removal of work orders to a MO linked to
an analytic account that has no company associated
"""
# Create an analytic account and remove the company
analytic_account_no_company = self.env['account.analytic.account'].create({
'name': 'test_analytic_account_no_company',
'plan_id': self.analytic_plan.id,
})
analytic_account_no_company.company_id = False
# Create a mo linked to an analytic account with no associated company
mo_no_company = self.env['mrp.production'].create({
'product_id': self.product.id,
'analytic_account_id': analytic_account_no_company.id,
'product_uom_id': self.bom.product_uom_id.id,
})
mo_no_c_form = Form(mo_no_company)
wo = self.env['mrp.workorder'].create({
'name': 'Work_order',
'workcenter_id': self.workcenter.id,
'product_uom_id': self.bom.product_uom_id.id,
'production_id': mo_no_c_form.id,
'duration': 60,
})
mo_no_c_form.save()
self.assertTrue(mo_no_company.workorder_ids)
self.assertEqual(wo.production_id.analytic_account_id, analytic_account_no_company)
self.assertEqual(len(analytic_account_no_company.line_ids), 1)
mo_no_company.workorder_ids.unlink()
self.assertEqual(len(analytic_account_no_company.line_ids), 0)
def test_update_components_qty_to_0(self):
""" Test that the analytic lines are deleted when the quantity of the component is set to 0.
Create a Mo with analytic account and a component, confirm and validate it,
set the quantity of the component to 0, the analytic lines should be deleted.
"""
component = self.env['product.product'].create({
'name': 'Component',
'type': 'product',
'standard_price': 100,
})
product = self.env['product.product'].create({
'name': 'Product',
'type': 'product',
})
bom = self.env['mrp.bom'].create({
'product_tmpl_id': product.product_tmpl_id.id,
'product_qty': 1,
'product_uom_id': product.uom_id.id,
'type': 'normal',
'bom_line_ids': [(0, 0, {
'product_id': component.id,
'product_qty': 1,
'product_uom_id': component.uom_id.id,
})],
})
analytic_account = self.env['account.analytic.account'].create({
'name': "Test Account",
'plan_id': self.analytic_plan.id,
})
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = product
mo_form.bom_id = bom
mo_form.product_qty = 1.0
mo_form.analytic_account_id = analytic_account
mo = mo_form.save()
mo.action_confirm()
self.assertEqual(mo.state, 'confirmed')
mo_form = Form(mo)
mo_form.qty_producing = 1
mo = mo_form.save()
self.assertEqual(mo.state, 'to_close')
mo.button_mark_done()
self.assertEqual(mo.state, 'done')
self.assertEqual(analytic_account.debit, 100)
mo.move_raw_ids[0].quantity_done = 0
self.assertEqual(analytic_account.debit, 0)
self.assertFalse(analytic_account.line_ids)