Merge remote-tracking branch 'origin/develop' into feature/临时分支

This commit is contained in:
hujiaying
2024-10-18 08:40:57 +08:00
19 changed files with 3754 additions and 91 deletions

View File

@@ -16,6 +16,8 @@
<field name='is_bfm' invisible="1"/>
<field name='categ_type' invisible="1"/>
<field name='part_number' attrs="{'invisible': [('categ_type', '!=', '成品')]}"/>
<!-- <field name='machining_drawings' attrs="{'invisible': [('categ_type', '!=', '成品')]}" widget="image"/>-->
<!-- <field name='quality_standard' attrs="{'invisible': [('categ_type', '!=', '成品')]}"/>-->
<field name='manual_quotation' attrs="{'invisible':[('upload_model_file', '=', [])]}"/>
<field name="upload_model_file"
widget="many2many_binary"

View File

@@ -402,20 +402,45 @@ class Sf_Dashboard_Connect(http.Controller):
try:
plan_obj = request.env['sf.production.plan'].sudo()
production_obj = request.env['mrp.production'].sudo()
work_order_obj = request.env['mrp.workorder'].sudo()
line_list = ast.literal_eval(kw['line_list'])
# print('line_list: %s' % line_list)
for line in line_list:
# 工单计划量
plan_data_total_counts = production_obj.search_count(
[('production_line_id.name', '=', line), ('state', 'not in', ['cancel']),
('active', '=', True)])
# 工单完成量
plan_data_finish_counts = plan_obj.search_count(
[('production_line_id.name', '=', line), ('state', 'in', ['finished'])])
# # 工单计划量
# plan_data_plan_counts = plan_obj.search_count(
# [('production_line_id.name', '=', line), ('state', 'not in', ['finished'])])
# plan_data_total_counts = production_obj.search_count(
# [('production_line_id.name', '=', line), ('state', 'not in', ['cancel']),
# ('active', '=', True)])
# 工单计划量切换为CNC工单
plan_data_total_counts = work_order_obj.search_count(
[('production_id.production_line_id.name', '=', line),
('state', 'in', ['ready', 'progress', 'done']), ('routing_type', '=', 'CNC加工')])
# # 工单完成量
# plan_data_finish_counts = plan_obj.search_count(
# [('production_line_id.name', '=', line), ('state', 'in', ['finished'])])
# 工单完成量切换为CNC工单
plan_data_finish_counts = work_order_obj.search_count(
[('production_id.production_line_id.name', '=', line),
('state', 'in', ['done']), ('routing_type', '=', 'CNC加工')])
# 超期完成量
# 搜索所有已经完成的工单
plan_data_overtime = work_order_obj.search([
('production_id.production_line_id.name', '=', line),
('state', 'in', ['done']),
('routing_type', '=', 'CNC加工')
])
# 使用 filtered 进行字段比较
plan_data_overtime_counts = plan_data_overtime.filtered(
lambda order: order.date_finished > order.date_planned_finished
)
# 获取数量
plan_data_overtime_counts = len(plan_data_overtime_counts)
# 查找符合条件的生产计划记录
plan_data = plan_obj.search([
@@ -517,7 +542,10 @@ class Sf_Dashboard_Connect(http.Controller):
'on_time_rate': on_time_rate,
# 'detection_data': detection_data,
'detection_data': plan_data_finish_counts,
'pass_rate': (plan_data_finish_counts - plan_data_fault_counts) / plan_data_finish_counts
'pass_rate': (plan_data_finish_counts - plan_data_fault_counts) / plan_data_finish_counts,
'plan_data_overtime_counts': plan_data_overtime_counts,
'overtime_rate': plan_data_overtime_counts / plan_data_finish_counts
if plan_data_finish_counts > 0 else 0,
}
res['data'][line] = data

3583
sf_maintenance/i18n/zh_CN.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -960,6 +960,13 @@ class MrpProduction(models.Model):
productions_not_delivered.write(
{'state': 'progress', 'programming_state': '已编程', 'is_rework': False})
# 对制造订单所以面的cnc工单的程序用刀进行校验
try:
logging.info(f'已更新制造订单:{productions_not_delivered}')
productions_not_delivered.production_cnc_tool_checkout()
except Exception as e:
logging.info(f'对cnc工单的程序用刀进行校验报错{e}')
# 从cloud获取重新编程过的最新程序
def get_new_program(self, processing_panel):
try:

View File

@@ -774,6 +774,8 @@ class ResProductMo(models.Model):
# bfm下单
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
part_number = fields.Char(string='零件图号', readonly=True)
# machining_drawings = fields.Binary('2D加工图纸', readonly=True)
# quality_standard = fields.Binary('质检标准', readonly=True)
@api.constrains('tool_length')
def _check_tool_length_size(self):
@@ -873,6 +875,8 @@ class ResProductMo(models.Model):
'manual_quotation': item['manual_quotation'] or False,
'part_number': item.get('part_number') or '',
'active': True,
# 'machining_drawings': '' if not item['machining_drawings'] else base64.b64decode(item['machining_drawings']),
# 'quality_standard': '' if not item['quality_standard'] else base64.b64decode(item['quality_standard']),
}
tax_id = self.env['account.tax'].sudo().search(
[('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')])

