diff --git a/stock_reserve_sale/__openerp__.py b/stock_reserve_sale/__openerp__.py
index fcc7763b3..b1ea77745 100644
--- a/stock_reserve_sale/__openerp__.py
+++ b/stock_reserve_sale/__openerp__.py
@@ -55,6 +55,7 @@ insufficient at the order date, you may want to install the
'demo': [],
'data': ['wizard/sale_stock_reserve_view.xml',
'view/sale.xml',
+ 'view/stock_reserve.xml',
],
'auto_install': False,
'test': [],
diff --git a/stock_reserve_sale/model/__init__.py b/stock_reserve_sale/model/__init__.py
index d65199e72..5c9fc5067 100644
--- a/stock_reserve_sale/model/__init__.py
+++ b/stock_reserve_sale/model/__init__.py
@@ -20,3 +20,4 @@
##############################################################################
from . import sale
+from . import stock_reserve
diff --git a/stock_reserve_sale/model/sale.py b/stock_reserve_sale/model/sale.py
index 4ff04ed92..2720de44b 100644
--- a/stock_reserve_sale/model/sale.py
+++ b/stock_reserve_sale/model/sale.py
@@ -33,7 +33,7 @@ class sale_order(orm.Model):
'is_stock_reservable': False}
for sale in self.browse(cr, uid, ids, context=context):
for line in sale.order_line:
- if line.reservation_id:
+ if line.reservation_ids:
result[sale.id]['has_stock_reservation'] = True
if line.is_stock_reservable:
result[sale.id]['is_stock_reservable'] = True
@@ -81,13 +81,14 @@ class sale_order_line(orm.Model):
continue
if (not line.product_id or line.product_id.type == 'service'):
continue
- if not line.reservation_id:
+ if not line.reservation_ids:
result[line.id] = True
return result
_columns = {
- 'reservation_id': fields.many2one(
+ 'reservation_ids': fields.one2many(
'stock.reservation',
+ 'sale_line_id',
string='Stock Reservation'),
'is_stock_reservable': fields.function(
_is_stock_reservable,
@@ -99,25 +100,27 @@ class sale_order_line(orm.Model):
def copy_data(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
- default['reservation_id'] = False
+ default['reservation_ids'] = False
return super(sale_order_line, self).copy_data(
cr, uid, id, default=default, context=context)
def release_stock_reservation(self, cr, uid, ids, context=None):
lines = self.browse(cr, uid, ids, context=context)
- reserv_ids = [line.reservation_id.id for line in lines
- if line.reservation_id]
+ reserv_ids = [reserv.id for line in lines
+ for reserv in line.reservation_ids]
reserv_obj = self.pool.get('stock.reservation')
reserv_obj.release(cr, uid, reserv_ids, context=context)
- self.write(cr, uid, ids, {'reservation_id': False}, context=context)
return True
def update_stock_reservation(self, cr, uid, ids, context=None):
+ reserv_obj = self.pool.get('stock.reservation')
for line in self.browse(cr, uid, ids, context=context):
- if not line.reservation_id:
+ if not line.reservation_ids:
continue
- line.reservation_id.write({'product_qty': line.product_uom_qty,
- 'product_uom': line.product_uom.id})
+ reserv_ids = [reserv.id for reserv in line.reservation_ids]
+ vals = {'product_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id}
+ reserv_obj.write(cr, uid, reserv_ids, vals, context=context)
return True
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
@@ -133,7 +136,7 @@ class sale_order_line(orm.Model):
return result
assert len(ids) == 1, "Expected 1 ID, got %r" % ids
line = self.browse(cr, uid, ids[0], context=context)
- if qty != line.product_uom_qty and line.reservation_id:
+ if qty != line.product_uom_qty and line.reservation_ids:
msg = _("As you changed the quantity of the line, "
"the quantity of the stock reservation will "
"be automatically adjusted to %.2f.") % qty
@@ -157,7 +160,7 @@ class sale_order_line(orm.Model):
test_update = keys.intersection(update_on_reserve)
if test_block:
for line in self.browse(cr, uid, ids, context=context):
- if not line.reservation_id:
+ if not line.reservation_ids:
continue
raise orm.except_orm(
_('Error'),
@@ -168,9 +171,17 @@ class sale_order_line(orm.Model):
res = super(sale_order_line, self).write(cr, uid, ids, vals, context=context)
if test_update:
for line in self.browse(cr, uid, ids, context=context):
- if not line.reservation_id:
+ if not line.reservation_ids:
continue
- line.reservation_id.write(
+ if len(line.reservation_ids) > 1:
+ raise orm.except_orm(
+ _('Error'),
+ _('Several stock reservations are linked with the '
+ 'line. Impossible to adjust their quantity. '
+ 'Please release the reservation '
+ 'before changing the quantity.'))
+
+ line.reservation_ids[0].write(
{'price_unit': line.price_unit,
'product_qty': line.product_uom_qty,
'product_uos_qty': line.product_uos_qty,
diff --git a/stock_reserve_sale/model/stock_reserve.py b/stock_reserve_sale/model/stock_reserve.py
new file mode 100644
index 000000000..0ea5fb958
--- /dev/null
+++ b/stock_reserve_sale/model/stock_reserve.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 2013 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
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+
+
+class stock_reservation(orm.Model):
+ _inherit = 'stock.reservation'
+
+ _columns = {
+ 'sale_line_id': fields.many2one(
+ 'sale.order.line',
+ string='Sale Order Line',
+ ondelete='cascade'),
+ 'sale_id': fields.related(
+ 'sale_line_id', 'order_id',
+ type='many2one',
+ relation='sale.order',
+ string='Sale Order')
+ }
+
+ def release(self, cr, uid, ids, context=None):
+ self.write(cr, uid, ids, {'sale_line_id': False}, context=context)
+ return super(stock_reservation, self).release(
+ cr, uid, ids, context=context)
+
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ if default is None:
+ default = {}
+ default['sale_line_id'] = False
+ return super(stock_reservation, self).copy_data(
+ cr, uid, id, default=default, context=context)
diff --git a/stock_reserve_sale/view/sale.xml b/stock_reserve_sale/view/sale.xml
index f743cb0ae..19dbc3e22 100644
--- a/stock_reserve_sale/view/sale.xml
+++ b/stock_reserve_sale/view/sale.xml
@@ -25,17 +25,17 @@
-
+
+ attrs="{'invisible': [('reservation_ids', '=', [])]}" />
-
-