[FIX] point_of_sale: create account move for shiplater pos order

Current behavior:
When using FIFO/AVCO and automated valuation, the accounting entries for
PoS orders where not correct if the ship later function was used and the
order was not invoiced. The COGS entries were created with an amount of
0. But when the shipping was done nothing was done to correct the
entries.

Steps to reproduce:
- Make sure you are using anglo saxon accounting
- Create a product with automated valuation and FIFO/AVCO
- Create a PoS order with the product
- Validate the order using the ship later option but do not invoice it
- The accounting entries for the expense are created with an amount of 0
  (wich makes sense because the product is not shipped yet)
- Validate the picking
- The accounting entries is still the same.

opw-3027579

closes odoo/odoo#116045

X-original-commit: 513c32b04aa6c06d58125ec8c4fb1b818f4a52e9
Signed-off-by: Trinh Jacky (trj) <trj@odoo.com>
Signed-off-by: Engels Robin (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2023-03-21 23:49:31 +01:00
parent e912cd50ee
commit 436331683c
3 changed files with 98 additions and 3 deletions
+2 -2
View File
@@ -771,7 +771,7 @@ class PosSession(models.Model):
signed_product_qty = move.product_qty
if move._is_in():
signed_product_qty *= -1
amount = signed_product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
amount = signed_product_qty * move.product_id._compute_average_price(0, move.quantity_done, move)
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
if move._is_in():
stock_return[out_key] = self._update_amounts(stock_return[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
@@ -800,7 +800,7 @@ class PosSession(models.Model):
signed_product_qty = move.product_qty
if move._is_in():
signed_product_qty *= -1
amount = signed_product_qty * move.product_id._compute_average_price(0, move.product_qty, move)
amount = signed_product_qty * move.product_id._compute_average_price(0, move.quantity_done, move)
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
if move._is_in():
stock_return[out_key] = self._update_amounts(stock_return[out_key], {'amount': amount}, move.picking_id.date, force_company_currency=True)
+27 -1
View File
@@ -100,6 +100,33 @@ class StockPicking(models.Model):
pickings = self.filtered(lambda p: p.picking_type_id != p.picking_type_id.warehouse_id.pos_type_id)
return super(StockPicking, pickings)._send_confirmation_email()
def _action_done(self):
res = super()._action_done()
if self.pos_order_id.shipping_date and not self.pos_order_id.to_invoice:
order_cost = sum(line.total_cost for line in self.pos_order_id.lines)
move_vals = {
'journal_id': self.pos_order_id.sale_journal.id,
'date': self.pos_order_id.date_order,
'ref': self.pos_order_id.name,
'line_ids': [
(0, 0, {
'name': self.pos_order_id.name,
'account_id': self.product_id.categ_id.property_account_income_categ_id.id,
'debit': order_cost,
'credit': 0.0,
}),
(0, 0, {
'name': self.pos_order_id.name,
'account_id': self.product_id.categ_id.property_account_expense_categ_id.id,
'debit': 0.0,
'credit': order_cost,
})
]
}
move = self.env['account.move'].create(move_vals)
self.pos_order_id.write({'account_move': move.id})
move.action_post()
return res
class StockPickingType(models.Model):
_inherit = 'stock.picking.type'
@@ -111,7 +138,6 @@ class StockPickingType(models.Model):
if picking_type == picking_type.warehouse_id.pos_type_id:
picking_type.hide_reservation_method = True
class ProcurementGroup(models.Model):
_inherit = 'procurement.group'
@@ -224,3 +224,72 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
line = pos_order_pos0.account_move.line_ids.filtered(lambda l: l.debit and l.account_id == self.category.property_account_expense_categ_id)
self.assertEqual(pos_order_pos0.account_move.journal_id, self.pos_config.invoice_journal_id)
self.assertEqual(line.debit, 27, 'As it is a fifo product, the move\'s value should be 5*5 + 2*1')
def test_cogs_with_ship_later_no_invoicing(self):
# This test will check that the correct journal entries are created when a product in real time valuation
# is sold using the ship later option and no invoice is created in a company using anglo-saxon
self.pos_config.open_ui()
current_session = self.pos_config.current_session_id
self.cash_journal.loss_account_id = self.account
current_session.set_cashbox_pos(0, None)
# I create a PoS order with 1 unit of New product at 450 EUR
self.pos_order_pos0 = self.PosOrder.create({
'company_id': self.company.id,
'partner_id': self.partner.id,
'pricelist_id': self.company.partner_id.property_product_pricelist.id,
'session_id': self.pos_config.current_session_id.id,
'to_invoice': False,
'shipping_date': '2023-01-01',
'lines': [(0, 0, {
'name': "OL/0001",
'product_id': self.product.id,
'price_unit': 450,
'discount': 0.0,
'qty': 1.0,
'price_subtotal': 450,
'price_subtotal_incl': 450,
})],
'amount_total': 450,
'amount_tax': 0,
'amount_paid': 0,
'amount_return': 0,
})
# I make a payment to fully pay the order
context_make_payment = {"active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
'amount': 450.0,
'payment_method_id': self.cash_payment_method.id,
})
# I click on the validate button to register the payment.
context_payment = {'active_id': self.pos_order_pos0.id}
self.pos_make_payment_0.with_context(context_payment).check()
# I close the current session to generate the journal entries
current_session_id = self.pos_config.current_session_id
current_session_id.post_closing_cash_details(450.0)
current_session_id.close_session_from_ui()
self.assertEqual(current_session_id.state, 'closed', 'Check that session is closed')
current_session.picking_ids.move_ids_without_package.quantity_done = 1
current_session.picking_ids.button_validate()
# I test that the generated journal entries are correct.
account_output = self.category.property_stock_account_output_categ_id
expense_account = self.category.property_account_expense_categ_id
aml = current_session._get_related_account_moves().line_ids
aml_output = aml.filtered(lambda l: l.account_id.id == account_output.id)
aml_expense = aml.filtered(lambda l: l.account_id.id == expense_account.id)
#Check the lines created after the picking validation
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[0].credit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
self.assertEqual(aml_expense[0].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[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")