From ef8e1fc31f0c1d589594e9c62a1f93ce579c89f8 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 11 Feb 2014 16:51:57 +0100 Subject: [PATCH 1/5] [FIX] stock: barcode scanner GUI somewhat functionally working bzr revid: qdp-launchpad@openerp.com-20140211155157-gu86q7it150u33tp --- addons/stock/__openerp__.py | 3 -- addons/stock/static/src/css/picking.css | 2 +- addons/stock/static/src/js/widgets.js | 60 ++++++++++++++++++++----- addons/stock/static/src/xml/picking.xml | 29 ++++++------ addons/stock/stock.py | 60 ++----------------------- addons/stock/stock_view.xml | 3 -- 6 files changed, 66 insertions(+), 91 deletions(-) diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 74f1c39d605..20a6ee1ccfd 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -107,9 +107,6 @@ Dashboard / Reports for Warehouse Management will include: 'static/src/css/stock.css', ], 'js': [ - 'static/lib/sparkline/jquery.sparkline.js', - 'static/lib/justgage.js', - 'static/src/js/stock_picking_type.js', 'static/src/js/widgets.js', ], 'qweb': ['static/src/xml/picking.xml'], diff --git a/addons/stock/static/src/css/picking.css b/addons/stock/static/src/css/picking.css index b27ef051b5b..80a89abe9c5 100644 --- a/addons/stock/static/src/css/picking.css +++ b/addons/stock/static/src/css/picking.css @@ -223,7 +223,7 @@ * ----------------------- */ .oe_pick_widget .oe_searchbox{ - float: right; + margin-top: 13px; } .oe_pick_widget .oe_searchbox input{ padding: 8px; diff --git a/addons/stock/static/src/js/widgets.js b/addons/stock/static/src/js/widgets.js index c015bca7c00..03abecc6ea8 100644 --- a/addons/stock/static/src/js/widgets.js +++ b/addons/stock/static/src/js/widgets.js @@ -54,6 +54,9 @@ function openerp_picking_widgets(instance){ console.log('Id:',id); self.getParent().scan_product_id(id); }); + + //remove navigtion bar from default openerp GUI + $('td.navbar').html('
'); }, }); @@ -159,7 +162,7 @@ function openerp_picking_widgets(instance){ } self.pickings_by_type[0] = []; - return new instance.web.Model('stock.picking').call('search_read',[ [['state','in',['confirmed','assigned']]], [] ], {context: new instance.web.CompoundContext()}); + return new instance.web.Model('stock.picking').call('search_read',[ [['state','in', ['assigned', 'partially_available']]], [] ], {context: new instance.web.CompoundContext()}); }).then(function(pickings){ self.pickings = pickings; @@ -182,6 +185,8 @@ function openerp_picking_widgets(instance){ this.$('.oe_searchbox input').keyup(function(event){ self.on_searchbox($(this).val()); }); + //remove navigtion bar from default openerp GUI + $('td.navbar').html('
'); }, start: function(){ this._super(); @@ -294,7 +299,6 @@ function openerp_picking_widgets(instance){ this.packages = null; this.barcode_scanner = new module.BarcodeScanner(); this.picking_type_id = params.context.active_id || 0; - if(params.context.picking_id){ this.loaded = this.load(params.context.picking_id); @@ -312,7 +316,6 @@ function openerp_picking_widgets(instance){ function load_picking_list(type_id){ var pickings = new $.Deferred(); - new instance.web.Model('stock.picking') .call('get_next_picking_for_ui',[{'default_picking_type_id':type_id}]) .then(function(picking_ids){ @@ -322,7 +325,7 @@ function openerp_picking_widgets(instance){ buttons: [{ text:_t('Ok'), click: function(){ - self.quit(); + self.menu(); } }] }, _t('

We could not find a picking to display.

