[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#120864 X-original-commit: d4d92029bf7c2a2c6a670170d3207b457dda5c68 Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
@@ -105,7 +105,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
|
||||
@@ -115,6 +115,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,
|
||||
@@ -146,7 +150,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
|
||||
@@ -183,7 +191,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
|
||||
@@ -191,7 +203,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.update({'type': 'service', 'purchase_method': 'receive'})
|
||||
cls.product_b.update({'type': 'service', 'purchase_method': 'receive'})
|
||||
#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}},
|
||||
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user