[MERGE] misc things: replacement of picking_ids on purchase.order by a fields.function; adding of a button on stock.warehouse to see all the routes related; usability improvement in stock.warehouse form view; bugfix in creation of picking/stock moves from purchase.order confirmation; view all picking-related from button on purchase.order instead of just the incoming shipment
bzr revid: qdp-launchpad@openerp.com-20131017160725-fjphdok34is6q4bc
This commit is contained in:
commit
9f2d0cc781
|
@ -154,6 +154,16 @@ class purchase_order(osv.osv):
|
|||
obj_data = self.pool.get('ir.model.data')
|
||||
return obj_data.get_object_reference(cr, uid, 'stock','picking_type_in') and obj_data.get_object_reference(cr, uid, 'stock','picking_type_in')[1] or False
|
||||
|
||||
def _get_picking_ids(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
for purchase_id in ids:
|
||||
picking_ids = set()
|
||||
move_ids = self.pool.get('stock.move').search(cr, uid, [('purchase_line_id.order_id','=', purchase_id)] , context=context)
|
||||
for move in self.pool.get('stock.move').browse(cr, uid, move_ids, context=context):
|
||||
picking_ids.add(move.picking_id.id)
|
||||
res[purchase_id] = list(picking_ids)
|
||||
return res
|
||||
|
||||
STATE_SELECTION = [
|
||||
('draft', 'Draft PO'),
|
||||
('sent', 'RFQ Sent'),
|
||||
|
@ -196,7 +206,7 @@ class purchase_order(osv.osv):
|
|||
'validator' : fields.many2one('res.users', 'Validated by', readonly=True),
|
||||
'notes': fields.text('Terms and Conditions'),
|
||||
'invoice_ids': fields.many2many('account.invoice', 'purchase_invoice_rel', 'purchase_id', 'invoice_id', 'Invoices', help="Invoices generated for a purchase order"),
|
||||
'picking_ids': fields.one2many('stock.picking', 'purchase_id', 'Picking List', readonly=True, help="This is the list of incoming shipments that have been generated for this purchase order."),
|
||||
'picking_ids': fields.function(_get_picking_ids, method=True, type='one2many', relation='stock.picking', string='Picking List', help="This is the list of operations that have been generated for this purchase order."),
|
||||
'shipped':fields.boolean('Received', readonly=True, select=True, help="It indicates that a picking has been done"),
|
||||
'shipped_rate': fields.function(_shipped_rate, string='Received Ratio', type='float'),
|
||||
'invoiced': fields.function(_invoiced, string='Invoice Received', type='boolean', help="It indicates that an invoice has been paid"),
|
||||
|
@ -235,7 +245,7 @@ class purchase_order(osv.osv):
|
|||
'bid_validity': fields.date('Bid Valid Until', help="Date on which the bid expired"),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Deliver To', help="This will determine picking type of incoming shipment", required=True,
|
||||
states={'confirmed': [('readonly', True)], 'approved': [('readonly', True)], 'done': [('readonly', True)]}),
|
||||
'related_location_id': fields.related('picking_type_id', 'default_location_dest_id', type='many2one', relation='stock.location', string="Related location", store=True),
|
||||
'related_location_id': fields.related('picking_type_id', 'default_location_dest_id', type='many2one', relation='stock.location', string="Related location", store=True),
|
||||
}
|
||||
_defaults = {
|
||||
'date_order': fields.date.context_today,
|
||||
|
@ -394,32 +404,22 @@ class purchase_order(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
dummy, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree'))
|
||||
action = self.pool.get('ir.actions.act_window').read(cr, uid, action_id, context=context)
|
||||
|
||||
pick_ids = []
|
||||
for po in self.browse(cr, uid, ids, context=context):
|
||||
pick_ids += [picking.id for picking in po.picking_ids]
|
||||
|
||||
action_model, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree'))
|
||||
action = self.pool[action_model].read(cr, uid, action_id, context=context)
|
||||
active_id = context.get('active_id',ids[0])
|
||||
picking_type_id = self.browse(cr, uid, active_id, context=context)['picking_type_id'].id
|
||||
|
||||
ctx = eval(action['context'],{'active_id': picking_type_id}, nocopy=True)
|
||||
ctx.update({
|
||||
'search_default_purchase_id': ids[0]
|
||||
})
|
||||
if pick_ids and len(pick_ids) == 1:
|
||||
form_view_ids = [view_id for view_id, view in action['views'] if view == 'form']
|
||||
view_id = form_view_ids and form_view_ids[0] or False
|
||||
action.update({
|
||||
'views': [],
|
||||
'view_mode': 'form',
|
||||
'view_id': view_id,
|
||||
'res_id': pick_ids[0]
|
||||
})
|
||||
|
||||
action.update({
|
||||
'context': ctx,
|
||||
})
|
||||
#override the context to get rid of the default filtering on picking type
|
||||
action['context'] = {}
|
||||
#choose the view_mode accordingly
|
||||
if len(pick_ids) > 1:
|
||||
action['domain'] = "[('id','in',[" + ','.join(map(str, pick_ids)) + "])]"
|
||||
else:
|
||||
res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_form')
|
||||
action['views'] = [(res and res[1] or False, 'form')]
|
||||
action['res_id'] = pick_ids and pick_ids[0] or False
|
||||
return action
|
||||
|
||||
def wkf_approve_order(self, cr, uid, ids, context=None):
|
||||
|
@ -429,15 +429,6 @@ class purchase_order(osv.osv):
|
|||
def wkf_bid_received(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state':'bid', 'bid_date': fields.date.context_today(self,cr,uid,context=context)})
|
||||
|
||||
def print_confirm(self,cr,uid,ids,context=None):
|
||||
print "Confirmed"
|
||||
|
||||
def print_double(self,cr,uid,ids,context=None):
|
||||
print "double Approval"
|
||||
|
||||
def print_router(self,cr,uid,ids,context=None):
|
||||
print "Routed"
|
||||
|
||||
def wkf_send_rfq(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
This function opens a window to compose an email, with the edi purchase template message loaded by default
|
||||
|
@ -497,8 +488,7 @@ class purchase_order(osv.osv):
|
|||
raise osv.except_osv(_('Error!'),_('You cannot confirm a purchase order without any purchase order line.'))
|
||||
for line in po.order_line:
|
||||
if line.state=='draft':
|
||||
todo.append(line.id)
|
||||
|
||||
todo.append(line.id)
|
||||
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
|
||||
for id in ids:
|
||||
self.write(cr, uid, [id], {'state' : 'confirmed', 'validator' : uid})
|
||||
|
@ -666,20 +656,6 @@ class purchase_order(osv.osv):
|
|||
return user_datetime.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
return user_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
|
||||
def _prepare_order_picking(self, cr, uid, order, context=None):
|
||||
return {
|
||||
'name': self.pool.get('ir.sequence').get_id(cr, uid, order.picking_type_id.sequence_id.id, 'id'),
|
||||
'origin': order.name + ((order.origin and (':' + order.origin)) or ''),
|
||||
'date': self.date_to_datetime(cr, uid, order.date_order, context),
|
||||
'partner_id': order.dest_address_id.id or order.partner_id.id,
|
||||
'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none',
|
||||
'partner_id': order.dest_address_id.id or order.partner_id.id,
|
||||
'purchase_id': order.id,
|
||||
'company_id': order.company_id.id,
|
||||
'move_lines' : [],
|
||||
'picking_type_id': order.picking_type_id.id,
|
||||
}
|
||||
|
||||
def _prepare_order_line_move(self, cr, uid, order, order_line, picking_id, group_id, context=None):
|
||||
''' prepare the stock move data from the PO line '''
|
||||
price_unit = order_line.price_unit
|
||||
|
@ -687,7 +663,7 @@ class purchase_order(osv.osv):
|
|||
price_unit *= order_line.product_uom.factor
|
||||
if order.currency_id.id != order.company_id.currency_id.id:
|
||||
price_unit = self.pool.get('res.currency').compute(cr, uid, order.currency_id.id, order.company_id.currency_id.id, price_unit, context=context)
|
||||
|
||||
|
||||
return {
|
||||
'name': order_line.name or '',
|
||||
'product_id': order_line.product_id.id,
|
||||
|
@ -708,15 +684,16 @@ class purchase_order(osv.osv):
|
|||
'price_unit': price_unit,
|
||||
'picking_type_id': order.picking_type_id.id,
|
||||
'group_id': group_id,
|
||||
'route_ids': order.picking_type_id.warehouse_id and [(6, 0, [x.id for x in order.picking_type_id.warehouse_id.route_ids])] or [],
|
||||
}
|
||||
|
||||
def _create_pickings(self, cr, uid, order, order_lines, picking_id=False, context=None):
|
||||
"""Creates pickings and appropriate stock moves for given order lines, then
|
||||
confirms the moves, makes them available, and confirms the picking.
|
||||
def _create_stock_moves(self, cr, uid, order, order_lines, picking_id=False, context=None):
|
||||
"""Creates appropriate stock moves for given order lines, whose can optionally create a
|
||||
picking if none is given or no suitable is found, then confirms the moves, makes them
|
||||
available, and confirms the pickings.
|
||||
|
||||
If ``picking_id`` is provided, the stock moves will be added to it, otherwise
|
||||
a standard outgoing picking will be created to wrap the stock moves, as returned
|
||||
by :meth:`~._prepare_order_picking`.
|
||||
If ``picking_id`` is provided, the stock moves will be added to it, otherwise a standard
|
||||
incoming picking will be created to wrap the stock moves (default behavior of the stock.move)
|
||||
|
||||
Modules that wish to customize the procurements or partition the stock moves over
|
||||
multiple stock pickings may override this method and call ``super()`` with
|
||||
|
@ -727,19 +704,16 @@ class purchase_order(osv.osv):
|
|||
and moves should be created.
|
||||
:param int picking_id: optional ID of a stock picking to which the created stock moves
|
||||
will be added. A new picking will be created if omitted.
|
||||
:return: list of IDs of pickings used/created for the given order lines (usually just one)
|
||||
:return: None
|
||||
"""
|
||||
stock_picking = self.pool.get('stock.picking')
|
||||
if not picking_id:
|
||||
picking_id = stock_picking.create(cr, uid, self._prepare_order_picking(cr, uid, order, context=context))
|
||||
todo_moves = []
|
||||
stock_move = self.pool.get('stock.move')
|
||||
|
||||
new_group = False
|
||||
if any([(not x.group_id) for x in order_lines]):
|
||||
new_group = self.pool.get("procurement.group").create(cr, uid, {'name':order.name, 'partner_id': order.partner_id.id}, context=context)
|
||||
|
||||
|
||||
|
||||
for order_line in order_lines:
|
||||
if not order_line.product_id:
|
||||
continue
|
||||
|
@ -750,9 +724,9 @@ class purchase_order(osv.osv):
|
|||
if order_line.move_dest_id:
|
||||
order_line.move_dest_id.write({'location_id': order.location_id.id})
|
||||
todo_moves.append(move)
|
||||
|
||||
stock_move.action_confirm(cr, uid, todo_moves)
|
||||
stock_move.force_assign(cr, uid, todo_moves)
|
||||
return [picking_id]
|
||||
|
||||
def test_moves_done(self, cr, uid, ids, context=None):
|
||||
'''PO is done at the delivery side if all the incoming shipments are done'''
|
||||
|
@ -784,15 +758,8 @@ class purchase_order(osv.osv):
|
|||
return res
|
||||
|
||||
def action_picking_create(self, cr, uid, ids, context=None):
|
||||
picking_ids = []
|
||||
for order in self.browse(cr, uid, ids):
|
||||
picking_ids.extend(self._create_pickings(cr, uid, order, order.order_line, None, context=context))
|
||||
|
||||
# Must return one unique picking ID: the one to connect in the subflow of the purchase order.
|
||||
# In case of multiple (split) pickings, we should return the ID of the critical one, i.e. the
|
||||
# one that should trigger the advancement of the purchase workflow.
|
||||
# By default we will consider the first one as most important, but this behavior can be overridden.
|
||||
return picking_ids[0] if picking_ids else False
|
||||
self._create_stock_moves(cr, uid, order, order.order_line, None, context=context)
|
||||
|
||||
def picking_done(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'shipped':1,'state':'approved'}, context=context)
|
||||
|
|
|
@ -136,6 +136,7 @@ class sale_order(osv.osv):
|
|||
of given sales order ids. It can either be a in a list or in a form
|
||||
view, if there is only one delivery order to show.
|
||||
'''
|
||||
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
act_obj = self.pool.get('ir.actions.act_window')
|
||||
|
||||
|
@ -147,6 +148,7 @@ class sale_order(osv.osv):
|
|||
pick_ids = []
|
||||
for so in self.browse(cr, uid, ids, context=context):
|
||||
pick_ids += [picking.id for picking in so.picking_ids]
|
||||
|
||||
#choose the view_mode accordingly
|
||||
if len(pick_ids) > 1:
|
||||
result['domain'] = "[('id','in',[" + ','.join(map(str, pick_ids)) + "])]"
|
||||
|
|
|
@ -25,7 +25,7 @@ import openerp.addons.decimal_precision as dp
|
|||
|
||||
class product_product(osv.osv):
|
||||
_inherit = "product.product"
|
||||
|
||||
|
||||
def _stock_move_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = dict([(id, {'reception_count': 0, 'delivery_count': 0}) for id in ids])
|
||||
move_pool=self.pool.get('stock.move')
|
||||
|
|
|
@ -562,6 +562,7 @@ class stock_picking(osv.osv):
|
|||
ptype_id = vals.get('picking_type_id', context.get('default_picking_type_id', False))
|
||||
sequence_id = self.pool.get('stock.picking.type').browse(cr, user, ptype_id, context=context).sequence_id.id
|
||||
vals['name'] = self.pool.get('ir.sequence').get_id(cr, user, sequence_id, 'id', context=context)
|
||||
|
||||
return super(stock_picking, self).create(cr, user, vals, context)
|
||||
|
||||
# The state of a picking depends on the state of its related stock.move
|
||||
|
@ -615,16 +616,10 @@ class stock_picking(osv.osv):
|
|||
continue
|
||||
return res
|
||||
|
||||
def _get_group_id(self, cr, uid, ids, field_name, args, context=None):
|
||||
res = {}
|
||||
for pick in self.browse(cr, uid, ids, context=context):
|
||||
if pick.move_lines and pick.move_lines[0].group_id:
|
||||
res[pick.id] = pick.move_lines[0].group_id.id
|
||||
else:
|
||||
res[pick.id] = False
|
||||
return res
|
||||
|
||||
|
||||
def action_assign_owner(self, cr, uid, ids, context=None):
|
||||
for picking in self.browse(cr, uid, ids, context=context):
|
||||
packop_ids = [op.id for op in picking.pack_operation_ids]
|
||||
self.pool.get('stock.pack.operation').write(cr, uid, packop_ids, {'owner_id': picking.owner_id.id}, context=context)
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
|
||||
|
@ -664,13 +659,14 @@ class stock_picking(osv.osv):
|
|||
'pack_operation_exist': fields.function(_get_pack_operation_exist, type='boolean', string='Pack Operation Exists?', help='technical field for attrs in view'),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True),
|
||||
|
||||
'owner_id': fields.many2one('res.partner', 'Owner', help="Default Owner"),
|
||||
# Used to search on pickings
|
||||
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),#?
|
||||
'location_id': fields.related('move_lines', 'location_id', type='many2one', relation='stock.location', string='Location', readonly=True),
|
||||
'location_dest_id': fields.related('move_lines', 'location_dest_id', type='many2one', relation='stock.location', string='Destination Location', readonly=True),
|
||||
'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True),
|
||||
# 'group_id': fields.function(_get_group_id, type='many2one', store={'stock.move': (_get_pickings, ['picking_id', 'group_id'], 10)}),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'name': lambda self, cr, uid, context: '/',
|
||||
'state': 'draft',
|
||||
|
@ -1431,10 +1427,12 @@ class stock_move(osv.osv):
|
|||
for move in moves:
|
||||
if not move.move_dest_id:
|
||||
routes = [x.id for x in move.product_id.route_ids + move.product_id.categ_id.total_route_ids]
|
||||
rules = push_obj.search(cr, uid, [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)], context=context)
|
||||
if rules:
|
||||
rule = push_obj.browse(cr, uid, rules[0], context=context)
|
||||
push_obj._apply(cr, uid, rule, move, context=context)
|
||||
routes = routes or [x.id for x in move.route_ids]
|
||||
if routes:
|
||||
rules = push_obj.search(cr, uid, [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)], context=context)
|
||||
if rules:
|
||||
rule = push_obj.browse(cr, uid, rules[0], context=context)
|
||||
push_obj._apply(cr, uid, rule, move, context=context)
|
||||
return True
|
||||
|
||||
# Create the stock.move.putaway records
|
||||
|
@ -2756,6 +2754,33 @@ class stock_warehouse(osv.osv):
|
|||
#TODO try to delete location and route and if not possible, put them in inactive
|
||||
return super(stock_warehouse, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
def get_all_routes_for_wh(self, cr, uid, warehouse, context=None):
|
||||
all_routes = []
|
||||
all_routes += [warehouse.crossdock_route_id.id]
|
||||
all_routes += [warehouse.reception_route_id.id]
|
||||
all_routes += [warehouse.delivery_route_id.id]
|
||||
all_routes += [warehouse.mto_pull_id.route_id.id]
|
||||
all_routes += [route.id for route in warehouse.resupply_route_ids]
|
||||
all_routes += [route.id for route in warehouse.route_ids]
|
||||
return all_routes
|
||||
|
||||
def view_all_routes_for_wh(self, cr, uid, ids, context=None):
|
||||
all_routes = []
|
||||
for wh in self.browse(cr, uid, ids, context=context):
|
||||
all_routes += self.get_all_routes_for_wh(cr, uid, wh, context=context)
|
||||
|
||||
res_id = ids and ids[0] or False
|
||||
domain = [('id', 'in', all_routes)]
|
||||
return {
|
||||
'name': _('Warehouse\'s Routes'),
|
||||
'domain': domain,
|
||||
'res_model': 'stock.location.route',
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_id': False,
|
||||
'view_mode': 'tree,form',
|
||||
'view_type': 'form',
|
||||
'limit': 20
|
||||
}
|
||||
|
||||
class stock_location_path(osv.osv):
|
||||
_name = "stock.location.path"
|
||||
|
@ -2814,7 +2839,7 @@ class stock_location_path(osv.osv):
|
|||
}
|
||||
def _apply(self, cr, uid, rule, move, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
newdate = (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=rule.delay or 0)).strftime('%Y-%m-%d')
|
||||
newdate = (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta.relativedelta(days=rule.delay or 0)).strftime('%Y-%m-%d')
|
||||
if rule.auto=='transparent':
|
||||
move_obj.write(cr, uid, [move.id], {
|
||||
'date': newdate,
|
||||
|
@ -3015,7 +3040,7 @@ class stock_package(osv.osv):
|
|||
class stock_pack_operation(osv.osv):
|
||||
_name = "stock.pack.operation"
|
||||
_description = "Packing Operation"
|
||||
|
||||
|
||||
def _get_remaining_qty(self, cr, uid, ids, context=None):
|
||||
res = {}
|
||||
for ops in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -3024,8 +3049,7 @@ class stock_pack_operation(osv.osv):
|
|||
qty -= quant.qty
|
||||
res[ops.id] = qty
|
||||
return res
|
||||
|
||||
|
||||
|
||||
_columns = {
|
||||
'picking_id': fields.many2one('stock.picking', 'Stock Picking', help='The stock operation where the packing has been made', required=True),
|
||||
'product_id': fields.many2one('product.product', 'Product', ondelete="CASCADE"), # 1
|
||||
|
@ -3045,7 +3069,7 @@ class stock_pack_operation(osv.osv):
|
|||
}
|
||||
|
||||
_defaults = {
|
||||
'date': fields.date.context_today,
|
||||
'date': fields.date.context_today,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -648,6 +648,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Warehouse" version="7.0">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="view_all_routes_for_wh" string="View Warehouse Routes" type="object"/>
|
||||
</div>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
<group>
|
||||
|
@ -668,9 +671,21 @@
|
|||
<field name="default_resupply_wh_id"/> <!-- TODO should be filtered on resupply_wh_ids only... -->
|
||||
</group>
|
||||
</page>
|
||||
<page string="Routes Information" colspan="4">
|
||||
<group colspan="4">
|
||||
<field name="route_ids" nolabel="1" readonly="1"/>
|
||||
<page string="Technical Information" groups='base.group_no_one'>
|
||||
<group>
|
||||
<group string="Locations">
|
||||
<field name="wh_input_stock_loc_id" readonly="1"/>
|
||||
<field name="wh_qc_stock_loc_id" readonly="1"/>
|
||||
<field name="wh_pack_stock_loc_id" readonly="1"/>
|
||||
<field name="wh_output_stock_loc_id" readonly="1"/>
|
||||
</group>
|
||||
<group string="Picking Types">
|
||||
<field name="in_type_id" readonly="1"/>
|
||||
<field name="int_type_id" readonly="1"/>
|
||||
<field name="pick_type_id" readonly="1"/>
|
||||
<field name="pack_type_id" readonly="1"/>
|
||||
<field name="out_type_id" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
@ -771,6 +786,12 @@
|
|||
<field name="date"/>
|
||||
<field name="min_date"/>
|
||||
<field name="origin" placeholder="e.g. PO0032" class="oe_inline"/>
|
||||
<label for="owner_id" groups="stock.group_tracking_owner"/>
|
||||
<div groups="stock.group_tracking_owner">
|
||||
<field name="owner_id"/>
|
||||
<button name="action_assign_owner" string="Assign Owner" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state', 'not in', ('draft','assigned','confirmed'))]}"
|
||||
class="oe_link oe_edit_only"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
|
@ -781,8 +802,8 @@
|
|||
<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','confirmed'))]}"/>
|
||||
<button name="do_split" string="Create Draft Backorder" groups="base.group_no_one" type="object" attrs="{'invisible': ['|',('pack_operation_exist', '=', False),('state','!=','assigned')]}"/>
|
||||
<field name="pack_operation_ids" attrs="{'invisible': [('pack_operation_exist', '=', False)]}">
|
||||
<tree editable="top">
|
||||
<field name="pack_operation_ids" attrs="{'invisible': [('pack_operation_exist', '=', False)]}" context="{'default_owner_id': owner_id}">
|
||||
<tree editable="top">
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom_id" groups="product.group_uom"/>
|
||||
<field name="lot_id" domain="[('product_id','=?', product_id)]" context="{'product_id': product_id}" groups="stock.group_production_lot"/>
|
||||
|
|
Loading…
Reference in New Issue