View File

@@ -104,9 +104,16 @@ access_mrp_production_split_group_sf_mrp_user,access.mrp.production.split,mrp.mo
access_mrp_production_split_line_group_sf_mrp_user,access.mrp.production.split.line,mrp.model_mrp_production_split_line,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_capacity_manager_group_sf_mrp_user,mrp.workcenter.capacity.manager,mrp.model_mrp_workcenter_capacity,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_productivity_loss_group_quality,mrp_workcenter_productivity_loss_group_quality,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_quality,1,0,0,0
access_mrp_workcenter_productivity_loss_group_quality_director,mrp_workcenter_productivity_loss_group_quality_director,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_quality_director,1,0,0,0
access_mrp_workcenter_productivity_group_quality,mrp_workcenter_productivity_group_quality,mrp.model_mrp_workcenter_productivity,sf_base.group_quality,1,1,1,0
access_mrp_workcenter_productivity_group_quality_director,mrp_workcenter_productivity_group_quality_director,mrp.model_mrp_workcenter_productivity,sf_base.group_quality_director,1,1,1,0
access_mrp_production_group_plan_dispatch,mrp_production,model_mrp_production,sf_base.group_plan_dispatch,1,1,0,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,1,0
access_mrp_production_group_quality,mrp_production,model_mrp_production,sf_base.group_quality,1,1,0,0
access_mrp_production_group_quality_director,mrp_production,model_mrp_production,sf_base.group_quality_director,1,1,0,0
access_mrp_workorder_group_quality,mrp_workorder,model_mrp_workorder,sf_base.group_quality,1,1,0,0
access_mrp_workorder_group_quality_director,mrp_workorder,model_mrp_workorder,sf_base.group_quality_director,1,1,0,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,0,0
access_sf_production_line_group_plan_dispatch,sf.production.line,model_sf_production_line,sf_base.group_plan_dispatch,1,0,0,0
access_sf_production_line_group_plan_director,sf.production.line,model_sf_production_line,sf_base.group_plan_director,1,1,1,0
access_sf_production_line,sf.production.line,model_sf_production_line,sf_maintenance.sf_group_equipment_user,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
104 access_mrp_workcenter_capacity_manager_group_sf_mrp_user mrp.workcenter.capacity.manager mrp.model_mrp_workcenter_capacity sf_base.group_sf_mrp_user 1 1 1 0
105 access_mrp_production_group_plan_dispatch access_mrp_workcenter_productivity_loss_group_quality mrp_production mrp_workcenter_productivity_loss_group_quality model_mrp_production mrp.model_mrp_workcenter_productivity_loss sf_base.group_plan_dispatch sf_base.group_quality 1 1 0 0 0
106 access_mrp_workorder access_mrp_workcenter_productivity_loss_group_quality_director mrp_workorder mrp_workcenter_productivity_loss_group_quality_director model_mrp_workorder mrp.model_mrp_workcenter_productivity_loss sf_base.group_plan_dispatch sf_base.group_quality_director 1 1 0 1 0 0
107 access_sf_production_line_group_plan_dispatch access_mrp_workcenter_productivity_group_quality sf.production.line mrp_workcenter_productivity_group_quality model_sf_production_line mrp.model_mrp_workcenter_productivity sf_base.group_plan_dispatch sf_base.group_quality 1 0 1 0 1 0
108 access_mrp_workcenter_productivity_group_quality_director mrp_workcenter_productivity_group_quality_director mrp.model_mrp_workcenter_productivity sf_base.group_quality_director 1 1 1 0
109 access_mrp_production_group_plan_dispatch mrp_production model_mrp_production sf_base.group_plan_dispatch 1 1 0 0
110 access_mrp_production_group_quality mrp_production model_mrp_production sf_base.group_quality 1 1 0 0
111 access_sf_production_line_group_plan_director access_mrp_production_group_quality_director sf.production.line mrp_production model_sf_production_line model_mrp_production sf_base.group_plan_director sf_base.group_quality_director 1 1 1 0 0
112 access_sf_production_line access_mrp_workorder_group_quality sf.production.line mrp_workorder model_sf_production_line model_mrp_workorder sf_maintenance.sf_group_equipment_user sf_base.group_quality 1 1 1 0 0
113 access_mrp_workorder_group_quality_director mrp_workorder model_mrp_workorder sf_base.group_quality_director 1 1 0 0
114 access_mrp_workorder mrp_workorder model_mrp_workorder sf_base.group_plan_dispatch 1 1 0 0
115 access_sf_production_line_group_plan_dispatch sf.production.line model_sf_production_line sf_base.group_plan_dispatch 1 0 0 0
116 access_sf_production_line_group_plan_director sf.production.line model_sf_production_line sf_base.group_plan_director 1 1 1 0
117 access_mrp_workcenter access_sf_production_line mrp_workcenter sf.production.line model_mrp_workcenter model_sf_production_line sf_base.group_plan_dispatch sf_maintenance.sf_group_equipment_user 1 1 1 0
118 access_mrp_bom_group_plan_dispatch access_mrp_workcenter mrp.bom mrp_workcenter mrp.model_mrp_bom model_mrp_workcenter sf_base.group_plan_dispatch 1 0 1 0 1 0
119 access_mrp_bom_line access_mrp_bom_group_plan_dispatch mrp.bom.line mrp.bom mrp.model_mrp_bom_line mrp.model_mrp_bom sf_base.group_plan_dispatch 1 0 0 0

