From 180db6b91e89b7b1aa5b013900e0594a842ec059 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 12 Apr 2024 16:15:02 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E8=B0=83=E6=95=B4=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=88=80=E5=85=B7=E6=B8=85=E5=8D=95=E6=A8=A1=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E4=BB=A3=E7=A0=81=E4=BD=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BE=9D=E8=B5=96=E5=86=B2=E7=AA=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B2=E3=80=81=E4=BA=A7=E5=93=81=E9=87=87?= =?UTF-8?q?=E8=B4=AD=E6=97=B6=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=90=8C=E6=97=B6=E9=87=87=E8=B4=AD=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E7=9B=B8=E5=90=8C=E4=BA=A7=E5=93=81=E7=9A=84=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=EF=BC=9B3=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80?= =?UTF-8?q?=E6=9F=84=E9=87=87=E8=B4=AD=E5=85=A5=E5=BA=93=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E7=9A=84=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8F=B7=E8=A7=84=E5=88=99=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/views/tool_menu.xml | 44 ++++++++++++-------- sf_base/views/tool_views.xml | 9 ---- sf_manufacturing/models/stock.py | 70 ++++++++++++++++++++++++++++++-- sf_sale/models/sale_order.py | 10 +++++ 4 files changed, 102 insertions(+), 31 deletions(-) diff --git a/sf_base/views/tool_menu.xml b/sf_base/views/tool_menu.xml index bad606d6..263d11fa 100644 --- a/sf_base/views/tool_menu.xml +++ b/sf_base/views/tool_menu.xml @@ -21,7 +21,7 @@ 刀具标准库 ir.actions.act_window sf.cutting_tool.standard.library - + tree,form @@ -69,14 +69,22 @@ sequence="20" action="action_sf_cutting_tool_standard_library" /> + + - - - - - - - + + + + + + + + id="menu_sf_maintenance_equipment_image" + name="能力特征库" + parent="menu_sf_cutting_tool" + action="action_maintenance_equipment_image" + sequence="40"/> + id="menu_sf_tool_groups" + name="刀具组" + parent="menu_sf_cutting_tool" + action="sf_tool_groups_view_act" + sequence="50"/> diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml index e52a6222..1e82b8c2 100644 --- a/sf_base/views/tool_views.xml +++ b/sf_base/views/tool_views.xml @@ -609,13 +609,4 @@ tree - - - diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 80a334ce..94a9d646 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -317,13 +317,15 @@ class ProductionLot(models.Model): """ now = datetime.now().strftime("%Y%m%d") last_serial = self.env['stock.lot'].search( - [('company_id', '=', company.id), ('product_id', '=', product.id), ('name', 'like', now)], + [('company_id', '=', company.id), ('product_id', '=', product.id)], limit=1, order='id DESC') if product.cutting_tool_model_id: + split_codes = product.cutting_tool_model_id.code.split('-') if not last_serial: - return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1) + return "%s-T-%s-%s-%03d" % (split_codes[0], now, product.specification_id.name, 1) else: - return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1) + return "%s-T-%s-%s-%03d" % ( + split_codes[0], now, product.specification_id.name, int(last_serial.name[-3:]) + 1) else: raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!') @@ -341,7 +343,8 @@ class ProductionLot(models.Model): return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1] now = datetime.now().strftime("%Y%m%d") if product.cutting_tool_model_id: - return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1) + split_codes = product.cutting_tool_model_id.code.split('-') + return "%s-T-%s-%s-%03d" % (split_codes[0], now, product.specification_id.name, 1) return "%s-%03d" % (product.name, 1) qr_code_image = fields.Binary(string='二维码', compute='_generate_qr_code') @@ -539,6 +542,65 @@ class ReStockMove(models.Model): else: raise UserError(_("没有可打印的标签数据")) + def action_show_details(self): + """ Returns an action that will open a form view (in a popup) allowing to work on all the + move lines of a particular move. This form view is used when "show operations" is not + checked on the picking type. + """ + self.ensure_one() + + # If "show suggestions" is not checked on the picking type, we have to filter out the + # reserved move lines. We do this by displaying `move_line_nosuggest_ids`. We use + # different views to display one field or another so that the webclient doesn't have to + # fetch both. + if self.picking_type_id.show_reserved: + view = self.env.ref('stock.view_stock_move_operations') + 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) + + return { + 'name': _('Detailed Operations'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'stock.move', + 'views': [(view.id, 'form')], + 'view_id': view.id, + 'target': 'new', + 'res_id': self.id, + 'context': dict( + self.env.context, + show_owner=self.picking_type_id.code != 'incoming', + show_lots_m2o=self.has_tracking != 'none' and ( + self.picking_type_id.use_existing_lots or self.state == 'done' or self.origin_returned_move_id.id), + # able to create lots, whatever the value of ` use_create_lots`. + show_lots_text=self.has_tracking != 'none' and self.picking_type_id.use_create_lots and not self.picking_type_id.use_existing_lots and self.state != 'done' and not self.origin_returned_move_id.id, + show_source_location=self.picking_type_id.code != 'incoming', + show_destination_location=self.picking_type_id.code != 'outgoing', + show_package=not self.location_id.usage == 'supplier', + show_reserved_quantity=self.state != 'done' and not self.picking_id.immediate_transfer and self.picking_type_id.code != 'incoming' + ), + } + + def _get_tool_next_serial(self, company, product, origin): + """Return the next serial number to be attributed to the product.""" + if product.tracking == "serial": + last_serial = self.env['stock.lot'].search( + [('company_id', '=', company.id), ('product_id', '=', product.id), ('name', 'ilike', origin)], + limit=1, order='id DESC') + split_codes = product.cutting_tool_model_id.code.split('-') + if last_serial: + return "%s-T-%s-%s-%03d" % ( + split_codes[0], origin, product.specification_id.name, int(last_serial.name[-3:]) + 1) + else: + return "%s-T-%s-%s-%03d" % (split_codes[0], origin, product.specification_id.name, 1) + class ReStockQuant(models.Model): _inherit = 'stock.quant' diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index e2313ba3..05523194 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -206,6 +206,16 @@ class RePurchaseOrder(models.Model): order.message_subscribe([order.partner_id.id]) return True + @api.onchange('order_line') + def _onchange_order_line(self): + for order in self: + if order.order_line: + line = order.order_line + product = line.product_id + product_id = product.ids + if len(product_id) != len(line): + raise ValidationError('【%s】已存在,请勿重复添加' % product[-1].name) + class ResPartnerToSale(models.Model): _inherit = 'res.partner'