diff --git a/stock_reserve/__openerp__.py b/stock_reserve/__openerp__.py index 8b3d84116..dd75c1a20 100644 --- a/stock_reserve/__openerp__.py +++ b/stock_reserve/__openerp__.py @@ -32,7 +32,7 @@ Stock Reserve ============= Allows to create stock reservation on a product or a selection of -products. The reservations can be monitored and lifter on the product +products. The reservations can be monitored and lifted on the product view. Each reservation can have a validity date, once reached, the reservation is automatically lifted. @@ -40,7 +40,9 @@ reservation is automatically lifted. 'depends': ['stock', ], 'demo': [], - 'data': [], + 'data': ['view/stock_reserve.xml', + 'data/stock_data.xml', + ], 'auto_install': False, 'test': [], 'installable': True, diff --git a/stock_reserve/data/stock_data.xml b/stock_reserve/data/stock_data.xml new file mode 100644 index 000000000..27832218d --- /dev/null +++ b/stock_reserve/data/stock_data.xml @@ -0,0 +1,9 @@ + + + + + Reservation Stock + + + + diff --git a/stock_reserve/model/stock_reserve.py b/stock_reserve/model/stock_reserve.py index b045a5ff0..c84b8c5f1 100644 --- a/stock_reserve/model/stock_reserve.py +++ b/stock_reserve/model/stock_reserve.py @@ -19,18 +19,12 @@ # ############################################################################## -from datetime import datetime from openerp.osv import orm, fields -from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DT_FMT class stock_reservation(orm.Model): """ Allow to reserve products. - - A stock reservation is basically a stock move, - but the reservation is handled by this model using - a ``_inherits``. """ _name = 'stock.reservation' _description = 'Stock Reservation' @@ -38,39 +32,17 @@ class stock_reservation(orm.Model): _columns = { 'move_id': fields.many2one('stock.move', - 'Move', - readonly=True, + 'Reservation Move', required=True, + readonly=True, ondelete='cascade', select=1), 'date_validity': fields.datetime('Validity Date'), } - def _prepare_reserve(self, cr, uid, product_id, quantity, location_id, - date_validity=None, context=None): - product_obj = self.pool.get('product.product') - product = product_obj.browse(cr, uid, product_id, context=context) - location_dest_id = self._get_reservation_location( - cr, uid, product_id, context=context) - vals = {'name': 'Reservation', # sequence? - 'product_id': product_id, - 'product_qty': quantity, - 'product_uom': product.uom_id.id, - 'location_id': location_id, - 'location_dest_id': location_dest_id, - 'price_unit': product.standard_price or 0.0, - } - if date_validity: - vals.update({'date_validity': date_validity, - 'date': date_validity, - 'date_expected': date_validity, - }) - else: - today = datetime.now().strftime(DT_FMT) - vals.update({'date': today, - 'date_expected': today, - }) - return vals + _defaults = { + 'type': 'internal', + } def _get_reservation_location(self, cr, uid, product_id, context=None): """ Returns the appropriate destination location to @@ -78,42 +50,30 @@ class stock_reservation(orm.Model): """ return 1 - def reserve(self, cr, uid, product_id, quantity, location_id, - date_validity=None, context=None): - """ Reserve a product. + def reserve(self, cr, uid, ids, context=None): + """ Confirm a reservation The reservation is done using the default UOM of the product. A date until which the product is reserved can be specified. - - :param product_id: id of the product to reserve - :param quantity: quantity of products to reserve - :param location_id: source location for the reservation - :param date_validity: optional datetime until which the reservation - is valid - :returns: id of the ``stock.reservation`` created """ - vals = self._prepare_reserve(cr, uid, product_id, quantity, - location_id, - date_validity=date_validity, - context=context) - reservation_id = self.create(cr, uid, vals, context=context) - move_id = self.read(cr, uid, - reservation_id, - ['move_id'], - context=context, - load='_classic_write')['move_id'] move_obj = self.pool.get('stock.move') - move_obj.action_confirm(cr, uid, [move_id], context=context) - # TODO: if no quantity in the location, it will stay 'confirmed' - # after action_confirm(), how to handle that? - move_obj.action_assign(cr, uid, [move_id]) - return reservation_id + reservations = self.browse(cr, uid, ids, context=context) + move_ids = [reserv.move_id.id for reserv in reservations] + move_obj.action_confirm(cr, uid, move_ids, context=context) + move_obj.force_assign(cr, uid, move_ids, context=context) + move_obj.action_done(cr, uid, move_ids, context=context) + return True def release(self, cr, uid, ids, context=None): - """ Release a reservation """ return self.unlink(cr, uid, ids, context=context) + def create(self, cr, uid, vals, context=None): + # TODO + return super(stock_reservation, self).create(cr, uid, vals, + context=context) + def unlink(self, cr, uid, ids, context=None): + """ Release the reservation """ if isinstance(ids, (int, long)): ids = [ids] reservations = self.read(cr, uid, ids, ['move_id'], @@ -121,4 +81,39 @@ class stock_reservation(orm.Model): move_obj = self.pool.get('stock.move') move_ids = [reserv['move_id'] for reserv in reservations] move_obj.action_cancel(cr, uid, move_ids, context=context) - return super(stock_reservation, self).unlink(cr, uid, ids, context=context) + return super(stock_reservation, self).unlink(cr, uid, ids, + context=context) + + def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, + loc_dest_id=False, partner_id=False): + """ On change of product id, if finds UoM, UoS, + quantity and UoS quantity. + """ + move_obj = self.pool.get('stock.move') + if ids: + reserv = self.read(cr, uid, ids, ['move_id'], load='_classic_write') + move_ids = [rv['move_id'] for rv in reserv] + else: + move_ids = [] + return move_obj.onchange_product_id( + cr, uid, move_ids, prod_id=prod_id, loc_id=loc_id, + loc_dest_id=loc_dest_id, partner_id=partner_id) + + def onchange_move_type(self, cr, uid, ids, type, context=None): + """ On change of move type gives source and destination location. + """ + move_obj = self.pool.get('stock.move') + location_obj = self.pool.get('stock.location') + data_obj = self.pool.get('ir.model.data') + result = move_obj.onchange_move_type(cr, uid, ids, type, + context=context) + get_ref = data_obj.get_object_reference + try: + __, dest_location_id = get_ref(cr, uid, 'stock_reserve', + 'stock_location_reservation') + location_obj.check_access_rule(cr, uid, [dest_location_id], + 'read', context=context) + except (orm.except_orm, ValueError): + dest_location_id = False + result['value']['location_dest_id'] = dest_location_id + return result diff --git a/stock_reserve/view/stock_reserve.xml b/stock_reserve/view/stock_reserve.xml new file mode 100644 index 000000000..27aeda5b0 --- /dev/null +++ b/stock_reserve/view/stock_reserve.xml @@ -0,0 +1,118 @@ + + + + + stock.reservation.form + stock.reservation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + stock.reservation.tree + stock.reservation + + + + + + + + + + + + + + + stock.reservation.search + stock.reservation + + + + + + + + + + + Stock Reservations + stock.reservation + ir.actions.act_window + form + + + {} + + + Click to create a stock reservation. + + This menu allow you to prepare and reserve some quantities + of products. + + + + + + +
+ Click to create a stock reservation. +
+ This menu allow you to prepare and reserve some quantities + of products. +