[FIX] point_of_sale: ship later with multiple expense account
Current behavior: If you had 2 products with different expense account and using real-time inventory valuation, there was an error when validating the picking. This was happening because move_vals we were trying to assign multiple moves to one pos_order here https://github.com/odoo/odoo/blob/95cec6ea3daebce6491cc2a8a69d9688322989ba/addons/point_of_sale/models/stock_picking.py#L155 The account move is actually reserved for the invoicing of the order. So we just need to remove that line. Steps to reproduce: - Create a product with expense account A - Create a product with expense account B - Make sure both products are set to real-time inventory valuation - Activate ship later in the PoS - Open the PoS and add both products to the order - Validate the order with ship later and no invoice - Close the PoS and try to validate the picking of the order. opw-3428033 closes odoo/odoo#136254 X-original-commit: a2c8ea0adbd93cb9d178977f73e93492e84dfec3 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com> Signed-off-by: Robin Engels (roen) <roen@odoo.com>
This commit is contained in:
@@ -1468,7 +1468,8 @@ class PosSession(models.Model):
|
||||
# we are querying over the account.move.line because its 'ref' is indexed.
|
||||
# And yes, we are only concern for split bank payment methods.
|
||||
diff_lines_ref = [self._get_diff_account_move_ref(pm) for pm in self.payment_method_ids if pm.type == 'bank' and pm.split_transactions]
|
||||
return self.env['account.move.line'].search([('ref', 'in', diff_lines_ref)]).mapped('move_id')
|
||||
cost_move_lines = ['pos_order_'+str(rec.id) for rec in self.order_ids]
|
||||
return self.env['account.move.line'].search([('ref', 'in', diff_lines_ref + cost_move_lines)]).mapped('move_id')
|
||||
|
||||
def _get_related_account_moves(self):
|
||||
pickings = self.picking_ids | self.order_ids.mapped('picking_ids')
|
||||
|
||||
@@ -136,7 +136,7 @@ class StockPicking(models.Model):
|
||||
move_vals.append({
|
||||
'journal_id': rec.pos_order_id.sale_journal.id,
|
||||
'date': rec.pos_order_id.date_order,
|
||||
'ref': rec.pos_order_id.name,
|
||||
'ref': 'pos_order_'+str(rec.pos_order_id.id),
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'name': rec.pos_order_id.name,
|
||||
@@ -153,7 +153,6 @@ class StockPicking(models.Model):
|
||||
],
|
||||
})
|
||||
move = self.env['account.move'].create(move_vals)
|
||||
rec.pos_order_id.write({'account_move': move.id})
|
||||
move.action_post()
|
||||
return res
|
||||
|
||||
|
||||
@@ -289,18 +289,18 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
|
||||
self.assertEqual(len(aml_output), 3, "There should be 3 output account move lines")
|
||||
# 2 moves in POS journal (Pos order + manual entry at delivery)
|
||||
self.assertEqual(aml_output[:2].move_id.journal_id, self.pos_config.journal_id)
|
||||
self.assertEqual(len(aml_output.move_id.filtered(lambda l: l.journal_id == self.pos_config.journal_id)), 2)
|
||||
# 1 move in stock journal (delivery from stock layers)
|
||||
self.assertEqual(aml_output[2].move_id.journal_id, self.category.property_stock_journal)
|
||||
self.assertEqual(len(aml_output.move_id.filtered(lambda l: l.journal_id == self.category.property_stock_journal)), 1)
|
||||
#Check the lines created after the picking validation
|
||||
self.assertEqual(aml_output[0].credit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[0].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[2].debit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[2].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[0].debit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[0].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
#Check the lines created by the PoS session
|
||||
self.assertEqual(aml_output[1].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[2].credit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[2].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[1].debit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[1].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[1].debit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[1].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[1].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
#Check the lines created by the PoS session
|
||||
self.assertEqual(aml_output[0].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_output[0].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[0].credit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
self.assertEqual(aml_expense[0].debit, 0.0, "Cost of Good Sold entry missing or mismatching")
|
||||
|
||||
@@ -1692,3 +1692,88 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
aml = session_id.move_id.line_ids.filtered(lambda x: x.account_id == self.account1 and x.tax_ids == self.tax1)
|
||||
self.assertEqual(aml.price_total, 220)
|
||||
self.assertEqual(aml.price_subtotal, 200)
|
||||
|
||||
def test_multi_exp_account_real_time(self):
|
||||
|
||||
#Create a real time valuation product category
|
||||
self.real_time_categ = self.env['product.category'].create({
|
||||
'name': 'test category',
|
||||
'parent_id': False,
|
||||
'property_cost_method': 'fifo',
|
||||
'property_valuation': 'real_time',
|
||||
})
|
||||
|
||||
#Create 2 accounts to be used for each product
|
||||
self.account1 = self.env['account.account'].create({
|
||||
'name': 'Account 1',
|
||||
'code': 'AC1',
|
||||
'reconcile': True,
|
||||
'account_type': 'expense',
|
||||
})
|
||||
self.account2 = self.env['account.account'].create({
|
||||
'name': 'Account 1',
|
||||
'code': 'AC2',
|
||||
'reconcile': True,
|
||||
'account_type': 'expense',
|
||||
})
|
||||
|
||||
self.product_a = self.env['product.product'].create({
|
||||
'name': 'Product A',
|
||||
'type': 'product',
|
||||
'categ_id': self.real_time_categ.id,
|
||||
'property_account_expense_id': self.account1.id,
|
||||
'property_account_income_id': self.account1.id,
|
||||
})
|
||||
self.product_b = self.env['product.product'].create({
|
||||
'name': 'Product B',
|
||||
'type': 'product',
|
||||
'categ_id': self.real_time_categ.id,
|
||||
'property_account_expense_id': self.account2.id,
|
||||
'property_account_income_id': self.account2.id,
|
||||
})
|
||||
|
||||
#Create an order with the 2 products
|
||||
self.pos_config.open_ui()
|
||||
order = self.PosOrder.create({
|
||||
'company_id': self.env.company.id,
|
||||
'session_id': self.pos_config.current_session_id.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'lines': [(0, 0, {
|
||||
'name': "OL/0001",
|
||||
'product_id': self.product_a.id,
|
||||
'price_unit': 100,
|
||||
'discount': 0,
|
||||
'qty': 1,
|
||||
'tax_ids': [],
|
||||
'price_subtotal': 100,
|
||||
'price_subtotal_incl': 100,
|
||||
}), (0, 0, {
|
||||
'name': "OL/0002",
|
||||
'product_id': self.product_b.id,
|
||||
'price_unit': 100,
|
||||
'discount': 0,
|
||||
'qty': 1,
|
||||
'tax_ids': [],
|
||||
'price_subtotal': 100,
|
||||
'price_subtotal_incl': 100,
|
||||
})],
|
||||
'pricelist_id': self.pos_config.pricelist_id.id,
|
||||
'amount_paid': 200.0,
|
||||
'amount_total': 200.0,
|
||||
'amount_tax': 0.0,
|
||||
'amount_return': 0.0,
|
||||
'to_invoice': False,
|
||||
'shipping_date': fields.Date.today(),
|
||||
})
|
||||
#make payment
|
||||
payment_context = {"active_ids": order.ids, "active_id": order.id}
|
||||
order_payment = self.PosMakePayment.with_context(**payment_context).create({
|
||||
'amount': order.amount_total,
|
||||
'payment_method_id': self.cash_payment_method.id
|
||||
})
|
||||
order_payment.with_context(**payment_context).check()
|
||||
self.pos_config.current_session_id.action_pos_session_closing_control()
|
||||
order.picking_ids._action_done()
|
||||
|
||||
moves = self.env['account.move'].search([('ref', '=', f'pos_order_{order.id}')])
|
||||
self.assertEqual(len(moves), 2)
|
||||
|
||||
Reference in New Issue
Block a user