[FIX] point_of_sale,pos_sale: correctly set analytic_distribution
Current behavior: When you create a sale order with an analytic account, and settle it in the POS, the analytic account is not set on the POS order invoice lines. Steps to reproduce: - Create a sale order with an analytic account (in other info tab) - Confirm the sale order - Go to the POS and settle the order - Pay and invoice the order - Go to the invoice and check the analytic account on the invoice lines Note: I based my fix on what was already done in the sale_order creation to set the analytic distribution correctly on the invoice lines. opw-3635140 closes odoo/odoo#147737 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
@@ -233,6 +233,18 @@ class PosOrder(models.Model):
|
||||
self.ensure_one()
|
||||
return self.lines._prepare_tax_base_line_values(sign=sign)
|
||||
|
||||
@api.model
|
||||
def _get_invoice_lines_values(self, line_values, pos_order_line):
|
||||
return {
|
||||
'product_id': line_values['product'].id,
|
||||
'quantity': line_values['quantity'],
|
||||
'discount': line_values['discount'],
|
||||
'price_unit': line_values['price_unit'],
|
||||
'name': line_values['name'],
|
||||
'tax_ids': [(6, 0, line_values['taxes'].ids)],
|
||||
'product_uom_id': line_values['uom'].id,
|
||||
}
|
||||
|
||||
def _prepare_invoice_lines(self):
|
||||
""" Prepare a list of orm commands containing the dictionaries to fill the
|
||||
'invoice_line_ids' field when creating an invoice.
|
||||
@@ -244,15 +256,8 @@ class PosOrder(models.Model):
|
||||
invoice_lines = []
|
||||
for line_values in line_values_list:
|
||||
line = line_values['record']
|
||||
invoice_lines.append((0, None, {
|
||||
'product_id': line_values['product'].id,
|
||||
'quantity': line_values['quantity'],
|
||||
'discount': line_values['discount'],
|
||||
'price_unit': line_values['price_unit'],
|
||||
'name': line_values['name'],
|
||||
'tax_ids': [(6, 0, line_values['taxes'].ids)],
|
||||
'product_uom_id': line_values['uom'].id,
|
||||
}))
|
||||
invoice_lines_values = self._get_invoice_lines_values(line_values, line)
|
||||
invoice_lines.append((0, None, invoice_lines_values))
|
||||
if line.order_id.pricelist_id.discount_policy == 'without_discount' and float_compare(line.price_unit, line.product_id.lst_price, precision_rounding=self.currency_id.rounding) < 0:
|
||||
invoice_lines.append((0, None, {
|
||||
'name': _('Price discount from %s -> %s',
|
||||
|
||||
@@ -113,6 +113,14 @@ class PosOrder(models.Model):
|
||||
'domain': [('id', 'in', linked_orders.ids)],
|
||||
}
|
||||
|
||||
def _get_invoice_lines_values(self, line_values, pos_line):
|
||||
inv_line_vals = super()._get_invoice_lines_values(line_values, pos_line)
|
||||
|
||||
if pos_line.sale_order_origin_id:
|
||||
origin_line = pos_line.sale_order_line_id
|
||||
origin_line._set_analytic_distribution(inv_line_vals)
|
||||
|
||||
return inv_line_vals
|
||||
|
||||
class PosOrderLine(models.Model):
|
||||
_inherit = 'pos.order.line'
|
||||
|
||||
@@ -170,3 +170,19 @@ registry
|
||||
|
||||
].flat(),
|
||||
});
|
||||
|
||||
registry
|
||||
.category("web_tour.tours")
|
||||
.add('PosSettleAndInvoiceOrder', {
|
||||
test: true,
|
||||
url: '/pos/ui',
|
||||
steps: () => [
|
||||
ProductScreen.confirmOpeningPopup(),
|
||||
ProductScreen.clickQuotationButton(),
|
||||
ProductScreen.selectFirstOrder(),
|
||||
ProductScreen.clickPayButton(),
|
||||
PaymentScreen.clickPaymentMethod("Bank"),
|
||||
PaymentScreen.clickInvoiceButton(),
|
||||
PaymentScreen.clickValidate(),
|
||||
].flat(),
|
||||
});
|
||||
|
||||
@@ -361,3 +361,30 @@ class TestPoSSale(TestPointOfSaleHttpCommon):
|
||||
|
||||
self.main_pos_config.open_ui()
|
||||
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderWithNote', login="accountman")
|
||||
def test_pos_invoice_analytic_account(self):
|
||||
#create a sale order with product_a
|
||||
self.analytic_plan_projects = self.env['account.analytic.plan'].create({'name': 'Projects'})
|
||||
self.analytic_plan_departments = self.env['account.analytic.plan'].create({'name': 'Departments test'})
|
||||
|
||||
self.analytic_account_partner_a_1 = self.env['account.analytic.account'].create({
|
||||
'name': 'analytic_account_partner_a_1',
|
||||
'partner_id': self.partner_a.id,
|
||||
'plan_id': self.analytic_plan_projects.id,
|
||||
})
|
||||
self.env['sale.order'].create({
|
||||
'partner_id': self.env.ref('base.res_partner_2').id,
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': self.desk_pad.id,
|
||||
'name': self.desk_pad.name,
|
||||
'product_uom_qty': 3.5,
|
||||
'product_uom': self.desk_pad.uom_id.id,
|
||||
'price_unit': self.desk_pad.lst_price,
|
||||
})],
|
||||
'analytic_account_id': self.analytic_account_partner_a_1.id,
|
||||
})
|
||||
self.main_pos_config.open_ui()
|
||||
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleAndInvoiceOrder', login="accountman")
|
||||
|
||||
pos_order = self.env['pos.order'].search([], order='id desc', limit=1)
|
||||
self.assertTrue(pos_order.account_move.line_ids[0].analytic_distribution, "Analytic distribution should be set on the invoice line")
|
||||
self.assertEqual(pos_order.account_move.line_ids[0].analytic_distribution.get(str(self.analytic_account_partner_a_1.id)), 100)
|
||||
|
||||
@@ -1127,21 +1127,24 @@ class SaleOrderLine(models.Model):
|
||||
'sale_line_ids': [Command.link(self.id)],
|
||||
'is_downpayment': self.is_downpayment,
|
||||
}
|
||||
analytic_account_id = self.order_id.analytic_account_id.id
|
||||
if self.analytic_distribution and not self.display_type:
|
||||
res['analytic_distribution'] = self.analytic_distribution
|
||||
if analytic_account_id and not self.display_type:
|
||||
analytic_account_id = str(analytic_account_id)
|
||||
if 'analytic_distribution' in res:
|
||||
res['analytic_distribution'][analytic_account_id] = res['analytic_distribution'].get(analytic_account_id, 0) + 100
|
||||
else:
|
||||
res['analytic_distribution'] = {analytic_account_id: 100}
|
||||
self._set_analytic_distribution(res, **optional_values)
|
||||
if optional_values:
|
||||
res.update(optional_values)
|
||||
if self.display_type:
|
||||
res['account_id'] = False
|
||||
return res
|
||||
|
||||
def _set_analytic_distribution(self, inv_line_vals, **optional_values):
|
||||
analytic_account_id = self.order_id.analytic_account_id.id
|
||||
if self.analytic_distribution and not self.display_type:
|
||||
inv_line_vals['analytic_distribution'] = self.analytic_distribution
|
||||
if analytic_account_id and not self.display_type:
|
||||
analytic_account_id = str(analytic_account_id)
|
||||
if 'analytic_distribution' in inv_line_vals:
|
||||
inv_line_vals['analytic_distribution'][analytic_account_id] = inv_line_vals['analytic_distribution'].get(analytic_account_id, 0) + 100
|
||||
else:
|
||||
inv_line_vals['analytic_distribution'] = {analytic_account_id: 100}
|
||||
|
||||
def _prepare_procurement_values(self, group_id=False):
|
||||
""" Prepare specific key for moves or other components that will be created from a stock rule
|
||||
coming from a sale order line. This method could be override in order to add other custom key that could
|
||||
|
||||
Reference in New Issue
Block a user