'))).open(); @@ -356,6 +359,7 @@ function openerp_picking_widgets(instance){ }) .then(function(picking){ self.picking = picking; + self.picking_type_id = picking.picking_type_id[0]; loaded_picking.resolve(); }); } @@ -395,10 +399,12 @@ function openerp_picking_widgets(instance){ this.barcode_scanner.connect(function(ean){ self.scan(ean); }); + this.$('.js_pick_quit').click(function(){ self.quit(); }); this.$('.js_pick_pack').click(function(){ self.pack(); }); this.$('.js_pick_done').click(function(){ self.done(); }); + this.$('.js_pick_print').click(function(){ self.print_picking(); }); this.$('.js_pick_prev').click(function(){ self.picking_prev(); }); this.$('.js_pick_next').click(function(){ self.picking_next(); }); this.$('.js_pick_menu').click(function(){ self.menu(); }); @@ -439,8 +445,6 @@ function openerp_picking_widgets(instance){ }); - - return this._super(); }, // reloads the data from the provided picking and refresh the ui. // (if no picking_id is provided, gets the first picking in the db) @@ -463,15 +467,14 @@ function openerp_picking_widgets(instance){ }else{ self.$('.js_pick_next').removeClass('oe_disabled'); } - self.$('.oe_pick_app_header').text(self.get_header()); }); }, get_header: function(){ if(this.picking){ - return _t('Picking:') +' '+this.picking.name; + return this.picking.name; }else{ - return _t('Picking:'); + return ''; } }, menu: function(){ @@ -515,9 +518,14 @@ function openerp_picking_widgets(instance){ done: function(){ var self = this; new instance.web.Model('stock.picking') - .call('action_done_from_ui',[self.picking.id]) - .then(function(new_picking_id){ - return self.refresh_ui(new_picking_id); + .call('action_done_from_ui',[self.picking.id, {'default_picking_type_id': self.picking_type_id}]) + .then(function(new_picking_ids){ + if (new_picking_ids){ + return self.refresh_ui(new_picking_ids[0]); + } + else { + return 0; + } }); }, print_package: function(package_id){ @@ -528,6 +536,26 @@ function openerp_picking_widgets(instance){ return self.do_action(action); }); }, + print_picking: function(){ + var self = this; + new instance.web.Model('stock.picking.type').call('read', [[self.picking_type_id], ['code'], new instance.web.CompoundContext()]) + .then(function(pick_type){ + console.log('self.picking_type_id.code '+pick_type[0]['code']); + if (pick_type[0]['code'] == 'outgoing'){ + new instance.web.Model('stock.picking').call('do_print_delivery',[[self.picking.id]]) + .then(function(action){ + return self.do_action(action); + }); + } + else { + console.log('self.picking_id '+picking_id); + new instance.web.Model('stock.picking').call('do_print_picking',[[self.picking.id]]) + .then(function(action){ + return self.do_action(action); + }); + } + }); + }, picking_next: function(){ for(var i = 0; i < this.pickings.length; i++){ if(this.pickings[i] === this.picking.id){ @@ -734,3 +762,11 @@ function openerp_picking_widgets(instance){ }); } + +openerp.stock = function(openerp) { + openerp.stock = openerp.stock || {}; + openerp_picking_widgets(openerp); + + +} + diff --git a/addons/stock/static/src/xml/picking.xml b/addons/stock/static/src/xml/picking.xml index 4f8496d499d..0dcca4be2e1 100644 --- a/addons/stock/static/src/xml/picking.xml +++ b/addons/stock/static/src/xml/picking.xml @@ -175,11 +175,14 @@ @@ -187,10 +190,6 @@
- -

Pickings

