Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/去掉客户部分字段必填校验和返工报废代码

This commit is contained in:
jinling.yang
2024-06-17 09:52:30 +08:00
19 changed files with 820 additions and 429 deletions

View File

@@ -50,8 +50,8 @@ class ResProductMo(models.Model):
cutting_tool_material_id = fields.Many2one('sf.cutting.tool.material', string='刀具物料')
cutting_tool_type = fields.Char(string="刀具物料类型", related='cutting_tool_material_id.name', store=True)
cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号')
specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='规格')
cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号名称')
specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='物料号')
cutting_tool_type_id = fields.Many2one('sf.cutting.tool.type', string='类型',
domain="[('cutting_tool_material_id.name', '=', cutting_tool_type)]")
@@ -104,6 +104,15 @@ class ResProductMo(models.Model):
compaction_way_id = fields.Many2one('maintenance.equipment.image',
'压紧方式', domain=[('type', '=', '压紧方式')])
name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False)
@api.depends('cutting_tool_model_id', 'specification_id')
def _compute_tool_name(self):
for item in self:
if item.cutting_tool_model_id and item.specification_id:
name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name)
item.name = name
@api.onchange('cutting_tool_model_id')
def _onchange_cutting_tool_model_id(self):
for item in self:
@@ -723,6 +732,10 @@ class ResProductMo(models.Model):
logging.info('create-model_file:%s' % len(vals['model_file']))
self._sanitize_vals(vals)
templates = super(ResProductMo, self).create(vals_list)
# 产品名称唯一性校验
for item in templates:
if len(self.search([('name', '=', item.name)])) > 1:
raise ValidationError('产品名称【%s】已存在' % item.name)
if "create_product_product" not in self._context:
templates._create_variant_ids()

View File

@@ -3,6 +3,7 @@ import base64
import qrcode
from collections import defaultdict, namedtuple
import logging
import io
import json
from re import split as regex_split
from re import findall as regex_findall
@@ -668,12 +669,14 @@ class ReStockMove(models.Model):
else:
view = self.env.ref('stock.view_stock_move_nosuggest_operations')
if self.product_id.tracking == "serial" and self.state == "assigned":
print(self.origin)
if self.product_id.categ_id.name == '刀具':
self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin)
else:
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
if self.state == "assigned":
if self.product_id.tracking == "serial":
if self.product_id.categ_id.name == '刀具':
self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin)
else:
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
elif self.product_id.tracking == "lot":
self._put_tool_lot(self.company_id, self.product_id, self.origin)
return {
'name': _('Detailed Operations'),
@@ -698,6 +701,35 @@ class ReStockMove(models.Model):
),
}
def _put_tool_lot(self, company, product, origin):
if product.tracking == "lot" and self.product_id.categ_id.name == '刀具':
if not self.move_line_nosuggest_ids:
lot_names = self.env['stock.lot'].generate_lot_names(
'%s-%s-%s' % ('%s-T-DJWL-%s' % (
product.cutting_tool_model_id.code.split('-')[0], product.cutting_tool_material_id.code),
datetime.now().strftime("%Y%m%d"), origin), 1)
move_lines_commands = self._generate_serial_move_line_commands_tool_lot(lot_names)
self.write({'move_line_nosuggest_ids': move_lines_commands})
for item in self.move_line_nosuggest_ids:
if item.lot_name:
item.lot_qr_code = self.compute_lot_qr_code(item.lot_name)
def compute_lot_qr_code(self, lot_name):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(lot_name)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
buffer = io.BytesIO()
img.save(buffer, format="PNG")
binary_data = buffer.getvalue()
data = base64.b64encode(binary_data).decode() # 确保返回的是字符串形式的数据
return data
def _get_tool_next_serial(self, company, product, origin):
"""Return the next serial number to be attributed to the product."""
if product.tracking == "serial":
@@ -711,6 +743,67 @@ class ReStockMove(models.Model):
else:
return "%s-T-%s-%s-%03d" % (split_codes[0], origin, product.specification_id.name, 1)
def _generate_serial_move_line_commands_tool_lot(self, lot_names, origin_move_line=None):
"""Return a list of commands to update the move lines (write on
existing ones or create new ones).
Called when user want to create and assign multiple serial numbers in
one time (using the button/wizard or copy-paste a list in the field).
:param lot_names: A list containing all serial number to assign.
:type lot_names: list
:param origin_move_line: A move line to duplicate the value from, default to None
:type origin_move_line: record of :class:`stock.move.line`
:return: A list of commands to create/update :class:`stock.move.line`
:rtype: list
"""
self.ensure_one()
# Select the right move lines depending of the picking type configuration.
move_lines = self.env['stock.move.line']
if self.picking_type_id.show_reserved:
move_lines = self.move_line_ids.filtered(lambda ml: not ml.lot_id and not ml.lot_name)
else:
move_lines = self.move_line_nosuggest_ids.filtered(lambda ml: not ml.lot_id and not ml.lot_name)
loc_dest = origin_move_line and origin_move_line.location_dest_id
move_line_vals = {
'picking_id': self.picking_id.id,
'location_id': self.location_id.id,
'product_id': self.product_id.id,
'product_uom_id': self.product_id.uom_id.id,
'qty_done': self.product_uom_qty,
}
if origin_move_line:
# `owner_id` and `package_id` are taken only in the case we create
# new move lines from an existing move line. Also, updates the
# `qty_done` because it could be usefull for products tracked by lot.
move_line_vals.update({
'owner_id': origin_move_line.owner_id.id,
'package_id': origin_move_line.package_id.id,
'qty_done': origin_move_line.qty_done or 1,
})
move_lines_commands = []
qty_by_location = defaultdict(float)
for lot_name in lot_names:
# We write the lot name on an existing move line (if we have still one)...
if move_lines:
move_lines_commands.append((1, move_lines[0].id, {
'lot_name': lot_name,
'qty_done': 1,
}))
qty_by_location[move_lines[0].location_dest_id.id] += 1
move_lines = move_lines[1:]
# ... or create a new move line with the serial name.
else:
loc = loc_dest or self.location_dest_id._get_putaway_strategy(self.product_id, quantity=1,
packaging=self.product_packaging_id,
additional_qty=qty_by_location)
move_line_cmd = dict(move_line_vals, lot_name=lot_name, location_dest_id=loc.id)
move_lines_commands.append((0, 0, move_line_cmd))
qty_by_location[loc.id] += 1
return move_lines_commands
class ReStockQuant(models.Model):
_inherit = 'stock.quant'