[MERGE] merged the branch with split of deliveries/receptions (second attempt)

bzr revid: qdp-launchpad@openerp.com-20120515113230-75y0zg9h5goouh83
This commit is contained in:
Quentin (OpenERP) 2012-05-15 13:32:30 +02:00
commit 9c38b33774
23 changed files with 459 additions and 506 deletions

View File

@ -177,28 +177,13 @@
<record id="view_picking_withcarrier_out_form" model="ir.ui.view">
<field name="name">delivery.stock.picking_withcarrier.out.form.view</field>
<field name="type">form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="model">stock.picking.out</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field name="carrier_id"/>
<field name="carrier_tracking_ref"/>
<field name="number_of_packages"/>
<field name="weight"/>
<field name="weight_net"/>
</field>
</field>
</record>
<record id="view_picking_withweight_in_form" model="ir.ui.view">
<field name="name">stock.picking_withweight.in.form.view</field>
<field name="type">form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_in_form"/>
<field name="arch" type="xml">
<field name="type" position="after">
<field name="weight"/>
<field name="weight_net"/>
</field>
</field>
</record>
@ -218,7 +203,7 @@
<record id="action_picking_tree4" model="ir.actions.act_window">
<field name="name">Picking to be invoiced</field>
<field name="res_model">stock.picking</field>
<field name="res_model">stock.picking.out</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@ -228,39 +213,13 @@
<field name="search_view_id" ref="stock.view_picking_out_search"/>
</record>
<record id="view_picking_withcarrier_out_move_form" model="ir.ui.view">
<field name="name">delivery.stock.picking_withcarrier.out.move.form.view</field>
<field name="type">form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<field name="weight"/>
<field name="weight_net"/>
</xpath>
</field>
</record>
<record id="view_picking_withweight_in_move_form" model="ir.ui.view">
<field name="name">stock.picking_withweight.in.move.form.view</field>
<field name="type">form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_in_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<field name="weight"/>
<field name="weight_net"/>
</xpath>
</field>
</record>
<record id="view_picking_withweight_internal_move_form" model="ir.ui.view">
<field name="name">stock.picking_withweight.internal.move.form.view</field>
<field name="type">form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<xpath expr="/form/sheet/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
<field name="weight"/>
<field name="weight_net"/>
</xpath>
@ -316,7 +275,7 @@
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='Products']/group/button[@string='Create Invoice']" position="after">
<xpath expr="/form/div[@class='oe_form_topbar']/button[@string='Create Invoice']" position="after">
<button name="%(report_shipping)d" string="Delivery Order" states="done" type="action" icon="gtk-print"/>
</xpath>
</field>

View File

@ -173,5 +173,34 @@ class stock_move(osv.osv):
stock_move()
# Redefinition of the new fields in order to update the model stock.picking.out in the orm
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
# the bug is fixed
class stock_picking_out(osv.osv):
_inherit = 'stock.picking.out'
def _cal_weight(self, cr, uid, ids, name, args, context=None):
return self.pool.get('stock.picking')._cal_weight(cr, uid, ids, name, args, context=context)
def _get_picking_line(self, cr, uid, ids, context=None):
return self.pool.get('stock.picking')._get_picking_line(cr, uid, ids, context=context)
_columns = {
'carrier_id':fields.many2one("delivery.carrier","Carrier"),
'volume': fields.float('Volume'),
'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
store={
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
}),
'weight_net': fields.function(_cal_weight, type='float', string='Net Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_weight',
store={
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
}),
'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32),
'number_of_packages': fields.integer('Number of Packages'),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -174,7 +174,7 @@ class purchase_order(osv.osv):
'validator' : fields.many2one('res.users', 'Validated by', readonly=True),
'notes': fields.text('Notes'),
'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 picking list that have been generated for this purchase"),
'picking_ids': fields.one2many('stock.picking.in', 'purchase_id', 'Picking List', readonly=True, help="This is the list of incomming shipments 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', type='float'),
'invoiced': fields.function(_invoiced, string='Invoiced & Paid', type='boolean', help="It indicates that an invoice has been paid"),
@ -442,9 +442,9 @@ class purchase_order(osv.osv):
'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.in'),
'origin': order.name + ((order.origin and (':' + order.origin)) or ''),
'date': order.date_order,
'type': 'in',
'partner_id': order.dest_address_id.id or order.partner_id.id,
'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none',
'type': 'in',
'purchase_id': order.id,
'company_id': order.company_id.id,
'move_lines' : [],

View File

