[FIX] stock_account: return dropship
- Set a product with real-time valuation - Create a SO, select the Drop Ship route - Validate the SO, the PO, and receive the picking => an accounting entry is created - Return the picking The reversed accounting entry is not created. This is because the return of a drop ship picking is not recognized as some kind of dropshipping. opw-1879117
This commit is contained in:
committed by
Nicolas Martinelli
parent
148182bf91
commit
2e6c1aa5d1
@@ -212,6 +212,14 @@ class StockMove(models.Model):
|
||||
"""
|
||||
return self.location_id.usage == 'supplier' and self.location_dest_id.usage == 'customer'
|
||||
|
||||
def _is_dropshipped_returned(self):
|
||||
""" Check if the move should be considered as a returned dropshipping move so that the cost
|
||||
method will be able to apply the correct logic.
|
||||
|
||||
:return: True if the move is a returned dropshipping one else False
|
||||
"""
|
||||
return self.location_id.usage == 'customer' and self.location_dest_id.usage == 'supplier'
|
||||
|
||||
@api.model
|
||||
def _run_fifo(self, move, quantity=None):
|
||||
""" Value `move` according to the FIFO rule, meaning we consume the
|
||||
@@ -323,7 +331,7 @@ class StockMove(models.Model):
|
||||
'value': value if quantity is None else self.value + value,
|
||||
'price_unit': value / valued_quantity,
|
||||
})
|
||||
elif self._is_dropshipped():
|
||||
elif self._is_dropshipped() or self._is_dropshipped_returned():
|
||||
curr_rounding = self.company_id.currency_id.rounding
|
||||
if self.product_id.cost_method in ['fifo']:
|
||||
price_unit = self._get_price_unit()
|
||||
@@ -335,8 +343,8 @@ class StockMove(models.Model):
|
||||
# In move have a positive value, out move have a negative value, let's arbitrary say
|
||||
# dropship are positive.
|
||||
self.write({
|
||||
'value': value,
|
||||
'price_unit': price_unit,
|
||||
'value': value if self._is_dropshipped() else -value,
|
||||
'price_unit': price_unit if self._is_dropshipped() else -price_unit,
|
||||
})
|
||||
|
||||
def _action_done(self):
|
||||
@@ -359,7 +367,7 @@ class StockMove(models.Model):
|
||||
if company_src and company_dst and company_src.id != company_dst.id:
|
||||
raise UserError(_("The move lines are not in a consistent states: they are doing an intercompany in a single step while they should go through the intercompany transit location."))
|
||||
move._run_valuation()
|
||||
for move in res.filtered(lambda m: m.product_id.valuation == 'real_time' and (m._is_in() or m._is_out() or m._is_dropshipped())):
|
||||
for move in res.filtered(lambda m: m.product_id.valuation == 'real_time' and (m._is_in() or m._is_out() or m._is_dropshipped() or m._is_dropshipped_returned())):
|
||||
move._account_entry_move()
|
||||
return res
|
||||
|
||||
@@ -642,10 +650,13 @@ class StockMove(models.Model):
|
||||
else:
|
||||
self.with_context(force_company=company_from.id)._create_account_move_line(acc_valuation, acc_dest, journal_id)
|
||||
|
||||
if self.company_id.anglo_saxon_accounting and self._is_dropshipped():
|
||||
if self.company_id.anglo_saxon_accounting:
|
||||
# Creates an account entry from stock_input to stock_output on a dropship move. https://github.com/odoo/odoo/issues/12687
|
||||
journal_id, acc_src, acc_dest, acc_valuation = self._get_accounting_data_for_valuation()
|
||||
self.with_context(force_company=self.company_id.id)._create_account_move_line(acc_src, acc_dest, journal_id)
|
||||
if self._is_dropshipped():
|
||||
self.with_context(force_company=self.company_id.id)._create_account_move_line(acc_src, acc_dest, journal_id)
|
||||
elif self._is_dropshipped_returned():
|
||||
self.with_context(force_company=self.company_id.id)._create_account_move_line(acc_dest, acc_src, journal_id)
|
||||
|
||||
|
||||
class StockReturnPicking(models.TransientModel):
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestStockValuation(AccountingTestCase):
|
||||
|
||||
# sell one unit of this product
|
||||
customer1 = self.env['res.partner'].create({'name': 'customer1'})
|
||||
sale_order1 = self.env['sale.order'].create({
|
||||
self.sale_order1 = self.env['sale.order'].create({
|
||||
'partner_id': customer1.id,
|
||||
'partner_invoice_id': customer1.id,
|
||||
'partner_shipping_id': customer1.id,
|
||||
@@ -50,38 +50,38 @@ class TestStockValuation(AccountingTestCase):
|
||||
'pricelist_id': self.env.ref('product.list0').id,
|
||||
'picking_policy': 'direct',
|
||||
})
|
||||
sale_order1.action_confirm()
|
||||
self.sale_order1.action_confirm()
|
||||
|
||||
# confirm the purchase order
|
||||
purchase_order1 = self.env['purchase.order'].search([('group_id', '=', sale_order1.procurement_group_id.id)])
|
||||
purchase_order1.button_confirm()
|
||||
self.purchase_order1 = self.env['purchase.order'].search([('group_id', '=', self.sale_order1.procurement_group_id.id)])
|
||||
self.purchase_order1.button_confirm()
|
||||
|
||||
# validate the dropshipping picking
|
||||
self.assertEqual(len(sale_order1.picking_ids), 1)
|
||||
self.assertEqual(sale_order1.picking_ids.move_lines._is_dropshipped(), True)
|
||||
wizard = sale_order1.picking_ids.button_validate()
|
||||
self.assertEqual(len(self.sale_order1.picking_ids), 1)
|
||||
self.assertEqual(self.sale_order1.picking_ids.move_lines._is_dropshipped(), True)
|
||||
wizard = self.sale_order1.picking_ids.button_validate()
|
||||
immediate_transfer = self.env[wizard['res_model']].browse(wizard['res_id'])
|
||||
immediate_transfer.process()
|
||||
self.assertEqual(sale_order1.picking_ids.state, 'done')
|
||||
self.assertEqual(self.sale_order1.picking_ids.state, 'done')
|
||||
|
||||
# create the vendor bill
|
||||
vendor_bill1 = self.env['account.invoice'].create({
|
||||
self.vendor_bill1 = self.env['account.invoice'].create({
|
||||
'partner_id': vendor1.id,
|
||||
'purchase_id': purchase_order1.id,
|
||||
'purchase_id': self.purchase_order1.id,
|
||||
'account_id': vendor1.property_account_payable_id.id,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
vendor_bill1.purchase_order_change()
|
||||
vendor_bill1.action_invoice_open()
|
||||
self.vendor_bill1.purchase_order_change()
|
||||
self.vendor_bill1.action_invoice_open()
|
||||
|
||||
# create the customer invoice
|
||||
customer_invoice1_id = sale_order1.action_invoice_create()
|
||||
customer_invoice1 = self.env['account.invoice'].browse(customer_invoice1_id)
|
||||
customer_invoice1.action_invoice_open()
|
||||
self.customer_invoice1_id = self.sale_order1.action_invoice_create()
|
||||
self.customer_invoice1 = self.env['account.invoice'].browse(self.customer_invoice1_id)
|
||||
self.customer_invoice1.action_invoice_open()
|
||||
|
||||
all_amls = vendor_bill1.move_id.line_ids + customer_invoice1.move_id.line_ids
|
||||
if sale_order1.picking_ids.move_lines.account_move_ids:
|
||||
all_amls |= sale_order1.picking_ids.move_lines.account_move_ids.line_ids
|
||||
all_amls = self.vendor_bill1.move_id.line_ids + self.customer_invoice1.move_id.line_ids
|
||||
if self.sale_order1.picking_ids.move_lines.account_move_ids:
|
||||
all_amls |= self.sale_order1.picking_ids.move_lines.account_move_ids.line_ids
|
||||
return all_amls
|
||||
|
||||
def _check_results(self, expected_aml, expected_aml_count, all_amls):
|
||||
@@ -267,3 +267,33 @@ class TestStockValuation(AccountingTestCase):
|
||||
|
||||
self._check_results(expected_aml, 8, all_amls)
|
||||
|
||||
def test_dropship_standard_perpetual_anglosaxon_ordered_return(self):
|
||||
self.env.user.company_id.anglo_saxon_accounting = True
|
||||
self.product1.product_tmpl_id.cost_method = 'standard'
|
||||
self.product1.product_tmpl_id.standard_price = 10
|
||||
self.product1.product_tmpl_id.valuation = 'real_time'
|
||||
self.product1.product_tmpl_id.invoice_policy = 'order'
|
||||
|
||||
all_amls = self._dropship_product1()
|
||||
|
||||
# return what we've done
|
||||
stock_return_picking = self.env['stock.return.picking']\
|
||||
.with_context(active_ids=self.sale_order1.picking_ids.ids, active_id=self.sale_order1.picking_ids.ids[0])\
|
||||
.create({})
|
||||
stock_return_picking_action = stock_return_picking.create_returns()
|
||||
return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id'])
|
||||
return_pick.move_lines[0].move_line_ids[0].qty_done = 1.0
|
||||
return_pick.do_transfer()
|
||||
self.assertEqual(return_pick.move_lines._is_dropshipped_returned(), True)
|
||||
|
||||
all_amls_return = self.vendor_bill1.move_id.line_ids + self.customer_invoice1.move_id.line_ids
|
||||
if self.sale_order1.picking_ids.mapped('move_lines.account_move_ids'):
|
||||
all_amls_return |= self.sale_order1.picking_ids.mapped('move_lines.account_move_ids.line_ids')
|
||||
|
||||
# Two extra AML should have been created for the return
|
||||
expected_aml = {
|
||||
self.acc_stock_in: (10.0, 0.0),
|
||||
self.acc_stock_out: (0.0, 10.0),
|
||||
}
|
||||
|
||||
self._check_results(expected_aml, 2, all_amls_return - all_amls)
|
||||
|
||||
Reference in New Issue
Block a user