[MERGE] jke's branch with usability stuff and merge of PO

bzr revid: qdp-launchpad@openerp.com-20131008123659-4g1bggnhfgepghaz
This commit is contained in:
Quentin (OpenERP) 2013-10-08 14:36:59 +02:00
commit 5ee7193c9c
11 changed files with 286 additions and 45 deletions

View File

@ -77,6 +77,34 @@
</form>
</field>
</record>
<record id="do_view_procurements" model="ir.actions.act_window">
<field name="name">Procurement for Groups </field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('group_id','=',active_id)]</field>
</record>
<record id="procurement_group_form_view" model="ir.ui.view">
<field name="name">procurement.group.form</field>
<field name="model">procurement.group</field>
<field name="arch" type="xml">
<form string="Procurement group" version="7.0">
<sheet>
<div class="oe_right oe_button_box">
<button name="%(do_view_procurements)d" string="View related procurements" type="action" />
</div>
<group>
<field name="name"/>
<field name="move_type"/>
<field name="partner_id"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_procurement_filter" model="ir.ui.view">
<field name="name">procurement.order.select</field>
<field name="model">procurement.order</field>
@ -97,7 +125,7 @@
</search>
</field>
</record>
<record id="procurement_action" model="ir.actions.act_window">
<field name="name">Procurement Orders</field>
<field name="type">ir.actions.act_window</field>
@ -121,7 +149,7 @@
</p>
</field>
</record>
<record id="procurement_exceptions" model="ir.actions.act_window">
<field name="name">Procurements</field>
<field name="type">ir.actions.act_window</field>

View File

