问题描述
好的,所以我一直在解决这个问题太久了。
我想在网上商店和 odoo 之间同步跟踪大量产品的库存水平。出于这个原因,我需要能够通过 API 进行大量的库存调整(在这种情况下是在 python 中)。
我发现了这种可能的方法:
odoo(
'stock.move','create',[{
"name": "Webshop stock adjustment","company_id": 1,"location_id": 8,# warehouse
"location_dest_id": 14,# virtual location
"product_id": batch["product_id"][0],"product_uom": 1,"lot_ids": [batch["id"]],# I am searching for the id by the lot name beforehand
"product_uom_qty": 1,"quantity_done": 1,"state": "done"
}]
)
然而,这会导致两个动作!一个移动有正确的手数,另一个没有指定手数。后者的举动当然是错误的,因为对产品进行了批量跟踪。这会导致错误批次条目,我无法手动更改数量,因为该字段无效。更糟糕的是,它会导致错误的库存水平。 You can see the problematic bookings here
我尝试创建一个 stock.move.line,如下所示:
odoo(
'stock.move.line',[{
"company_id": 1,"display_name": "Webshop adjustment",# does not appear
"location_id": location_id,"location_dest_id": location_dest_id,"product_id": batch["product_id"][0],"product_uom_id": 1,"lot_id": batch["id"],"product_uom_qty": quantity,"qty_done": quantity,"state": "done" # has no effect
}]
)
然而,这会导致一行无效:Line
我也试图找到股票调整向导,但我在代码中找到的唯一一个而不是用户界面,没有一个用于批次的字段..
我很乐意就如何解决这个问题提供任何意见!
解决方法
与此同时,我设法可靠地解决了这个问题。我需要为此实现一个函数,而不是使用外部 API。
此处的函数期望 vals
具有以下格式。它减少了需要先处理的批次。
[{
'sku': sku,'qty': quantity
},]
@api.model
def reduce_lots(self,vals):
log(vals)
for product_req in vals:
product = self.env['product.product'].search(
[['default_code','=',product_req['sku']]]
)
if len(product) == 0:
return "product not found"
lots = self.env['stock.quant'].search(
['&',('product_id',product[0]['id']),('on_hand',True)],order='removal_date asc'
)
move = self.env['stock.move'].create({
'name': product_req['order'],'location_id': 8,# Our Warehouse
'location_dest_id': 14,# Virtual Location,Customer. If you need to increase stock,reverse the two numbers.
'product_id': product.id,'product_uom': product.uom_id.id,'product_uom_qty': product_req['qty'],})
move._action_confirm()
move._action_assign()
product_req['lots'] = []
for line in move.move_line_ids:
line.write({'qty_done': line['product_uom_qty']})
product_req['lots'].append({
'_qty': line['product_uom_qty'],'_lot_id': line.lot_id.name,'_best_before': line.lot_id.removal_date
})
move._action_done()
return vals