diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml
index f39e8a59f39..11defc97dd9 100644
--- a/addons/delivery/delivery_view.xml
+++ b/addons/delivery/delivery_view.xml
@@ -177,28 +177,13 @@
delivery.stock.picking_withcarrier.out.form.viewform
- stock.picking
-
+ stock.picking.out
+
-
-
-
-
-
-
-
- stock.picking_withweight.in.form.view
- form
- stock.picking
-
-
-
-
-
@@ -218,7 +203,7 @@
Picking to be invoiced
- stock.picking
+ stock.picking.outir.actions.act_windowformtree,form
@@ -228,39 +213,13 @@
-
- delivery.stock.picking_withcarrier.out.move.form.view
- form
- stock.picking
-
-
-
-
-
-
-
-
-
-
- stock.picking_withweight.in.move.form.view
- form
- stock.picking
-
-
-
-
-
-
-
-
-
stock.picking_withweight.internal.move.form.viewformstock.picking
-
+
@@ -316,7 +275,7 @@
stock.picking
-
+
diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py
index b441a8e5efe..64ebf0ff9fa 100644
--- a/addons/delivery/stock.py
+++ b/addons/delivery/stock.py
@@ -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:
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 687221f371b..ea90baae99c 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -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' : [],
diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py
index 35193dfa07b..06b391513e0 100644
--- a/addons/purchase/stock.py
+++ b/addons/purchase/stock.py
@@ -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:
diff --git a/addons/purchase/stock_view.xml b/addons/purchase/stock_view.xml
index f29783c67ae..cc414c284db 100644
--- a/addons/purchase/stock_view.xml
+++ b/addons/purchase/stock_view.xml
@@ -19,7 +19,7 @@
-
+
@@ -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'}" />
@@ -47,28 +47,28 @@
Incoming Picking Inherited
- stock.picking
+ stock.picking.inform
-
+
-
+
-
+
stock.picking.in.search
- stock.picking
+ stock.picking.insearch
-
+
@@ -89,7 +89,7 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/sale/stock.py b/addons/sale/stock.py
index 44b993ec0e1..83cd8f89e11 100644
--- a/addons/sale/stock.py
+++ b/addons/sale/stock.py
@@ -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:
diff --git a/addons/sale_analytic_plans/sale_analytic_plans_view.xml b/addons/sale_analytic_plans/sale_analytic_plans_view.xml
index 743bbcb48d9..2d4ff082288 100644
--- a/addons/sale_analytic_plans/sale_analytic_plans_view.xml
+++ b/addons/sale_analytic_plans/sale_analytic_plans_view.xml
@@ -18,7 +18,7 @@
form
-
+
diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py
index 88ddead6645..102d54ae9ed 100644
--- a/addons/stock/__openerp__.py
+++ b/addons/stock/__openerp__.py
@@ -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",
diff --git a/addons/stock/report/picking.rml b/addons/stock/report/picking.rml
index 63706a940e6..707ba3646d2 100644
--- a/addons/stock/report/picking.rml
+++ b/addons/stock/report/picking.rml
@@ -1,6 +1,6 @@
-
+
@@ -31,7 +31,6 @@
-
@@ -52,14 +51,12 @@
-
-
@@ -161,7 +158,9 @@
- Shipping Address :
+ Supplier Address : [[ (picking.type == 'in' or removeParentNode('para')) and '' ]]
+ Customer Address : [[ (picking.type == 'out' or removeParentNode('para')) and '' ]]
+ Warehouse Address : [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]][[ (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 ]][[ picking.partner_id and display_address(picking.partner_id,'delivery') ]]
@@ -181,16 +180,16 @@
- Packing List: [[ (picking.type == 'out' or removeParentNode('para')) and '' ]] [[ picking.name ]]
- Reception: [[ (picking.type == 'in' or removeParentNode('para')) and '' ]] [[ picking.name ]]
- Picking List: [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]] [[ picking.name ]]
+ Delivery Order : [[ (picking.type == 'out' or removeParentNode('para')) and '' ]] [[ picking.name ]]
+ Incoming Shipment : [[ (picking.type == 'in' or removeParentNode('para')) and '' ]] [[ picking.name ]]
+ Internal Shipment : [[ (picking.type == 'internal' or removeParentNode('para')) and '' ]] [[ picking.name ]]
-
+
Journal
@@ -209,7 +208,7 @@
-
+
[[ picking.stock_journal_id.name]]
@@ -240,7 +239,7 @@
Lot
- State
+ State
Location
@@ -287,7 +286,9 @@
[[ (move_lines.prodlot_id and move_lines.prodlot_id.name) or '' ]]
- [[ move_lines.state ]]
+ [[ (picking.type == 'in' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Received' or move_lines.state]]
+ [[ (picking.type == 'out' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Delivered' or move_lines.state]]
+ [[ (picking.type == 'internal' or removeParentNode('para')) ]][[ move_lines.state == 'done' and 'Transferred' or move_lines.state]]
[[ (move_lines.location_id and move_lines.location_id.name) or '' ]]
diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py
index da6be7873c3..bdd094b7233 100644
--- a/addons/stock/report/report_stock_move.py
+++ b/addons/stock/report/report_stock_move.py
@@ -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."),
diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml
index 01ef4a70289..967ac202d2e 100644
--- a/addons/stock/report/report_stock_move_view.xml
+++ b/addons/stock/report/report_stock_move_view.xml
@@ -117,7 +117,7 @@
-
+
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index dee8e2a6c25..49eda7c289b 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -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:
diff --git a/addons/stock/stock_demo.yml b/addons/stock/stock_demo.yml
index 0db509e40ba..245e55c38c6 100644
--- a/addons/stock/stock_demo.yml
+++ b/addons/stock/stock_demo.yml
@@ -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
diff --git a/addons/stock/stock_report.xml b/addons/stock/stock_report.xml
index 96e0ee5cd59..540e6a8f902 100644
--- a/addons/stock/stock_report.xml
+++ b/addons/stock/stock_report.xml
@@ -2,7 +2,9 @@
-
+
+
+
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 500d3f6ffd8..4627482812e 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -654,6 +654,16 @@
+
+
+
+
stock.picking.calendarstock.picking
@@ -667,6 +677,7 @@
+
stock.picking.treestock.picking
@@ -685,13 +696,28 @@
+
stock.picking.formstock.pickingform
-
-
-
-
-
-
-
-
-
-
-
@@ -817,42 +833,67 @@
+
-
- stock.picking.list.select
+
+ stock.picking.internal.searchstock.pickingsearch
-
+
-
-
+
+
-
-
-
-
-
+
+
-
+
+
+
+
+
-
-
-
+
+
+ Internal Moves
+ stock.picking
+ ir.actions.act_window
+ form
+ tree,form,calendar
+ [('type','=','internal')]
+ {'contact_display': 'partner_address', 'search_default_available': 1}
+
+ 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.
+
+
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
stock.picking.in.tree
- stock.picking
+ stock.picking.intree
@@ -1097,138 +1040,35 @@
stock.picking.in.form
- stock.picking
+ stock.picking.in
+ form
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
stock.picking.in.search
- stock.picking
+ stock.picking.insearch
@@ -1262,12 +1102,12 @@
Incoming Shipments
- stock.picking
+ stock.picking.inir.actions.act_windowformtree,form,calendar[('type','=','in')]
- {'contact_display': 'partner_address'}
+ {'contact_display': 'partner_address', 'default_type': 'in'}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.
@@ -1290,61 +1130,12 @@
-
- stock.picking.internal.search
- stock.picking
- search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Internal Moves
- stock.picking
- ir.actions.act_window
- form
- tree,form,calendar
- [('type','=','internal')]
- {'default_type': 'internal', 'contact_display': 'partner_address', 'search_default_available': 1}
-
- 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.
-
-
-
- tree
-
-
-
-
-
- form
-
-
-
+
@@ -1640,12 +1431,12 @@
-
+
-
+
diff --git a/addons/stock/test/shipment.yml b/addons/stock/test/shipment.yml
index 96c42c6c488..b30feccdacf 100644
--- a/addons/stock/test/shipment.yml
+++ b/addons/stock/test/shipment.yml
@@ -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."
diff --git a/addons/stock/wizard/stock_invoice_onshipping_view.xml b/addons/stock/wizard/stock_invoice_onshipping_view.xml
index 5e2f25c3bbf..5095a40fa50 100644
--- a/addons/stock/wizard/stock_invoice_onshipping_view.xml
+++ b/addons/stock/wizard/stock_invoice_onshipping_view.xml
@@ -23,7 +23,7 @@
new
+
stock.partial.picking.formstock.partial.picking
@@ -16,7 +17,7 @@