添加禁止负库存功能
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
# 'security/sf_stock_security.xml',
|
# 'security/sf_stock_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'wizard/wizard_view.xml',
|
'wizard/wizard_view.xml',
|
||||||
|
'views/product.xml',
|
||||||
'views/view.xml',
|
'views/view.xml',
|
||||||
'views/shelf_location.xml',
|
'views/shelf_location.xml',
|
||||||
'views/change_stock_move_views.xml',
|
'views/change_stock_move_views.xml',
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
from . import model
|
from . import model
|
||||||
from . import sync_common
|
from . import sync_common
|
||||||
|
from . import product
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ class ShelfLocation(models.Model):
|
|||||||
record.display_rfid = record.product_sn_id.rfid if record.product_sn_id else ''
|
record.display_rfid = record.product_sn_id.rfid if record.product_sn_id else ''
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
record.display_rfid = ''
|
record.display_rfid = ''
|
||||||
|
|
||||||
@api.depends('product_id')
|
@api.depends('product_id')
|
||||||
def _compute_tool(self):
|
def _compute_tool(self):
|
||||||
"""计算工具 RFID"""
|
"""计算工具 RFID"""
|
||||||
@@ -594,7 +594,7 @@ class ShelfLocation(models.Model):
|
|||||||
_layer_capacity = _cc_code % record.shelf_id.layer_capacity
|
_layer_capacity = _cc_code % record.shelf_id.layer_capacity
|
||||||
if _layer_capacity == 0:
|
if _layer_capacity == 0:
|
||||||
_layer_capacity = record.shelf_id.layer_capacity
|
_layer_capacity = record.shelf_id.layer_capacity
|
||||||
else:
|
else:
|
||||||
_layer_capacity = _layer_capacity
|
_layer_capacity = _layer_capacity
|
||||||
_layer = _layer+1
|
_layer = _layer+1
|
||||||
_layer_capacity = f"{_layer_capacity:02d}"
|
_layer_capacity = f"{_layer_capacity:02d}"
|
||||||
@@ -634,7 +634,7 @@ class SfShelfLocationLot(models.Model):
|
|||||||
for item in self:
|
for item in self:
|
||||||
if item.qty_num > item.qty:
|
if item.qty_num > item.qty:
|
||||||
raise ValidationError('变更数量不能比库存数量大!!!')
|
raise ValidationError('变更数量不能比库存数量大!!!')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SfStockMoveLine(models.Model):
|
class SfStockMoveLine(models.Model):
|
||||||
@@ -899,7 +899,7 @@ class SfStockMoveLine(models.Model):
|
|||||||
def _compute_current_location_id(self):
|
def _compute_current_location_id(self):
|
||||||
# 批量获取所有相关记录的picking
|
# 批量获取所有相关记录的picking
|
||||||
pickings = self.mapped('picking_id')
|
pickings = self.mapped('picking_id')
|
||||||
|
|
||||||
# 构建源picking的移库行与目标位置的映射
|
# 构建源picking的移库行与目标位置的映射
|
||||||
origin_location_map = {}
|
origin_location_map = {}
|
||||||
for picking in pickings:
|
for picking in pickings:
|
||||||
@@ -907,11 +907,11 @@ class SfStockMoveLine(models.Model):
|
|||||||
origin_move = picking.move_ids[:1].move_orig_ids[:1]
|
origin_move = picking.move_ids[:1].move_orig_ids[:1]
|
||||||
if not origin_move:
|
if not origin_move:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
origin_picking = origin_move.picking_id
|
origin_picking = origin_move.picking_id
|
||||||
if not origin_picking:
|
if not origin_picking:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 为每个picking构建lot_id到location的映射
|
# 为每个picking构建lot_id到location的映射
|
||||||
origin_location_map[picking.id] = {
|
origin_location_map[picking.id] = {
|
||||||
move_line.lot_id.id: move_line.destination_location_id
|
move_line.lot_id.id: move_line.destination_location_id
|
||||||
@@ -919,17 +919,17 @@ class SfStockMoveLine(models.Model):
|
|||||||
lambda ml: ml.destination_location_id and ml.lot_id
|
lambda ml: ml.destination_location_id and ml.lot_id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# 批量更新current_location_id
|
# 批量更新current_location_id
|
||||||
for record in self:
|
for record in self:
|
||||||
current_picking = record.picking_id
|
current_picking = record.picking_id
|
||||||
if not current_picking:
|
if not current_picking:
|
||||||
record.current_location_id = False
|
record.current_location_id = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 获取当前picking对应的lot_location映射
|
# 获取当前picking对应的lot_location映射
|
||||||
lot_dest_map = origin_location_map.get(current_picking.id, {})
|
lot_dest_map = origin_location_map.get(current_picking.id, {})
|
||||||
|
|
||||||
# 查找匹配的lot_id
|
# 查找匹配的lot_id
|
||||||
for move_line in current_picking.move_line_ids:
|
for move_line in current_picking.move_line_ids:
|
||||||
if move_line.lot_id and move_line.lot_id.id in lot_dest_map:
|
if move_line.lot_id and move_line.lot_id.id in lot_dest_map:
|
||||||
@@ -1082,6 +1082,10 @@ class SfStockPicking(models.Model):
|
|||||||
重写验证方法,当验证时意味着调拨单已经完成,已经移动到了目标货位,所以需要将当前货位的状态改为空闲
|
重写验证方法,当验证时意味着调拨单已经完成,已经移动到了目标货位,所以需要将当前货位的状态改为空闲
|
||||||
"""
|
"""
|
||||||
res = super(SfStockPicking, self).button_validate()
|
res = super(SfStockPicking, self).button_validate()
|
||||||
|
if any(ml.state == 'done' for ml in self.move_line_ids):
|
||||||
|
# 验证产品库存为负库存问题
|
||||||
|
self.move_ids.product_id.verify_product_repertory(self.location_id)
|
||||||
|
|
||||||
for line in self.move_line_ids:
|
for line in self.move_line_ids:
|
||||||
if line:
|
if line:
|
||||||
if line.destination_location_id:
|
if line.destination_location_id:
|
||||||
|
|||||||
29
sf_warehouse/models/product.py
Normal file
29
sf_warehouse/models/product.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from odoo import models, fields
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class SfProductCategory(models.Model):
|
||||||
|
_inherit = 'product.category'
|
||||||
|
|
||||||
|
negative_inventory_allowed = fields.Boolean('可负库存', default=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SfProductTemplate(models.Model):
|
||||||
|
_inherit = 'product.product'
|
||||||
|
|
||||||
|
def verify_product_repertory(self, location_id):
|
||||||
|
"""
|
||||||
|
验证产品 负库存
|
||||||
|
"""
|
||||||
|
if not location_id:
|
||||||
|
raise ValidationError('当前位置为空!!')
|
||||||
|
elif len(location_id) != 1:
|
||||||
|
raise ValidationError(f'存在多个当前位置{[item.name for item in location_id]}')
|
||||||
|
elif location_id.usage == 'supplier':
|
||||||
|
return True
|
||||||
|
for pp in self:
|
||||||
|
if not pp.categ_id.negative_inventory_allowed:
|
||||||
|
sq = pp.stock_quant_ids.filtered(lambda sq: sq.quantity < 0 and sq.location_id == location_id)
|
||||||
|
if sq:
|
||||||
|
raise ValidationError(
|
||||||
|
f'产品{pp.name}的产品类型设置为不可负库存,当前操作会导致产品{pp.name}在库存{location_id.name}上的库存数量为负!!!')
|
||||||
17
sf_warehouse/views/product.xml
Normal file
17
sf_warehouse/views/product.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="product_category_form_view_sf_warehouse" model="ir.ui.view">
|
||||||
|
<field name="name">product.category.property.form.warehouse</field>
|
||||||
|
<field name="model">product.category</field>
|
||||||
|
<field name="inherit_id" ref="account.view_category_property_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//group[@name='account_property']" position="after">
|
||||||
|
<group name="other">
|
||||||
|
<group string="其他">
|
||||||
|
<field name="negative_inventory_allowed"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user