@ -126,4 +126,13 @@ class stock_partial_picking(osv.osv_memory):
'currency': move.picking_id.purchase_id.pricelist_id.currency_id.id}
return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
# Redefinition of the new field in order to update the model stock.picking.in in the orm
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
# the bug is fixed
class stock_picking_in(osv.osv):
_inherit = 'stock.picking.in'
_columns = {
'purchase_id': fields.many2one('purchase.order', 'Purchase Order',
ondelete='set null', select=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,7 +19,7 @@
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<field name="auto_picking" position="after">
<field name="purchase_id"/>
<field name="purchase_id" invisible="1"/>
</field>
</field>
</record>
@ -28,9 +28,9 @@
domain="[('purchase_id', '=', active_id)]"
id="act_purchase_order_2_stock_picking"
name="Receptions"
res_model="stock.picking"
res_model="stock.picking.in"
src_model="purchase.order"
context="{'default_purchase_id': active_id, 'contact_display': 'partner'}" />
context="{'default_purchase_id': active_id, 'contact_display': 'partner', 'default_type': 'in'}" />
<record id="action_picking_in_tree_view" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
@ -47,28 +47,28 @@
<record id="stock_picking_in_inherit_purchase" model="ir.ui.view">
<field name="name">Incoming Picking Inherited</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.in</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock.view_picking_in_form"/>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<field name="backorder_id" position="after">
<xpath expr="/form/sheet/group/group/field[@name='date']" position="before">
<field name="purchase_id"/>
</field>
</xpath>
</field>
</record>
<!-- Picking to Invoice -->
<record id="view_picking_in_search_picking_to_invoice" model="ir.ui.view">
<field name="name">stock.picking.in.search</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.in</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Picking to Invoice">
<group col="8" colspan="4">
<filter icon="terp-check" name="available" string="Available"
domain="[('state','=','assigned')]" help="Incoming Shipments Available"/>
<filter icon="terp-dialog-close" name="done" string="Done"
domain="[('state','=','done')]" help="Incoming Shipments already processed"/>
<filter icon="terp-dialog-close" name="done" string="Received"
domain="[('state','=','done')]" help="Incoming Shipments already Received"/>
<separator orientation="vertical"/>
<filter icon="terp-accessories-archiver-minus" string="Back Orders"
domain="[('backorder_id', '!=', False)]" help="Is a Back Order"/>
@ -89,7 +89,7 @@
<separator orientation="vertical"/>
<filter string="Order Date" icon="terp-go-month"
domain="[]" context="{'group_by':'date'}"/>
<filter string="Expected Date" icon="terp-go-month"
<filter string="Scheduled Date" icon="terp-go-month"
domain="[]" context="{'group_by':'min_date'}"/>
<separator orientation="vertical"/>
<filter string="Journal" icon="terp-folder-orange"

View File

@ -238,7 +238,7 @@ class sale_order(osv.osv):
'order_line': fields.one2many('sale.order.line', 'order_id', 'Order Lines', readonly=True, states={'draft': [('readonly', False)]}),
'invoice_ids': fields.many2many('account.invoice', 'sale_order_invoice_rel', 'order_id', 'invoice_id', 'Invoices', readonly=True, help="This is the list of invoices that have been generated for this sales order. The same sales order may have been invoiced in several times (by line for example)."),
'picking_ids': fields.one2many('stock.picking', 'sale_id', 'Related Picking', readonly=True, help="This is a list of picking that has been generated for this sales order."),
'picking_ids': fields.one2many('stock.picking.out', 'sale_id', 'Related Picking', readonly=True, help="This is a list of delivery orders that has been generated for this sales order."),
'shipped': fields.boolean('Delivered', readonly=True, help="It indicates that the sales order has been delivered. This field is updated only after the scheduler(s) have been launched."),
'picked_rate': fields.function(_picked_rate, string='Picked', type='float'),
'invoiced_rate': fields.function(_invoiced_rate, string='Invoiced', type='float'),

View File

@ -242,8 +242,21 @@
<page string="History">
<separator colspan="4" string="Invoices"/>
<field colspan="4" name="invoice_ids" nolabel="1" context="{'form_view_ref':'account.invoice_form'}"/>
<separator colspan="4" string="Packings"/>
<field colspan="4" name="picking_ids" nolabel="1"/>
<separator colspan="4" string="Delivery Orders"/>
<field colspan="4" name="picking_ids" nolabel="1" context="{'default_type': 'out'}">
<tree colors="blue:state == 'draft';grey:state == 'cancel';red:state not in ('cancel', 'done') and min_date &lt; current_date" string="Delivery Orders">
<field name="name"/>
<field name="partner_id"/>
<field name="origin"/>
<field name="date"/>
<field name="min_date"/>
<field name="backorder_id"/>
<field name="invoice_state"/>
<field name="stock_journal_id" widget="selection"/>
<field name="state"/>
<button name="action_process" states="assigned" string="Deliver" type="object" icon="gtk-go-forward" context="{'default_type': 'out'}"/>
</tree>
</field>
</page>
</notebook>
</sheet>

View File

@ -186,4 +186,13 @@ class stock_picking(osv.osv):
})
return result
# Redefinition of the new field in order to update the model stock.picking.out in the orm
# FIXME: this is a temporary workaround because of a framework bug (ref: lp996816). It should be removed as soon as
# the bug is fixed
class stock_picking_out(osv.osv):
_inherit = 'stock.picking.out'
_columns = {
'sale_id': fields.many2one('sale.order', 'Sale Order',
ondelete='set null', select=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -18,7 +18,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='order_line']/form/notebook/page/field[@name='delay']" position="after">
<xpath expr="/form/sheet/notebook/page/field[@name='order_line']/form/notebook/page/field[@name='delay']" position="after">
<field name="analytics_id" domain="[('plan_id','&lt;&gt;',False)]" groups="analytic.group_analytic_accounting"/>
</xpath>
</field>

View File

@ -72,8 +72,8 @@ Thanks to the double entry management, the inventory controlling is powerful and
'wizard/stock_return_picking_view.xml',
"stock_workflow.xml",
"stock_incoterms.xml",
"stock_view.xml",
"stock_report.xml",
"stock_view.xml",
"stock_sequence.xml",
"product_data.xml",
"product_view.xml",

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<document filename="Packing List.pdf">
<template title="Packing List" author="OpenERP S.A.(sales@openerp.com)" allowSplitting="20">
<template pageSize="(595.0,842.0)" title="Packing List" author="OpenERP S.A.(sales@openerp.com)" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="0.0" y1="57.0" width="538" height="728"/>
</pageTemplate>
@ -31,7 +31,6 @@
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
@ -52,14 +51,12 @@
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
</blockTableStyle>
<blockTableStyle id="Move_Line_Header">
<blockAlignment value="LEFT"/>
@ -161,7 +158,9 @@
<blockTable colWidths="269.0,269.0" style="Table_Address_detail">
<tr>
<td>
<para style="terp_default_Bold_9">Shipping Address :</para>
<para style="terp_default_Bold_9">Supplier Address : [[ (picking.type == 'in' or removeParentNode('para')) and '' ]]</para>
<para style="terp_default_Bold_9">Customer Address : [[ (picking.type == 'out' or removeParentNode('para')) and '' ]]</para>
<para style="terp_default_Bold_9">Warehouse Address : [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]]</para>
<para style="terp_default_9">[[ (picking.partner_id and picking.partner_id.id and picking.partner_id.title.name) or '' ]] [[ picking.partner_id and picking.partner_id.id and picking.partner_id.name ]]</para>
<para style="terp_default_9">[[ picking.partner_id and display_address(picking.partner_id,'delivery') ]]</para>
</td>
@ -181,16 +180,16 @@
<blockTable colWidths="538.0" style="Table_Title_String">
<tr>
<td>
<para style="terp_header">Packing List: [[ (picking.type == 'out' or removeParentNode('para')) and '' ]] [[ picking.name ]] </para>
<para style="terp_header">Reception: [[ (picking.type == 'in' or removeParentNode('para')) and '' ]] [[ picking.name ]]</para>
<para style="terp_header">Picking List: [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]] [[ picking.name ]]</para>
<para style="terp_header">Delivery Order : [[ (picking.type == 'out' or removeParentNode('para')) and '' ]] [[ picking.name ]]</para>
<para style="terp_header">Incoming Shipment : [[ (picking.type == 'in' or removeParentNode('para')) and '' ]] [[ picking.name ]]</para>
<para style="terp_header">Internal Shipment : [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]] [[ picking.name ]]</para>
</td>
</tr>
</blockTable>
<para style="terp_default_5cm_Above_Space">
<font color="white"> </font>
</para>
<blockTable colWidths="100.0,110.0,130.0,120.0,60.0" style="Header_Order_Reference_Tbl">
<blockTable colWidths="100.0,100.0,108.0,107.0,109.0" style="Header_Order_Reference_Tbl">
<tr>
<td>
<para style="terp_tblheader_General_Centre">Journal</para>
@ -209,7 +208,7 @@
</td>
</tr>
</blockTable>
<blockTable colWidths="100.0,110.0,130.0,120.0,60.0" style="Content_Order_Reference_Table">
<blockTable colWidths="100.0,100.0,108.0,107.0,109.0" style="Content_Order_Reference_Table">
<tr>
<td>
<para style="terp_default_Centre_8">[[ picking.stock_journal_id.name]]</para>
@ -240,7 +239,7 @@
<para style="terp_tblheader_Details_Centre">Lot</para>
</td>
<td>
<para style="terp_tblheader_Details">State</para>
<para style="terp_tblheader_Details_Centre">State</para>
</td>
<td>
<para style="terp_tblheader_Details_Right">Location</para>
@ -287,7 +286,9 @@
<para style="terp_default_Centre_9">[[ (move_lines.prodlot_id and move_lines.prodlot_id.name) or '' ]]</para>
</td>
<td>
<para style="terp_default_9">[[ move_lines.state ]]</para>
<para style="terp_default_9">[[ (picking.type == 'in' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Received' or move_lines.state]]</para>
<para style="terp_default_9">[[ (picking.type == 'out' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Delivered' or move_lines.state]]</para>
<para style="terp_default_9">[[ (picking.type == 'internal' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Transferred' or move_lines.state]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ (move_lines.location_id and move_lines.location_id.name) or '' ]] </para>

View File

@ -38,7 +38,7 @@ class report_stock_move(osv.osv):
'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'picking_id':fields.many2one('stock.picking', 'Packing', readonly=True),
'picking_id':fields.many2one('stock.picking', 'Shipment', readonly=True),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('other', 'Others')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
'location_id': fields.many2one('stock.location', 'Source Location', readonly=True, select=True, help="Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', readonly=True, select=True, help="Location where the system will stock the finished products."),

View File

@ -117,7 +117,7 @@
<filter name="group_categ_id" string="Product Category" icon="terp-stock_symbol-selection" context="{'group_by':'categ_id'}"/>
<filter name="group_product" string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/>
<separator orientation="vertical"/>
<filter name="group_picking" string="Packing" icon="terp-accessories-archiver" context="{'group_by':'picking_id'}"/>
<filter name="group_picking" string="Shipment" icon="terp-accessories-archiver" context="{'group_by':'picking_id'}"/>
<separator orientation="vertical"/>
<filter string="Source Location" name="src_location" icon="terp-gtk-jump-to-rtl" context="{'group_by':'location_id'}"/>
<filter string="Dest. Location" name="dest_location" icon="terp-gtk-jump-to-ltr" context="{'group_by':'location_dest_id'}"/>

View File

@ -19,6 +19,7 @@
#
##############################################################################
from lxml import etree
from datetime import datetime
from dateutil.relativedelta import relativedelta
import time
@ -605,7 +606,7 @@ class stock_picking(osv.osv):
res[pick]['min_date'] = dt1
res[pick]['max_date'] = dt2
return res
def create(self, cr, user, vals, context=None):
if ('name' not in vals) or (vals.get('name')=='/'):
seq_obj_name = 'stock.picking.' + vals['type']
@ -616,52 +617,52 @@ class stock_picking(osv.osv):
return new_id
_columns = {
'name': fields.char('Reference', size=64, select=True),
'origin': fields.char('Origin', size=64, help="Reference of the document that produced this picking.", select=True),
'backorder_id': fields.many2one('stock.picking', 'Back Order of', help="If this picking was split this field links to the picking that contains the other part that has been processed already.", select=True),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
'note': fields.text('Notes'),
'stock_journal_id': fields.many2one('stock.journal','Stock Journal', select=True),
'location_id': fields.many2one('stock.location', 'Location', help="Keep empty if you produce at the location where the finished products are needed." \
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'origin': fields.char('Origin', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
'backorder_id': fields.many2one('stock.picking', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Shipping type specify, goods coming in or going out."),
'note': fields.text('Notes', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'stock_journal_id': fields.many2one('stock.journal','Stock Journal', select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'location_id': fields.many2one('stock.location', 'Location', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Keep empty if you produce at the location where the finished products are needed." \
"Set a location if you produce at a fixed location. This can be a partner location " \
"if you subcontract the manufacturing operations.", select=True),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location',help="Location where the system will stock the finished products.", select=True),
'move_type': fields.selection([('direct', 'Partial Delivery'), ('one', 'All at once')], 'Delivery Method', required=True, help="It specifies goods to be delivered all at once or by direct delivery"),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Location where the system will stock the finished products.", select=True),
'move_type': fields.selection([('direct', 'Partial'), ('one', 'All at once')], 'Delivery Method', required=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="It specifies goods to be deliver partially or all at once"),
'state': fields.selection([
('draft', 'New'),
('draft', 'Draft'),
('auto', 'Waiting Another Operation'),
('confirmed', 'Waiting Availability'),
('assigned', 'Ready to Process'),
('done', 'Done'),
('cancel', 'Cancelled'),
], 'State', readonly=True, select=True,
help="* Draft: not confirmed yet and will not be scheduled until confirmed\n"\
"* Confirmed: still waiting for the availability of products\n"\
"* Available: products reserved, simply waiting for confirmation.\n"\
"* Waiting: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n"\
"* Done: has been processed, can't be modified or cancelled anymore\n"\
"* Cancelled: has been cancelled, can't be confirmed anymore"),
('assigned', 'Ready to Transfer'),
('done', 'Transferred'),
('cancel', 'Cancelled'),], 'State', readonly=True, select=True, help="""
* Draft: not confirmed yet and will not be scheduled until confirmed\n
* Waiting Another Operation: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n
* Waiting Availability: still waiting for the availability of products\n
* Ready to Transfer: products reserved, simply waiting for confirmation.\n
* 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, fnct_inv=_set_minimum_date, multi="min_max_date",
store=True, type='datetime', string='Expected Date', select=1, help="Expected date for the picking to be processed"),
'date': fields.datetime('Order Date', help="Date of Order", select=True),
'date_done': fields.datetime('Date Done', help="Date of Completion"),
store=True, type='datetime', string='Scheduled Date', select=1, help="Scheduled date for the shipment to be processed"),
'date': fields.datetime('Order Date', help="Date of order", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'date_done': fields.datetime('Date Done', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date",
store=True, type='datetime', string='Max. Expected Date', select=2),
'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}),
'auto_picking': fields.boolean('Auto-Picking'),
'partner_id': fields.many2one('res.partner', 'Partner'),
'auto_picking': fields.boolean('Auto-Picking', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'partner_id': fields.many2one('res.partner', 'Partner', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'invoice_state': fields.selection([
("invoiced", "Invoiced"),
("2binvoiced", "To Be Invoiced"),
("none", "Not Applicable")], "Invoice Control",
select=True, required=True, readonly=True, states={'draft': [('readonly', False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
}
_defaults = {
'name': lambda self, cr, uid, context: '/',
'state': 'draft',
'move_type': 'direct',
'type': 'in',
'type': 'internal',
'invoice_state': 'none',
'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)
@ -671,21 +672,14 @@ class stock_picking(osv.osv):
]
def action_process(self, cr, uid, ids, context=None):
if context is None: context = {}
context = dict(context, active_ids=ids, active_model=self._name)
partial_id = self.pool.get("stock.partial.picking").create(cr, uid, {}, context=context)
return {
'name':_("Products to Process"),
'view_mode': 'form',
'view_id': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.partial.picking',
'res_id': partial_id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context': context,
'nodestroy': True,
}
def copy(self, cr, uid, id, default=None, context=None):
@ -740,6 +734,9 @@ class stock_picking(osv.osv):
@return: True
"""
for pick in self.browse(cr, uid, ids):
if pick.state == 'draft':
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_confirm', cr)
move_ids = [x.id for x in pick.move_lines if x.state == 'confirmed']
if not move_ids:
raise osv.except_osv(_('Warning !'),_('Not enough stock, unable to reserve the products.'))
@ -821,6 +818,10 @@ class stock_picking(osv.osv):
ok = True
for pick in self.browse(cr, uid, ids):
mt = pick.move_type
# incomming shipments are always set as available if they aren't chained
if pick.type == 'in':
if all([x.state != 'waiting' for x in pick.move_lines]):
return True
for move in pick.move_lines:
if (move.state in ('confirmed', 'draft')) and (mt == 'one'):
return False
@ -873,7 +874,7 @@ class stock_picking(osv.osv):
def _get_partner_to_invoice(self, cr, uid, picking, context=None):
""" Gets the partner that will be invoiced
Note that this function is inherited in the sale module
Note that this function is inherited in the sale and purchase modules
@param picking: object of the picking for which we are selecting the partner to invoice
@return: object of the partner to invoice
"""
@ -1630,9 +1631,17 @@ class stock_move(osv.osv):
'move_history_ids2': fields.many2many('stock.move', 'stock_move_history_ids', 'child_id', 'parent_id', 'Move History (parent moves)'),
'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
'note': fields.text('Notes'),
'state': fields.selection([('draft', 'New'), ('waiting', 'Waiting Another Move'), ('confirmed', 'Waiting Availability'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
help='When the stock move is created it is in the \'Draft\' state.\n After that, it is set to \'Not Available\' state if the scheduler did not find the products.\n When products are reserved it is set to \'Available\'.\n When the picking is done the state is \'Done\'.\
\nThe state is \'Waiting\' if the move is waiting for another one.'),
'state': fields.selection([('draft', 'New'),
('waiting', 'Waiting Another Move'),
('confirmed', 'Waiting Availability'),
('assigned', 'Available'),
('done', 'Done'),
('cancel', 'Cancelled')], 'State', readonly=True, select=True,
help= "* New: When the stock move is created and not yet confirmed.\n"\
"* Waiting Another Move: This state can be seen when a move is waiting for another one, for example in a chained flow.\n"\
"* Waiting Availability: This state is reached when the procurement resolution is not straight forward. It may need the scheduler to run, a component to me manufactured...\n"\
"* Available: When products are reserved, it is set to \'Available\'.\n"\
"* Done: When the shipment is processed, the state is \'Done\'."),
'price_unit': fields.float('Unit Price', digits_compute= dp.get_precision('Account'), help="Technical field used to record the product cost set by the user during a picking confirmation (when average price costing method is used)"),
'price_currency_id': fields.many2one('res.currency', 'Currency for average price', help="Technical field used to record the currency chosen by the user during a picking confirmation (when average price costing method is used)"),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
@ -2110,11 +2119,11 @@ class stock_move(osv.osv):
return True
if context is None:
context = {}
pickings = {}
pickings = set()
for move in self.browse(cr, uid, ids, context=context):
if move.state in ('confirmed', 'waiting', 'assigned', 'draft'):
if move.picking_id:
pickings[move.picking_id.id] = True
pickings.add(move.picking_id.id)
if move.move_dest_id and move.move_dest_id.state == 'waiting':
self.write(cr, uid, [move.move_dest_id.id], {'state': 'assigned'})
if context.get('call_unlink',False) and move.move_dest_id.picking_id:
@ -2122,7 +2131,7 @@ class stock_move(osv.osv):
wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
if not context.get('call_unlink',False):
for pick in self.pool.get('stock.picking').browse(cr, uid, pickings.keys()):
for pick in self.pool.get('stock.picking').browse(cr, uid, list(pickings), context=context):
if all(move.state == 'cancel' for move in pick.move_lines):
self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'})
@ -2822,4 +2831,86 @@ class stock_warehouse(osv.osv):
stock_warehouse()
#----------------------------------------------------------
# "Empty" Classes that are used to vary from the original stock.picking (that are dedicated to the internal pickings)
# in order to offer a different usability with different views, labels, available reports/wizards...
#----------------------------------------------------------
class stock_picking_in(osv.osv):
_name = "stock.picking.in"
_inherit = "stock.picking"
_table = "stock_picking"
_description = "Incomming Shipments"
def check_access_rights(self, cr, uid, operation, raise_exception=True):
#override in order to redirect the check of acces rights on the stock.picking object
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
def check_access_rule(self, cr, uid, ids, operation, context=None):
#override in order to redirect the check of acces rules on the stock.picking object
return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
#override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
#instead of it's own workflow (which is not existing)
return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
_columns = {
'state': fields.selection(
[('draft', 'Draft'),
('auto', 'Waiting Another Operation'),
('confirmed', 'Waiting Availability'),
('assigned', 'Ready to Receive'),
('done', 'Received'),
('cancel', 'Cancelled'),],
'State', readonly=True, select=True,
help="""* Draft: not confirmed yet and will not be scheduled until confirmed\n
* Waiting Another Operation: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n
* Waiting Availability: still waiting for the availability of products\n
* Ready to Receive: products reserved, simply waiting for confirmation.\n
* Received: has been processed, can't be modified or cancelled anymore\n
* Cancelled: has been cancelled, can't be confirmed anymore"""),
}
_defaults = {
'type': 'in',
}
class stock_picking_out(osv.osv):
_name = "stock.picking.out"
_inherit = "stock.picking"
_table = "stock_picking"
_description = "Delivery Orders"
def check_access_rights(self, cr, uid, operation, raise_exception=True):
#override in order to redirect the check of acces rights on the stock.picking object
return self.pool.get('stock.picking').check_access_rights(cr, uid, operation, raise_exception=raise_exception)
def check_access_rule(self, cr, uid, ids, operation, context=None):
#override in order to redirect the check of acces rules on the stock.picking object
return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
#override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
#instead of it's own workflow (which is not existing)
return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
_columns = {
'state': fields.selection(
[('draft', 'Draft'),
('auto', 'Waiting Another Operation'),
('confirmed', 'Waiting Availability'),
('assigned', 'Ready to Deliver'),
('done', 'Delivered'),
('cancel', 'Cancelled'),],
'State', readonly=True, select=True,
help="""* Draft: not confirmed yet and will not be scheduled until confirmed\n
* Waiting Another Operation: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n
* Waiting Availability: still waiting for the availability of products\n
* Ready to Deliver: products reserved, simply waiting for confirmation.\n
* Delivered: has been processed, can't be modified or cancelled anymore\n
* Cancelled: has been cancelled, can't be confirmed anymore"""),
}
_defaults = {
'type': 'out',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -18,11 +18,7 @@
-
!record {model: stock.location, id: location_convenience_shop}:
name: Convenient Store
chained_auto_packing: auto
chained_location_type: fixed
usage: supplier
chained_location_id: location_refrigerator
location_id: stock_location_suppliers
-
!record {model: stock.warehouse, id: warehouse_icecream}:
name: Ice Cream Shop

View File

@ -2,7 +2,9 @@
<openerp>
<data>
<report auto="False" id="report_product_history" model="product.product" name="stock.product.history" string="Stock Level Forecast"/>
<report id="report_picking_list" model="stock.picking" name="stock.picking.list" string="Packing list" rml="stock/report/picking.rml"/>
<report id="report_picking_list" model="stock.picking" name="stock.picking.list" string="Picking Slip" rml="stock/report/picking.rml"/>
<report id="report_picking_list_in" model="stock.picking.in" name="stock.picking.list" string="Receipt Slip" rml="stock/report/picking.rml"/>
<report id="report_picking_list_out" model="stock.picking.out" name="stock.picking.list" string="Delivery Slip" rml="stock/report/picking.rml"/>
<report id="report_move_labels" model="stock.move" name="stock.move.label" string="Item Labels" xml="stock/report/lot_move_label.xml" xsl="stock/report/lot_move_label.xsl"/>
<report auto="False" id="report_location_overview" model="stock.location" name="lot.stock.overview" string="Location Inventory Overview" rml="stock/report/lot_overview.rml"/>
<report id="report_location_overview_all" model="stock.location" name="lot.stock.overview_all" string="Location Content" rml="stock/report/lot_overview_all.rml"/>

View File

@ -654,6 +654,16 @@
<menuitem action="action_warehouse_form" id="menu_action_warehouse_form" groups="stock.group_locations"
parent="menu_stock_configuration" sequence="1"/>
<!--
STOCK PICKING
-->
<!--
#
# Defaults and Internal Pickings
#
-->
<record model="ir.ui.view" id="stock_picking_calendar">
<field name="name">stock.picking.calendar</field>
<field name="model">stock.picking</field>
@ -667,6 +677,7 @@
</calendar>
</field>
</record>
<record id="vpicktree" model="ir.ui.view">
<field name="name">stock.picking.tree</field>
<field name="model">stock.picking</field>
@ -685,13 +696,28 @@
</tree>
</field>
</record>
<record id="view_picking_form" model="ir.ui.view">
<field name="name">stock.picking.form</field>
<field name="model">stock.picking</field>
<field name="type">form</field>
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<form string="Internal Picking List">
<form layout="manual">
<div class="oe_form_topbar">
<button name="draft_force_assign" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
<button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" icon="gtk-media-play"/>
<!-- <button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/> -->
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="action_process" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" icon="gtk-go-forward"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" icon="terp-gtk-go-back-rtl" />
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action" icon="terp-gtk-go-back-rtl" />
<button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel" icon="gtk-cancel"/>
<div class="oe_right">
<field name="state" nolabel="1" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
</div>
</div>
<sheet string="Internal Picking List" layout="auto">
<group colspan="4" col="6">
<group colspan="4" col="4">
<field name="name" readonly="1"/>
@ -795,16 +821,6 @@
</group>
</form>
</field>
<group col="10" colspan="4">
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" statusbar_colors='{"auto":"blue", "confirmed":"blue"}'/>
<button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel" icon="gtk-cancel"/>
<button name="draft_force_assign" states="draft" string="Process Later" type="object" icon="gtk-apply"/>
<button name="draft_validate" states="draft" string="Process Now" type="object" icon="gtk-media-play"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="action_process" states="assigned" string="Process" groups="stock.group_stock_user" type="object" icon="gtk-go-forward"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" icon="terp-gtk-go-back-rtl" />
</group>
</page>
<page string="Additional info">
<field name="auto_picking"/>
@ -817,42 +833,67 @@
<field colspan="4" name="note" nolabel="1"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="view_stock_picking_filter" model="ir.ui.view">
<field name="name">stock.picking.list.select</field>
<record id="view_picking_internal_search" model="ir.ui.view">
<field name="name">stock.picking.internal.search</field>
<field name="model">stock.picking</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Stock Picking">
<search string="Internal Picking List">
<group>
<filter icon="terp-check" name="available" string="Available" domain="[('state','=','assigned')]" help="Available Pickings"/>
<filter icon="terp-camera_test" string="Confirmed" domain="[('state','=','confirmed')]" help="Confirmed Pickings"/>
<filter icon="terp-check" string="Ready" domain="[('state','=','assigned')]" help="Assigned Internal Moves"/>
<filter icon="terp-camera_test" name="confirmed" string="Waiting" domain="[('state','=','confirmed')]" help="Confirmed Internal Moves" />
<filter icon="terp-dialog-close" name="done" string="Done" domain="[('state','=','done')]" help="Pickings already processed"/>
<separator orientation="vertical"/>
<filter icon="terp-accessories-archiver-minus" string="Back Orders" domain="[('backorder_id', '!=', False)]" help="Is a Back Order"/>
<separator orientation="vertical"/>
<filter icon="terp-dolar" name="to_invoice" string="To Invoice" domain="[('invoice_state','=','2binvoiced')]" help="Internal Pickings to invoice"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="partner_id"/>
<field name="origin"/>
<field name="stock_journal_id" widget="selection"/>
<field name="company_id" widget="selection"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
<filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'min_date'}"/>
<separator orientation="vertical"/>
<filter string="Origin" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
<separator orientation="vertical" />
<filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
<separator orientation="vertical" />
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'stock_journal_id'}" />
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'stock_journal_id'}"/>
</group>
</search>
</field>
</record>
<record id="action_picking_tree6" model="ir.actions.act_window">
<field name="name">Internal Moves</field>
<field name="res_model">stock.picking</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="domain">[('type','=','internal')]</field>
<field name="context">{'contact_display': 'partner_address', 'search_default_available': 1}</field>
<field name="search_view_id" ref="view_picking_internal_search"/>
<field name="help">Internal Moves display all inventory operations you have to perform in your warehouse. All operations can be categorized into stock journals, so that each worker has his own list of operations to perform in his own journal. Most operations are prepared automatically by OpenERP according to your preconfigured logistics rules, but you can also record manual stock operations.</field>
</record>
<record model="ir.actions.act_window.view" id="action_picking_tree6_tree_view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="vpicktree"/>
<field name="act_window_id" ref="action_picking_tree6"/>
</record>
<record model="ir.actions.act_window.view" id="action_picking_tree6_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_picking_form"/>
<field name="act_window_id" ref="action_picking_tree6"/>
</record>
<!--
#
# Sending Products
@ -878,137 +919,34 @@
</record>
<record id="view_picking_out_form" model="ir.ui.view">
<field name="name">stock.picking.out.form</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.out</field>
<field name="inherit_id" ref="view_picking_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Delivery Orders">
<group col="6" colspan="4">
<group colspan="4" col="4">
<field name="name" readonly="1"/>
<field name="origin" readonly="1"/>
<field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4"/>
<field name="invoice_state"/>
<field name="backorder_id" readonly="1"/>
</group>
<group colspan="2" col="2">
<field name="date"/>
<field name="min_date" readonly="1"/>
<field name="stock_journal_id" widget="selection"/>
</group>
</group>
<notebook colspan="4">
<page string="Products">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" context="{'address_out_id': partner_id, 'picking_type': type}" >
<tree colors="grey:scrapped==True" string="Stock Moves">
<field name="product_id"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom" string="UoM" groups="product.group_uom"/>
<field name="product_uos" groups="product.group_uos"/>
<button name="%(stock.move_scrap)d"
string="Scrap Products" type="action"
icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned" />
<field name="scrapped" invisible="1"/>
<field name="prodlot_id" groups="stock.group_production_lot"/>
<button name="%(track_line)d" string="Split in production lots" type="action"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('prodlot_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed"
groups="stock.group_production_lot"/>
<field name="tracking_id" groups="stock.group_tracking_lot"/>
<button name="setlast_tracking" string="Put in current pack" type="object"
attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
groups="stock.group_tracking_lot"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed"/>
<button name="%(split_into)d" string="Put in a new pack" type="action"
icon="terp-stock_effects-object-colorize"
groups="product.group_stock_packaging"
states="draft,assigned,confirmed"/>
<field name="location_id"/>
<field name="date"/>
<field name="state"/>
<button name="%(action_partial_move_server)d" string="Process" type="action" states="confirmed,assigned" icon="gtk-go-forward"/>
</tree>
<form string="Stock Moves">
<group colspan="2" col="4">
<separator colspan="4" string="Move Information"/>
<field name="name" invisible="1" colspan="4" />
<field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, parent.partner_id)" colspan="4" />
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" colspan="3" />
<button name="%(stock.move_scrap)d"
string="Scrap" type="action"
icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned" colspan="1"/>
<field name="product_uom" string="Unit Of Measure" colspan="4" groups="product.group_uom"/>
<field name="product_uos_qty" groups="product.group_uos" on_change="onchange_uos_quantity(product_id, product_uos_qty, product_uos, product_uom)" colspan="4" />
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" colspan="4" />
<field name="product_packaging" groups="product.group_stock_packaging" domain="[('product_id','=',product_id)]" colspan="4" />
</group>
<group colspan="2" col="2">
<separator string="Locations" colspan="2" />
<field name="location_id" domain="[('usage','=','internal')]" />
<field name="location_dest_id" domain="[('usage','&lt;&gt;','view')]" />
</group>
<group colspan="2" col="2">
<separator string="Dates" colspan="2" />
<field name="create_date" invisible="1"/>
<field name="date"/>
<field name="date_expected" on_change="onchange_date(date,date_expected)"/>
</group>
<group colspan="2" col="4">
<separator string="Traceability" colspan="4" groups="stock.group_tracking_lot"/>
<field name="tracking_id" groups="stock.group_tracking_lot" colspan="3" />
<button name="%(split_into)d" string="New Pack" type="action"
groups="stock.group_tracking_lot"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed" colspan="1"/>
<field name="prodlot_id" groups="stock.group_production_lot"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=?',product_id)]"
on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id, product_uom)" colspan="3"/>
<button name="%(track_line)d"
groups="stock.group_tracking_lot"
states="draft,waiting,confirmed,assigned"
string="Split" type="action" icon="terp-stock_effects-object-colorize" colspan="1" />
</group>
<label string="" colspan="4"/>
<field name="state"/>
<group col="4" colspan="2">
<button name="action_cancel" states="assigned" string="Cancel" type="object" icon="gtk-cancel"/>
<button name="action_confirm" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-find"/>
</group>
</form>
</field>
<group col="12" colspan="4">
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" statusbar_colors='{"auto":"blue", "confirmed":"blue"}'/>
<button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel" icon="gtk-cancel"/>
<button name="draft_force_assign" states="draft" string="Process Later" type="object" icon="gtk-ok"/>
<button name="draft_validate" states="draft" string="Process Now" type="object" icon="gtk-yes"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="action_process" states="assigned" string="Process" type="object" icon="gtk-go-forward"/>
<button name="%(act_stock_return_picking)d" string="Return Products" states="done" type="action" icon="gtk-execute"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" icon="terp-gtk-go-back-rtl"/>
</group>
</page>
<page string="Additional info">
<field name="auto_picking"/>
<field name="date_done"/>
<field name="move_type"/>
<field name="type"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</page>
<page string="Notes">
<field colspan="4" name="note" nolabel="1"/>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
<data>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='%(act_stock_return_picking)d']" position="replace">
<button name="%(report_picking_list_out)d" string="Print Delivery Slip" type="action" icon="gtk-print" states="done"/>
<button name="%(act_stock_return_picking)d" string="Return Products" states="done" type="action" icon="terp-gtk-go-back-rtl" />
</xpath>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='draft_validate']" position="replace">
<button name="draft_validate" states="draft" string="Confirm &amp; Deliver" type="object" icon="gtk-media-play"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/>
</xpath>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='action_process']" position="replace">
<button name="action_process" states="assigned" string="Deliver" type="object" icon="gtk-go-forward"/>
</xpath>
<xpath expr="/form/div[@class='oe_form_topbar']/div[@class='oe_right']/field[@name='state']" position="replace">
<field name="state" nolabel="1" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" statusbar_colors='{"auto":"blue", "confirmed":"blue"}'/>
</xpath>
<xpath expr="/form/sheet/group/group/field[@name='partner_id']" position="replace">
<field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4" string="Customer"/>
</xpath>
<xpath expr="/form/sheet" position="after">
<div class="oe_form_sheet_width">
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</div>
</xpath>
</data>
</field>
</record>
@ -1048,7 +986,7 @@
<record id="action_picking_tree" model="ir.actions.act_window">
<field name="name">Delivery Orders</field>
<field name="res_model">stock.picking</field>
<field name="res_model">stock.picking.out</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
@ -1076,9 +1014,14 @@
</record>
<menuitem action="action_picking_tree" id="menu_action_picking_tree" parent="menu_stock_warehouse_mgmt" sequence="3"/>
<!--
#
# Incomming Shipments
#
-->
<record id="view_picking_in_tree" model="ir.ui.view">
<field name="name">stock.picking.in.tree</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.in</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';grey:state == 'done';red:state not in ('cancel', 'done') and date &lt; current_date" string="Picking list">
@ -1097,138 +1040,35 @@
</record>
<record id="view_picking_in_form" model="ir.ui.view">
<field name="name">stock.picking.in.form</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.in</field>
<field name="inherit_id" ref="view_picking_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Input Picking List">
<group colspan="4" col="6">
<group colspan="4" col="4">
<field name="name" readonly="1"/>
<field name="origin"/>
<field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4"/>
<field name="invoice_state" string="Invoice Control"/>
<field name="backorder_id" readonly="1"/>
</group>
<group colspan="2" col="2">
<field name="date"/>
<field name="min_date" readonly="1"/>
<field name="stock_journal_id" widget="selection"/>
</group>
</group>
<notebook colspan="4">
<page string="General Information">
<field colspan="4" name="move_lines" nolabel="1" widget="one2many_list" context="{'address_in_id': partner_id, 'picking_type': type}" >
<tree colors="grey:scrapped==True" string="Stock Moves">
<field name="product_id" />
<field name="product_qty" />
<field name="product_uom" string="UoM" groups="product.group_uom"/>
<button name="%(stock.move_scrap)d"
string="Scrap Products" type="action"
icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned"/>
<field name="scrapped" invisible="1"/>
<field name="prodlot_id" groups="stock.group_production_lot"/>
<button
name="%(stock.track_line)d"
string="Split in production lots"
groups="stock.group_production_lot"
type="action" icon="terp-stock_effects-object-colorize"
states="draft,waiting,confirmed,assigned" />
<field name="tracking_id" groups="stock.group_tracking_lot"/>
<button name="setlast_tracking" string="Put in current pack" type="object"
groups="stock.group_tracking_lot"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
states="draft,assigned,confirmed"/>
<button name="%(split_into)d" string="Put in a new pack" type="action"
groups="product.group_stock_packaging"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed"/>
<field name="location_dest_id"/>
<field name="state"/>
</tree>
<form string="Stock Moves">
<group colspan="2" col="4">
<separator colspan="4" string="Move Information"/>
<field name="name" invisible="1" colspan="4"/>
<field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, parent.partner_id)" colspan="4"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" colspan="3"/>
<button name="%(stock.move_scrap)d"
string="Scrap" type="action"
icon="gtk-convert" context="{'scrap': True}"
states="draft,waiting,confirmed,assigned" colspan="1"/>
<field name="product_uom" string="Unit Of Measure" groups="product.group_uom" colspan="4"/>
<field name="product_uos_qty" groups="product.group_uos" on_change="onchange_uos_quantity(product_id, product_uos_qty, product_uos, product_uom)" colspan="4"/>
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" colspan="4"/>
<field name="product_packaging" groups="product.group_stock_packaging" domain="[('product_id','=',product_id)]" colspan="4"/>
</group>
<group colspan="2" col="2">
<separator string="Locations" colspan="2" />
<field name="location_id" domain="[('usage','&lt;&gt;','view')]" />
<field name="location_dest_id" domain="[('usage','=','internal')]" />
</group>
<group colspan="2" col="2">
<separator string="Dates" colspan="2" />
<field name="create_date" invisible="1"/>
<field name="date"/>
<field name="date_expected" on_change="onchange_date(date,date_expected)"/>
</group>
<group colspan="2" col="4">
<separator string="Traceability" colspan="4" groups="stock.group_tracking_lot"/>
<field name="tracking_id" groups="stock.group_tracking_lot" colspan="3" />
<button name="%(split_into)d" string="New Pack" type="action"
groups="product.group_stock_packaging"
icon="terp-stock_effects-object-colorize"
states="draft,assigned,confirmed" colspan="1"/>
<field name="prodlot_id" groups="stock.group_production_lot"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=?',product_id)]"
on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id, product_uom)" colspan="3"/>
<button name="%(track_line)d"
groups="stock.group_tracking_lot"
states="draft,waiting,confirmed,assigned"
string="Split" type="action" icon="terp-stock_effects-object-colorize" colspan="1" />
</group>
<label string="" colspan="4"/>
<field name="state"/>
<group col="4" colspan="2">
<button name="action_cancel" states="assigned" string="_Cancel" type="object" icon="gtk-cancel"/>
<button name="action_confirm" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-find"/>
</group>
</form>
</field>
<group col="10" colspan="4">
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"auto":"blue", "confirmed":"blue"}'/>
<button name="button_cancel" states="assigned,confirmed,draft" string="_Cancel" icon="gtk-cancel"/>
<button name="draft_force_assign" states="draft" string="Process Later" type="object" icon="gtk-ok"/>
<button name="draft_validate" states="draft" string="Process Now" type="object" icon="gtk-media-play"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" icon="gtk-find"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="action_process" states="assigned" string="Process" type="object" icon="gtk-go-forward"/>
<button name="%(act_stock_return_picking)d" string="Return Products" states="done" type="action" icon="gtk-execute"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" type="action" icon="terp-gtk-go-back-rtl" />
</group>
</page>
<page string="Additional Info">
<field name="type"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</page>
<page string="Notes">
<field colspan="4" name="note" nolabel="1"/>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
<data>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='%(act_stock_return_picking)d']" position="replace">
<button name="%(act_stock_return_picking)d" string="Return Products" states="done" type="action" icon="terp-gtk-go-back-rtl" />
</xpath>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='draft_validate']" position="replace">
<button name="draft_validate" states="draft" string="Confirm &amp; Receive" type="object" icon="gtk-media-play"/>
</xpath>
<xpath expr="/form/div[@class='oe_form_topbar']/button[@name='action_process']" position="replace">
<button name="action_process" states="assigned" string="Receive" type="object" icon="gtk-go-forward"/>
</xpath>
<xpath expr="/form/sheet/group/group/field[@name='partner_id']" position="replace">
<field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4" string="Supplier"/>
</xpath>
<xpath expr="/form/sheet" position="after">
<div class="oe_form_sheet_width">
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</div>
</xpath>
</data>
</field>
</record>
<record id="view_picking_in_search" model="ir.ui.view">
<field name="name">stock.picking.in.search</field>
<field name="model">stock.picking</field>
<field name="model">stock.picking.in</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Incoming Shipments">
@ -1262,12 +1102,12 @@
<record id="action_picking_tree4" model="ir.actions.act_window">
<field name="name">Incoming Shipments</field>
<field name="res_model">stock.picking</field>
<field name="res_model">stock.picking.in</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="domain">[('type','=','in')]</field>
<field name="context">{'contact_display': 'partner_address'}</field>
<field name="context">{'contact_display': 'partner_address', 'default_type': 'in'}</field>
<field name="search_view_id" ref="view_picking_in_search"/>
<field name="help">The Incoming Shipments is the list of all orders you will receive from your suppliers. An incoming shipment contains a list of products to be received according to the original purchase order. You can validate the shipment totally or partially.</field>
</record>
@ -1290,61 +1130,12 @@
</record>
<menuitem action="action_picking_tree4" id="menu_action_picking_tree4" parent="menu_stock_warehouse_mgmt" sequence="1"/>
<record id="view_picking_internal_search" model="ir.ui.view">
<field name="name">stock.picking.internal.search</field>
<field name="model">stock.picking</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Internal Picking List">
<group>
<filter icon="terp-check" string="Ready" domain="[('state','=','assigned')]" help="Assigned Internal Moves"/>
<filter icon="terp-camera_test" name="confirmed" string="Waiting" domain="[('state','=','confirmed')]" help="Confirmed Internal Moves" />
<separator orientation="vertical"/>
<field name="name"/>
<field name="origin"/>
<field name="stock_journal_id" widget="selection"/>
<field name="company_id" widget="selection"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
<filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'min_date'}"/>
<separator orientation="vertical"/>
<filter string="Origin" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
<separator orientation="vertical" />
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'stock_journal_id'}"/>
</group>
</search>
</field>
</record>
<record id="action_picking_tree6" model="ir.actions.act_window">
<field name="name">Internal Moves</field>
<field name="res_model">stock.picking</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="domain">[('type','=','internal')]</field>
<field name="context">{'default_type': 'internal', 'contact_display': 'partner_address', 'search_default_available': 1}</field>
<field name="search_view_id" ref="view_picking_internal_search"/>
<field name="help">Internal Moves display all inventory operations you have to perform in your warehouse. All operations can be categorized into stock journals, so that each worker has his own list of operations to perform in his own journal. Most operations are prepared automatically by OpenERP according to your preconfigured logistics rules, but you can also record manual stock operations.</field>
</record>
<record model="ir.actions.act_window.view" id="action_picking_tree6_tree_view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="vpicktree"/>
<field name="act_window_id" ref="action_picking_tree6"/>
</record>
<record model="ir.actions.act_window.view" id="action_picking_tree6_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="view_picking_form"/>
<field name="act_window_id" ref="action_picking_tree6"/>
</record>
<!--
STOCK MOVES
-->
<menuitem action="action_picking_tree6" id="menu_action_picking_tree6" parent="menu_stock_warehouse_mgmt" sequence="2"/>
@ -1640,12 +1431,12 @@
</group>
<separator colspan="4"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" statusbar_colors='{"waiting":"blue","confirmed":"blue"}'/>
<field name="state" nolabel="1" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"waiting":"blue","confirmed":"blue"}'/>
<group col="5" colspan="2">
<button name="action_cancel" states="assigned,confirmed" string="_Cancel" type="object" icon="gtk-cancel"/>
<button name="action_confirm" states="draft" string="Process Later" type="object" icon="gtk-apply"/>
<button name="force_assign" states="confirmed" string="Set Available" type="object" icon="gtk-yes"/>
<button name="%(action_partial_move_server)d" string="Process" type="action" states="assigned" icon="gtk-go-forward"/>
<button name="%(action_partial_move_server)d" string="Confirm &amp; Receive" type="action" states="assigned" icon="gtk-go-forward"/>
</group>
</form>
</field>

View File

@ -73,6 +73,7 @@
assert shipment.state == 'done', "shipment should be close after received."
for move_line in shipment.move_lines:
assert move_line.product_qty == 10, "Qty does not correspond."
assert move_line.product_id.virtual_available == 20, "Virtual stock does not correspond."
assert move_line.state == 'done', "Move line should be closed."
-
@ -82,11 +83,15 @@
invoice_state: none
-
!python {model: stock.return.picking }: |
# this work without giving the id of the picking to return, magically, thanks to the context
self.create_returns(cr, uid, [ref('return_incomming')], context=context)
-
I cancel incomming shipment after return it.
-
!python {model: stock.picking}: |
# the cancel is not on the return, but on the incomming shipment (which now has a quantity of 10, thanks to the
# backorder). This situation is a little weird as we returned a move that we finally cancelled... As result, only
# 30Kg from the original 50Kg will be counted in the stock (50 - 10 (cancelled quantity) - 10 (returned quantity))
self.action_cancel(cr, uid, [ref("incomming_shipment")], context=context)
-
I make invoice of backorder of incomming shipment.
@ -107,12 +112,12 @@
shipment = self.browse(cr, uid, ref("incomming_shipment"))
assert shipment.backorder_id.invoice_state == 'invoiced', 'Invoice state is not upadted.'
-
I check availabile stock after received incomming shipping.
I check available stock after received incomming shipping.
-
!python {model: product.product}: |
product = self.browse(cr, uid, ref('product_icecream'), context=context)
assert product.qty_available == 140, "Stock does not correspond."
assert product.virtual_available == 10, "Vitual stock does not correspond."
assert product.virtual_available == 0, "Vitual stock does not correspond."
-
I split incomming shipment into lots. each lot contain 10 kgm Ice-cream.
-
@ -198,7 +203,7 @@
!python {model: product.product}: |
product = self.browse(cr, uid, ref('product_icecream'), context=context)
assert product.qty_available == 135.96, "Stock does not correspond."
assert round(product.virtual_available, 2) == 5.96, "Vitual stock does not correspond."
assert round(product.virtual_available, 2) == -4.04, "Vitual stock does not correspond."
-
I trace all incoming lots.
-
@ -269,9 +274,9 @@
for move_line in shipment.move_lines:
assert move_line.state == "done", "Move should be closed."
-
I check availabile stock after deliver.
I check availaible stock after deliver.
-
!python {model: product.product}: |
product = self.browse(cr, uid, ref('product_icecream'), context=context)
assert round(product.qty_available, 2) == 5.96, "Stock does not correspond."
assert round(product.virtual_available, 2) == 5.96, "Vitual stock does not correspond."
assert round(product.virtual_available, 2) == -4.04, "Vitual stock does not correspond."

View File

@ -23,7 +23,7 @@
<act_window name="Create invoice"
res_model="stock.invoice.onshipping"
src_model="stock.picking"
src_model="stock.picking.out"
key2="client_action_multi"
multi="True"
view_mode="form"

View File

@ -20,6 +20,7 @@
##############################################################################
import time
from lxml import etree
from osv import fields, osv
from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import decimal_precision as dp
@ -71,15 +72,40 @@ class stock_partial_picking(osv.osv_memory):
'picking_id': fields.many2one('stock.picking', 'Picking', required=True, ondelete='CASCADE'),
'hide_tracking': fields.function(_hide_tracking, string='Tracking', type='boolean', help='This field is for internal purpose. It is used to decide if the column prodlot has to be shown on the move_ids field or not'),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
#override of fields_view_get in order to change the label of the process button and the separator accordingly to the shipping type
if context is None:
context={}
res = super(stock_partial_picking, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
type = context.get('active_model','').split('.')[-1]
if type:
doc = etree.XML(res['arch'])
for node in doc.xpath("//button[@name='do_partial']"):
if type == 'in':
node.set('string', _('_Receive'))
elif type == 'out':
node.set('string', _('_Deliver'))
for node in doc.xpath("//separator[@name='product_separator']"):
if type == 'in':
node.set('string', _('Receive Products'))
elif type == 'out':
node.set('string', _('Deliver Products'))
res['arch'] = etree.tostring(doc)
return res
def default_get(self, cr, uid, fields, context=None):
if context is None: context = {}
res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
picking_ids = context.get('active_ids', [])
if not picking_ids or (not context.get('active_model') == 'stock.picking') \
or len(picking_ids) != 1:
if not picking_ids or len(picking_ids) != 1:
# Partial Picking Processing may only be done for one picking at a time
return res
# The check about active_model is there in case the client mismatched the context during propagation of it
# (already seen in previous bug where context passed was containing ir.ui.menu as active_model and the menu
# ID as active_id). Though this should be fixed in clients now, this place is sensitive enough to ensure the
# consistancy of the context.
assert context.get('active_model') in ('stock.picking', 'stock.picking.in', 'stock.picking.out'), 'Bad context propagation'
picking_id, = picking_ids
if 'picking_id' in fields:
res.update(picking_id=picking_id)
@ -111,7 +137,7 @@ class stock_partial_picking(osv.osv_memory):
def _partial_move_for(self, cr, uid, move):
partial_move = {
'product_id' : move.product_id.id,
'quantity' : move.state in ('assigned','new') and move.product_qty or 0,
'quantity' : move.state in ('assigned','draft','confirmed') and move.product_qty or 0,
'product_uom' : move.product_uom.id,
'prodlot_id' : move.prodlot_id.id,
'move_id' : move.id,

View File

@ -9,6 +9,7 @@
<field name="target">new</field>
</record>
<!-- this view of stock.partial.picking wizard is dedicated to internal picking. The fields_view_get is ovveridden in order to change the label of the process button and the separator. -->
<record id="stock_partial_picking_form" model="ir.ui.view">
<field name="name">stock.partial.picking.form</field>
<field name="model">stock.partial.picking</field>
@ -16,7 +17,7 @@
<field name="arch" type="xml">
<form>
<field name="hide_tracking" invisible="1"/>
<separator colspan="4" string="Products"/>
<separator colspan="4" string="Transfer Products" name="product_separator"/>
<field name="move_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" context="{'hide_tracking': hide_tracking}">
<tree editable="bottom" string="Product Moves">
<field name="product_id" />
@ -34,7 +35,7 @@
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel" string="_Cancel" />
<button name="do_partial" string="_Validate" colspan="1" type="object" icon="gtk-go-forward" />
<button name="do_partial" string="_Transfer" colspan="1" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>

View File

@ -45,7 +45,7 @@ class stock_return_picking(osv.osv_memory):
_columns = {
'product_return_moves' : fields.one2many('stock.return.picking.memory', 'wizard_id', 'Moves'),
'invoice_state': fields.selection([('2binvoiced', 'To be refunded/invoiced'), ('none', 'No invoicing')], 'Invoicing',required=True),
}
}
def default_get(self, cr, uid, fields, context=None):
"""
@ -143,6 +143,8 @@ class stock_return_picking(osv.osv_memory):
pick_obj = self.pool.get('stock.picking')
uom_obj = self.pool.get('product.uom')
data_obj = self.pool.get('stock.return.picking.memory')
act_obj = self.pool.get('ir.actions.act_window')
model_obj = self.pool.get('ir.model.data')
wf_service = netsvc.LocalService("workflow")
pick = pick_obj.browse(cr, uid, record_id, context=context)
data = self.read(cr, uid, ids[0], context=context)
@ -152,15 +154,20 @@ class stock_return_picking(osv.osv_memory):
returned_lines = 0
# Create new picking for returned products
if pick.type=='out':
if pick.type =='out':
new_type = 'in'
elif pick.type=='in':
elif pick.type =='in':
new_type = 'out'
else:
new_type = 'internal'
new_picking = pick_obj.copy(cr, uid, pick.id, {'name':'%s-return' % pick.name,
'move_lines':[], 'state':'draft', 'type':new_type,
'date':date_cur, 'invoice_state':data['invoice_state'],})
new_picking = pick_obj.copy(cr, uid, pick.id, {
'name': _('%s-return') % pick.name,
'move_lines': [],
'state':'draft',
'type': new_type,
'date':date_cur,
'invoice_state': data['invoice_state'],
})
val_id = data['product_return_moves']
for v in val_id:
@ -178,35 +185,34 @@ class stock_return_picking(osv.osv_memory):
if new_qty:
returned_lines += 1
new_move=move_obj.copy(cr, uid, move.id, {
'product_qty': new_qty,
'product_uos_qty': uom_obj._compute_qty(cr, uid, move.product_uom.id,
new_qty, move.product_uos.id),
'picking_id':new_picking, 'state':'draft',
'location_id':new_location, 'location_dest_id':move.location_id.id,
'date':date_cur,})
move_obj.write(cr, uid, [move.id], {'move_history_ids2':[(4,new_move)]})
'product_qty': new_qty,
'product_uos_qty': uom_obj._compute_qty(cr, uid, move.product_uom.id, new_qty, move.product_uos.id),
'picking_id':new_picking,
'state': 'draft',
'location_id': new_location,
'location_dest_id': move.location_id.id,
'date': date_cur,
})
move_obj.write(cr, uid, [move.id], {'move_history_ids2':[(4,new_move)]}, context=context)
if not returned_lines:
raise osv.except_osv(_('Warning !'), _("Please specify at least one non-zero quantity!"))
if set_invoice_state_to_none:
pick_obj.write(cr, uid, [pick.id], {'invoice_state':'none'})
pick_obj.write(cr, uid, [pick.id], {'invoice_state':'none'}, context=context)
wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
pick_obj.force_assign(cr, uid, [new_picking], context)
# Update view id in context, lp:702939
view_list = {
'out': 'view_picking_out_tree',
'in': 'view_picking_in_tree',
'internal': 'vpicktree',
}
data_obj = self.pool.get('ir.model.data')
res = data_obj.get_object_reference(cr, uid, 'stock', view_list.get(new_type, 'vpicktree'))
context.update({'view_id': res and res[1] or False})
model_list = {
'out': 'stock.picking.out',
'in': 'stock.picking.in',
'internal': 'stock.picking',
}
return {
'domain': "[('id', 'in', ["+str(new_picking)+"])]",
'name': 'Picking List',
'name': _('Returned Picking'),
'view_type':'form',
'view_mode':'tree,form',
'res_model':'stock.picking',
'res_model': model_list.get(new_type, 'stock.picking'),
'type':'ir.actions.act_window',
'context':context,
}
@ -214,4 +220,3 @@ class stock_return_picking(osv.osv_memory):
stock_return_picking()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,14 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<act_window name="Return Picking"
res_model="stock.return.picking"
src_model="stock.picking"
view_mode="form"
target="new"
<act_window name="Return Shipment"
res_model="stock.return.picking"
src_model="stock.picking"
view_mode="form"
target="new"
key2="client_action_multi"
multi="True"
id="act_stock_return_picking"/>
id="act_stock_return_picking"/>
<act_window name="Return Shipment"
res_model="stock.return.picking"
src_model="stock.picking.in"
view_mode="form"
target="new"
key2="client_action_multi"
multi="True"
id="act_stock_return_picking_in"/>
<act_window name="Return Shipment"
res_model="stock.return.picking"
src_model="stock.picking.out"
view_mode="form"
target="new"
key2="client_action_multi"
multi="True"
id="act_stock_return_picking_out"/>
<record id="stock_return_memory_tree_in" model="ir.ui.view">
<field name="name">stock.return.picking.memory.tree</field>