@ -832,6 +832,7 @@ class purchase_order(osv.osv):
@return: new purchase order id
"""
#TOFIX: merged order line should be unlink
def make_key(br, fields):
list_key = []
@ -854,14 +855,15 @@ class purchase_order(osv.osv):
context = {}
# Compute what the new orders should contain
new_orders = {}
order_lines_to_move = []
for porder in [order for order in self.browse(cr, uid, ids, context=context) if order.state == 'draft']:
order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
new_order = new_orders.setdefault(order_key, ({}, []))
new_order[1].append(porder.id)
order_infos = new_order[0]
if not order_infos:
order_infos.update({
'origin': porder.origin,
@ -885,21 +887,7 @@ class purchase_order(osv.osv):
order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
for order_line in porder.order_line:
line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'product_id', 'move_dest_id', 'account_analytic_id'))
o_line = order_infos['order_line'].setdefault(line_key, {})
if o_line:
# merge the line with an existing line
o_line['product_qty'] += order_line.product_qty * order_line.product_uom.factor / o_line['uom_factor']
else:
# append a new "standalone" line
for field in ('product_qty', 'product_uom'):
field_val = getattr(order_line, field)
if isinstance(field_val, browse_record):
field_val = field_val.id
o_line[field] = field_val
o_line['uom_factor'] = order_line.product_uom and order_line.product_uom.factor or 1.0
order_lines_to_move += [order_line.id]
allorders = []
orders_info = {}
@ -913,7 +901,7 @@ class purchase_order(osv.osv):
for key, value in order_data['order_line'].iteritems():
del value['uom_factor']
value.update(dict(key))
order_data['order_line'] = [(0, 0, value) for value in order_data['order_line'].itervalues()]
order_data['order_line'] = [(6, 0, order_lines_to_move)]
# create the new order
context.update({'mail_create_nolog': True})
@ -925,7 +913,8 @@ class purchase_order(osv.osv):
# make triggers pointing to the old orders point to the new order
for old_id in old_ids:
self.redirect_workflow(cr, uid, [(old_id, neworder_id)])
self.signal_purchase_cancel(cr, uid, [old_id]) # TODO Is it necessary to interleave the calls?
self.signal_purchase_cancel(cr, uid, [old_id])
return orders_info

View File

@ -66,12 +66,7 @@ class purchase_order_group(osv.osv_memory):
id = mod_obj.read(cr, uid, result, ['res_id'])
allorders = order_obj.do_merge(cr, uid, context.get('active_ids',[]), context)
for new_order in allorders:
proc_ids = proc_obj.search(cr, uid, [('purchase_id', 'in', allorders[new_order])], context=context)
for proc in proc_obj.browse(cr, uid, proc_ids, context=context):
if proc.purchase_id:
proc_obj.write(cr, uid, [proc.id], {'purchase_id': new_order}, context)
return {
'domain': "[('id','in', [" + ','.join(map(str, allorders.keys())) + "])]",
'name': _('Purchase Orders'),

View File

@ -90,7 +90,7 @@ class procurement_rule(osv.osv):
class procurement_order(osv.osv):
_inherit = "procurement.order"
_columns = {
'location_id': fields.many2one('stock.location', 'Procurement Location'),
'location_id': fields.many2one('stock.location', 'Procurement Location', required=True),
'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"),
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"),
}

View File

@ -477,7 +477,13 @@ class stock_picking(osv.osv):
_name = "stock.picking"
_inherit = ['mail.thread']
_description = "Picking List"
_order = "id desc"
_order = "priority desc, date desc, id desc"
def _set_min_date(self, cr, uid, id, field, value, arg, context=None):
move_obj = self.pool.get("stock.move")
move_ids = [move.id for move in self.browse(cr, uid, id, context=context).move_lines]
move_obj.write(cr, uid, move_ids, {'date_expected': value}, context=context)
def get_min_max_date(self, cr, uid, ids, field_name, arg, context=None):
""" Finds minimum and maximum dates for picking.
@return: Dictionary of values
@ -551,6 +557,15 @@ class stock_picking(osv.osv):
res[pick.id] = True
return res
def _get_quant_reserved_exist(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for pick in self.browse(cr, uid, ids, context=context):
res[pick.id] = False
for move in pick.move_lines:
if move.reserved_quant_ids:
res[pick.id] = True
continue
return res
def _get_group_id(self, cr, uid, ids, field_name, args, context=None):
res = {}
@ -586,13 +601,15 @@ class stock_picking(osv.osv):
* Transferred: has been processed, can't be modified or cancelled anymore\n
* Cancelled: has been cancelled, can't be confirmed anymore"""
),
'min_date': fields.function(get_min_max_date, multi="min_max_date",
'priority': fields.selection([('0', 'Low'), ('1', 'Normal'), ('2', 'High')], string='Priority', required=True),
'min_date': fields.function(get_min_max_date, multi="min_max_date", fnct_inv=_set_min_date,
store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Scheduled Date', select=1, help="Scheduled time for the first part of the shipment to be processed"),
'max_date': fields.function(get_min_max_date, multi="min_max_date",
store={'stock.move': (_get_pickings, ['state', 'date_expected'], 20)}, type='datetime', string='Max. Expected Date', select=2, help="Scheduled time for the last part of the shipment to be processed"),
'date': fields.datetime('Commitment Date', help="Date promised for the completion of the transfer order, usually set the time of the order and revised later on.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'date_done': fields.datetime('Date of Transfer', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}),
'quant_reserved_exist': fields.function(_get_quant_reserved_exist, type='boolean', string='Quant already reserved ?', help='technical field used to know if there is already at least one quant reserved on moves of a given picking'),
'partner_id': fields.many2one('res.partner', 'Partner', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'pack_operation_ids': fields.one2many('stock.pack.operation', 'picking_id', string='Related Packing Operations'),
@ -610,6 +627,7 @@ class stock_picking(osv.osv):
'name': lambda self, cr, uid, context: '/',
'state': 'draft',
'move_type': 'one',
'priority' : '1', #normal
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.picking', context=c)
}
@ -813,8 +831,17 @@ class stock_picking(osv.osv):
'''
self.rereserve(cr, uid, picking_ids, context=context)
def do_unreserve(self,cr,uid,picking_ids, context=None):
"""
Will remove all quants for picking in picking_ids
"""
ids_to_free = []
quant_obj = self.pool.get("stock.quant")
for picking in self.browse(cr, uid, picking_ids, context=context):
for move in picking.move_lines:
ids_to_free += [quant.id for quant in move.reserved_quant_ids]
if ids_to_free:
quant_obj.write(cr, uid, ids_to_free, {'reservation_id' : False, 'reservation_op_id': False }, context = context)
def _reserve_quants_ops_move(self, cr, uid, ops, move, qty, create=False, context=None):
"""
@ -1244,6 +1271,7 @@ class stock_move(osv.osv):
'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: previous stock move when chaining them", select=True),
'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
'picking_priority': fields.related('picking_id','priority', type='selection', selection=[('0','Low'),('1','Normal'),('2','High')], string='Picking Priority'),
'note': fields.text('Notes'),
'state': fields.selection([('draft', 'New'),
('cancel', 'Cancelled'),
@ -2115,7 +2143,7 @@ class stock_warehouse(osv.osv):
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
'partner_id': fields.many2one('res.partner', 'Address'),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]),
'code': fields.char('Warehouse Unique Identifier', size=5, required=True, help="Short name used to identify your warehouse"),
'code': fields.char('Short Name', size=5, required=True, help="Short name used to identify your warehouse"),
}
def _default_stock_id(self, cr, uid, context=None):

View File

@ -154,9 +154,6 @@ watch your stock valuation, and track production lots upstream and downstream (b
</record>
<!--
Procurement rules
-->

View File

@ -574,6 +574,7 @@
<field name="min_date"/>
<field name="backorder_id"/>
<field name="state"/>
<field name="priority"/>
<field name="picking_type_id" invisible="1"/>
</tree>
</field>
@ -594,6 +595,7 @@
<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','!=','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,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), ('state','!=','assigned')]}"/>
<field name="state" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
</header>
<sheet>
@ -607,7 +609,7 @@
</group>
<group>
<field name="date"/>
<field name="min_date" readonly="1" attrs="{'invisible': [('min_date','=',False)]}"/>
<field name="min_date" attrs="{'invisible': [('min_date','=',False)]}"/>
<field name="origin" placeholder="e.g. PO0032" class="oe_inline"/>
</group>
</group>
@ -637,6 +639,8 @@
<group>
<field name="move_type"/>
<field name="picking_type_id"/>
<field name="priority"/>
<field name="quant_reserved_exist" invisible="1"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
@ -886,7 +890,7 @@
<group>
<group name="main_grp" string="Details">
<field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, False)"/>
<field name="procure_method"/>
<field name="procure_method" attrs="{'invisible': [('state', '=', 'confirmed')], 'readonly': [('group_id', '=', False)]}"/>
<field name="group_id"/>
<label for="product_uom_qty"/>
<div>
@ -913,6 +917,7 @@
<field name="origin"/>
<field name="picking_id" domain="[('picking_type_id','=',picking_type_id)]"/>
<field name="picking_type_id"/>
<field name="picking_priority"/>
<field name="location_id" groups="stock.group_locations"/>
<field name="create_date" groups="base.group_no_one"/>
</group>
@ -1343,12 +1348,25 @@
</p>
</field>
</record>
<record id="action_picking_type_list" model="ir.actions.act_window">
<field name="name">All Operations</field>
<field name="res_model">stock.picking.type</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">list,form</field>
</record>
<menuitem
action="action_picking_type_form"
id="menu_action_picking_type_form"
parent="menu_stock_warehouse_mgmt" sequence="1"/>
<menuitem
id="menu_pickingtype"
name="Types of Operation"
parent="stock.menu_stock_configuration"
action="action_picking_type_list" />
<!-- Order Point -->
@ -1624,6 +1642,7 @@
<menuitem action="action_orderpoint_form" id="menu_stock_order_points" parent="stock.menu_stock_configuration" sequence="10"/>
<menuitem id="menu_quants" name="Current Inventory" parent="stock.menu_stock_inventory_control" sequence="20" action="quantsact"/>
<menuitem id="menu_procurement_rules" name="Procurement Rules" parent="stock.menu_stock_configuration" action="procrules" groups="base.group_no_one"/>
<menuitem id="menu_pickingtype" name="Types of Operation" parent="stock.menu_stock_configuration" action="action_picking_type_list"/>
@ -1863,5 +1882,24 @@
</form>
</field>
</record>
<record id="do_view_pickings" model="ir.actions.act_window">
<field name="name">Pickings for Groups</field>
<field name="res_model">stock.picking</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('group_id','=',active_id)]</field>
</record>
<record id="procurement_group_form_view_herited" model="ir.ui.view">
<field name="name">procurement.group.form.herited</field>
<field name="model">procurement.group</field>
<field name="inherit_id" ref="procurement.procurement_group_form_view"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/div/button" position="after">
<button name="%(do_view_pickings)d" string="View related pickings" type="action" />
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -394,6 +394,16 @@ class stock_warehouse(osv.osv):
output_loc = wh_output_stock_loc
if warehouse.delivery_steps == 'ship_only':
output_loc = wh_stock_loc
#choose the next available color for the picking types of this warehouse
color = 0
all_used_color = self.pool.get('stock.picking.type').search_read(cr, uid, [('warehouse_id','!=',False), ('color','!=',False)], ['color'], order='color')
for nColor in all_used_color:
if nColor['color'] == color and color < 9:
color += 1
elif nColor['color'] > color or color == 9:
break;
in_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Receptions'),
'warehouse_id': new_id,
@ -401,7 +411,8 @@ class stock_warehouse(osv.osv):
'auto_force_assign': True,
'sequence_id': in_seq_id,
'default_location_src_id': supplier_loc.id,
'default_location_dest_id': input_loc.id}, context=context)
'default_location_dest_id': input_loc.id,
'color' : color}, context=context)
out_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Delivery Orders'),
'warehouse_id': new_id,
@ -409,7 +420,8 @@ class stock_warehouse(osv.osv):
'sequence_id': out_seq_id,
'delivery': True,
'default_location_src_id': output_loc.id,
'default_location_dest_id': customer_loc.id}, context=context)
'default_location_dest_id': customer_loc.id,
'color' : color}, context=context)
int_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Internal Transfers'),
'warehouse_id': new_id,
@ -418,7 +430,8 @@ class stock_warehouse(osv.osv):
'default_location_src_id': wh_stock_loc.id,
'default_location_dest_id': wh_stock_loc.id,
'active': reception_steps != 'one_step',
'pack': False}, context=context)
'pack': False,
'color' : color}, context=context)
pack_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Pack'),
'warehouse_id': new_id,
@ -427,7 +440,8 @@ class stock_warehouse(osv.osv):
'default_location_src_id': wh_pack_stock_loc.id,
'default_location_dest_id': output_loc.id,
'active': delivery_steps == 'pick_pack_ship',
'pack': True}, context=context)
'pack': True,
'color' : color}, context=context)
pick_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Pick'),
'warehouse_id': new_id,
@ -436,7 +450,8 @@ class stock_warehouse(osv.osv):
'default_location_src_id': wh_stock_loc.id,
'default_location_dest_id': wh_pack_stock_loc.id,
'active': delivery_steps != 'ship_only',
'pack': False}, context=context)
'pack': False,
'color' : color}, context=context)
#write picking types on WH
vals = {

View File

@ -33,8 +33,11 @@ This module adds the picking wave option in warehouse management.
'data': ['security/ir.model.access.csv',
'stock_picking_wave_view.xml',
'stock_picking_wave_sequence.xml',
'wizard/picking_to_wave_view.xml'],
'demo': [],
'wizard/picking_to_wave_view.xml',
],
'demo': [
'stock_picking_wave_demo.xml',
],
'installable': True,
'auto_install': False,
}

View File

@ -14,7 +14,6 @@ class stock_picking_wave(osv.osv):
'capacity_uom': fields.many2one('product.uom', 'Unit of Measure', help='The Unity Of Measure of the transport capacity'),
'wave_type_id': fields.many2one('stock.picking.wave.type', 'Picking Wave Type'),
'state': fields.selection([('in_progress', 'Running'), ('done', 'Done'), ('cancel', 'Cancelled')], required=True),
}
_defaults = {

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Add picking wave type
-->
<record id="wave_type_freeze" model="stock.picking.wave.type">
<field name="name">Type Freeze</field>
</record>
<record id="wave_type_dry" model="stock.picking.wave.type">
<field name="name">Type Dry</field>
</record>
<!--
Add picking wave
-->
<record id="stock_picking_wave_dry_1" model="stock.picking.wave">
<field name="name">Picking Dry for John</field>
<field name="capacity">15</field>
<field name="capacity_uom" ref="product.product_uom_ton" />
<field name="state">in_progress</field>
<field name="wave_type_id" ref="wave_type_dry" />
</record>
<record id="stock_picking_wave_freeze_1" model="stock.picking.wave">
<field name="name">Picking Freeze for Mickael</field>
<field name="capacity">600</field>
<field name="capacity_uom" ref="product.product_uom_kgm" />
<field name="state">in_progress</field>
<field name="wave_type_id" ref="wave_type_freeze" />
</record>
<!--
Add picking
-->
<record id="Picking_A" model="stock.picking">
<field name="name">Picking #1</field>
<field name="move_type">one</field>
<field name="priority">2</field>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="wave_id" ref="stock_picking_wave_freeze_1"/>
</record>
<record id="Picking_B" model="stock.picking">
<field name="name">Picking #2</field>
<field name="move_type">one</field>
<field name="state">assigned</field>
<field name="priority">1</field>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="wave_id" ref="stock_picking_wave_dry_1"/>
</record>
<record id="Picking_C" model="stock.picking">
<field name="name">Picking #3</field>
<field name="move_type">one</field>
<field name="state">assigned</field>
<field name="priority">1</field>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="wave_id" ref="stock_picking_wave_freeze_1"/>
</record>
<!-- add Product -->
<record id="product_category_icecream" model="product.category">
<field name="parent_id" ref="product.product_category_all"/>
<field name="name">Ice Cream</field>
</record>
<record id="product_category_dry" model="product.category">
<field name="parent_id" ref="product.product_category_all"/>
<field name="name">Dry</field>
</record>
<record id="product_product_ice_cream_choco" model="product.product">
<field name="name">Ice Cream Chocolate</field>
<field name="default_code">IC-CHOCO</field>
<field name="categ_id" ref="product_category_icecream"/>
<field name="list_price">450.0</field>
<field name="standard_price">300.0</field>
<field name="type">consu</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description_sale">Ice Cream Chocolate with stucks</field>
</record>
<record id="product_product_ice_cream_vani" model="product.product">
<field name="name">Ice Cream Vanilla</field>
<field name="default_code">IC-VANI</field>
<field name="categ_id" ref="product_category_icecream"/>
<field name="list_price">450.0</field>
<field name="standard_price">300.0</field>
<field name="type">consu</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description_sale">Ice Cream Vanilla</field>
</record>
<record id="product_product_dry_specu" model="product.product">
<field name="name">Speculoos</field>
<field name="default_code">DRY-SPEC</field>
<field name="categ_id" ref="product_category_dry"/>
<field name="list_price">150.0</field>
<field name="standard_price">100.0</field>
<field name="type">consu</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description_sale">Speculoos - A belgian speciality</field>
</record>
<!--
Add stock move
-->
<record id="stock_move1" model="stock.move">
<field name="name">A first stock move</field>
<field name="picking_id" ref="Picking_A"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="product_uom" ref="product.product_uom_unit" />
<field name="product_id" ref="product_product_ice_cream_choco"/>
</record>
<record id="stock_move2" model="stock.move">
<field name="name">A second stock move</field>
<field name="picking_id" ref="Picking_A"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="product_uom" ref="product.product_uom_unit" />
<field name="product_id" ref="product_product_ice_cream_vani"/>
</record>
<record id="stock_move3" model="stock.move">
<field name="name">A third stock move</field>
<field name="picking_id" ref="Picking_B"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="product_uom" ref="product.product_uom_unit" />
<!--<field name="product_id" ref="product.product_product_10"/>-->
<field name="product_id" ref="product_product_dry_specu"/>
</record>
<record id="stock_move4" model="stock.move">
<field name="name">A fourth stock move</field>
<field name="picking_id" ref="Picking_C"/>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_dest_id" ref="stock.stock_location_output"/>
<field name="product_uom" ref="product.product_uom_unit" />
<field name="product_id" ref="product_product_ice_cream_vani"/>
</record>
</data>
</openerp>