mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
make stock_reserve_sale owner_aware
This commit is contained in:
committed by
Carlos Roca
parent
b0af83dd93
commit
eda6864dab
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# Copyright 2013 Camptocamp SA
|
||||
# Author: Guewen Baconnier, Leonardo Pistone
|
||||
# Copyright 2013-2015 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
@@ -20,7 +20,7 @@
|
||||
##############################################################################
|
||||
|
||||
{'name': 'Stock Reserve Sales',
|
||||
'version': '0.1',
|
||||
'version': '1.0',
|
||||
'author': "Camptocamp,Odoo Community Association (OCA)",
|
||||
'category': 'Warehouse',
|
||||
'license': 'AGPL-3',
|
||||
@@ -48,6 +48,13 @@ If you want to prevent sales orders to be confirmed when the stock is
|
||||
insufficient at the order date, you may want to install the
|
||||
`sale_exception_nostock` module.
|
||||
|
||||
Additionally, if the sale_owner_stock_sourcing module is installed, the owner
|
||||
specified on the sale order line will be proposed as owner of the reservation.
|
||||
If you try to make a reservation for an order whose lines have different, you
|
||||
will get a message suggesting to reserve each line individually. There is no
|
||||
module dependency: this modules is fully functional even without ownership
|
||||
management.
|
||||
|
||||
""",
|
||||
'depends': ['sale_stock',
|
||||
'stock_reserve',
|
||||
|
||||
@@ -41,18 +41,14 @@
|
||||
order_id: sale_reserve_02
|
||||
-
|
||||
And I create a stock reserve for this line
|
||||
-
|
||||
!record {model: sale.stock.reserve, id: wizard_reserve_02_01}:
|
||||
note: Reservation for the sales order line
|
||||
-
|
||||
I call the wizard to reserve the products of the sales order
|
||||
-
|
||||
!python {model: sale.stock.reserve}: |
|
||||
active_id = ref('sale_line_reserve_02_01')
|
||||
context['active_id'] = active_id
|
||||
context['active_ids'] = [active_id]
|
||||
context['active_model'] = 'sale.order.line'
|
||||
self.button_reserve(cr, uid, [ref('wizard_reserve_02_01')], context=context)
|
||||
wizard_id = self.create(cr, uid, {}, context=context)
|
||||
self.button_reserve(cr, uid, [wizard_id], context=context)
|
||||
-
|
||||
I check Virtual stock of yogurt after update reservation
|
||||
-
|
||||
@@ -83,18 +79,14 @@
|
||||
product_uom: product.product_uom_unit
|
||||
-
|
||||
And I try to create a stock reserve for this MTO line
|
||||
-
|
||||
!record {model: sale.stock.reserve, id: wizard_reserve_02_02}:
|
||||
note: Reservation for the sales order line
|
||||
-
|
||||
I call the wizard to reserve the products of the sales order
|
||||
-
|
||||
!python {model: sale.stock.reserve}: |
|
||||
active_id = ref('sale_line_reserve_02_02')
|
||||
context['active_id'] = active_id
|
||||
context['active_ids'] = [active_id]
|
||||
context['active_model'] = 'sale.order.line'
|
||||
self.button_reserve(cr, uid, [ref('wizard_reserve_02_02')], context=context)
|
||||
wizard_id = self.create(cr, uid, {}, context=context)
|
||||
self.button_reserve(cr, uid, [wizard_id], context=context)
|
||||
-
|
||||
I should not have a stock reservation for a MTO line
|
||||
-
|
||||
|
||||
@@ -35,22 +35,20 @@
|
||||
product_uom_qty: 4
|
||||
-
|
||||
I call the wizard to reserve the products of the sales order
|
||||
-
|
||||
!record {model: sale.stock.reserve, id: wizard_reserve_01}:
|
||||
note: Reservation for the sales order
|
||||
-
|
||||
!python {model: sale.stock.reserve}: |
|
||||
active_id = ref('sale_reserve_01')
|
||||
context['active_id'] = active_id
|
||||
context['active_ids'] = [active_id]
|
||||
context['active_model'] = 'sale.order'
|
||||
self.button_reserve(cr, uid, [ref('wizard_reserve_01')], context=context)
|
||||
wizard_id = self.create(cr, uid, {}, context=context)
|
||||
self.button_reserve(cr, uid, [wizard_id], context=context)
|
||||
-
|
||||
I check Virtual stock of Gelato after update reservation
|
||||
-
|
||||
!python {model: product.product}: |
|
||||
product = self.browse(cr, uid, ref('product_gelato'), context=context)
|
||||
assert product.virtual_available == 6, "Stock is not updated."
|
||||
!python {model: product.product, id: product_gelato}: |
|
||||
from nose.tools import *
|
||||
assert_almost_equal(self.virtual_available, 6.0)
|
||||
-
|
||||
I release the sales order's reservations
|
||||
-
|
||||
@@ -59,6 +57,6 @@
|
||||
-
|
||||
I check Virtual stock of Gelato after release of reservations
|
||||
-
|
||||
!python {model: product.product}: |
|
||||
product = self.browse(cr, uid, ref('product_gelato'), context=context)
|
||||
assert product.virtual_available == 10, "Stock is not updated."
|
||||
!python {model: product.product, id: product_gelato}: |
|
||||
from nose.tools import *
|
||||
assert_almost_equal(self.virtual_available, 10.0)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# Copyright 2013 Camptocamp SA
|
||||
# Author: Guewen Baconnier, Leonardo Pistone
|
||||
# Copyright 2013-2015 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp import models, fields, api, exceptions
|
||||
|
||||
|
||||
class SaleStockReserve(models.TransientModel):
|
||||
@@ -33,6 +33,32 @@ class SaleStockReserve(models.TransientModel):
|
||||
def _default_location_dest_id(self):
|
||||
return self.env['stock.reservation']._default_location_dest_id()
|
||||
|
||||
def _default_owner(self):
|
||||
"""If sale_owner_stock_sourcing is installed, it adds an owner field
|
||||
on sale order lines. Use it.
|
||||
|
||||
"""
|
||||
model = self.env[self.env.context['active_model']]
|
||||
if model._name == 'sale.order':
|
||||
lines = model.browse(self.env.context['active_id']).order_line
|
||||
else:
|
||||
lines = model.browse(self.env.context['active_ids'])
|
||||
|
||||
try:
|
||||
owners = set([l.stock_owner_id for l in lines])
|
||||
except AttributeError:
|
||||
return self.env['res.partner']
|
||||
# module sale_owner_stock_sourcing not installed, fine
|
||||
|
||||
if len(owners) == 1:
|
||||
return owners.pop()
|
||||
elif len(owners) > 1:
|
||||
raise exceptions.Warning(
|
||||
'The lines have different owners. Please reserve them '
|
||||
'individually with the reserve button on each one.')
|
||||
|
||||
return self.env['res.partner']
|
||||
|
||||
location_id = fields.Many2one(
|
||||
'stock.location',
|
||||
'Source Location',
|
||||
@@ -50,6 +76,8 @@ class SaleStockReserve(models.TransientModel):
|
||||
help="If a date is given, the reservations will be released "
|
||||
"at the end of the validity.")
|
||||
note = fields.Text('Notes')
|
||||
owner_id = fields.Many2one('res.partner', 'Stock Owner',
|
||||
default=_default_owner)
|
||||
|
||||
@api.multi
|
||||
def _prepare_stock_reservation(self, line):
|
||||
@@ -67,6 +95,7 @@ class SaleStockReserve(models.TransientModel):
|
||||
'product_uos': product_uos,
|
||||
'price_unit': line.price_unit,
|
||||
'sale_line_id': line.id,
|
||||
'restrict_partner_id': self.owner_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<field name="location_id"/>
|
||||
<field name="location_dest_id"/>
|
||||
<field name="date_validity"/>
|
||||
<field name="owner_id" groups="stock.group_tracking_owner"/>
|
||||
</group>
|
||||
<group name="note" string="Notes">
|
||||
<field name="note" nolabel="1"/>
|
||||
|
||||
Reference in New Issue
Block a user