View File

@@ -584,6 +584,12 @@
position="after">
<field name="duration" string="实际时长"/>
</xpath>
<xpath expr="//page[@name='time_tracking']" position="attributes">
<attribute name="groups">
mrp.group_mrp_manager,sf_base.group_sf_mrp_manager,sf_base.group_sf_equipment_user,sf_base.group_sf_order_user
</attribute>
</xpath>
</field>
</record>

View File

@@ -58,17 +58,8 @@
<field name="name">订单发货提醒</field>
<field name="model">stock.picking</field>
</record>
<!-- <record id="bussiness_mrp_workorder_pre_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">装夹预调工单逾期预警</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_pre_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">装夹预调工单已逾期</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<record id="bussiness_mrp_workorder_pre_overdue_warning" model="jikimo.message.bussiness.node">
<record id="bussiness_mrp_workorder_pre_overdue_warning" model="jikimo.message.bussiness.node">
<field name="name">装夹预调工单逾期预警</field>
<field name="model">mrp.workorder</field>
</record>
@@ -77,12 +68,12 @@
<field name="model">mrp.workorder</field>
</record>
<record id="bussiness_mrp_workorder_cnc_overdue_warning" model="jikimo.message.bussiness.node">
<record id="bussiness_mrp_workorder_cnc_overdue_warning" model="jikimo.message.bussiness.node">
<field name="name">CNC加工工单逾期预警</field>
<field name="model">mrp.workorder</field>
</record>
<record id="bussiness_mrp_workorder_cnc_overdue" model="jikimo.message.bussiness.node">
<field name="name">CNC工单已逾期</field>
<field name="name">CNC加工工单已逾期</field>
<field name="model">mrp.workorder</field>
</record>
@@ -96,7 +87,7 @@
<field name="model">mrp.workorder</field>
</record>
<record id="bussiness_mrp_workorder_surface_overdue_warning" model="jikimo.message.bussiness.node">
<record id="bussiness_mrp_workorder_surface_overdue_warning" model="jikimo.message.bussiness.node">
<field name="name">表面工艺工单逾期预警</field>
<field name="model">mrp.workorder</field>
</record>

View File

