[MERGE]merge with latest trunk-wms
bzr revid: csn@openerp.com-20140210101953-dnnm61zzjdeghkwm
This commit is contained in:
+21
-11
@@ -49,6 +49,7 @@ class sale_order(osv.osv):
|
||||
'date_confirm': False,
|
||||
'client_order_ref': '',
|
||||
'name': self.pool.get('ir.sequence').get(cr, uid, 'sale.order'),
|
||||
'procurement_group_id': False,
|
||||
})
|
||||
return super(sale_order, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
@@ -668,6 +669,11 @@ class sale_order(osv.osv):
|
||||
res.append(sale_line_obj.need_procurement(cr, uid, [line.id for line in order.order_line], context=context))
|
||||
return any(res)
|
||||
|
||||
def action_ignore_delivery_exception(self, cr, uid, ids, context=None):
|
||||
for sale_order in self.browse(cr, uid, ids, context=context):
|
||||
self.write(cr, uid, ids, {'state': 'progress' if sale_order.invoice_exists else 'manual'}, context=context)
|
||||
return True
|
||||
|
||||
def action_ship_create(self, cr, uid, ids, context=None):
|
||||
"""Create the required procurements to supply sales order lines, also connecting
|
||||
the procurements to appropriate stock moves in order to bring the goods to the
|
||||
@@ -680,34 +686,38 @@ class sale_order(osv.osv):
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
proc_ids = []
|
||||
vals = self._prepare_procurement_group(cr, uid, order, context=context)
|
||||
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
|
||||
if not order.procurement_group_id:
|
||||
group_id = self.pool.get("procurement.group").create(cr, uid, vals, context=context)
|
||||
order.write({'procurement_group_id': group_id}, context=context)
|
||||
|
||||
order.write({'procurement_group_id': group_id}, context=context)
|
||||
for line in order.order_line:
|
||||
#cancel existing procurements if any (possible when after a shipping exception the user choose to recreate), to avoid duplicates
|
||||
#Try to fix exception procurement (possible when after a shipping exception the user choose to recreate)
|
||||
if line.procurement_ids:
|
||||
procurement_obj.cancel(cr, uid, [x.id for x in line.procurement_ids if x.state != 'cancel'], context=context)
|
||||
if sale_line_obj.need_procurement(cr, uid, [line.id], context=context):
|
||||
#first check them to see if they are in exception or not (one of the related moves is cancelled)
|
||||
procurement_obj.check(cr, uid, [x.id for x in line.procurement_ids if x.state not in ['cancel', 'done']])
|
||||
line.refresh()
|
||||
#run again procurement that are in exception in order to trigger another move
|
||||
proc_ids += [x.id for x in line.procurement_ids if x.state == 'exception']
|
||||
elif sale_line_obj.need_procurement(cr, uid, [line.id], context=context):
|
||||
if (line.state == 'done') or not line.product_id:
|
||||
continue
|
||||
vals = self._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
|
||||
proc_id = procurement_obj.create(cr, uid, vals, context=context)
|
||||
proc_ids.append(proc_id)
|
||||
#Confirm procurement order such that rules will be applied on it
|
||||
#note that the workflow ensure proc_ids isn't an empty list
|
||||
#note that the workflow normally ensure proc_ids isn't an empty list
|
||||
procurement_obj.run(cr, uid, proc_ids, context=context)
|
||||
# FP NOTE: do we need this? isn't it the workflow that should set this
|
||||
val = {}
|
||||
|
||||
#if shipping was in exception and the user choose to recreate the delivery order, write the new status of SO
|
||||
if order.state == 'shipping_except':
|
||||
val['state'] = 'progress'
|
||||
val['shipped'] = False
|
||||
val = {'state': 'progress', 'shipped': False}
|
||||
|
||||
if (order.order_policy == 'manual'):
|
||||
for line in order.order_line:
|
||||
if (not line.invoiced) and (line.state not in ('cancel', 'draft')):
|
||||
val['state'] = 'manual'
|
||||
break
|
||||
order.write(val)
|
||||
order.write(val)
|
||||
return True
|
||||
|
||||
# if mode == 'finished':
|
||||
|
||||
@@ -187,6 +187,13 @@
|
||||
<field name="kind">function</field>
|
||||
<field name="action">action_ship_create()</field>
|
||||
</record>
|
||||
|
||||
<record id="act_ship_ignore" model="workflow.activity">
|
||||
<field name="wkf_id" ref="sale.wkf_sale"/>
|
||||
<field name="name">ship_ignore</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">action_ignore_delivery_exception()</field>
|
||||
</record>
|
||||
|
||||
<record id="act_ship_end" model="workflow.activity">
|
||||
<field name="wkf_id" ref="sale.wkf_sale"/>
|
||||
@@ -272,11 +279,16 @@
|
||||
<field name="signal">ship_recreate</field>
|
||||
</record>
|
||||
|
||||
<record id="trans_ship_except_ship_end" model="workflow.transition">
|
||||
<record id="trans_ship_except_ship_ignore" model="workflow.transition">
|
||||
<field name="act_from" ref="act_ship_except"/>
|
||||
<field name="act_to" ref="act_ship_end"/>
|
||||
<field name="act_to" ref="act_ship_ignore"/>
|
||||
<field name="signal">ship_corrected</field>
|
||||
</record>
|
||||
|
||||
<record id="trans_ship_ignore_ship_end" model="workflow.transition">
|
||||
<field name="act_from" ref="act_ship_ignore"/>
|
||||
<field name="act_to" ref="act_ship_end"/>
|
||||
</record>
|
||||
|
||||
<record id="trans_ship_except_ship_cancel" model="workflow.transition">
|
||||
<field name="act_from" ref="act_ship_except"/>
|
||||
|
||||
@@ -172,14 +172,23 @@ class procurement_order(osv.osv):
|
||||
group_id = procurement.group_id and procurement.group_id.id or False
|
||||
elif procurement.rule_id.group_propagation_option == 'fixed':
|
||||
group_id = procurement.rule_id.group_id and procurement.rule_id.group_id.id or False
|
||||
#it is possible that we've already got some move done, so check for the done qty and create
|
||||
#a new move with the correct qty
|
||||
already_done_qty = 0
|
||||
already_done_qty_uos = 0
|
||||
for move in procurement.move_ids:
|
||||
already_done_qty += move.product_uom_qty if move.state == 'done' else 0
|
||||
already_done_qty_uos += move.product_uos_qty if move.state == 'done' else 0
|
||||
qty_left = max(procurement.product_qty - already_done_qty, 0)
|
||||
qty_uos_left = max(procurement.product_uos_qty - already_done_qty_uos, 0)
|
||||
vals = {
|
||||
'name': procurement.name,
|
||||
'company_id': procurement.company_id.id,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_qty': qty_left,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uom_qty': procurement.product_qty,
|
||||
'product_uos_qty': (procurement.product_uos and procurement.product_uos_qty) or procurement.product_qty,
|
||||
'product_uom_qty': qty_left,
|
||||
'product_uos_qty': (procurement.product_uos and qty_uos_left) or qty_left,
|
||||
'product_uos': (procurement.product_uos and procurement.product_uos.id) or procurement.product_uom.id,
|
||||
'partner_id': procurement.group_id and procurement.group_id.partner_id and procurement.group_id.partner_id.id or False,
|
||||
'location_id': procurement.rule_id.location_src_id.id,
|
||||
@@ -212,23 +221,33 @@ class procurement_order(osv.osv):
|
||||
return super(procurement_order, self)._run(cr, uid, procurement, context)
|
||||
|
||||
def _check(self, cr, uid, procurement, context=None):
|
||||
''' Implement the procurement checking for rules of type 'move'. The procurement will be satisfied only if all related
|
||||
moves are done/cancel and if the requested quantity is moved.
|
||||
'''
|
||||
if procurement.rule_id and procurement.rule_id.action == 'move':
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
done_test_list = []
|
||||
done_cancel_test_list = []
|
||||
qty_done = 0
|
||||
for move in procurement.move_ids:
|
||||
done_test_list.append(move.state == 'done')
|
||||
done_cancel_test_list.append(move.state in ('done', 'cancel'))
|
||||
qty_done += move.product_qty if move.state == 'done' else 0
|
||||
qty_done = uom_obj._compute_qty(cr, uid, procurement.product_id.uom_id.id, qty_done, procurement.product_uom.id)
|
||||
at_least_one_done = any(done_test_list)
|
||||
all_done_or_cancel = all(done_cancel_test_list)
|
||||
if not all_done_or_cancel:
|
||||
return False
|
||||
elif at_least_one_done and all_done_or_cancel:
|
||||
elif all_done_or_cancel and procurement.product_qty == qty_done:
|
||||
return True
|
||||
elif at_least_one_done:
|
||||
#some move cancelled and some validated
|
||||
self.message_post(cr, uid, [procurement.id], body=_('Some stock moves have been cancelled for this procurement. Run the procurement again to trigger a move for the remaining quantity or change the procurement quantity to finish it directly'), context=context)
|
||||
else:
|
||||
#all move are cancelled
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
self.message_post(cr, uid, [procurement.id], body=_('All stock moves have been cancelled for this procurement.'), context=context)
|
||||
return False
|
||||
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
|
||||
return False
|
||||
|
||||
return super(procurement_order, self)._check(cr, uid, procurement, context)
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ class stock_location(osv.osv):
|
||||
'parent_right': fields.integer('Right Parent', select=1),
|
||||
|
||||
'company_id': fields.many2one('res.company', 'Company', select=1, help='Let this field empty if this location is shared between all companies'),
|
||||
'scrap_location': fields.boolean('Is a Scrap Location', help='Check this box to allow using this location to put scrapped/damaged goods.'),
|
||||
'scrap_location': fields.boolean('Is a Scrap Location?', help='Check this box to allow using this location to put scrapped/damaged goods.'),
|
||||
'removal_strategy_ids': fields.one2many('product.removal', 'location_id', 'Removal Strategies'),
|
||||
'putaway_strategy_ids': fields.one2many('product.putaway', 'location_id', 'Put Away Strategies'),
|
||||
}
|
||||
@@ -1307,7 +1307,7 @@ class stock_move(osv.osv):
|
||||
res = dict.fromkeys(ids, '')
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.state in ('draft', 'done', 'cancel') or move.location_id.usage != 'internal':
|
||||
res[move.id] = _('n/a')
|
||||
res[move.id] = '' # 'not applicable' or 'n/a' could work too
|
||||
continue
|
||||
total_available = min(move.product_qty, move.reserved_availability + move.availability)
|
||||
total_available = uom_obj._compute_qty(cr, uid, move.product_id.uom_id.id, total_available, move.product_uom.id)
|
||||
|
||||
@@ -733,13 +733,13 @@
|
||||
<field name="name"/>
|
||||
<field name="location_dest_id"/>
|
||||
<field name="date"/>
|
||||
<field name="min_date"/>
|
||||
<field name="min_date" invisible="1"/>
|
||||
<field name="origin"/>
|
||||
<field name="group_id" invisible="1"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="group_id"/>
|
||||
<field name="state"/>
|
||||
<field name="priority"/>
|
||||
<field name="priority" invisible="1"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="origin" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -756,7 +756,9 @@
|
||||
<button name="force_assign" states="confirmed,partially_available" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="do_transfer" states="assigned" string="Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
|
||||
<button name="do_transfer" string="Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', False), ('state', '!=', 'partially_available')]}"/>
|
||||
<button name="do_prepare_partial" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', True),('state','not in',('assigned', 'partially_available'))]}"/>
|
||||
<button name="do_prepare_partial" string="Enter Transfer Details" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', True),('state','not in',('assigned', 'partially_available'))]}"/>
|
||||
<button name="do_print_delivery" string="Print Delivery Order" groups="stock.group_stock_user" type="object" attrs="{'invisible': ['|', ('picking_type_code', '!=', 'outgoing'), ('state', '!=', 'done')]}"/>
|
||||
<button name="do_print_picking" string="Print Picking List" groups="stock.group_stock_user" type="object" attrs="{'invisible': ['|', ('picking_type_code', '=', 'outgoing'), ('state', '!=', 'assigned')]}"/>
|
||||
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action" groups="base.group_user"/>
|
||||
<button name="action_cancel" states="assigned,confirmed,partially_available,draft" string="Cancel Transfer" groups="base.group_user" type="object"/>
|
||||
<button name="do_unreserve" string="Unreserve" groups="base.group_user" type="object" attrs="{'invisible': [('quant_reserved_exist', '=', False)]}"/>
|
||||
@@ -764,8 +766,6 @@
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="do_print_delivery" string="Delivery Order" groups="stock.group_stock_user" type="object" attrs="{'invisible': ['|', ('picking_type_code', '!=', 'outgoing'), ('state', '!=', 'assigned')]}"/>
|
||||
<button name="do_print_picking" string="Picking List" groups="stock.group_stock_user" type="object" attrs="{'invisible': ['|', ('picking_type_code', '=', 'outgoing'), ('state', '!=', 'assigned')]}"/>
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name" class="oe_inline" attrs="{'invisible': [('name','=','/')]}" readonly="1"/>
|
||||
|
||||
Reference in New Issue
Block a user