Files
test/sf_warehouse/models/model.py
2023-11-27 17:08:11 +08:00

270 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
from odoo import api, fields, models
from odoo.osv import expression
class SfLocation(models.Model):
_inherit = 'stock.location'
# 重写字段定义
name = fields.Char('Location Name', required=True, size=20)
barcode = fields.Char('Barcode', copy=False, size=15)
# 仓库类别selection库区、库位、货位
location_type = fields.Selection([
('库区', '库区'),
('货架', '货架'),
('货位', '货位')
], string='存储类型')
# 库区类型selection拣货区、存货区、收货区、退货区、次品区
area_type = fields.Selection([
('拣货区', '拣货区'),
('存货区', '存货区'),
('收货区', '收货区'),
('退货区', '退货区'),
('次品区', '次品区')
], string='库区类型')
# 存储类型selection库区、货架
# storage_type = fields.Selection([
# ('库区', '库区'),
# ('货架', '货架')
# ], string='存储类型')
# 产品类别 关联product.category
product_type = fields.Many2many('product.category', string='产品类别')
# 货架独有字段通道、方向、货架高度m、货架层数、层数容量
channel = fields.Char(string='通道')
direction = fields.Selection([
('R', 'R'),
('L', 'L')
], string='方向')
shelf_height = fields.Float(string='货架高度(m)')
shelf_layer = fields.Integer(string='货架层数')
layer_capacity = fields.Integer(string='层数容量')
# 货位独有字段:货位状态、产品(关联产品对象)、产品序列号(关联产品序列号对象)
location_status = fields.Selection([
('空闲', '空闲'),
('占用', '占用'),
('禁用', '禁用')
], string='货位状态', default='空闲')
# product_id = fields.Many2one('product.template', string='产品')
product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', readonly=True)
product_sn_id = fields.Many2one('stock.lot', string='产品序列号')
# time_test = fields.Char(string='time')
# 添加SQL约束
# _sql_constraints = [
# ('name_uniq', 'unique(name)', '位置名称必须唯一!'),
# ]
hide_location_type = fields.Boolean(compute='_compute_hide_what', string='隐藏仓库')
hide_area = fields.Boolean(compute='_compute_hide_what', string='隐藏库区')
hide_shelf = fields.Boolean(compute='_compute_hide_what', string='隐藏货架')
hide_location = fields.Boolean(compute='_compute_hide_what', string='隐藏货位')
# @api.model
# def create(self, vals):
# """
# 重写create方法添加自定义的约束
# """
# print('create', vals)
# if vals.get('location_id'):
# location = self.env['stock.location'].browse(vals.get('location_id'))
# if location.storage_type == '库区':
# raise UserError('库区不能作为父级仓库')
# return super().create(vals)
#
# @api.onchange('location_id')
# def _onchange_location_id(self):
# """
# 重写onchange方法添加自定义的约束
# """
# if self.location_id:
# if self.location_id.storage_type == '库区':
# raise UserError('库区不能作为父级仓库')
# @api.constrains('shelf_height')
# def _check_shelf_height(self):
# for record in self:
# if not (0 <= record.shelf_height < 1000): # 限制字段值在0到999之间
# raise UserError('shelf_height的值必须在0到1000之间')
#
# @api.constrains('shelf_layer')
# def _check_shelf_layer(self):
# for record in self:
# if not (0 < record.shelf_layer < 1000):
# raise UserError('shelf_layer的值必须在0到999之间,且不能为0')
#
# @api.constrains('layer_capacity')
# def _check_layer_capacity(self):
# for record in self:
# if not (0 <= record.layer_capacity < 1000):
# raise UserError('layer_capacity的值必须在0到999之间,且不能为0')
@api.depends('product_sn_id')
def _compute_product_id(self):
"""
根据产品序列号,获取产品
"""
for record in self:
if record.product_sn_id:
record.product_id = record.product_sn_id.product_id
record.location_status = '占用'
else:
record.product_id = False
# record.location_status = '空闲'
@api.depends('location_type')
def _compute_hide_what(self):
"""
根据仓库类别,隐藏不需要的字段
:return:
"""
for record in self:
record.hide_location_type = False
record.hide_area = False
record.hide_shelf = False
record.hide_location = False
if record.location_type and record.location_type == '仓库':
record.hide_location_type = True
elif record.location_type and record.location_type == '库区':
record.hide_area = True
elif record.location_type and record.location_type == '货架':
record.hide_shelf = True
elif record.location_type and record.location_type == '货位':
record.hide_location = True
else:
pass
# # 添加Python约束
# @api.constrains('name', 'barcode')
# def _check_len(self):
# for rec in self:
# if len(rec.name) > 20:
# raise ValidationError("Location Name length must be less equal than 20!")
# if len(rec.barcode) > 15:
# raise ValidationError("Barcode length must be less equal than 15!")
# @api.model
# def default_get(self, fields):
# print('fields:', fields)
# res = super(SfLocation, self).default_get(fields)
# print('res:', res)
# if 'barcode' in fields and 'barcode' not in res:
# # 这里是你生成barcode的代码
# pass
# # res['barcode'] = self.generate_barcode() # 假设你有一个方法generate_barcode来生成barcode
# return res
# @api.model
# def create(self, vals):
# """
# 重写create方法当仓库类型为货架时自动生成其下面的货位数量为货架层数*层数容量
# """
# res = super(SfLocation, self).create(vals)
# if res.location_type == '货架':
# for i in range(res.shelf_layer):
# for j in range(res.layer_capacity):
# self.create({
# 'name': res.name + '-' + str(i+1) + '-' + str(j+1),
# 'location_id': res.id,
# 'location_type': '货位',
# 'barcode': self.generate_barcode(res, i, j),
# 'location_status': '空闲'
# })
# return res
# 生成货位
def create_location(self):
"""
当仓库类型为货架时,自动生成其下面的货位,数量为货架层数*层数容量
"""
if self.location_type == '货架':
for i in range(self.shelf_layer):
for j in range(self.layer_capacity):
self.create({
'name': self.name + '-' + str(i + 1) + '' + '-' + str(j + 1) + '位置',
'location_id': self.id,
'location_type': '货位',
'barcode': self.generate_barcode(i, j),
'location_status': '空闲'
})
def generate_barcode(self, i, j):
"""
生成货位条码
"""
# 这里是你生成barcode的代码
# area_type_barcode = self.location_id.barcode
area_type_barcode = self.barcode
i_str = str(i + 1).zfill(3) # 确保是两位数如果不足两位左侧补0
j_str = str(j + 1).zfill(3) # 确保是两位数如果不足两位左侧补0
return area_type_barcode + self.channel + self.direction + '-' + self.barcode + '-' + i_str + '-' + j_str
# def generate_barcode(self, i, j):
# # 这里是你生成barcode的代码
# area_type_barcode = self.location_id.barcode
# return area_type_barcode + self.channel + self.direction + '-' + self.barcode + '-' + str(i + 1) + '-'
# + str(j + 1)
class SfProcurementGroup(models.Model):
_inherit = 'procurement.group'
@api.model
def _search_rule(self, route_ids, packaging_id, product_id, warehouse_id, domain):
"""
修改路线多规则条件选取
"""
if warehouse_id:
domain = expression.AND(
[['|', ('warehouse_id', '=', warehouse_id.id), ('warehouse_id', '=', False)], domain])
Rule = self.env['stock.rule']
res = self.env['stock.rule']
if route_ids:
res_list = Rule.search(expression.AND([[('route_id', 'in', route_ids.ids)], domain]),
order='route_sequence, sequence')
for res1 in res_list:
if product_id.categ_id in res1.location_dest_id.product_type or product_id.categ_id in \
res1.location_src_id.product_type:
res = res1
if not res:
res = Rule.search(expression.AND([[('route_id', 'in', route_ids.ids)], domain]),
order='route_sequence, sequence', limit=1)
if not res and packaging_id:
packaging_routes = packaging_id.route_ids
if packaging_routes:
res_list = Rule.search(expression.AND([[('route_id', 'in', packaging_routes.ids)], domain]),
order='route_sequence, sequence')
for res1 in res_list:
if product_id.categ_id in res1.location_dest_id.product_type or product_id.categ_id in \
res1.location_src_id.product_type:
res = res1
if not res:
res = Rule.search(expression.AND([[('route_id', 'in', packaging_routes.ids)], domain]),
order='route_sequence, sequence', limit=1)
if not res:
product_routes = product_id.route_ids | product_id.categ_id.total_route_ids
if product_routes:
res_list = Rule.search(expression.AND([[('route_id', 'in', product_routes.ids)], domain]),
order='route_sequence, sequence')
for res1 in res_list:
if product_id.categ_id in res1.location_dest_id.product_type or product_id.categ_id in \
res1.location_src_id.product_type:
res = res1
if not res:
res = Rule.search(expression.AND([[('route_id', 'in', product_routes.ids)], domain]),
order='route_sequence, sequence', limit=1)
if not res and warehouse_id:
warehouse_routes = warehouse_id.route_ids
if warehouse_routes:
res_list = Rule.search(expression.AND([[('route_id', 'in', warehouse_routes.ids)], domain]),
order='route_sequence, sequence')
for res1 in res_list:
if product_id.categ_id in res1.location_dest_id.product_type or product_id.categ_id in \
res1.location_src_id.product_type:
res = res1
if not res:
res = Rule.search(expression.AND([[('route_id', 'in', warehouse_routes.ids)], domain]),
order='route_sequence, sequence', limit=1)
return res