Skip to content
Snippets Groups Projects
Commit d4d92029 authored by smdc-odoo's avatar smdc-odoo
Browse files

[FIX] account: Propagate analytic on accrued entries


We want to propagate the analytic breakdown on the accrued
entries that user can already create from the PO/SO list views.

task-3096126

closes odoo/odoo#108288

Signed-off-by: default avatarWilliam André (wan) <wan@odoo.com>
parent f2f45cdd
No related branches found
No related tags found
No related merge requests found
......@@ -110,7 +110,7 @@ class AccruedExpenseRevenue(models.TransientModel):
})
def _compute_move_vals(self):
def _get_aml_vals(order, balance, amount_currency, account_id, label=""):
def _get_aml_vals(order, balance, amount_currency, account_id, label="", analytic_distribution=None):
if not is_purchase:
balance *= -1
amount_currency *= -1
......@@ -120,6 +120,10 @@ class AccruedExpenseRevenue(models.TransientModel):
'credit': balance * -1 if balance < 0 else 0.0,
'account_id': account_id,
}
if analytic_distribution:
values.update({
'analytic_distribution': analytic_distribution,
})
if len(order) == 1 and self.company_id.currency_id != order.currency_id:
values.update({
'amount_currency': amount_currency,
......@@ -151,7 +155,11 @@ class AccruedExpenseRevenue(models.TransientModel):
account = order_line.product_id.property_account_expense_id or order_line.product_id.categ_id.property_account_expense_categ_id
else:
account = order_line.product_id.property_account_income_id or order_line.product_id.categ_id.property_account_income_categ_id
values = _get_aml_vals(order, self.amount, 0, account.id, label=_('Manual entry'))
distribution = order_line.analytic_distribution if order_line.analytic_distribution else {}
if not is_purchase and order.analytic_account_id:
analytic_account_id = str(order.analytic_account_id.id)
distribution[analytic_account_id] = distribution.get(analytic_account_id, 0) + 100.0
values = _get_aml_vals(order, self.amount, 0, account.id, label=_('Manual entry'), analytic_distribution=distribution)
move_lines.append(Command.create(values))
else:
other_currency = self.company_id.currency_id != order.currency_id
......@@ -188,7 +196,11 @@ class AccruedExpenseRevenue(models.TransientModel):
amount_currency = order_line.untaxed_amount_to_invoice
fnames = ['qty_to_invoice', 'untaxed_amount_to_invoice', 'qty_invoiced', 'qty_delivered', 'invoice_lines']
label = _('%s - %s; %s Invoiced, %s Delivered at %s each', order.name, _ellipsis(order_line.name, 20), order_line.qty_invoiced, order_line.qty_delivered, formatLang(self.env, order_line.price_unit, currency_obj=order.currency_id))
values = _get_aml_vals(order, amount, amount_currency, account.id, label=label)
distribution = order_line.analytic_distribution if order_line.analytic_distribution else {}
if not is_purchase and order.analytic_account_id:
analytic_account_id = str(order.analytic_account_id.id)
distribution[analytic_account_id] = distribution.get(analytic_account_id, 0) + 100.0
values = _get_aml_vals(order, amount, amount_currency, account.id, label=label, analytic_distribution=distribution)
move_lines.append(Command.create(values))
total_balance += amount
# must invalidate cache or o can mess when _create_invoices().action_post() of original order after this
......@@ -196,7 +208,18 @@ class AccruedExpenseRevenue(models.TransientModel):
if not self.company_id.currency_id.is_zero(total_balance):
# globalized counterpart for the whole orders selection
values = _get_aml_vals(orders, -total_balance, 0.0, self.account_id.id, label=_('Accrued total'))
analytic_distribution = {}
total = sum(order.amount_total for order in orders)
for line in orders.order_line:
ratio = line.price_total / total
if not is_purchase and line.order_id.analytic_account_id:
account_id = str(line.order_id.analytic_account_id.id)
analytic_distribution.update({account_id: analytic_distribution.get(account_id, 0) +100.0*ratio})
if not line.analytic_distribution:
continue
for account_id, distribution in line.analytic_distribution.items():
analytic_distribution.update({account_id : analytic_distribution.get(account_id, 0) + distribution*ratio})
values = _get_aml_vals(orders, -total_balance, 0.0, self.account_id.id, label=_('Accrued total'), analytic_distribution=analytic_distribution)
move_lines.append(Command.create(values))
move_type = _('Expense') if is_purchase else _('Revenue')
......
......@@ -15,6 +15,18 @@ class TestAccruedPurchaseOrders(AccountTestInvoicingCommon):
# set 'type' to 'service' to allow manualy set 'qty_delivered' even with purchase_stock installed
cls.product_a.type = 'service'
cls.product_b.type = 'service'
#analytic distribution
cls.default_plan = cls.env['account.analytic.plan'].create({'name': 'Default', 'company_id': False})
cls.analytic_account_a = cls.env['account.analytic.account'].create({
'name': 'analytic_account_a',
'plan_id': cls.default_plan.id,
'company_id': False,
})
cls.analytic_account_b = cls.env['account.analytic.account'].create({
'name': 'analytic_account_b',
'plan_id': cls.default_plan.id,
'company_id': False,
})
cls.product_b.property_account_expense_id = cls.alt_exp_account
cls.purchase_order = cls.env['purchase.order'].with_context(tracking_disable=True).create({
'partner_id': cls.partner_a.id,
......@@ -26,6 +38,10 @@ class TestAccruedPurchaseOrders(AccountTestInvoicingCommon):
'product_uom': cls.product_a.uom_id.id,
'price_unit': cls.product_a.list_price,
'taxes_id': False,
'analytic_distribution': {
cls.analytic_account_a.id : 80.0,
cls.analytic_account_b.id : 20.0,
},
}),
Command.create({
'name': cls.product_b.name,
......@@ -34,6 +50,9 @@ class TestAccruedPurchaseOrders(AccountTestInvoicingCommon):
'product_uom': cls.product_b.uom_id.id,
'price_unit': cls.product_b.list_price,
'taxes_id': False,
'analytic_distribution': {
cls.analytic_account_b.id : 100.0,
},
}),
],
})
......@@ -88,3 +107,17 @@ class TestAccruedPurchaseOrders(AccountTestInvoicingCommon):
{'account_id': self.alt_exp_account.id, 'debit': 1000 / 2, 'credit': 0, 'amount_currency': 1000},
{'account_id': self.account_revenue.id, 'debit': 0, 'credit': 6000 / 2, 'amount_currency': 0.0},
])
def test_analytic_account_accrued_order(self):
self.purchase_order.order_line.qty_received = 10
self.assertRecordValues(self.env['account.move'].search(self.wizard.create_entries()['domain']).line_ids, [
# reverse move lines
{'account_id': self.account_expense.id, 'debit': 0.0, 'credit': 10000.0, 'analytic_distribution': {str(self.analytic_account_a.id): 80.0, str(self.analytic_account_b.id): 20.0}},
{'account_id': self.alt_exp_account.id, 'debit': 0.0, 'credit': 2000.0, 'analytic_distribution': {str(self.analytic_account_b.id): 100.0}},
{'account_id': self.account_revenue.id, 'debit': 12000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_a.id): 66.67, str(self.analytic_account_b.id): 33.33}},
# move lines
{'account_id': self.account_expense.id, 'debit': 10000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_a.id): 80.0, str(self.analytic_account_b.id): 20.0}},
{'account_id': self.alt_exp_account.id, 'debit': 2000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_b.id): 100.0}},
{'account_id': self.account_revenue.id, 'debit': 0.0, 'credit': 12000.0, 'analytic_distribution': {str(self.analytic_account_a.id): 66.67, str(self.analytic_account_b.id): 33.33}},
])
......@@ -25,6 +25,22 @@ class TestAccruedSaleOrders(AccountTestInvoicingCommon):
'invoice_policy': 'delivery',
'property_account_income_id': cls.alt_inc_account.id,
})
cls.default_plan = cls.env['account.analytic.plan'].create({'name': 'Default', 'company_id': False})
cls.analytic_account_a = cls.env['account.analytic.account'].create({
'name': 'analytic_account_a',
'plan_id': cls.default_plan.id,
'company_id': False,
})
cls.analytic_account_b = cls.env['account.analytic.account'].create({
'name': 'analytic_account_b',
'plan_id': cls.default_plan.id,
'company_id': False,
})
cls.analytic_account_c = cls.env['account.analytic.account'].create({
'name': 'analytic_account_c',
'plan_id': cls.default_plan.id,
'company_id': False,
})
cls.sale_order = cls.env['sale.order'].with_context(tracking_disable=True).create({
'partner_id': cls.partner_a.id,
'order_line': [
......@@ -35,6 +51,10 @@ class TestAccruedSaleOrders(AccountTestInvoicingCommon):
'product_uom': cls.product_a.uom_id.id,
'price_unit': cls.product_a.list_price,
'tax_id': False,
'analytic_distribution': {
cls.analytic_account_a.id : 80.0,
cls.analytic_account_b.id : 20.0,
},
}),
Command.create({
'name': cls.product_b.name,
......@@ -43,9 +63,13 @@ class TestAccruedSaleOrders(AccountTestInvoicingCommon):
'product_uom': cls.product_b.uom_id.id,
'price_unit': cls.product_b.list_price,
'tax_id': False,
'analytic_distribution': {
cls.analytic_account_b.id : 100.0,
},
})
]
})
cls.sale_order.analytic_account_id = cls.analytic_account_c
cls.sale_order.action_confirm()
cls.account_expense = cls.company_data['default_account_expense']
cls.account_revenue = cls.company_data['default_account_revenue']
......@@ -96,3 +120,18 @@ class TestAccruedSaleOrders(AccountTestInvoicingCommon):
{'account_id': self.alt_inc_account.id, 'debit': 0, 'credit': 1000 / 2, 'amount_currency': -1000},
{'account_id': self.account_expense.id, 'debit': 6000 / 2, 'credit': 0, 'amount_currency': 0.0},
])
def test_analytic_account_accrued_order(self):
self.sale_order.order_line.qty_delivered = 10
self.assertRecordValues(self.env['account.move'].search(self.wizard.create_entries()['domain']).line_ids, [
# reverse move lines
{'account_id': self.account_revenue.id, 'debit': 10000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_a.id): 80.0, str(self.analytic_account_b.id): 20.0, str(self.analytic_account_c.id): 100.0}},
{'account_id': self.alt_inc_account.id, 'debit': 2000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_b.id): 100.0, str(self.analytic_account_c.id): 100.0}},
{'account_id': self.account_expense.id, 'debit': 0.0, 'credit': 12000.0, 'analytic_distribution': {str(self.analytic_account_a.id): 66.67, str(self.analytic_account_b.id): 33.33, str(self.analytic_account_c.id): 100.0}},
# move lines
{'account_id': self.account_revenue.id, 'debit': 0.0, 'credit': 10000.0, 'analytic_distribution': {str(self.analytic_account_a.id): 80.0, str(self.analytic_account_b.id): 20.0, str(self.analytic_account_c.id): 100.0}},
{'account_id': self.alt_inc_account.id, 'debit': 0.0, 'credit': 2000.0, 'analytic_distribution': {str(self.analytic_account_b.id): 100.0, str(self.analytic_account_c.id): 100.0}},
{'account_id': self.account_expense.id, 'debit': 12000.0, 'credit': 0.0, 'analytic_distribution': {str(self.analytic_account_a.id): 66.67, str(self.analytic_account_b.id): 33.33, str(self.analytic_account_c.id): 100.0}},
])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment