[MERGE] main trunk-wms branch
bzr revid: qdp-launchpad@openerp.com-20140213110209-907jqb8n4sjpwji9
This commit is contained in:
commit
697c9d5f3e
|
@ -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'],
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
* ----------------------- */
|
||||
|
||||
.oe_pick_widget .oe_searchbox{
|
||||
float: right;
|
||||
margin-top: 13px;
|
||||
}
|
||||
.oe_pick_widget .oe_searchbox input{
|
||||
padding: 8px;
|
||||
|
|
|
@ -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('<div></div>');
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -68,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: {
|
||||
|
@ -118,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();
|
||||
|
@ -159,7 +160,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 +183,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('<div></div>');
|
||||
},
|
||||
start: function(){
|
||||
this._super();
|
||||
|
@ -214,6 +217,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++){
|
||||
|
@ -234,7 +238,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;
|
||||
}
|
||||
|
@ -294,7 +298,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 +315,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 +324,7 @@ function openerp_picking_widgets(instance){
|
|||
buttons: [{
|
||||
text:_t('Ok'),
|
||||
click: function(){
|
||||
self.quit();
|
||||
self.menu();
|
||||
}
|
||||
}]
|
||||
}, _t('<p>We could not find a picking to display.</p>'))).open();
|
||||
|
@ -356,11 +358,12 @@ function openerp_picking_widgets(instance){
|
|||
})
|
||||
.then(function(picking){
|
||||
self.picking = picking;
|
||||
self.picking_type_id = picking.picking_type_id[0];
|
||||
loaded_picking.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
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){
|
||||
|
@ -369,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();
|
||||
|
@ -395,10 +395,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(); });
|
||||
|
@ -437,10 +439,8 @@ function openerp_picking_widgets(instance){
|
|||
|
||||
self.$('.oe_pick_app_header').text(self.get_header());
|
||||
|
||||
});
|
||||
}).fail(function(error) {console.log(error);});
|
||||
|
||||
|
||||
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 +463,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 +514,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 +532,24 @@ 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){
|
||||
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 {
|
||||
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){
|
||||
|
@ -548,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(){
|
||||
|
@ -631,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);
|
||||
});
|
||||
|
@ -652,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);
|
||||
},
|
||||
|
@ -734,3 +743,11 @@ function openerp_picking_widgets(instance){
|
|||
});
|
||||
|
||||
}
|
||||
|
||||
openerp.stock = function(openerp) {
|
||||
openerp.stock = openerp.stock || {};
|
||||
openerp_picking_widgets(openerp);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -175,11 +175,14 @@
|
|||
<table class='oe_pick_layout'>
|
||||
<tr class='oe_pick_header_row'>
|
||||
<td class='oe_pick_header'>
|
||||
|
||||
<div class='oe_pick_right_toolbar'>
|
||||
<div class='oe_pick_button js_pick_quit'> Quit </div>
|
||||
</div>
|
||||
|
||||
<div class='oe_pick_toolbar'>
|
||||
<div class='oe_searchbox oe_left'>
|
||||
<input type='text' placeholder='Search'/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='oe_pick_body_row'>
|
||||
|
@ -187,10 +190,6 @@
|
|||
<div class='oe_pick_body'>
|
||||
<div class='oe_pick_app'>
|
||||
|
||||
<div class='oe_searchbox'>
|
||||
<input type='text' placeholder='Search'/>
|
||||
</div>
|
||||
|
||||
<h3 class='oe_pick_app_title'>Pickings</h3>
|
||||
|
||||
<div class='oe_picking_not_found oe_hidden'>
|
||||
|
@ -208,7 +207,7 @@
|
|||
<div t-att-class="'oe_picking ' + (widget.pickings_by_type[type.id].length === 0 ? 'oe_empty':'js_pick_last') "
|
||||
t-att-data-id="type.id">
|
||||
|
||||
<span class='oe_picking_name'><t t-esc="type.name" /></span>
|
||||
<span class='oe_picking_name'><t t-esc="type.complete_name" /></span>
|
||||
<t t-if="widget.pickings_by_type[type.id].length === 0">
|
||||
<span class='oe_pick_app_info'>Nothing to do</span>
|
||||
</t>
|
||||
|
@ -229,22 +228,19 @@
|
|||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
|
||||
<t t-name="PickingMainWidget">
|
||||
<div class='oe_pick_widget'>
|
||||
<table class='oe_pick_layout'>
|
||||
<tr class='oe_pick_header_row'>
|
||||
<td class='oe_pick_header'>
|
||||
|
||||
<div class='oe_pick_right_toolbar'>
|
||||
<div class='oe_pick_button js_pick_menu'> Menu </div>
|
||||
<div class='oe_pick_button js_pick_quit'> Quit </div>
|
||||
</div>
|
||||
|
||||
<div class='oe_pick_toolbar'>
|
||||
<div class='oe_pick_button oe_small oe_disabled oe_left js_pick_prev'><</div>
|
||||
<div class='oe_pick_button js_pick_pack'> Pack </div>
|
||||
<div class='oe_pick_button js_pick_done'> Done </div>
|
||||
<div class='oe_pick_button oe_small oe_disabled oe_right js_pick_next'>></div>
|
||||
<div class='oe_pick_button oe_disabled js_pick_prev'>< Previous</div>
|
||||
<div class='oe_pick_button oe_disabled js_pick_next'>Next ></div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
@ -253,10 +249,13 @@
|
|||
<td class='oe_pick_body_cont'>
|
||||
<div class='oe_pick_body'>
|
||||
<div class='oe_pick_app'>
|
||||
<div class='oe_pick_button js_pick_done'> Done </div>
|
||||
<div class='oe_pick_button js_pick_print'> Print </div>
|
||||
<div class='oe_pick_app_header'>
|
||||
<t t-esc='widget.get_header()' />
|
||||
</div>
|
||||
|
||||
|
||||
<div class='oe_pick_button js_pick_pack'> Put in Pack </div>
|
||||
<div class='oe_placeholder_picking_editor'></div>
|
||||
<div class='oe_placeholder_package_editor'></div>
|
||||
<div class='oe_placeholder_package_selector'></div>
|
||||
|
|
|
@ -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")
|
||||
|
@ -914,6 +914,10 @@ class stock_picking(osv.osv):
|
|||
return self.action_confirm(cr, uid, [backorder_id], context=context)
|
||||
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 {}
|
||||
|
@ -1008,31 +1012,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
|
||||
|
@ -1127,13 +1111,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)
|
||||
|
@ -1912,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:
|
||||
ids = self.action_confirm(cr, uid, todo, context=context)
|
||||
|
@ -3317,6 +3300,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"
|
||||
|
@ -3405,6 +3406,44 @@ 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)
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
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'''
|
||||
|
@ -3445,7 +3484,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 = {
|
||||
|
@ -3620,39 +3659,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, [])
|
||||
|
@ -3670,24 +3676,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 = {
|
||||
|
@ -3797,9 +3785,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'),
|
||||
|
|
|
@ -799,7 +799,7 @@
|
|||
<field name="pack_operation_exist" invisible="1"/>
|
||||
<button name="action_pack" string="Create Package" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state', 'not in', ('draft','assigned','partially_available','confirmed'))]}" class="oe_link oe_right oe_inline" groups="product.group_stock_packaging"/>
|
||||
<button name="do_split" string="Create Draft Backorder" groups="base.group_no_one" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state','not in',('assigned', 'partially_available'))]}" class="oe_link oe_right oe_inline"/>
|
||||
<button name="do_prepare_partial" string="Recheck Availability" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state','not in',('assigned', 'partially_available'))]}" groups="stock.group_stock_user" class="oe_link oe_right oe_inline"/>
|
||||
<button name="recheck_availability" string="Recheck Availability" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state','not in',('assigned', 'partially_available'))]}" groups="stock.group_stock_user" class="oe_link oe_right oe_inline"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="pack_operation_ids" attrs="{'invisible': [('pack_operation_exist', '=', False)]}" context="{'default_owner_id': owner_id}">
|
||||
|
@ -1494,9 +1494,6 @@
|
|||
</div>
|
||||
<div>
|
||||
<a name="%(action_picking_tree)d" type="action">All Operations</a>
|
||||
<!--<a name="%(action_picking_tree_done_grouped)d" type="action" class="oe_sparkline_bar_link">
|
||||
<field name="monthly_picking" widget="sparkline_bar">Monthly Done Operations</field>
|
||||
</a>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_picking_type_gauge">
|
||||
|
|
Loading…
Reference in New Issue