制造订单工序自动生成规则
This commit is contained in:
@@ -2,14 +2,10 @@
|
|||||||
import logging
|
import logging
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
from odoo.addons.stock.models.stock_rule import ProcurementException
|
from odoo.addons.stock.models.stock_rule import ProcurementException
|
||||||
|
from re import findall as regex_findall
|
||||||
from dateutil.relativedelta import relativedelta
|
from re import split as regex_split
|
||||||
|
|
||||||
from odoo import SUPERUSER_ID, _, api, fields, models, registry
|
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 import float_compare, float_is_zero, html_escape
|
||||||
from odoo.tools.misc import split_every
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -29,6 +25,20 @@ class MrpProduction(models.Model):
|
|||||||
_inherit = 'mrp.production'
|
_inherit = 'mrp.production'
|
||||||
_description = "制造订单"
|
_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中没有工序时,
|
# 重载根据工序生成工单的程序:如果产品BOM中没有工序时,
|
||||||
# 根据产品对应的模板类型中工序,去生成工单;
|
# 根据产品对应的模板类型中工序,去生成工单;
|
||||||
# CNC加工工序的选取规则:
|
# CNC加工工序的选取规则:
|
||||||
@@ -238,7 +248,6 @@ class StockRule(models.Model):
|
|||||||
'''
|
'''
|
||||||
创建制造订单时生成序列号
|
创建制造订单时生成序列号
|
||||||
'''
|
'''
|
||||||
production.lot_producing_id._get_next_serial(production.company_id, production.product_id)
|
|
||||||
production.action_generate_serial()
|
production.action_generate_serial()
|
||||||
origin_production = production.move_dest_ids and production.move_dest_ids[
|
origin_production = production.move_dest_ids and production.move_dest_ids[
|
||||||
0].raw_material_production_id or False
|
0].raw_material_production_id or False
|
||||||
@@ -259,3 +268,49 @@ class StockRule(models.Model):
|
|||||||
values={'self': production, 'origin': origin_production},
|
values={'self': production, 'origin': origin_production},
|
||||||
subtype_id=self.env.ref('mail.mt_note').id)
|
subtype_id=self.env.ref('mail.mt_note').id)
|
||||||
return True
|
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)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
from io import BytesIO
|
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 pystrich.code128 import Code128Encoder
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
@@ -146,18 +146,18 @@ class MrpWorkOrder(models.Model):
|
|||||||
(x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4))
|
(x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4))
|
||||||
y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / (
|
y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / (
|
||||||
(y3 - y4) * (x1 - x2) - (y1 - y2) * (x3 - 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));
|
(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))
|
(y7 - y8) * (x5 - x6) - (y5 - y6) * (x7 - x8))
|
||||||
x = (x0 + x1) / 2
|
x = (x0 + x1) / 2
|
||||||
y = (y0 + y1) / 2
|
y = (y0 + y1) / 2
|
||||||
z = z1 / 2
|
z = z1 / 2
|
||||||
|
|
||||||
jd = math.atan2((x7 - x8), (y7 - y8))
|
jd = math.atan2((x5 - x6), (y5 - y6))
|
||||||
jdz = jd * 180 / math.pi
|
jdz = jd * 180 / math.pi
|
||||||
print("(%s,%s)" % (x, y))
|
print("(%.2f,%.2f)" % (x, y))
|
||||||
self.material_center_point = ("(%s,%s,%s)" % (x, y, z))
|
self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z))
|
||||||
self.X_deviation_angle = jdz
|
self.X_deviation_angle = jdz
|
||||||
|
|
||||||
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
|
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
|
||||||
@@ -185,8 +185,8 @@ class MrpWorkOrder(models.Model):
|
|||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
raise ValidationError('该托盘编码已失效')
|
raise ValidationError('该托盘编码已失效')
|
||||||
else:return ""
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
# 解除托盘绑定
|
# 解除托盘绑定
|
||||||
def unbindtray(self):
|
def unbindtray(self):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<data>
|
||||||
<!-- 打印尺寸-->
|
<!-- 托盘码打印尺寸-->
|
||||||
<record id="sf_tray1" model="report.paperformat">
|
<record id="sf_tray1" model="report.paperformat">
|
||||||
<field name="name">Dymo Label Sheet</field>
|
<field name="name">Dymo Label Sheet</field>
|
||||||
<field name="default" eval="True"/>
|
<field name="default" eval="True"/>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<field name="dpi">96</field>
|
<field name="dpi">96</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- 打印动作-->
|
<!-- 托盘码打印动作-->
|
||||||
<record id="label_sf_tray_code" model="ir.actions.report">
|
<record id="label_sf_tray_code" model="ir.actions.report">
|
||||||
<field name="name">打印条形码</field>
|
<field name="name">打印条形码</field>
|
||||||
<field name="model">sf.tray</field>
|
<field name="model">sf.tray</field>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<field name="paperformat_id" ref="sf_route_workcenter.sf_tray1"/>
|
<field name="paperformat_id" ref="sf_route_workcenter.sf_tray1"/>
|
||||||
|
|
||||||
</record>
|
</record>
|
||||||
<!-- 打印模板-->
|
<!-- 托盘码打印模板-->
|
||||||
<template id="sf_tray_template">
|
<template id="sf_tray_template">
|
||||||
<t t-call="web.html_container">
|
<t t-call="web.html_container">
|
||||||
<t t-call="web.external_layout">
|
<t t-call="web.external_layout">
|
||||||
@@ -46,6 +46,40 @@
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 产品信息打印动作-->
|
||||||
|
<record id="label_sf_tray_code1" model="ir.actions.report">
|
||||||
|
<field name="name">打印产品信息</field>
|
||||||
|
<field name="model">mrp.workorder</field>
|
||||||
|
<field name="report_type">qweb-pdf</field>
|
||||||
|
<field name="report_name">sf_route_workcenter.sf_tray_template1</field>
|
||||||
|
<field name="report_file">sf_route_workcenter.sf_tray_template1</field>
|
||||||
|
<field name="binding_model_id" ref="model_mrp_workorder"/>
|
||||||
|
<field name="binding_type">report</field>
|
||||||
|
<field name="paperformat_id" ref="sf_route_workcenter.sf_tray1"/>
|
||||||
|
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 产品信息打印模板-->
|
||||||
|
<template id="sf_tray_template1">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<t t-foreach="docs" t-as="o">
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<div t-field="o.production_id" style="text-align: center"/>
|
||||||
|
|
||||||
|
<div t-field="o.name" style="text-align: center"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -72,93 +72,113 @@
|
|||||||
<group>
|
<group>
|
||||||
<div>左面:</div>
|
<div>左面:</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X1_axis" string="x1"/>
|
<label for="X1_axis" string="x1"/>
|
||||||
<field name='X1_axis' class="o_address_city"/>
|
<field name='X1_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y1_axis" string="y1"/>
|
<label for="Y1_axis" string="y1"/>
|
||||||
<field name='Y1_axis' class="o_address_city"/>
|
<field name='Y1_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z1_axis" string="z1"/>
|
<label for="Z1_axis" string="z1"/>
|
||||||
<field name='Z1_axis' class="o_address_city"/>
|
<field name='Z1_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X2_axis" string="x2"/>
|
<label for="X2_axis" string="x2"/>
|
||||||
<field name='X2_axis' class="o_address_city"/>
|
<field name='X2_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y2_axis" string="y2"/>
|
<label for="Y2_axis" string="y2"/>
|
||||||
<field name='Y2_axis' class="o_address_city"/>
|
<field name='Y2_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z2_axis" string="z2"/>
|
<label for="Z2_axis" string="z2"/>
|
||||||
<field name='Z2_axis' class="o_address_city"/>
|
<field name='Z2_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div>前面:</div>
|
<div>前面:</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X3_axis" string="x1"/>
|
<label for="X3_axis" string="x1"/>
|
||||||
<field name='X3_axis' class="o_address_city"/>
|
<field name='X3_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y3_axis" string="y1"/>
|
<label for="Y3_axis" string="y1"/>
|
||||||
<field name='Y3_axis' class="o_address_city"/>
|
<field name='Y3_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z3_axis" string="z1"/>
|
<label for="Z3_axis" string="z1"/>
|
||||||
<field name='Z3_axis' class="o_address_city"/>
|
<field name='Z3_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X4_axis" string="x2"/>
|
<label for="X4_axis" string="x2"/>
|
||||||
<field name='X4_axis' class="o_address_city"/>
|
<field name='X4_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y4_axis" string="y2"/>
|
<label for="Y4_axis" string="y2"/>
|
||||||
<field name='Y4_axis' class="o_address_city"/>
|
<field name='Y4_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z4_axis" string="z2"/>
|
<label for="Z4_axis" string="z2"/>
|
||||||
<field name='Z4_axis' class="o_address_city"/>
|
<field name='Z4_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div>右面:</div>
|
<div>右面:</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X5_axis" string="x1"/>
|
<label for="X5_axis" string="x1"/>
|
||||||
<field name='X5_axis' class="o_address_city"/>
|
<field name='X5_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y5_axis" string="y1"/>
|
<label for="Y5_axis" string="y1"/>
|
||||||
<field name='Y5_axis' class="o_address_city"/>
|
<field name='Y5_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z5_axis" string="z1"/>
|
<label for="Z5_axis" string="z1"/>
|
||||||
<field name='Z5_axis' class="o_address_city"/>
|
<field name='Z5_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X6_axis" string="x2"/>
|
<label for="X6_axis" string="x2"/>
|
||||||
<field name='X6_axis' class="o_address_city"/>
|
<field name='X6_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y6_axis" string="y2"/>
|
<label for="Y6_axis" string="y2"/>
|
||||||
<field name='Y6_axis' class="o_address_city"/>
|
<field name='Y6_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z6_axis" string="z2"/>
|
<label for="Z6_axis" string="z2"/>
|
||||||
<field name='Z6_axis' class="o_address_city"/>
|
<field name='Z6_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div>下面:</div>
|
<div>后面:</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X7_axis" string="x1"/>
|
<label for="X7_axis" string="x1"/>
|
||||||
<field name='X7_axis' class="o_address_city"/>
|
<field name='X7_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y7_axis" string="y1"/>
|
<label for="Y7_axis" string="y1"/>
|
||||||
<field name='Y7_axis' class="o_address_city"/>
|
<field name='Y7_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z7_axis" string="z1"/>
|
<label for="Z7_axis" string="z1"/>
|
||||||
<field name='Z7_axis' class="o_address_city"/>
|
<field name='Z7_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X8_axis" string="x2"/>
|
<label for="X8_axis" string="x2"/>
|
||||||
<field name='X8_axis' class="o_address_city"/>
|
<field name='X8_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y8_axis" string="y2"/>
|
<label for="Y8_axis" string="y2"/>
|
||||||
<field name='Y8_axis' class="o_address_city"/>
|
<field name='Y8_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z8_axis" string="z2"/>
|
<label for="Z8_axis" string="z2"/>
|
||||||
<field name='Z8_axis' class="o_address_city"/>
|
<field name='Z8_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div>上面:</div>
|
<div>上面:</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X9_axis" string="x1"/>
|
<label for="X9_axis" string="x1"/>
|
||||||
<field name='X9_axis' class="o_address_city"/>
|
<field name='X9_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y9_axis" string="y1"/>
|
<label for="Y9_axis" string="y1"/>
|
||||||
<field name='Y9_axis' class="o_address_city"/>
|
<field name='Y9_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z9_axis" string="z1"/>
|
<label for="Z9_axis" string="z1"/>
|
||||||
<field name='Z9_axis' class="o_address_city"/>
|
<field name='Z9_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="o_address_city">
|
<div class="o_address_format">
|
||||||
<label for="X10_axis" string="x2"/>
|
<label for="X10_axis" string="x2"/>
|
||||||
<field name='X10_axis' class="o_address_city"/>
|
<field name='X10_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Y10_axis" string="y2"/>
|
<label for="Y10_axis" string="y2"/>
|
||||||
<field name='Y10_axis' class="o_address_city"/>
|
<field name='Y10_axis' class="o_address_zip"/>
|
||||||
|
<span>&nbsp;</span>
|
||||||
<label for="Z10_axis" string="z2"/>
|
<label for="Z10_axis" string="z2"/>
|
||||||
<field name='Z10_axis' class="o_address_city"/>
|
<field name='Z10_axis' class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -232,6 +252,7 @@
|
|||||||
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|||||||
Reference in New Issue
Block a user