@@ -208,7 +207,7 @@
- + Nothing to do @@ -229,22 +228,19 @@
+ +
-
Quit
- +
+ +
@@ -253,10 +249,13 @@
-
Menu
-
Quit
-
-
<
-
Pack
-
Done
-
>
+
< Previous
+
Next >
+
Done
+
Print
- + +
Put in Pack
diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 4274abb00f2..b41480e76f2 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -596,7 +596,7 @@ class stock_picking(osv.osv): _name = "stock.picking" _inherit = ['mail.thread'] _description = "Picking List" - _order = "priority desc, date desc, id desc" + _order = "priority desc, date asc, id desc" def _set_min_date(self, cr, uid, id, field, value, arg, context=None): move_obj = self.pool.get("stock.move") @@ -1129,13 +1129,13 @@ class stock_picking(osv.osv): """ returns the next pickings to process. Used in the barcode scanner UI""" if context is None: context = {} - domain = [('state', 'in', ('confirmed', 'assigned'))] + domain = [('state', 'in', ('assigned', 'partially_available'))] if context.get('default_picking_type_id'): domain.append(('picking_type_id', '=', context['default_picking_type_id'])) return self.search(cr, uid, domain, context=context) def action_done_from_ui(self, cr, uid, picking_id, context=None): - """ called when button 'done' in pused in the barcode scanner UI """ + """ called when button 'done' is pushed in the barcode scanner UI """ self.do_transfer(cr, uid, [picking_id], context=context) #return id of next picking to work on return self.get_next_picking_for_ui(cr, uid, context=context) @@ -3622,39 +3622,6 @@ class stock_picking_type(osv.osv): _description = "The picking type determines the picking view" _order = 'sequence' - def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, context=None): - """ Generic method to generate data for bar chart values using SparklineBarWidget. - This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field). - - :param obj: the target model (i.e. crm_lead) - :param domain: the domain applied to the read_group - :param list read_fields: the list of fields to read in the read_group - :param str value_field: the field used to compute the value of the bar slice - :param str groupby_field: the fields used to group - - :return list section_result: a list of dicts: [ - { 'value': (int) bar_column_value, - 'tootip': (str) bar_column_tooltip, - } - ] - """ - month_begin = date.today().replace(day=1) - section_result = [{ - 'value': 0, - 'tooltip': (month_begin + relativedelta.relativedelta(months=i)).strftime('%B'), - } for i in range(-2, 2, 1)] - group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) - for group in group_obj: - group_begin_date = datetime.strptime(group['__domain'][0][2], DEFAULT_SERVER_DATE_FORMAT) - month_delta = relativedelta.relativedelta(month_begin, group_begin_date) - section_result[-month_delta.months + 2] = {'value': group.get(value_field, 0), 'tooltip': group_begin_date.strftime('%B')} - inner_groupby = (group.get('__context', {})).get('group_by',[]) - if inner_groupby: - groupby_picking = obj.read_group(cr, uid, group.get('__domain'), read_fields, inner_groupby, context=context) - for groupby in groupby_picking: - section_result[-month_delta.months + 2]['value'] = groupby.get(value_field, 0) - return section_result - def _get_tristate_values(self, cr, uid, ids, field_name, arg, context=None): picking_obj = self.pool.get('stock.picking') res = dict.fromkeys(ids, []) @@ -3672,24 +3639,6 @@ class stock_picking_type(osv.osv): res[picking_type_id] = tristates return res - - - def _get_monthly_pickings(self, cr, uid, ids, field_name, arg, context=None): - obj = self.pool.get('stock.picking') - res = dict.fromkeys(ids, False) - month_begin = date.today().replace(day=1) - groupby_begin = (month_begin + relativedelta.relativedelta(months=-2)).strftime(DEFAULT_SERVER_DATE_FORMAT) - groupby_end = (month_begin + relativedelta.relativedelta(months=2)).strftime(DEFAULT_SERVER_DATE_FORMAT) - for id in ids: - created_domain = [ - ('picking_type_id', '=', id), - ('state', '=', 'done'), - ('date', '>=', groupby_begin), - ('date', '<', groupby_end), - ] - res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['date', 'picking_type_id'], 'picking_type_id_count', ['date', 'picking_type_id'], context=context) - return res - def _get_picking_count(self, cr, uid, ids, field_names, arg, context=None): obj = self.pool.get('stock.picking') domains = { @@ -3799,9 +3748,6 @@ class stock_picking_type(osv.osv): 'active': fields.boolean('Active'), # Statistics for the kanban view - 'monthly_picking': fields.function(_get_monthly_pickings, - type='string', - string='Done Pickings per Month'), 'last_done_picking': fields.function(_get_tristate_values, type='string', string='Last 10 Done Pickings'), diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index bd8238c398a..6106135ea3e 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -1494,9 +1494,6 @@
From 2c46d1b35f8be7540c824fad4f81bcf4384407e3 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Wed, 12 Feb 2014 11:55:53 +0100 Subject: [PATCH 2/5] [FIX] stock: barcode scanner UI now support the search on a scanned picking name and decrease the remaining_qty at each product scanned bzr revid: qdp-launchpad@openerp.com-20140212105553-26jye3367tljbpw5 --- addons/stock/static/src/js/widgets.js | 3 +- addons/stock/stock.py | 66 +++++++++++++++++---------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/addons/stock/static/src/js/widgets.js b/addons/stock/static/src/js/widgets.js index 03abecc6ea8..c136f75b7f3 100644 --- a/addons/stock/static/src/js/widgets.js +++ b/addons/stock/static/src/js/widgets.js @@ -219,6 +219,7 @@ function openerp_picking_widgets(instance){ }); }, search_picking: function(barcode){ + //TODO don't crash if a not supported char is given var re = RegExp("([0-9]+):.*?"+barcode.toUpperCase(),"gi"); var results = []; for(var i = 0; i < 100; i++){ @@ -239,7 +240,7 @@ function openerp_picking_widgets(instance){ for(var i = 0, len = this.pickings.length; i < len; i++){ var picking = this.pickings[i]; - if(picking.name.toUpperCase() === barcode.toUpperCase()){ + if(picking.name.toUpperCase() === $.trim(barcode.toUpperCase())){ this.goto_picking(picking.id); break; } diff --git a/addons/stock/stock.py b/addons/stock/stock.py index b41480e76f2..4dccfda1b5f 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1010,31 +1010,11 @@ class stock_picking(osv.osv): self.pool.get('stock.move').do_unreserve(cr, uid, moves_to_unreserve, context=context) def do_recompute_remaining_quantities(self, cr, uid, picking_ids, context=None): - def _create_link_for_product(product_id, qty): - qty_to_assign = qty - for move in picking.move_lines: - if move.product_id.id == product_id and move.state not in ['done', 'cancel']: - qty_on_link = min(move.remaining_qty, qty_to_assign) - link_obj.create(cr, uid, {'move_id': move.id, 'operation_id': op.id, 'qty': qty_on_link}, context=context) - qty_to_assign -= qty_on_link - move.refresh() - if qty_to_assign <= 0: - break - - link_obj = self.pool.get('stock.move.operation.link') - uom_obj = self.pool.get('product.uom') - package_obj = self.pool.get('stock.quant.package') + pack_op_obj = self.pool.get('stock.pack.operation') for picking in self.browse(cr, uid, picking_ids, context=context): - for op in picking.pack_operation_ids: - to_unlink_ids = [x.id for x in op.linked_move_operation_ids] - if to_unlink_ids: - link_obj.unlink(cr, uid, to_unlink_ids, context=context) - if op.product_id: - normalized_qty = uom_obj._compute_qty(cr, uid, op.product_uom_id.id, op.product_qty, op.product_id.uom_id.id) - _create_link_for_product(op.product_id.id, normalized_qty) - elif op.package_id: - for product_id, qty in package_obj._get_all_products_quantities(cr, uid, op.package_id.id, context=context).items(): - _create_link_for_product(product_id, qty) + op_ids = [op.id for op in picking.pack_operation_ids] + if op_ids: + pack_op_obj.recompute_rem_qty_from_operation(cr, uid, op_ids, context=context) def _create_extra_moves(self, cr, uid, picking, context=None): '''This function creates move lines on a picking, at the time of do_transfer, based on @@ -3407,6 +3387,42 @@ class stock_pack_operation(osv.osv): 'date': fields.date.context_today, } + def write(self, cr, uid, ids, vals, context=None): + res = super(stock_pack_operation, self).write(cr, uid, ids, vals, context=context) + self.recompute_rem_qty_from_operation(cr, uid, ids, context=context) + return res + + def create(self, cr, uid, vals, context=None): + res_id = super(stock_pack_operation, self).create(cr, uid, vals, context=context) + self.recompute_rem_qty_from_operation(cr, uid, [res_id], context=context) + return res_id + + def recompute_rem_qty_from_operation(self, cr, uid, op_ids, context=None): + def _create_link_for_product(product_id, qty): + qty_to_assign = qty + for move in op.picking_id.move_lines: + if move.product_id.id == product_id and move.state not in ['done', 'cancel']: + qty_on_link = min(move.remaining_qty, qty_to_assign) + link_obj.create(cr, uid, {'move_id': move.id, 'operation_id': op.id, 'qty': qty_on_link}, context=context) + qty_to_assign -= qty_on_link + move.refresh() + if qty_to_assign <= 0: + break + + link_obj = self.pool.get('stock.move.operation.link') + uom_obj = self.pool.get('product.uom') + package_obj = self.pool.get('stock.quant.package') + for op in self.browse(cr, uid, op_ids, context=context): + to_unlink_ids = [x.id for x in op.linked_move_operation_ids] + if to_unlink_ids: + link_obj.unlink(cr, uid, to_unlink_ids, context=context) + if op.product_id: + normalized_qty = uom_obj._compute_qty(cr, uid, op.product_uom_id.id, op.product_qty, op.product_id.uom_id.id) + _create_link_for_product(op.product_id.id, normalized_qty) + elif op.package_id: + for product_id, qty in package_obj._get_all_products_quantities(cr, uid, op.package_id.id, context=context).items(): + _create_link_for_product(product_id, qty) + def process_packaging(self, cr, uid, operation, quants, context=None): ''' Process the packaging of a given operation, after the quants have been moved. If there was not enough quants found a quant already has been with the good package information so we don't consider that case in this method''' @@ -3447,7 +3463,7 @@ class stock_pack_operation(osv.osv): #existing operation found for the given domain and picking => increment its quantity operation_id = existing_operation_ids[0] qty = self.browse(cr, uid, operation_id, context=context).product_qty + 1 - self.write(cr, uid, operation_id, {'product_qty': qty}, context=context) + self.write(cr, uid, [operation_id], {'product_qty': qty}, context=context) else: #no existing operation found for the given domain and picking => create a new one values = { From db3d8abc35e05a97a7cfb3f4fc7188c4f1546bd3 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 13 Feb 2014 10:40:54 +0100 Subject: [PATCH 3/5] [FIX] stock: barcode UI. Fixed all features including the numpad and all buttons bzr revid: qdp-launchpad@openerp.com-20140213094054-qtxv79ge16e2vras --- addons/stock/static/src/js/widgets.js | 86 ++++++++++----------------- addons/stock/stock.py | 18 ++++++ 2 files changed, 51 insertions(+), 53 deletions(-) diff --git a/addons/stock/static/src/js/widgets.js b/addons/stock/static/src/js/widgets.js index c136f75b7f3..bf824a43c3f 100644 --- a/addons/stock/static/src/js/widgets.js +++ b/addons/stock/static/src/js/widgets.js @@ -71,7 +71,6 @@ function openerp_picking_widgets(instance){ var model = this.getParent(); var rows = []; var ops = model.get_current_operations(); - _.each( ops, function(op){ rows.push({ cols: { @@ -121,10 +120,9 @@ function openerp_picking_widgets(instance){ var model = this.getParent(); this.$('.js_pack_row').each(function(){ var pack_id = parseInt($(this).attr('pack-id')); - $('.js_pack_print', this).click(function(){ model.print_package(pack_id); }); - $('.js_pack_plus', this).click(function(){ model.copy_package(pack_id); }); - $('.js_pack_minus', this).click(function(){ model.delete_package(pack_id); }); + $('.js_pack_plus', this).click(function(){ model.copy_package_op(pack_id); }); + $('.js_pack_minus', this).click(function(){ model.delete_package_op(pack_id); }); $('.js_pack_select', this).click(function(){ if(model.get_selected_package() && model.get_selected_package().id === pack_id){ model.deselect_package(); @@ -365,7 +363,7 @@ function openerp_picking_widgets(instance){ }); } - var loaded = loaded_picking.then(function(){ + return loaded_picking.then(function(){ return new instance.web.Model('stock.move').call('read',[self.picking.move_lines, [], new instance.web.CompoundContext()]); }).then(function(movelines){ @@ -374,23 +372,20 @@ function openerp_picking_widgets(instance){ return new instance.web.Model('stock.pack.operation').call('read',[self.picking.pack_operation_ids, [], new instance.web.CompoundContext()]); }).then(function(operations){ self.operations = operations; - var package_ids = []; for(var i = 0; i < operations.length; i++){ if(!_.contains(package_ids,operations[i].result_package_id[0])){ - package_ids.push(operations[i].result_package_id[0]); + if (operations[i].result_package_id[0]){ + package_ids.push(operations[i].result_package_id[0]); + } } } - - return new instance.web.Model('stock.quant.package').call('read',[package_ids, [], new instance.web.CompoundContext()]); }).then(function(packages){ self.packages = packages; }); - return loaded; - }, start: function(){ this._super(); @@ -444,7 +439,7 @@ function openerp_picking_widgets(instance){ self.$('.oe_pick_app_header').text(self.get_header()); - }); + }).fail(function(error) {console.log(error);}); }, // reloads the data from the provided picking and refresh the ui. @@ -541,7 +536,6 @@ function openerp_picking_widgets(instance){ var self = this; new instance.web.Model('stock.picking.type').call('read', [[self.picking_type_id], ['code'], new instance.web.CompoundContext()]) .then(function(pick_type){ - console.log('self.picking_type_id.code '+pick_type[0]['code']); if (pick_type[0]['code'] == 'outgoing'){ new instance.web.Model('stock.picking').call('do_print_delivery',[[self.picking.id]]) .then(function(action){ @@ -549,7 +543,6 @@ function openerp_picking_widgets(instance){ }); } else { - console.log('self.picking_id '+picking_id); new instance.web.Model('stock.picking').call('do_print_picking',[[self.picking.id]]) .then(function(action){ return self.do_action(action); @@ -577,20 +570,21 @@ function openerp_picking_widgets(instance){ } } }, - copy_package: function(package_id){ + copy_package_op: function(pack_id){ var self = this; - new instance.web.Model('stock.quant.package') - .call('copy',[[package_id]]) + new instance.web.Model('stock.quant.package').call('copy_pack',[pack_id]) .then(function(){ return self.refresh_ui(self.picking.id); }); }, - delete_package: function(package_id){ + delete_package_op: function(pack_id){ var self = this; - new instance.web.Model('stock.quant.package') - .call('unlink',[[package_id]]) - .then(function(){ - return self.refresh_ui(self.picking.id); + new instance.web.Model('stock.pack.operation').call('search', [[['result_package_id', '=', pack_id]]]) + .then(function(op_ids) { + new instance.web.Model('stock.pack.operation').call('unlink', [op_ids]) + .then(function() { + return self.refresh_ui(self.picking.id); + }); }); }, deselect_package: function(){ @@ -660,15 +654,9 @@ function openerp_picking_widgets(instance){ return; } - if(quantity === '++'){ - quantity = op.product_qty + 1; - }else if(quantity === '--'){ - quantity = op.product_qty - 1; - } - if(typeof quantity === 'number' && quantity >= 0){ new instance.web.Model('stock.pack.operation') - .call('write',[[op.id],{'product_qty': quantity }]) + .call('write',[[op],{'product_qty': quantity }]) .then(function(){ self.refresh_ui(self.picking.id); }); @@ -681,31 +669,23 @@ function openerp_picking_widgets(instance){ var numpad_timestamp; this.numpad_handler = function(e){ - // upper row numbers are reserved for the barcode scanner - if( e.keyCode < 48 && e.keyCode >= 58){ - if(numpad_timestamp + 1500 < new Date().getTime()){ - numpad = []; - } - if(e.keyCode === 27 || e.keyCode === 8){ // ESC or BACKSPACE - numpad = []; - }else if(e.keyCode >= 96 && e.keyCode <= 105){ // NUMPAD NUMBERS - numpad.push(e.keyCode - 96); - }else if(e.keyCode === 13){ // ENTER - if(numpad.length > 0){ - self.set_operation_quantity(parseInt(numpad.join(''))); - } - numpad = []; - }else if(e.keyCode === 107){ // NUMPAD + - self.set_operation_quantity('++'); - numpad = []; - }else if(e.keyCode === 109){ // NUMPAD - - self.set_operation_quantity('--'); - numpad = []; - }else{ - numpad = []; - } - numpad_timestamp = new Date().getTime(); + if(numpad_timestamp + 1500 < new Date().getTime()){ + numpad = []; } + if(e.keyCode === 27 || e.keyCode === 8){ // ESC or BACKSPACE + numpad = []; + }else if(e.keyCode >= 48 && e.keyCode <= 57){ // NUMPAD NUMBERS + numpad.push(e.keyCode - 48); + }else if(e.keyCode === 13){ // ENTER + console.log('enter'); + if(numpad.length > 0){ + self.set_operation_quantity(parseInt(numpad.join(''))); + } + numpad = []; + }else{ + numpad = []; + } + numpad_timestamp = new Date().getTime(); }; $('body').on('keypress', this.numpad_handler); }, diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 4dccfda1b5f..b09f6a5f067 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3299,6 +3299,24 @@ class stock_package(osv.osv): res[quant.product_id.id] += quant.qty return res + def copy(self, cr, uid, id, default=None, context=None): + if default is None: + default = {} + if not default.get('name'): + default['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.quant.package') or _('Unknown Pack') + return super(stock_package, self).copy(cr, uid, id, default, context=context) + + def copy_pack(self, cr, uid, id, default_pack_values=None, default=None, context=None): + stock_pack_operation_obj = self.pool.get('stock.pack.operation') + if default is None: + default = {} + new_package_id = self.copy(cr, uid, id, default_pack_values, context=context) + default['result_package_id'] = new_package_id + op_ids = stock_pack_operation_obj.search(cr, uid, [('result_package_id', '=', id)], context=context) + for op_id in op_ids: + stock_pack_operation_obj.copy(cr, uid, op_id, default, context=context) + + class stock_pack_operation(osv.osv): _name = "stock.pack.operation" _description = "Packing Operation" From 06d516beae1bb33c094fe025a7d894528494e152 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 13 Feb 2014 11:51:48 +0100 Subject: [PATCH 4/5] [FIX] stock: recheck_availability button bzr revid: qdp-launchpad@openerp.com-20140213105148-l0560ztdos5epzya --- addons/stock/stock.py | 5 ++++- addons/stock/stock_view.xml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index b09f6a5f067..9a0a572d937 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -916,6 +916,10 @@ class stock_picking(osv.osv): return backorder_id return False + def recheck_availability(self, cr, uid, picking_ids, context=None): + self.action_assign(cr, uid, picking_ids, context=context) + self.do_prepare_partial(cr, uid, picking_ids, context=context) + def do_prepare_partial(self, cr, uid, picking_ids, context=None): #TODO refactore me context = context or {} @@ -1892,7 +1896,6 @@ class stock_move(osv.osv): picking_obj = self.pool.get("stock.picking") quant_obj = self.pool.get("stock.quant") pack_op_obj = self.pool.get("stock.pack.operation") - pack_obj = self.pool.get("stock.quant.package") todo = [move.id for move in self.browse(cr, uid, ids, context=context) if move.state == "draft"] if todo: self.action_confirm(cr, uid, todo, context=context) diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml index 6106135ea3e..208907a262a 100644 --- a/addons/stock/stock_view.xml +++ b/addons/stock/stock_view.xml @@ -799,7 +799,7 @@