[IMP] stock: cleanup stock.partial.{picking,move} wizards and fix dependencies and tests
bzr revid: odo@openerp.com-20110926003612-0wa6sghmlwbezwzk
This commit is contained in:
parent
3b1196867b
commit
e45e0b75d8
|
@ -205,9 +205,8 @@
|
|||
I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water.
|
||||
-
|
||||
!python {model: procurement.order}: |
|
||||
from tools.translate import _
|
||||
proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_orange0'),ref('product_product_sugar0'),ref('product_product_water0')])])
|
||||
assert proc_ids, _('No Procurements!')
|
||||
assert proc_ids, 'No Procurements!'
|
||||
-
|
||||
The scheduler runs.
|
||||
-
|
||||
|
@ -219,9 +218,8 @@
|
|||
stock moves for Oranges, Sugar and Water made correctly.
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('type','=','internal')])
|
||||
assert pick_ids, _('No Internal Pickings!')
|
||||
assert pick_ids, 'No Internal Pickings!'
|
||||
-
|
||||
According to minimum stock rules. I have 2 purchase orders for
|
||||
Sugar with 6 Kg from Axelor and Orange 60 Kg from ASUStek.
|
||||
|
@ -229,50 +227,24 @@
|
|||
I confirm the purchase order of Sugar and Orange.
|
||||
-
|
||||
!python {model: purchase.order}: |
|
||||
from tools.translate import _
|
||||
import netsvc
|
||||
purch_ids = self.search(cr, uid, [('state','=','draft')])
|
||||
assert purch_ids, _('No Purchase Orders were made!')
|
||||
assert purch_ids, 'No Purchase Orders were made!'
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for p_id in purch_ids:
|
||||
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
|
||||
-
|
||||
I see two incoming pickings for Orange and Sugar.
|
||||
I see two incoming pickings for Orange and Sugar, and receive them.
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('type','=','in')])
|
||||
assert pick_ids, _('No Incoming Shipments found!')
|
||||
-
|
||||
I receive both the products. My incoming pickings are done.
|
||||
-
|
||||
I create record for the incoming picking wizard.
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking0}:
|
||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
||||
-
|
||||
I make my pickings done.
|
||||
-
|
||||
!python {model: stock.partial.picking}: |
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
picking_ids = pick_obj.search(cr, uid, [('type','=','in'),('state','=','assigned')])
|
||||
partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
|
||||
partial_datas = {
|
||||
'delivery_date': partial.date
|
||||
}
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids):
|
||||
for m in pick.move_lines:
|
||||
partial_datas['move%s'%(m.id)] = {
|
||||
'product_id': m.product_id.id,
|
||||
'product_qty': m.product_qty,
|
||||
'product_uom': m.product_uom.id
|
||||
}
|
||||
if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s'%(m.id)].update({
|
||||
'product_price': m.product_price,
|
||||
'product_currency': m.product_currency
|
||||
})
|
||||
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
|
||||
assert pick_ids, 'No Incoming Shipments found!'
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
for pick_id in pick_ids:
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick_id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
Again the scheduler runs.
|
||||
-
|
||||
|
@ -283,19 +255,15 @@
|
|||
I check my internal picking of "Orange Juice" is done.
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('type','=','internal'),('state','=','done')])
|
||||
assert pick_ids, _('Internal Picking is not done yet!')
|
||||
assert pick_ids, 'Internal Picking is not done yet!'
|
||||
-
|
||||
I check my manufacturing order for "Orange Juice" is ready or not.
|
||||
-
|
||||
!python {model: mrp.production}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
|
||||
assert pick_ids, _('Manufacturing order is not ready!')
|
||||
prod_ids = self.search(cr, uid, [('state','=','ready'),('id','=',ref('mrp_production_mo0'))])
|
||||
assert prod_ids, 'Manufacturing order is not ready!'
|
||||
-
|
||||
I start the production order.
|
||||
-
|
||||
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
|
||||
|
||||
|
||||
|
|
|
@ -195,74 +195,26 @@
|
|||
I Check incoming shipments for cloth. And receive products.
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
|
||||
assert pick_ids, _('No Incoming Shipments found!')
|
||||
-
|
||||
I create record for partial picking.
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking0}:
|
||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
-
|
||||
I make my picking done.
|
||||
-
|
||||
!python {model: stock.partial.picking}: |
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
|
||||
partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
|
||||
partial_datas = {
|
||||
'delivery_date' : partial.date
|
||||
}
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids):
|
||||
for m in pick.move_lines:
|
||||
partial_datas['move%s'%(m.id)] = {
|
||||
'product_id' : m.product_id.id,
|
||||
'product_qty' : m.product_qty,
|
||||
'product_uom' : m.product_uom.id
|
||||
}
|
||||
if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s'%(m.id)].update({
|
||||
'product_price' : m.product_price,
|
||||
'product_currency': m.product_currency
|
||||
})
|
||||
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
|
||||
assert pick_ids, 'No Incoming Shipments found!'
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
for pick_id in pick_ids:
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick_id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I Check incoming shipments for buttons and receive products.
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
from tools.translate import _
|
||||
pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
|
||||
assert pick_ids, _('No Incoming Shipments found!')
|
||||
-
|
||||
I create record for partial picking.
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking0}:
|
||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
-
|
||||
I make my picking done.
|
||||
-
|
||||
!python {model: stock.partial.picking}: |
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
|
||||
partial = self.browse(cr, uid, ref('stock_partial_picking0'), context)
|
||||
partial_datas = {
|
||||
'delivery_date': partial.date
|
||||
}
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids):
|
||||
for m in pick.move_lines:
|
||||
partial_datas['move%s'%(m.id)] = {
|
||||
'product_id': m.product_id.id,
|
||||
'product_qty': m.product_qty,
|
||||
'product_uom': m.product_uom.id
|
||||
}
|
||||
if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s'%(m.id)].update({
|
||||
'product_price': m.product_price,
|
||||
'product_currency': m.product_currency
|
||||
})
|
||||
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
|
||||
assert pick_ids, 'No Incoming Shipments found!'
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
for pick_id in pick_ids:
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick_id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
Run scheduler again.
|
||||
-
|
||||
|
@ -297,7 +249,6 @@
|
|||
I produce 2 products with 5.00 quantities each.
|
||||
-
|
||||
!python {model: mrp.product.produce}: |
|
||||
from tools.translate import _
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
|
||||
self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
|
||||
|
@ -321,8 +272,7 @@
|
|||
And finally production order is done.
|
||||
-
|
||||
!python {model: mrp.product.produce}: |
|
||||
from tools.translate import _
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
|
||||
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
|
||||
self.do_produce(cr, uid, [ref('mrp_product_produce0')], context={'active_ids': prod_ids})
|
||||
|
||||
|
|
|
@ -124,68 +124,15 @@ class stock_picking(osv.osv):
|
|||
purchase_obj.write(cursor, user, [picking.purchase_id.id], {'invoice_id': invoice_id,})
|
||||
return super(stock_picking, self)._invoice_hook(cursor, user, picking, invoice_id)
|
||||
|
||||
stock_picking()
|
||||
|
||||
class stock_partial_picking(osv.osv_memory):
|
||||
_inherit = 'stock.partial.picking'
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
""" To get default values for the object.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
|
||||
for pick in pick_obj.browse(cr, uid, context.get('active_ids', []), context=context):
|
||||
has_product_cost = (pick.type == 'in' and pick.purchase_id)
|
||||
for m in pick.move_lines:
|
||||
if m.state in ('done','cancel') :
|
||||
continue
|
||||
if has_product_cost and m.product_id.cost_method == 'average' and m.purchase_line_id:
|
||||
# We use the original PO unit purchase price as the basis for the cost, expressed
|
||||
# in the currency of the PO (i.e the PO's pricelist currency)
|
||||
list_index = 0
|
||||
for item in res['product_moves_in']:
|
||||
if item['move_id'] == m.id:
|
||||
res['product_moves_in'][list_index]['cost'] = m.purchase_line_id.price_unit
|
||||
res['product_moves_in'][list_index]['currency'] = m.picking_id.purchase_id.pricelist_id.currency_id.id
|
||||
list_index += 1
|
||||
return res
|
||||
stock_partial_picking()
|
||||
# Overridden to inject the purchase price as true 'cost price' when processing
|
||||
# incoming pickings.
|
||||
def _product_cost_for_average_update(self, cr, uid, move):
|
||||
if move.picking_id.purchase_id:
|
||||
return {'cost': move.purchase_line_id.price_unit,
|
||||
'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)
|
||||
|
||||
class stock_partial_move(osv.osv_memory):
|
||||
_inherit = "stock.partial.move"
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
""" To get default values for the object.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
|
||||
move_obj = self.pool.get('stock.move')
|
||||
for m in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
|
||||
if m.picking_id.type == 'in' and m.product_id.cost_method == 'average' \
|
||||
and m.purchase_line_id and m.picking_id.purchase_id:
|
||||
# We use the original PO unit purchase price as the basis for the cost, expressed
|
||||
# in the currency of the PO (i.e the PO's pricelist currency)
|
||||
list_index = 0
|
||||
for item in res['product_moves_in']:
|
||||
if item['move_id'] == m.id:
|
||||
res['product_moves_in'][list_index]['cost'] = m.purchase_line_id.price_unit
|
||||
res['product_moves_in'][list_index]['currency'] = m.picking_id.purchase_id.pricelist_id.currency_id.id
|
||||
list_index += 1
|
||||
return res
|
||||
stock_partial_move()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -31,39 +31,17 @@
|
|||
-
|
||||
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so9}
|
||||
-
|
||||
I verify that the picking has been generated for the sale order
|
||||
I verify that the picking has been generated for the sale order and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so9"))
|
||||
assert so.picking_ids,"Picking has not been generated for sale_order_so9"
|
||||
-
|
||||
Then I confirm the picking
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
Then I done the picking
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so9"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
|
||||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': '100',
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
picking, = so.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I click on Create Invoice button to create the invoice.
|
||||
-
|
||||
|
|
|
@ -30,41 +30,21 @@
|
|||
-
|
||||
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so6}
|
||||
-
|
||||
I verify that the picking has been generated for the sale order
|
||||
I verify that the picking has been generated for the sale order and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so6"))
|
||||
assert so.picking_ids,"Picking has not been generated for sale_order_so6"
|
||||
-
|
||||
Then I click on the "Product Sent" button of Outgoing Shipments
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I change the quantity on the picking to 199, and confirm partially 100 PCE.
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so6"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
|
||||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
self.pool.get('stock.move').write(cr, uid, [pick.move_lines[0].id], {'product_qty': 199, 'product_uos_qty': 199})
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': '100',
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
picking, = so.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
# I change the qty to 100 for a partial delivery
|
||||
partial = stock_partial_picking.browse(cr,uid,partial_id)
|
||||
line_id = partial.move_ids[0].id
|
||||
partial.write({'move_ids': [(1,line_id,{'quantity':100})]})
|
||||
partial.do_partial()
|
||||
-
|
||||
Then I click on 'Create Invoices' button
|
||||
-
|
||||
|
@ -72,7 +52,7 @@
|
|||
import time
|
||||
sale_obj = self.pool.get('sale.order')
|
||||
sale_id = sale_obj.browse(cr, uid, ref("sale_order_so6"))
|
||||
ids = [x.id for x in sale_id.picking_ids]
|
||||
ids = [x.id for x in sale_id.picking_ids if x.state == 'done']
|
||||
wiz_id = self.create(cr, uid, {'invoice_date': time.strftime('%Y-%m-%d'), 'journal_id': ref('account.sales_journal')},
|
||||
{'active_ids': ids, 'active_model': 'stock.picking'})
|
||||
self.create_invoice(cr, uid, [wiz_id], {"active_ids": ids, "active_id": ids[0]})
|
||||
|
@ -98,7 +78,7 @@
|
|||
inv_brw = self.browse(cr,uid,inv_id)[0]
|
||||
for inv_lines in inv_brw.invoice_line:
|
||||
qty1=inv_lines.quantity
|
||||
assert (qty1 == qty), "Quantities are not the same"
|
||||
assert (qty1 == qty), "Quantities are not the same: invoiced: %s, shipped: %s" % (qty1,qty)
|
||||
-
|
||||
I open the Invoice for the SO.
|
||||
-
|
||||
|
|
|
@ -136,15 +136,10 @@
|
|||
I verify that a procurement state is "running"
|
||||
-
|
||||
!python {model: procurement.order}: |
|
||||
from tools.translate import _
|
||||
modules = self.pool.get('ir.module.module')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if (mod_brw.state == 'installed'):
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
|
||||
proc_ids = self.search(cr, uid, [('origin','=',so.name),('state','=','running')])
|
||||
assert(proc_ids),"Procurement is not in the running state!"
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
|
||||
proc_ids = self.search(cr, uid, [('origin','=',so.name),('state','=','running')])
|
||||
assert(proc_ids),"Procurement is not in the running state!"
|
||||
-
|
||||
I verify that a purchase order has been generated
|
||||
-
|
||||
|
@ -192,7 +187,7 @@
|
|||
for pur in pur_ids:
|
||||
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
|
||||
-
|
||||
I verify that a picking related to purchase order has been generated.
|
||||
I verify that a picking related to purchase order has been generated and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
|
@ -204,29 +199,12 @@
|
|||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
assert(po.picking_ids),"Picking for purchase order has not been generated"
|
||||
-
|
||||
Then I click on the "Products Received" button of Incoming Shipments
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I click on the "Validate" button
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
pur_obj = self.pool.get('purchase.order')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if (mod_brw.state == 'installed'):
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
|
||||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
|
||||
import netsvc
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for pick in pick_ser_id:
|
||||
wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
|
||||
picking, = po.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that picking for purchase order has been done.
|
||||
-
|
||||
|
@ -244,7 +222,7 @@
|
|||
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
|
||||
assert(ids),"Picking is not in the done state!"
|
||||
-
|
||||
Then I done the picking
|
||||
Then I process the picking
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
|
@ -254,18 +232,11 @@
|
|||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that picking for sale order is in done state.
|
||||
-
|
||||
|
@ -275,38 +246,6 @@
|
|||
picking_id = self.search(cr, uid, [('origin','=',so.name),('type','=','out')])
|
||||
pick = self.browse(cr,uid,picking_id[0])
|
||||
assert (pick.state) =='done', "Picking for SO is not in done state."
|
||||
-
|
||||
Then I done the delivery order
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name)])
|
||||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
-
|
||||
I verify that delivery state is done
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so0"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name)])
|
||||
pick = self.browse(cr,uid,picking_id[0])
|
||||
assert (pick.state) =='done', "Picking for SO is not in done state."
|
||||
-
|
||||
I verify that a "Picked" has been set to true
|
||||
-
|
||||
|
|
|
@ -46,18 +46,11 @@
|
|||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
Then I click on 'Create Invoices' button
|
||||
-
|
||||
|
@ -197,7 +190,7 @@
|
|||
for pur in pur_ids:
|
||||
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
|
||||
-
|
||||
I verify that a picking related to purchase order has been generated.
|
||||
I verify that a picking related to purchase order has been generated and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
|
@ -209,29 +202,12 @@
|
|||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
assert(po.picking_ids),"Picking for purchase order has not been generated"
|
||||
-
|
||||
Then I click on the "Products Received" button of Incoming Shipments
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I click on the "Validate" button
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if (mod_brw.state == 'installed'):
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
pur_obj = self.pool.get('purchase.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
|
||||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
|
||||
import netsvc
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for pick in pick_ser_id:
|
||||
wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
|
||||
picking, = po.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that picking for purchase order has been done.
|
||||
-
|
||||
|
@ -249,36 +225,20 @@
|
|||
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
|
||||
assert ids, _('Picking is not in the done state!')
|
||||
-
|
||||
I verify that delivery order has been generated for sale order
|
||||
I verify that delivery order has been generated for sale order, and process it
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name)])
|
||||
assert (picking_id),"Delivery order has not been generated"
|
||||
-
|
||||
I verify that delivery has been done
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so7"))
|
||||
picking_id = self.search(cr, uid, [('origin','=',so.name)])
|
||||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that delivery state is done
|
||||
-
|
||||
|
@ -290,7 +250,7 @@
|
|||
pick = self.browse(cr,uid,picking_id[0])
|
||||
assert (pick.state) =='done', "Picking for SO is not in done state."
|
||||
-
|
||||
I verify that a "Picked" has been set to true
|
||||
I verify that the sale order is marked as delivered
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so7"))
|
||||
|
|
|
@ -45,18 +45,11 @@
|
|||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that picking order is in done state.
|
||||
-
|
||||
|
@ -76,7 +69,7 @@
|
|||
picking_id = self.search(cr, uid, [('origin','=',so.name)])
|
||||
assert (picking_id),"Delivery order has not been generated"
|
||||
-
|
||||
I click on the Products Sent button and then on the Validate button
|
||||
I process the delivery order
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
|
@ -86,20 +79,13 @@
|
|||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that delivery state is done
|
||||
I verify that delivery order is marked done
|
||||
-
|
||||
!python {model: stock.picking }: |
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
|
@ -187,7 +173,7 @@
|
|||
for pur in pur_ids:
|
||||
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
|
||||
-
|
||||
I verify that a picking related to purchase order has been generated.
|
||||
I verify that a picking related to purchase order has been generated and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
|
@ -199,31 +185,14 @@
|
|||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
assert(po.picking_ids),"Picking for purchase order has not been generated"
|
||||
picking, = po.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
Then I click on the "Products Received" button of Incoming Shipments
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I click on the "Validate" button
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if (mod_brw.state == 'installed'):
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
pur_obj = self.pool.get('purchase.order')
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so8"))
|
||||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
|
||||
import netsvc
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for pick in pick_ser_id:
|
||||
wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
|
||||
-
|
||||
I verify that picking for purchase order has been done.
|
||||
I verify that picking for purchase order has been marked done.
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
from tools.translate import _
|
||||
|
@ -239,7 +208,7 @@
|
|||
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
|
||||
assert ids, _('Picking is not in the done state!')
|
||||
-
|
||||
I verify that a "Picked" has been set to true
|
||||
I verify that the sale order is marked as delivered
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so8"))
|
||||
|
|
|
@ -101,18 +101,11 @@
|
|||
if picking_id:
|
||||
pick=self.browse(cr,uid,picking_id[0])
|
||||
pick.force_assign(cr, uid)
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d'),
|
||||
}
|
||||
move = pick.move_lines[0]
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [pick.id],partial_datas)
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
I verify that picking order is in done state.
|
||||
-
|
||||
|
@ -201,7 +194,7 @@
|
|||
for pur in pur_ids:
|
||||
wf_service.trg_validate(uid, 'purchase.order',pur,'purchase_approve', cr)
|
||||
-
|
||||
I verify that a picking related to purchase order has been generated.
|
||||
I verify that a picking related to purchase order has been generated and I process it
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
|
@ -213,51 +206,21 @@
|
|||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
assert(po.picking_ids),"Picking for purchase order has not been generated"
|
||||
-
|
||||
Then I click on the "Products Received" button of Incoming Shipments
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I click on the "Validate" button
|
||||
-
|
||||
!python {model: stock.picking}: |
|
||||
modules = self.pool.get('ir.module.module')
|
||||
sale_order_obj = self.pool.get('sale.order')
|
||||
pur_obj = self.pool.get('purchase.order')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if (mod_brw.state == 'installed'):
|
||||
so = sale_order_obj.browse(cr, uid, ref("sale_order_so1"))
|
||||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
pick_ser_id = self.search(cr, uid, [('purchase_id', '=', po.id )])
|
||||
import netsvc
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for pick in pick_ser_id:
|
||||
wf_service.trg_validate(uid, 'stock.picking',pick,'button_done', cr)
|
||||
-
|
||||
I verify that picking for purchase order has been done.
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
from tools.translate import _
|
||||
modules = self.pool.get('ir.module.module')
|
||||
mod_pur = modules.search(cr, uid, [('name','=','purchase')])
|
||||
mod_brw = modules.browse(cr,uid,mod_pur)[0]
|
||||
if(mod_brw.state == 'installed'):
|
||||
pur_obj = self.pool.get('purchase.order')
|
||||
so = self.browse(cr, uid, ref("sale_order_so1"))
|
||||
pur_id = pur_obj.search(cr, uid, [('origin','=',so.name)])
|
||||
po = pur_obj.browse(cr, uid, pur_id)[0]
|
||||
picking, = po.picking_ids
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [picking.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
picking_obj = self.pool.get('stock.picking')
|
||||
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id ),('state', '=', 'done')])
|
||||
assert ids, _('Picking is not in the done state!')
|
||||
ids = picking_obj.search(cr, uid, [('purchase_id', '=', po.id),('state', '=', 'done')])
|
||||
assert ids, 'Picking should be marked done!'
|
||||
-
|
||||
I verify that a "Picked" has been set to true
|
||||
I verify that the sale order is marked as delivered
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so1"))
|
||||
assert (so.shipped == True), "Picking is not done."
|
||||
assert (so.shipped == True), "Sale order is not marked as delivered"
|
||||
-
|
||||
I verify that a sale order is in done state
|
||||
-
|
||||
|
|
|
@ -664,8 +664,8 @@ class stock_picking(osv.osv):
|
|||
|
||||
def action_process(self, cr, uid, ids, context=None):
|
||||
if context is None: context = {}
|
||||
partial_id = self.pool.get("stock.partial.picking").create(
|
||||
cr, uid, {}, context=dict(context, active_ids=ids))
|
||||
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',
|
||||
|
@ -677,7 +677,7 @@ class stock_picking(osv.osv):
|
|||
'nodestroy': True,
|
||||
'target': 'new',
|
||||
'domain': '[]',
|
||||
'context': dict(context, active_ids=ids)
|
||||
'context': context,
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -1470,6 +1470,8 @@ class stock_move(osv.osv):
|
|||
|
||||
def action_partial_move(self, cr, uid, ids, context=None):
|
||||
if context is None: context = {}
|
||||
if context.get('active_model') != self._name:
|
||||
context.update(active_ids=ids, active_model=self._name)
|
||||
partial_id = self.pool.get("stock.partial.move").create(
|
||||
cr, uid, {}, context=context)
|
||||
return {
|
||||
|
@ -2123,14 +2125,9 @@ class stock_move(osv.osv):
|
|||
""" Makes the move done and if all moves are done, it will finish the picking.
|
||||
@return:
|
||||
"""
|
||||
partial_datas=''
|
||||
picking_ids = []
|
||||
move_ids = []
|
||||
partial_obj=self.pool.get('stock.partial.picking')
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
partial_id=partial_obj.search(cr,uid,[])
|
||||
if partial_id:
|
||||
partial_datas = partial_obj.read(cr, uid, partial_id, context=context)[0]
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
|
@ -2160,9 +2157,6 @@ class stock_move(osv.osv):
|
|||
self.action_done(cr, uid, [move.move_dest_id.id], context=context)
|
||||
|
||||
self._create_product_valuation_moves(cr, uid, move, context=context)
|
||||
prodlot_id = partial_datas and partial_datas.get('move%s_prodlot_id' % (move.id), False)
|
||||
if prodlot_id:
|
||||
self.write(cr, uid, [move.id], {'prodlot_id': prodlot_id}, context=context)
|
||||
if move.state not in ('confirmed','done','assigned'):
|
||||
todo.append(move.id)
|
||||
|
||||
|
|
|
@ -287,16 +287,9 @@
|
|||
-
|
||||
!python {model: stock.picking }: |
|
||||
import time
|
||||
pick=self.browse(cr,uid,ref('stock_picking_0'))
|
||||
move =pick.move_lines[0]
|
||||
partial_datas = {
|
||||
'partner_id':pick.address_id.partner_id.id,
|
||||
'address_id': pick.address_id.id,
|
||||
'delivery_date' : time.strftime('%Y-%m-%d')
|
||||
}
|
||||
partial_datas['move%s'%(move.id)]= {
|
||||
'product_id': move.product_id,
|
||||
'product_qty': move.product_qty,
|
||||
'product_uom': move.product_uom.id,
|
||||
}
|
||||
self.do_partial(cr, uid, [ref('stock_picking_0')],partial_datas)
|
||||
pick = self.browse(cr,uid,ref('stock_picking_0'))
|
||||
stock_partial_picking = self.pool.get('stock.partial.picking')
|
||||
partial_id = stock_partial_picking.create(cr, uid, {},
|
||||
context={'active_model': 'stock.picking',
|
||||
'active_ids': [pick.id]})
|
||||
stock_partial_picking.do_partial(cr, uid, [partial_id])
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2004-TODAY OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -20,204 +20,65 @@
|
|||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
import time
|
||||
import decimal_precision as dp
|
||||
|
||||
class stock_partial_move_line(osv.osv_memory):
|
||||
_inherit = "stock.partial.picking.line"
|
||||
_name = "stock.partial.move.line"
|
||||
_columns = {
|
||||
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard", ondelete='CASCADE'),
|
||||
}
|
||||
|
||||
class stock_partial_move_memory_out(osv.osv_memory):
|
||||
_inherit = "stock.picking.memory.out"
|
||||
_name = "stock.move.memory.out"
|
||||
_columns = {
|
||||
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
|
||||
}
|
||||
|
||||
class stock_partial_move_memory_in(osv.osv_memory):
|
||||
_inherit = "stock.picking.memory.in"
|
||||
_name = "stock.move.memory.in"
|
||||
_columns = {
|
||||
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
|
||||
}
|
||||
|
||||
class stock_partial_move(osv.osv_memory):
|
||||
_name = "stock.partial.move"
|
||||
_description = "Partial Move"
|
||||
_inherit = 'stock.partial.picking'
|
||||
_description = "Partial Move Processing Wizard"
|
||||
_columns = {
|
||||
'date': fields.datetime('Date', required=True),
|
||||
'type': fields.char("Type", size=3),
|
||||
'product_moves_out' : fields.one2many('stock.move.memory.out', 'wizard_id', 'Moves'),
|
||||
'product_moves_in' : fields.one2many('stock.move.memory.in', 'wizard_id', 'Moves'),
|
||||
}
|
||||
|
||||
|
||||
def __is_in(self,cr, uid, move_ids):
|
||||
"""
|
||||
@return: True if one of the moves has as picking type 'in'
|
||||
"""
|
||||
if not move_ids:
|
||||
return False
|
||||
|
||||
move_obj = self.pool.get('stock.move')
|
||||
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
|
||||
|
||||
for move in move_obj.browse(cr, uid, move_ids):
|
||||
if move.picking_id.type == 'in' and move.product_id.cost_method == 'average':
|
||||
return True
|
||||
return False
|
||||
|
||||
def __get_picking_type(self, cr, uid, move_ids):
|
||||
if self.__is_in(cr, uid, move_ids):
|
||||
return "product_moves_in"
|
||||
else:
|
||||
return "product_moves_out"
|
||||
|
||||
def view_init(self, cr, uid, fields_list, context=None):
|
||||
res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
|
||||
move_obj = self.pool.get('stock.move')
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
for move in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
|
||||
if move.state in ('done', 'cancel'):
|
||||
raise osv.except_osv(_('Invalid action !'), _('Cannot deliver products which are already delivered !'))
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def __create_partial_move_memory(self, move):
|
||||
move_memory = {
|
||||
'product_id' : move.product_id.id,
|
||||
'quantity' : move.product_qty,
|
||||
'product_uom' : move.product_uom.id,
|
||||
'prodlot_id' : move.prodlot_id.id,
|
||||
'move_id' : move.id,
|
||||
}
|
||||
|
||||
if move.picking_id.type == 'in':
|
||||
move_memory.update({
|
||||
'cost' : move.product_id.standard_price,
|
||||
'currency' : move.product_id.company_id and move.product_id.company_id.currency_id and move.product_id.company_id.currency_id.id or False,
|
||||
})
|
||||
return move_memory
|
||||
'move_ids' : fields.one2many('stock.partial.move.line', 'wizard_id', 'Moves'),
|
||||
|
||||
def __get_active_stock_moves(self, cr, uid, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
res = []
|
||||
for move in move_obj.browse(cr, uid, context.get('active_ids', []), context=context):
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
res.append(self.__create_partial_move_memory(move))
|
||||
|
||||
# picking_id is not used for move processing, so we remove the required attribute
|
||||
# from the inherited column, and ignore it
|
||||
'picking_id': fields.many2one('stock.picking', 'Picking'),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
if context is None: context = {}
|
||||
# no call to super!
|
||||
res = {}
|
||||
move_ids = context.get('active_ids', [])
|
||||
if not move_ids or not context.get('active_model') == 'stock.move':
|
||||
return res
|
||||
if 'move_ids' in fields:
|
||||
move_ids = self.pool.get('stock.move').browse(cr, uid, move_ids, context=context)
|
||||
moves = [self._partial_move_for(cr, uid, m) for m in move_ids if m.state not in ('done','cancel')]
|
||||
res.update(move_ids=moves)
|
||||
if 'date' in fields:
|
||||
res.update(date=time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))
|
||||
return res
|
||||
|
||||
_defaults = {
|
||||
'product_moves_in' : __get_active_stock_moves,
|
||||
'product_moves_out' : __get_active_stock_moves,
|
||||
'date' : lambda *a : time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
message = {
|
||||
'title' : _('Deliver Products'),
|
||||
'info' : _('Delivery Information'),
|
||||
'button' : _('Deliver'),
|
||||
}
|
||||
if context:
|
||||
if context.get('product_receive', False):
|
||||
message = {
|
||||
'title' : _('Receive Products'),
|
||||
'info' : _('Receive Information'),
|
||||
'button' : _('Receive'),
|
||||
}
|
||||
|
||||
move_ids = context.get('active_ids', False)
|
||||
message['picking_type'] = self.__get_picking_type(cr, uid, move_ids)
|
||||
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
|
||||
_moves_fields = result['fields']
|
||||
_moves_fields.update({
|
||||
'product_moves_in' : {'relation': 'stock.move.memory.in', 'type' : 'one2many', 'string' : 'Product Moves'},
|
||||
'product_moves_out' : {'relation': 'stock.move.memory.out', 'type' : 'one2many', 'string' : 'Product Moves'}
|
||||
})
|
||||
|
||||
_moves_arch_lst = """
|
||||
<form string="%(title)s">
|
||||
<separator colspan="4" string="%(info)s"/>
|
||||
<field name="date" colspan="2"/>
|
||||
<separator colspan="4" string="Move Detail"/>
|
||||
<field name="%(picking_type)s" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" ></field>
|
||||
<separator string="" colspan="4" />
|
||||
<label string="" colspan="2"/>
|
||||
<group col="2" colspan="2">
|
||||
<button icon='gtk-cancel' special="cancel" string="_Cancel" />
|
||||
<button name="do_partial" string="%(button)s"
|
||||
colspan="1" type="object" icon="gtk-apply" />
|
||||
</group>
|
||||
</form> """ % message
|
||||
|
||||
result['arch'] = _moves_arch_lst
|
||||
result['fields'] = _moves_fields
|
||||
return result
|
||||
|
||||
|
||||
def do_partial(self, cr, uid, ids, context=None):
|
||||
""" Makes partial moves and pickings done.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
move_obj = self.pool.get('stock.move')
|
||||
|
||||
move_ids = context.get('active_ids', False)
|
||||
# no call to super!
|
||||
assert len(ids) == 1, 'Partial move processing may only be done one form at a time'
|
||||
partial = self.browse(cr, uid, ids[0], context=context)
|
||||
partial_datas = {
|
||||
partial_data = {
|
||||
'delivery_date' : partial.date
|
||||
}
|
||||
|
||||
p_moves = {}
|
||||
picking_type = self.__get_picking_type(cr, uid, move_ids)
|
||||
|
||||
moves_list = picking_type == 'product_moves_in' and partial.product_moves_in or partial.product_moves_out
|
||||
for product_move in moves_list:
|
||||
p_moves[product_move.move_id.id] = product_move
|
||||
|
||||
moves_ids_final = []
|
||||
for move in move_obj.browse(cr, uid, move_ids, context=context):
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
if not p_moves.get(move.id):
|
||||
continue
|
||||
partial_datas['move%s' % (move.id)] = {
|
||||
'product_id' : p_moves[move.id].product_id.id,
|
||||
'product_qty' : p_moves[move.id].quantity,
|
||||
'product_uom' :p_moves[move.id].product_uom.id,
|
||||
'prodlot_id' : p_moves[move.id].prodlot_id.id,
|
||||
moves_ids = []
|
||||
for move in partial.move_ids:
|
||||
move_id = move.move_id.id
|
||||
partial_data['move%s' % (move_id)] = {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.quantity,
|
||||
'product_uom': move.product_uom.id,
|
||||
'prodlot_id': move.prodlot_id.id,
|
||||
}
|
||||
|
||||
moves_ids_final.append(move.id)
|
||||
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s' % (move.id)].update({
|
||||
'product_price' : p_moves[move.id].cost,
|
||||
'product_currency': p_moves[move.id].currency.id,
|
||||
})
|
||||
|
||||
|
||||
move_obj.do_partial(cr, uid, moves_ids_final, partial_datas, context=context)
|
||||
moves_ids.append(move_id)
|
||||
if (move.move_id.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
partial_data['move%s' % (move_id)].update(product_price=move.cost,
|
||||
product_currency=move.currency.id)
|
||||
self.pool.get('stock.move').do_partial(cr, uid, moves_ids, partial_data, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
stock_partial_move()
|
||||
stock_partial_move_memory_out()
|
||||
stock_partial_move_memory_in()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,16 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
|
||||
|
||||
<record id="action_partial_move_server" model="ir.actions.server">
|
||||
<field name="name">Deliver/Receive Products</field>
|
||||
<field name="model_id" ref="model_stock_move"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = obj.action_partial_move(context=context)</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="ir_open_partial_move_wizard" model="ir.values">
|
||||
<field eval="'client_action_multi'" name="key2"/>
|
||||
<field eval="'stock.move'" name="model"/>
|
||||
|
@ -19,75 +16,60 @@
|
|||
<field eval="True" name="object"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record id="stock_move_memory_tree_in" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.tree</field>
|
||||
<field name="model">stock.move.memory.in</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Product Moves">
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="cost" />
|
||||
<field name="currency" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_move_memory_form_in" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.form</field>
|
||||
<field name="model">stock.move.memory.in</field>
|
||||
<record id="stock_partial_move_form" model="ir.ui.view">
|
||||
<field name="name">stock.partial.move.form</field>
|
||||
<field name="model">stock.partial.move</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="cost" />
|
||||
<field name="currency" />
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_move_memory_tree_out" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.tree</field>
|
||||
<field name="model">stock.move.memory.out</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Product Moves">
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_move_memory_form_out" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.form</field>
|
||||
<field name="model">stock.move.memory.out</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<separator colspan="4" string="Products"/>
|
||||
<field name="move_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200"/>
|
||||
<separator string="" colspan="4" />
|
||||
<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" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</record>
|
||||
|
||||
<record id="stock_partial_move_line_list" model="ir.ui.view">
|
||||
<field name="name">stock.partial.move.line.list</field>
|
||||
<field name="model">stock.partial.move.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Product Moves">
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="update_cost" invisible="1"/>
|
||||
<field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
<field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_partial_move_line_form" model="ir.ui.view">
|
||||
<field name="name">stock.partial.move.line.form</field>
|
||||
<field name="model">stock.partial.move.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="update_cost" invisible="1"/>
|
||||
<field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
<field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2004-TODAY OpenERP SA (<http://openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -20,191 +19,119 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import time
|
||||
from osv import fields, osv
|
||||
from tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
class stock_partial_picking_memory_out(osv.osv_memory):
|
||||
_name = "stock.picking.memory.out"
|
||||
class stock_partial_picking_line(osv.TransientModel):
|
||||
_name = "stock.partial.picking.line"
|
||||
_rec_name = 'product_id'
|
||||
_columns = {
|
||||
'product_id' : fields.many2one('product.product', string="Product", required=True),
|
||||
'product_id' : fields.many2one('product.product', string="Product", required=True, ondelete='CASCADE'),
|
||||
'quantity' : fields.float("Quantity", required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True),
|
||||
'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot'),
|
||||
'location_id': fields.many2one('stock.location', 'Location', required=True),
|
||||
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True),
|
||||
'move_id' : fields.many2one('stock.move', "Move"),
|
||||
'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard"),
|
||||
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, ondelete='CASCADE'),
|
||||
'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot', ondelete='CASCADE'),
|
||||
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete='CASCADE'),
|
||||
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, ondelete='CASCADE'),
|
||||
'move_id' : fields.many2one('stock.move', "Move", ondelete='CASCADE'),
|
||||
'wizard_id' : fields.many2one('stock.partial.picking', string="Wizard", ondelete='CASCADE'),
|
||||
'update_cost': fields.boolean('Need cost update'),
|
||||
'cost' : fields.float("Cost", help="Unit Cost for this product line"),
|
||||
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed"),
|
||||
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
||||
}
|
||||
|
||||
class stock_partial_picking_memory_in(osv.osv_memory):
|
||||
_inherit = "stock.picking.memory.out"
|
||||
_name = "stock.picking.memory.in"
|
||||
|
||||
class stock_partial_picking(osv.osv_memory):
|
||||
_name = "stock.partial.picking"
|
||||
_description = "Partial Picking"
|
||||
_description = "Partial Picking Processing Wizard"
|
||||
_columns = {
|
||||
'date': fields.datetime('Date', required=True),
|
||||
'product_moves_out' : fields.one2many('stock.picking.memory.out', 'wizard_id', 'Moves'),
|
||||
'product_moves_in' : fields.one2many('stock.picking.memory.in', 'wizard_id', 'Moves'),
|
||||
'move_ids' : fields.one2many('stock.partial.picking.line', 'wizard_id', 'Product Moves'),
|
||||
'picking_id': fields.many2one('stock.picking', 'Picking', required=True, ondelete='CASCADE'),
|
||||
}
|
||||
|
||||
def get_picking_type(self, cr, uid, picking, context=None):
|
||||
picking_type = picking.type
|
||||
for move in picking.move_lines:
|
||||
if picking.type == 'in' and move.product_id.cost_method == 'average':
|
||||
picking_type = 'in'
|
||||
break
|
||||
else:
|
||||
picking_type = 'out'
|
||||
return picking_type
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
""" To get default values for the object.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
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:
|
||||
if not picking_ids or (not context.get('active_model') == 'stock.picking') \
|
||||
or len(picking_ids) != 1:
|
||||
# Partial Picking Processing may only be done for one picking at a time
|
||||
return res
|
||||
|
||||
result = []
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
|
||||
pick_type = self.get_picking_type(cr, uid, pick, context=context)
|
||||
for m in pick.move_lines:
|
||||
if m.state in ('done', 'cancel'):
|
||||
continue
|
||||
result.append(self.__create_partial_picking_memory(m, pick_type))
|
||||
|
||||
if 'product_moves_in' in fields:
|
||||
res.update({'product_moves_in': result})
|
||||
if 'product_moves_out' in fields:
|
||||
res.update({'product_moves_out': result})
|
||||
picking_id, = picking_ids
|
||||
if 'picking_id' in fields:
|
||||
res.update(picking_id=picking_id)
|
||||
if 'move_ids' in fields:
|
||||
picking = self.pool.get('stock.picking').browse(cr, uid, picking_id, context=context)
|
||||
moves = [self._partial_move_for(cr, uid, m) for m in picking.move_lines if m.state not in ('done','cancel')]
|
||||
res.update(move_ids=moves)
|
||||
if 'date' in fields:
|
||||
res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
res.update(date=time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))
|
||||
return res
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
result = super(stock_partial_picking, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
|
||||
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
picking_ids = context.get('active_ids', False)
|
||||
|
||||
if not picking_ids:
|
||||
# not called through an action (e.g. buildbot), return the default.
|
||||
return result
|
||||
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
|
||||
picking_type = self.get_picking_type(cr, uid, pick, context=context)
|
||||
def _product_cost_for_average_update(self, cr, uid, move):
|
||||
"""Returns product cost and currency ID for the given move, suited for re-computing
|
||||
the average product cost.
|
||||
|
||||
_moves_arch_lst = """<form string="%s">
|
||||
<field name="date" invisible="1"/>
|
||||
<separator colspan="4" string="%s"/>
|
||||
<field name="%s" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" ></field>
|
||||
""" % (_('Process Document'), _('Products'), "product_moves_" + picking_type)
|
||||
_moves_fields = result['fields']
|
||||
:return: map of the form::
|
||||
|
||||
# add field related to picking type only
|
||||
_moves_fields.update({
|
||||
'product_moves_' + picking_type: {'relation': 'stock.move.memory.'+picking_type, 'type' : 'one2many', 'string' : 'Product Moves'},
|
||||
})
|
||||
{'cost': 123.34,
|
||||
'currency': 42}
|
||||
"""
|
||||
# Currently, the cost on the product form is supposed to be expressed in the currency
|
||||
# of the company owning the product. If not set, we fall back to the picking's company,
|
||||
# which should work in simple cases.
|
||||
return {'cost': move.product_id.standard_price,
|
||||
'currency': move.product_id.company_id.currency_id.id \
|
||||
or move.picking_id.company_id.currency_id.id \
|
||||
or False}
|
||||
|
||||
_moves_arch_lst += """
|
||||
<separator string="" colspan="4" />
|
||||
<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" />
|
||||
</group>
|
||||
</form>"""
|
||||
result['arch'] = _moves_arch_lst
|
||||
result['fields'] = _moves_fields
|
||||
return result
|
||||
|
||||
def __create_partial_picking_memory(self, picking, pick_type):
|
||||
move_memory = {
|
||||
'product_id' : picking.product_id.id,
|
||||
'quantity' : picking.product_qty,
|
||||
'product_uom' : picking.product_uom.id,
|
||||
'prodlot_id' : picking.prodlot_id.id,
|
||||
'move_id' : picking.id,
|
||||
'location_id' : picking.location_id.id,
|
||||
'location_dest_id' : picking.location_dest_id.id,
|
||||
def _partial_move_for(self, cr, uid, move):
|
||||
partial_move = {
|
||||
'product_id' : move.product_id.id,
|
||||
'quantity' : move.product_qty,
|
||||
'product_uom' : move.product_uom.id,
|
||||
'prodlot_id' : move.prodlot_id.id,
|
||||
'move_id' : move.id,
|
||||
'location_id' : move.location_id.id,
|
||||
'location_dest_id' : move.location_dest_id.id,
|
||||
}
|
||||
|
||||
if pick_type == 'in':
|
||||
move_memory.update({
|
||||
'cost' : picking.product_id.standard_price,
|
||||
'currency' : picking.product_id.company_id and picking.product_id.company_id.currency_id and picking.product_id.company_id.currency_id.id or False,
|
||||
})
|
||||
return move_memory
|
||||
if move.picking_id.type == 'in' and move.product_id.cost_method == 'average':
|
||||
partial_move.update(update_cost=True, **self._product_cost_for_average_update(cr, uid, move))
|
||||
return partial_move
|
||||
|
||||
def do_partial(self, cr, uid, ids, context=None):
|
||||
""" Makes partial moves and pickings done.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
stock_move_obj = self.pool.get('stock.move')
|
||||
picking_ids = context.get('active_ids', False)
|
||||
assert len(ids) == 1, 'Partial picking processing may only be done one at a time'
|
||||
stock_picking = self.pool.get('stock.picking')
|
||||
stock_move = self.pool.get('stock.move')
|
||||
partial = self.browse(cr, uid, ids[0], context=context)
|
||||
partial_datas = {
|
||||
partial_data = {
|
||||
'delivery_date' : partial.date
|
||||
}
|
||||
for pick in pick_obj.browse(cr, uid, picking_ids, context=context):
|
||||
picking_type = self.get_picking_type(cr, uid, pick, context=context)
|
||||
moves_list = picking_type == 'in' and partial.product_moves_in or partial.product_moves_out
|
||||
for move in moves_list:
|
||||
if not move.move_id.id:
|
||||
seq_obj_name = 'stock.picking.' + picking_type
|
||||
move_id = stock_move_obj.create(cr,uid,{'name' : self.pool.get('ir.sequence').get(cr, uid, seq_obj_name),
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.quantity,
|
||||
'product_uom': move.product_uom.id,
|
||||
'prodlot_id': move.prodlot_id.id,
|
||||
'location_id' : move.location_id.id,
|
||||
'location_dest_id' : move.location_dest_id.id,
|
||||
'picking_id': pick.id
|
||||
},context=context)
|
||||
stock_move_obj.action_done(cr, uid, [move_id], context)
|
||||
else:
|
||||
move_id = move.move_id.id
|
||||
|
||||
partial_datas['move%s' % (move_id)] = {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.quantity,
|
||||
'product_uom': move.product_uom.id,
|
||||
'prodlot_id': move.prodlot_id.id,
|
||||
}
|
||||
if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s' % (move.move_id.id)].update({
|
||||
'product_price' : move.cost,
|
||||
'product_currency': move.currency.id,
|
||||
})
|
||||
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
|
||||
picking_type = partial.picking_id.type
|
||||
for move in partial.move_ids:
|
||||
move_id = move.move_id.id
|
||||
if not move_id:
|
||||
seq_obj_name = 'stock.picking.' + picking_type
|
||||
move_id = stock_move.create(cr,uid,{'name' : self.pool.get('ir.sequence').get(cr, uid, seq_obj_name),
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.quantity,
|
||||
'product_uom': move.product_uom.id,
|
||||
'prodlot_id': move.prodlot_id.id,
|
||||
'location_id' : move.location_id.id,
|
||||
'location_dest_id' : move.location_dest_id.id,
|
||||
'picking_id': partial.picking_id.id
|
||||
},context=context)
|
||||
stock_move.action_done(cr, uid, [move_id], context)
|
||||
partial_data['move%s' % (move_id)] = {
|
||||
'product_id': move.product_id.id,
|
||||
'product_qty': move.quantity,
|
||||
'product_uom': move.product_uom.id,
|
||||
'prodlot_id': move.prodlot_id.id,
|
||||
}
|
||||
if (picking_type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
partial_data['move%s' % (move.move_id.id)].update(product_price=move.cost,
|
||||
product_currency=move.currency.id)
|
||||
stock_picking.do_partial(cr, uid, [partial.picking_id.id], partial_data, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
stock_partial_picking()
|
||||
stock_partial_picking_memory_out()
|
||||
stock_partial_picking_memory_in()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -9,5 +9,59 @@
|
|||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<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>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<separator colspan="4" string="Products"/>
|
||||
<field name="move_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200"/>
|
||||
<separator string="" colspan="4" />
|
||||
<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" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_partial_picking_line_list" model="ir.ui.view">
|
||||
<field name="name">stock.partial.picking.line.list</field>
|
||||
<field name="model">stock.partial.picking.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Product Moves">
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="update_cost" invisible="1"/>
|
||||
<field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
<field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="stock_partial_picking_line_form" model="ir.ui.view">
|
||||
<field name="name">stock.partial.picking.line.form</field>
|
||||
<field name="model">stock.partial.picking.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom" />
|
||||
<field name="location_id" />
|
||||
<field name="location_dest_id" />
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" />
|
||||
<field name="update_cost" invisible="1"/>
|
||||
<field name="cost" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
<field name="currency" attrs="{'invisible': [('update_cost','=', False)]}"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -38,27 +38,12 @@
|
|||
"active_ids": [ref("stock.menu_action_picking_tree")], "active_id": ref("stock.menu_action_picking_tree"),
|
||||
})
|
||||
-
|
||||
I create a record for partial picking.
|
||||
-
|
||||
!record {model: stock.partial.picking, id: stock_partial_picking_0}:
|
||||
date: !eval time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
-
|
||||
I make picking order Done.
|
||||
I process the delivery
|
||||
-
|
||||
!python {model: stock.partial.picking}: |
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
partial = self.browse(cr, uid, ref('stock_partial_picking_0'), context)
|
||||
partial_datas = {
|
||||
'delivery_date' : partial.date
|
||||
}
|
||||
for pick in pick_obj.browse(cr, uid, [ref('stock_picking_out0')]):
|
||||
for m in pick.move_lines:
|
||||
partial_datas['move%s'%(m.id)] = {
|
||||
'product_id' : m.product_id.id,
|
||||
'product_qty' : m.product_qty,
|
||||
'product_uom' : m.product_uom.id
|
||||
}
|
||||
pick_obj.do_partial(cr, uid, [ref('stock_picking_out0')], partial_datas, context=context)
|
||||
partial_id = self.create(cr, uid, {}, context={'active_model':'stock.picking',
|
||||
'active_ids':[ref('stock_picking_out0')]})
|
||||
self.do_partial(cr, uid, [partial_id])
|
||||
-
|
||||
As the Invoice state of the picking order is To be invoiced. I create invoice for my outgoing picking order.
|
||||
-
|
||||
|
|
|
@ -25,24 +25,15 @@ class invoice_directly(osv.osv_memory):
|
|||
_inherit = 'stock.partial.picking'
|
||||
|
||||
def do_partial(self, cr, uid, ids, context=None):
|
||||
""" Makes partial moves and pickings done and
|
||||
launches Create invoice wizard if invoice state is To be Invoiced.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param context: A standard dictionary
|
||||
@return:
|
||||
"""Launch Create invoice wizard if invoice state is To be Invoiced,
|
||||
after processing the partial picking.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
if context is None: context = {}
|
||||
result = super(invoice_directly, self).do_partial(cr, uid, ids, context)
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
context.update({'active_model':'stock.picking'})
|
||||
picking_ids = context.get('active_ids', False)
|
||||
if picking_ids:
|
||||
context.update({'active_id':picking_ids[0]})
|
||||
pick = pick_obj.browse(cr, uid, picking_ids, context=context)[0]
|
||||
if pick.invoice_state == '2binvoiced':
|
||||
partial = self.browse(cr, uid, ids[0], context)
|
||||
context.update(active_model='stock.picking',
|
||||
active_ids=[partial.picking_id.id])
|
||||
if partial.picking_id.invoice_state == '2binvoiced':
|
||||
return {
|
||||
'name': 'Create Invoice',
|
||||
'view_type': 'form',
|
||||
|
@ -55,5 +46,5 @@ class invoice_directly(osv.osv_memory):
|
|||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
invoice_directly()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
Loading…
Reference in New Issue