@@ -26,7 +26,7 @@
<field name="active" eval="True"/>
</record>
<record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">
<record model="ir.cron" id="ir_cron_mrp_workorder_recover_time_warning">
<field name="name">检查工单是否完成并恢复正常时效</field>
<field name="model_id" ref="model_mrp_workorder"/>
<field name="state">code</field>

View File

@@ -15,4 +15,5 @@ class SfMessageTemplate(models.Model):
res.append('purchase.order')
res.append('mrp.workorder')
res.append('sf.maintenance.logs')
res.append('quality.cnc.test')
return res

View File

@@ -109,16 +109,21 @@ class SFMessageWork(models.Model):
for item in orders:
if item.date_planned_finished:
current_time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_time_datetime = datetime.strptime(current_time_str, '%Y-%m-%d %H:%M:%S')
current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_str)
current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
date_planned_finished_str = self.env['sf.sync.common'].sudo().get_add_time(
item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S"))
date_planned_finished = datetime.strptime(date_planned_finished_str, '%Y-%m-%d %H:%M:%S')
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {date_planned_finished}")
twelve_hours_ago = current_time_datetime - timedelta(hours=12)
if current_time_datetime >= date_planned_finished:
logging.info("------overdue-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {date_planned_finished}")
item.delivery_warning = 'overdue'
elif twelve_hours_ago <= current_time_datetime <= date_planned_finished:
logging.info("------warning-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {date_planned_finished}")
item.delivery_warning = 'warning'
business_node_ids = {
'装夹预调': self.env.ref('sf_message.bussiness_mrp_workorder_pre_overdue_warning').id,

View File

@@ -82,24 +82,29 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
if files_panel:
for file in files_panel:
file_extension = os.path.splitext(file)[1]
logging.info('file_extension:%s' % file_extension)
if file_extension.lower() == '.pdf':
panel_file_path = os.path.join(program_path_tmp_panel, file)
logging.info('panel_file_path:%s' % panel_file_path)
logging.info('更新工作指令:%s' % cnc_workorder)
cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
logging.info('更新工作指令完成:%s' % cnc_workorder)
pre_workorder = productions.workorder_ids.filtered(
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', 'rework'
'cancel'] and ap.processing_panel == panel)
if pre_workorder:
logging.info('更新加工图纸:%s' % pre_workorder)
pre_workorder.write(
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
logging.info('更新加工图纸完成:%s' % pre_workorder)
productions.write({'programming_state': '已编程', 'work_state': '已编程'})
logging.info('已更新制造订单编程状态:%s' % productions.ids)
res.update({
'production_ids': productions.ids
})
# 对制造订单所以面的cnc工单的程序用刀进行校验
try:
logging.info(f'已更新制造订单:{productions}')
productions.production_cnc_tool_checkout()
except Exception as e:
logging.info(f'对cnc工单的程序用刀进行校验报错{e}')
@@ -111,5 +116,6 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
return json.JSONEncoder().encode(res)
except Exception as e:
res = {'status': -1, 'message': '系统解析失败'}
request.cr.rollback()
logging.info('get_cnc_processing_create error:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -31,19 +31,31 @@ class SfQualityCncTest(models.Model):
("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因")
detailed_reason = fields.Text('详细原因')
# machining_drawings = fields.Binary(related='workorder_id.machining_drawings', string='2D加工图纸', readonly=True)
# quality_standard = fields.Binary(related='workorder_id.quality_standard', string='质检标准', readonly=True)
def submit_pass(self):
self.write({'result': 'pass', 'test_results': self.test_results, 'state': 'done'})
if self.test_results in ['返工', '报废']:
raise UserError(_('请重新选择【判定结果】-【检测结果】'))
self.write({'result': 'pass', 'test_results': '合格', 'state': 'done'})
self.workorder_id.write({'test_results': self.test_results})
self.workorder_id.button_finish()
def submit_fail(self):
if not self.reason and not self.detailed_reason and not self.test_results:
if not self.test_results:
raise UserError(_('请填写【判定结果】里的信息'))
else:
self.write({'result': 'fail', 'test_results': self.test_results, 'state': 'done'})
self.workorder_id.write(
{'test_results': self.test_results, 'reason': self.reason, 'detailed_reason': self.detailed_reason})
self.workorder_id.button_finish()
if self.test_results == '合格':
raise UserError(_('请重新选择【判定结果】-【检测结果】'))
self.write({'result': 'fail', 'test_results': self.test_results, 'state': 'done'})
self.workorder_id.write(
{'test_results': self.test_results, 'reason': self.reason, 'detailed_reason': self.detailed_reason})
self.workorder_id.button_finish()
@api.onchange('test_results')
def _onchange_test_results(self):
if self.test_results == '合格':
self.reason = False
self.detailed_reason = False
class SfQualityWorkOrder(models.Model):
@@ -62,7 +74,9 @@ class SfQualityWorkOrder(models.Model):
def write(self, vals):
res = super(SfQualityWorkOrder, self).write(vals)
if self.state == 'to be detected':
quality_cnc_test = self.env['quality.cnc.test'].search([('workorder_id', '=', self.id)])
if not quality_cnc_test:
self.env['quality.cnc.test'].sudo().create({'workorder_id': self.id})
for item in self:
if item.state == 'to be detected':
quality_cnc_test = self.env['quality.cnc.test'].search([('workorder_id', '=', item.id)])
if not quality_cnc_test:
self.env['quality.cnc.test'].sudo().create({'workorder_id': item.id})
return res

View File

@@ -5,7 +5,7 @@
<field name="name">加工质检单编码规则</field>
<field name="code">quality.cnc.test</field>
<field name="prefix">QCT</field>
<field name="padding">4</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
@@ -20,10 +20,12 @@
<field name="product_id"/>
<field name="part_number"/>
<field name="number"/>
<field name="state"/>
<field name="result"/>
<field name="write_uid" widget='many2one_avatar_user' string="判定人" optional="hide"/>
<field name="write_date" string="判定时间" optional="hide"/>
<field name="state" widget="badge"
decoration-success="state == 'done'"
decoration-warning="state == 'waiting'"/>
<field name="result" widget="badge"
decoration-success="result == 'pass'"
decoration-danger="result == 'fail'"/>
</tree>
</field>
</record>
@@ -89,7 +91,6 @@
<group>
<field name="part_number"/>
<field name="processing_panel"/>
<field name="detection_report"/>
</group>
</group>
<notebook>
@@ -99,17 +100,19 @@
<page string="判定结果">
<group>
<field name="test_results" attrs="{'readonly': [('state','=', 'done')]}"/>
<field name="reason" attrs="{'readonly': [('state','=', 'done')]}"/>
<field name="detailed_reason" attrs="{'readonly': [('state','=', 'done')]}"/>
<field name="reason"
attrs="{'readonly': [('state','=', 'done')],'required': [('test_results','in', ['返工','报废'])],'invisible': [('test_results','in', ['合格',False])]}"/>
<field name="detailed_reason"
attrs="{'readonly': [('state','=', 'done')],'required': [('reason','!=', False)],'invisible': [('test_results','in', ['合格',False])]}"/>
</group>
</page>
<page string="2D图纸">
<!-- <field name="detection_report" string="" widget="pdf_viewer"/>-->
<!-- <field name="machining_drawings" string="" widget="pdf_viewer"/>-->
</page>
<page string="客户质量标准">
<!-- <field name="detection_report" string="" widget="pdf_viewer"/>-->
<!-- <field name="quality_standard" string=""/>-->
</page>
<page string="其他" attrs="{'readonly': [('state','=', 'done')]}">
<page string="其他" attrs="{'invisible': [('state','=', 'waiting')]}">
<group>
<field name="write_uid" widget='many2one_avatar_user' string="判定人" readonly="1"/>
<field name="write_date" string="判定时间" readonly="1"/>
@@ -171,7 +174,7 @@
<field name="name">驾驶舱</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">quality.cnc.test</field>
<field name="view_mode">kanban,form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="quality_cnc_test_view_kanban"/>
<field name="search_view_id" ref="quality_cnc_test_search"/>
<field name="domain">[]</field>

View File

@@ -34,36 +34,36 @@
</field>
</record>
<record model="ir.ui.view" id="quality_point_view_form_inherit_sf">
<field name="name">quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality.quality_point_view_form"/>
<field name="arch" type="xml">
<!-- <xpath expr="//sheet//group//group//field[@name='title']" position="replace"> -->
<!-- <field name="title" class="custom_required" required="1"/> -->
<!-- </xpath> -->
<xpath expr="//sheet//group//group//field[@name='title']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//sheet//group//group//field[@name='picking_type_ids']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="quality_point_view_form_inherit_sf">
<field name="name">quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality.quality_point_view_form"/>
<field name="arch" type="xml">
<!-- <xpath expr="//sheet//group//group//field[@name='title']" position="replace"> -->
<!-- <field name="title" class="custom_required" required="1"/> -->
<!-- </xpath> -->
<xpath expr="//sheet//group//group//field[@name='title']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//sheet//group//group//field[@name='picking_type_ids']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="sf_quality_point_view_form_inherit_quality_control">
<field name="name">sf.quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality_control.quality_point_view_form_inherit_quality_control"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='measure_on']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
<xpath expr="//field[@name='measure_frequency_type']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="sf_quality_point_view_form_inherit_quality_control">
<field name="name">sf.quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality_control.quality_point_view_form_inherit_quality_control"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='measure_on']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
<xpath expr="//field[@name='measure_frequency_type']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@@ -80,8 +80,8 @@
<field name="unit_price"/>
<field name="price" options="{'format': false}"/>
<field name="part_drawing_number"/>
<field name="machining_drawings" filename="machining_drawings_name" widget="pdf_viewer"/>
<field name="machining_drawings_name" invisible="1"/>
<!-- <field name="machining_drawings" filename="machining_drawings_name" widget="pdf_viewer"/>-->
<!-- <field name="machining_drawings_name" invisible="1"/>-->
<field name="sale_order_id"
attrs='{"invisible": [("sale_order_id","=",False)],"readonly": [("sale_order_id","!=",False)]}'/>
</group>

View File

@@ -687,7 +687,7 @@ class FunctionalToolAssembly(models.Model):
sf_cam_work_order_program_knife_plan_id = fields.Many2one('sf.cam.work.order.program.knife.plan',
'CAM工单程序用刀计划', readonly=True)
active = fields.Boolean(string='已归档', default=True, groups='base.user_root')
active = fields.Boolean(string='已归档', default=True)
code = fields.Char('功能刀具编码', compute='_compute_code')

View File

@@ -554,7 +554,7 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
sf_functional_tool_entity_ids = fields.One2many('sf.functional.cutting.tool.entity', 'safe_inventory_id',
string='功能刀具信息')
active = fields.Boolean(string='已归档', default=True, groups='base.user_root')
active = fields.Boolean(string='已归档', default=True)
@api.depends('functional_name_id', 'functional_name_id.diameter', 'functional_name_id.angle',
'functional_name_id.functional_cutting_tool_model_id')

View File

@@ -170,6 +170,7 @@ class MrpProduction(models.Model):
# 修改cnc程序的刀具状态
workorder_ids = self.env['mrp.workorder'].sudo().search([('production_id', 'in', self.ids)])
if invalid_tool:
logging.info(f'无效刀:{invalid_tool}')
# 修改cnc程序的刀具状态为 ‘无效刀’
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', invalid_tool)])
@@ -194,15 +195,18 @@ class MrpProduction(models.Model):
# 自动调用重新获取编程的方法
logging.info('cnc用刀校验到无效刀自动调用重新编程方法update_programming_state()')
self[0].update_programming_state()
# 修改制造订单 编程状态变为“编程中”
self.write({'programming_state': '编程中', 'work_state': '编程中'})
self[0].write({'is_rework': False})
# 修改制造订单 编程状态变为“编程中” 制造订单状态为‘返工’
self.write({'programming_state': '编程中', 'work_state': '编程中', 'state': 'rework'})
if missing_tool_1:
logging.info(f'线边、机内缺刀:{missing_tool_1}')
# 修改 修改cnc程序的刀具状态 为 ‘缺刀’
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', missing_tool_1)])
if cnc_ids:
cnc_ids.write({'tool_state': '1'})
if missing_tool_2 and not invalid_tool:
if missing_tool_2 and invalid_tool == []:
logging.info(f'库存缺刀:{missing_tool_2}')
# 调用CAM工单程序用刀计划创建方法
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.filtered(lambda a: a.production_id == self[0].id).ids),
@@ -210,4 +214,6 @@ class MrpProduction(models.Model):
if cnc_ids:
logging.info('调用CAM工单程序用刀计划创建方法')
self.env['sf.cam.work.order.program.knife.plan'].sudo().create_cam_work_plan(cnc_ids)
if not invalid_tool and not missing_tool_1:
logging.info('校验cnc用刀正常!')
logging.info('工单cnc程序用刀校验完成')