From 4f0df9f2bd68417b9a9bd3311c1a59b5a1b17f90 Mon Sep 17 00:00:00 2001 From: gqh Date: Wed, 16 Nov 2022 17:35:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E5=B7=A5?= =?UTF-8?q?=E5=BA=8F=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/sf_production.py | 73 +++++++++++-- sf_route_workcenter/models/workcenter.py | 16 +-- sf_route_workcenter/report/sf_tray_report.xml | 40 ++++++- sf_route_workcenter/views/sf_workorder.xml | 103 +++++++++++------- 4 files changed, 171 insertions(+), 61 deletions(-) diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index a41e34f3..ae2db189 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -2,14 +2,10 @@ import logging from collections import defaultdict, namedtuple from odoo.addons.stock.models.stock_rule import ProcurementException - -from dateutil.relativedelta import relativedelta - +from re import findall as regex_findall +from re import split as regex_split from odoo import SUPERUSER_ID, _, api, fields, models, registry -from odoo.exceptions import UserError -from odoo.osv import expression from odoo.tools import float_compare, float_is_zero, html_escape -from odoo.tools.misc import split_every _logger = logging.getLogger(__name__) @@ -29,6 +25,20 @@ class MrpProduction(models.Model): _inherit = 'mrp.production' _description = "制造订单" + def action_generate_serial(self): + self.ensure_one() + self.lot_producing_id = self.env['stock.production.lot'].create({ + 'product_id': self.product_id.id, + 'company_id': self.company_id.id, + 'name': self.env['stock.production.lot']._get_next_serial(self.company_id, self.product_id) or self.env[ + 'ir.sequence'].next_by_code('stock.lot.serial'), + }) + if self.move_finished_ids.filtered(lambda m: m.product_id == self.product_id).move_line_ids: + self.move_finished_ids.filtered( + lambda m: m.product_id == self.product_id).move_line_ids.lot_id = self.lot_producing_id + if self.product_id.tracking == 'serial': + self._set_qty_producing() + # 重载根据工序生成工单的程序:如果产品BOM中没有工序时, # 根据产品对应的模板类型中工序,去生成工单; # CNC加工工序的选取规则: @@ -232,13 +242,12 @@ class StockRule(models.Model): productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( - p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() + p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() for production in productions: ''' 创建制造订单时生成序列号 ''' - production.lot_producing_id._get_next_serial(production.company_id, production.product_id) production.action_generate_serial() origin_production = production.move_dest_ids and production.move_dest_ids[ 0].raw_material_production_id or False @@ -258,4 +267,50 @@ class StockRule(models.Model): 'mail.message_origin_link', values={'self': production, 'origin': origin_production}, subtype_id=self.env.ref('mail.mt_note').id) - return True \ No newline at end of file + return True + + +class ProductionLot(models.Model): + _inherit = 'stock.production.lot' + + @api.model + def generate_lot_names1(self, display_name, first_lot, count): + """Generate `lot_names` from a string.""" + if first_lot.__contains__(display_name): + first_lot = first_lot[(len(display_name)+1):] + + # We look if the first lot contains at least one digit. + caught_initial_number = regex_findall(r"\d+", first_lot) + if not caught_initial_number: + return self.generate_lot_names1(display_name, first_lot + "0", count) + # We base the series on the last number found in the base lot. + initial_number = caught_initial_number[-1] + padding = len(initial_number) + # We split the lot name to get the prefix and suffix. + splitted = regex_split(initial_number, first_lot) + # initial_number could appear several times, e.g. BAV023B00001S00001 + prefix = initial_number.join(splitted[:-1]) + suffix = splitted[-1] + initial_number = int(initial_number) + + lot_names = [] + for i in range(0, count): + lot_names.append('%s-%s%s%s' % ( + display_name, + prefix, + str(initial_number + i).zfill(padding), + suffix + )) + return lot_names + + @api.model + def _get_next_serial(self, company, product): + """Return the next serial number to be attributed to the product.""" + if product.tracking == "serial": + last_serial = self.env['stock.production.lot'].search( + [('company_id', '=', company.id), ('product_id', '=', product.id)], + limit=1, order='id DESC') + if last_serial: + return self.env['stock.production.lot'].generate_lot_names1(product.display_name, last_serial.name, 2)[ + 1] + return "%s-%03d" %(product.display_name,1) diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index 25a8b5b2..012ff74a 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -5,7 +5,7 @@ import logging import math from io import BytesIO -from odoo import api, fields, models, SUPERUSER_ID +from odoo import api, fields, models, SUPERUSER_ID, _ from pystrich.code128 import Code128Encoder from odoo.exceptions import ValidationError @@ -146,18 +146,18 @@ class MrpWorkOrder(models.Model): (x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)) y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / ( (y3 - y4) * (x1 - x2) - (y1 - y2) * (x3 - x4)) - x1 = ((x7 - x8) * (x6 * y5 - x5 * y7) - (x5 - x6) * (x8 * y7 - x7 * y8)) / ( + x1 = ((x7 - x8) * (x6 * y5 - x5 * y6) - (x5 - x6) * (x8 * y7 - x7 * y8)) / ( (x7 - x8) * (y5 - y6) - (x5 - x6) * (y7 - y8)); - y1 = ((y7 - y8) * (y6 * x5 - y5 * x7) - (y5 - y6) * (y8 * x7 - y7 * x8)) / ( + y1 = ((y7 - y8) * (y6 * x5 - y5 * x6) - (y5 - y6) * (y8 * x7 - y7 * x8)) / ( (y7 - y8) * (x5 - x6) - (y5 - y6) * (x7 - x8)) x = (x0 + x1) / 2 y = (y0 + y1) / 2 z = z1 / 2 - jd = math.atan2((x7 - x8), (y7 - y8)) + jd = math.atan2((x5 - x6), (y5 - y6)) jdz = jd * 180 / math.pi - print("(%s,%s)" % (x, y)) - self.material_center_point = ("(%s,%s,%s)" % (x, y, z)) + print("(%.2f,%.2f)" % (x, y)) + self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z)) self.X_deviation_angle = jdz X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) @@ -185,8 +185,8 @@ class MrpWorkOrder(models.Model): }) else: raise ValidationError('该托盘编码已失效') - else:return "" - + else: + return "" # 解除托盘绑定 def unbindtray(self): diff --git a/sf_route_workcenter/report/sf_tray_report.xml b/sf_route_workcenter/report/sf_tray_report.xml index f0bcc642..ba6368dd 100644 --- a/sf_route_workcenter/report/sf_tray_report.xml +++ b/sf_route_workcenter/report/sf_tray_report.xml @@ -1,6 +1,6 @@ - + Dymo Label Sheet @@ -16,7 +16,7 @@ 96 - + 打印条形码 sf.tray @@ -28,7 +28,7 @@ - + + + + 打印产品信息 + mrp.workorder + qweb-pdf + sf_route_workcenter.sf_tray_template1 + sf_route_workcenter.sf_tray_template1 + + report + + + + + + + + + + diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml index 85d641fb..a3c0f6dd 100644 --- a/sf_route_workcenter/views/sf_workorder.xml +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -72,93 +72,113 @@
左面:
-
+
-
+
前面:
-
+
-
+
右面:
-
+
-
+
-
下面:
+
后面:
-
+
-
+
上面:
-
+
-
+
@@ -232,6 +252,7 @@ />
+