From 73ab43f16a0ebf08f035128de5789dfc1c56be12 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 28 Nov 2024 10:05:17 +0800 Subject: [PATCH 001/147] =?UTF-8?q?=E4=BA=BA=E5=B7=A5=E7=BA=BF=E4=B8=8B?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index d72b8738..309bb0aa 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1012,7 +1012,7 @@ class MrpProduction(models.Model): if self.production_type == '自动化产线加工': date_planned_start, date_planned_end, last_time = work.auto_production_process(last_time, count, type_map) - elif self.production_type == '': + elif self.production_type == '人工线下加工': date_planned_start, date_planned_end, last_time = work.manual_offline_process(last_time, index) work.update_work_start_end(date_planned_start, date_planned_end) From 37c47b0a54610ddebdba1944b9c7dd4ff10f3d6d Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Thu, 5 Dec 2024 18:14:19 +0800 Subject: [PATCH 002/147] =?UTF-8?q?=E5=AF=B9=E5=90=88=E5=B9=B6=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E9=87=87=E8=B4=AD=E5=8D=95=E4=BF=AE=E6=94=B9=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_dlm/models/stock_rule_inherit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_dlm/models/stock_rule_inherit.py b/sf_dlm/models/stock_rule_inherit.py index b1e5b911..4a40ca2f 100644 --- a/sf_dlm/models/stock_rule_inherit.py +++ b/sf_dlm/models/stock_rule_inherit.py @@ -44,7 +44,7 @@ class StockRuleInherit(models.Model): po = self.env['purchase.order'].sudo().search([ ('partner_id', '=', supplier.partner_id.id), ('company_id', '=', procurement.company_id.id), # 保证公司一致 - ('origin', '=', procurement.origin), # 根据来源匹配 + ('origin', 'like', procurement.origin), # 根据来源匹配 ('state', '=', 'draft') # 状态为草稿 ], limit=1) logging.info("po=: %s", po) From a6979b213bac33ec54cea90a1a847ce0b707e613 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 9 Dec 2024 09:35:41 +0800 Subject: [PATCH 003/147] =?UTF-8?q?=E6=89=8B=E5=8A=A8=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=9A=84=E9=87=87=E8=B4=AD=E5=8D=95=E7=94=9F=E6=88=90=E7=9A=84?= =?UTF-8?q?=E5=86=85=E9=83=A8=E8=B0=83=E6=8B=A8=E5=8D=95=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=BA=90=E5=8D=95=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 0c01a57c..ea8ca7c6 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -980,7 +980,8 @@ class ReStockMove(models.Model): production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc') productions = self.env['mrp.production'].search( [('origin', '=', production.origin), ('product_id', '=', production.product_id.id)]) - res['origin'] = ','.join(productions.mapped('name')) + if productions.mapped('name'): + res['origin'] = ','.join(productions.mapped('name')) res['retrospect_ref'] = production.product_id.name return res From 1c4a6ca85e781a6338e4c6b80c66e2ee3526d3e2 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 9 Dec 2024 16:07:34 +0800 Subject: [PATCH 004/147] =?UTF-8?q?=E5=BC=80=E6=94=BE=E8=BF=94=E5=B7=A5?= =?UTF-8?q?=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 2 +- sf_manufacturing/views/mrp_workorder_view.xml | 2 +- sf_quality/models/quality_cnc_test.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index bc012ab9..bab7e282 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -129,7 +129,7 @@ class ResMrpWorkOrder(models.Model): Y10_axis = fields.Float(default=0) Z10_axis = fields.Float(default=0) X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) - test_results = fields.Selection([("合格", "合格")], default='合格', + test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格', string="检测结果", tracking=True) cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序") cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序") diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index be1a6523..13fff868 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -200,7 +200,7 @@ - diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index bab7e282..acbb4bfe 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1114,9 +1114,7 @@ class ResMrpWorkOrder(models.Model): # ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]========================== if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework' or workorder.production_id.schedule_state != '已排' - or workorder.production_id.reservation_state not in ['assigned'] - or workorder.production_id.workorder_ids.filtered( - lambda wk: wk.sequence == workorder.sequence - 1).test_results in ['报废', '返工']): + or workorder.production_id.reservation_state not in ['assigned']): if workorder.state != 'waiting': workorder.state = 'waiting' continue diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 043990ef..d08ff81f 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -442,7 +442,7 @@ + From f3e08f5cccec9a893310e90cd1c093e4506bb97c Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 30 Dec 2024 09:43:20 +0800 Subject: [PATCH 083/147] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=9B=B6=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E7=A7=B0,=E9=9B=B6=E4=BB=B6=E5=9B=BE=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/__manifest__.py | 2 +- sf_manufacturing/models/stock.py | 75 ++++++++++++------- sf_manufacturing/views/stock_picking_view.xml | 17 ++++- sf_warehouse/models/model.py | 2 +- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/sf_machine_connect/__manifest__.py b/sf_machine_connect/__manifest__.py index 48857914..50a157d4 100644 --- a/sf_machine_connect/__manifest__.py +++ b/sf_machine_connect/__manifest__.py @@ -25,7 +25,7 @@ # 只有它被屏蔽了 # 'views/SfWorkOrderBarcodes.xml', 'views/WorkCenterBarcodes.xml', - 'views/Stock_picking_Barcodes.xml', + # 'views/Stock_picking_Barcodes.xml', 'views/machine_monitor.xml', 'views/machine_info_present.xml', 'views/delivery_record.xml', diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 6506cc1a..6c70c245 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -588,40 +588,33 @@ class StockPicking(models.Model): address_of_delivery = fields.Char('联系地址', compute='_compute_move_ids', store=True) retrospect_ref = fields.Char('追溯参考', compute='_compute_move_ids', store=True) - + sale_order_id = fields.Many2one('sale.order', '销售单号', compute='_compute_move_ids', store=True) picking_type_sequence_code = fields.Char(related='picking_type_id.sequence_code') @api.depends('move_ids', 'move_ids.product_id') def _compute_move_ids(self): for item in self: if item.move_ids: - if item.picking_type_id.sequence_code == 'DL': - sale_name = item.move_ids[0].product_id.name.split('-')[1] - if 'S' in sale_name: - sale_id = self.env['sale.order'].sudo().search([('name', '=', sale_name)]) - item.person_of_delivery = sale_id.person_of_delivery - item.telephone_of_delivery = sale_id.telephone_of_delivery - item.address_of_delivery = sale_id.address_of_delivery + product_id = item.move_ids[0].product_id + if product_id: + sale_info = None + if product_id.categ_id.type == '坯料' and product_id.name.startswith('R-S'): + parts = product_id.name.split('-') + if len(parts) >= 3: + sale_name = parts[1] + sale_info = self.env['sale.order'].sudo().search( + [('name', '=', sale_name)]) else: - raise ValidationError('坯料名称格式错误,正确格式为[R-S???-?]!!!') - move_ids = [] - for move_id in item.move_ids: - move_ids.append(move_id.product_id.id) - boms = self.env['mrp.bom'].sudo().search([('bom_line_ids.product_id', 'in', move_ids)]) - if boms: - codes_list = [] - for bom in boms: - if bom.product_tmpl_id.default_code: - code_list = bom.product_tmpl_id.default_code.split('-') - if len(code_list) >= 4: - code = '-'.join(code_list[:4]) - if code not in codes_list: - codes_list.append(code) - else: - raise ValidationError('坯料成品的内部参考值格式错误') - item.retrospect_ref = ','.join(codes_list) - elif item.picking_type_id.sequence_code in ['INT', 'PC']: - pass + production_list = self.env['mrp.production'].sudo().search( + [('product_id', '=', product_id.id)]) + if production_list: + sale_info = production_list[0].sale_order_id + if sale_info: + item.sale_order_id = sale_info.id + if item.picking_type_id.sequence_code == 'DL': + item.person_of_delivery = sale_info.person_of_delivery + item.telephone_of_delivery = sale_info.telephone_of_delivery + item.address_of_delivery = sale_info.address_of_delivery # 设置外协出入单的名称 def _get_name_Res(self, rescode): @@ -727,6 +720,34 @@ class ReStockMove(models.Model): materiel_length = fields.Float(string='物料长度', digits=(16, 4)) materiel_width = fields.Float(string='物料宽度', digits=(16, 4)) materiel_height = fields.Float(string='物料高度', digits=(16, 4)) + part_number = fields.Char(string='零件图号', compute='_compute_part_info', store=True) + part_name = fields.Char(string='零件名称', compute='_compute_part_info', store=True) + + @api.depends('product_id') + def _compute_part_info(self): + for move in self: + if move.product_id.categ_id.type == '成品': + move.part_number = move.product_id.part_number + move.part_name = move.product_id.part_name + elif move.product_id.categ_id.type == '坯料': + if move.origin: + origin = move.origin.split(',')[0] if ',' in move.origin else move.origin + mrp_productio_info = self.env['mrp.production'].sudo().search( + [('name', '=', origin)]) + if mrp_productio_info: + move.part_number = mrp_productio_info.part_number + move.part_name = mrp_productio_info.part_name + else: + purchase_order_info = self.env['purchase.order'].sudo().search( + [('name', '=', origin)]) + if purchase_order_info: + mrp_production_ids = purchase_order_info._get_mrp_productions().ids + if mrp_production_ids: + mrp_productio_info = self.env['mrp.production'].sudo().search( + [('id', '=', mrp_production_ids[0])]) + if mrp_productio_info: + move.part_number = mrp_productio_info.part_number + move.part_name = mrp_productio_info.part_name def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False): route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id diff --git a/sf_manufacturing/views/stock_picking_view.xml b/sf_manufacturing/views/stock_picking_view.xml index 30264f89..8b6fc571 100644 --- a/sf_manufacturing/views/stock_picking_view.xml +++ b/sf_manufacturing/views/stock_picking_view.xml @@ -17,6 +17,9 @@ stock.picking + + + + + + + @@ -34,6 +41,9 @@ stock.picking + + + @@ -45,8 +55,13 @@ stock.picking + + + + + - diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 30024239..79881920 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -1123,7 +1123,7 @@ class SfPickingType(models.Model): if not self.env.user.has_group('base.group_system'): action['context']['create'] = False if self.sequence_code in ['DL', 'INT', 'PC']: - action['context']['search_default_retrospect_ref'] = 1 + action['context']['search_default_retrospect'] = 1 return action From 676f8eb7eb8a99ea2d540977c949593171496060 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 30 Dec 2024 09:52:32 +0800 Subject: [PATCH 084/147] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E7=9A=84=E8=A7=A3=E7=BB=91=E6=89=98=E7=9B=98?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=97=B6=EF=BC=8C=E4=BF=AE=E6=94=B9=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E6=89=98=E7=9B=98=E7=8A=B6=E6=80=81=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E9=97=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 410f8d1b..ef2c654b 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1464,6 +1464,9 @@ class ResMrpWorkOrder(models.Model): 'tray_type_id': False, 'tray_model_id': False, 'is_trayed': False}) + for item in self: + self.env['stock.lot'].sudo().search([('rfid', '=', item.rfid_code)]).write({ + 'tool_material_status': '可用'}) # 将FTP的检测报告文件下载到临时目录 def download_reportfile_tmp(self, workorder, reportpath): From 4e7993d035abee4113752be9b67d8138460774d3 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 30 Dec 2024 09:56:49 +0800 Subject: [PATCH 085/147] =?UTF-8?q?=E8=BF=BD=E6=BA=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 1 + sf_manufacturing/views/stock_picking_view.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 6c70c245..48907a82 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -611,6 +611,7 @@ class StockPicking(models.Model): sale_info = production_list[0].sale_order_id if sale_info: item.sale_order_id = sale_info.id + item.retrospect_ref = sale_info.order_code if item.picking_type_id.sequence_code == 'DL': item.person_of_delivery = sale_info.person_of_delivery item.telephone_of_delivery = sale_info.telephone_of_delivery diff --git a/sf_manufacturing/views/stock_picking_view.xml b/sf_manufacturing/views/stock_picking_view.xml index 8b6fc571..6c268b82 100644 --- a/sf_manufacturing/views/stock_picking_view.xml +++ b/sf_manufacturing/views/stock_picking_view.xml @@ -17,6 +17,9 @@ stock.picking + + + From b35f84291509894b02bcfa9920415b1d0d7833bb Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 30 Dec 2024 09:57:36 +0800 Subject: [PATCH 086/147] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=89=98=E7=9B=98?= =?UTF-8?q?=E8=A7=A3=E7=BB=91=E4=BF=AE=E6=94=B9=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index ef2c654b..d121bae8 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1456,6 +1456,9 @@ class ResMrpWorkOrder(models.Model): # 解绑托盘 def unbind_tray(self): + for item in self: + self.env['stock.lot'].sudo().search([('rfid', '=', item.rfid_code)]).write( + {'tool_material_status': '可用'}) self.production_id.workorder_ids.write({ 'rfid_code': False, 'tray_serial_number': False, @@ -1464,9 +1467,6 @@ class ResMrpWorkOrder(models.Model): 'tray_type_id': False, 'tray_model_id': False, 'is_trayed': False}) - for item in self: - self.env['stock.lot'].sudo().search([('rfid', '=', item.rfid_code)]).write({ - 'tool_material_status': '可用'}) # 将FTP的检测报告文件下载到临时目录 def download_reportfile_tmp(self, workorder, reportpath): From 993d720c404b0d6b6333fa7543bba4c3f355f8fc Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 10:01:43 +0800 Subject: [PATCH 087/147] =?UTF-8?q?sf-=E9=87=87=E8=B4=AD=E8=AF=A2=E4=BB=B7?= =?UTF-8?q?=E5=8D=95=E3=80=90=E4=B8=8A=E4=BC=A0=E5=90=88=E5=90=8C=E3=80=91?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=B1=95=E7=A4=BA=E6=9D=A1=E4=BB=B6=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/views/views.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/views/views.xml b/jikimo_purchase_tier_validation/views/views.xml index 6d6995ef..765603c8 100644 --- a/jikimo_purchase_tier_validation/views/views.xml +++ b/jikimo_purchase_tier_validation/views/views.xml @@ -16,7 +16,7 @@ - + + + + + \ No newline at end of file From c28c00a47bca1497c217daa03750e0437f61527e Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 17:11:08 +0800 Subject: [PATCH 100/147] =?UTF-8?q?=E8=B0=83=E6=95=B4description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index 9077ee22..b991d393 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -8,6 +8,7 @@ _logger = logging.getLogger(__name__) class jikimo_purchase_tier_validation(models.Model): _name = 'purchase.order' _inherit = ['purchase.order', 'tier.validation'] + _description = "采购订单" _tier_validation_buttons_xpath = "/form/header/button[@id='draft_confirm'][1]" From 4137b304f3c3c83d49289595ab7a8bacbdac94ec Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 30 Dec 2024 17:25:32 +0800 Subject: [PATCH 101/147] =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quality_control/views/quality_views.xml | 2 ++ sf_message/models/sf_message_product.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/quality_control/views/quality_views.xml b/quality_control/views/quality_views.xml index ad8e861c..790f8cef 100644 --- a/quality_control/views/quality_views.xml +++ b/quality_control/views/quality_views.xml @@ -266,6 +266,8 @@ + + diff --git a/sf_message/models/sf_message_product.py b/sf_message/models/sf_message_product.py index 3b82dac7..85ac4ce2 100644 --- a/sf_message/models/sf_message_product.py +++ b/sf_message/models/sf_message_product.py @@ -28,7 +28,7 @@ class SFMessagePlan(models.Model): '{{number}}', str(production_num)).replace( '{{request_url}}', url) contents.append(content) - return contents + return contents, message_queue_ids def get_request_url(self): url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') From 5e72e3d1dd61cc03e14a88064e9173f58e5dfebd Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 17:27:00 +0800 Subject: [PATCH 102/147] =?UTF-8?q?=E5=AE=A1=E6=89=B9=E6=98=8E=E7=BB=86?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/__manifest__.py | 6 ++++++ .../static/src/js/ir_model_extend.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js diff --git a/jikimo_purchase_tier_validation/__manifest__.py b/jikimo_purchase_tier_validation/__manifest__.py index 2c59b177..83df5447 100644 --- a/jikimo_purchase_tier_validation/__manifest__.py +++ b/jikimo_purchase_tier_validation/__manifest__.py @@ -33,4 +33,10 @@ 'demo': [ 'demo/demo.xml', ], + + 'assets': { + 'web.assets_backend': [ + 'jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js', + ], + }, } diff --git a/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js b/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js new file mode 100644 index 00000000..fa61232b --- /dev/null +++ b/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js @@ -0,0 +1,14 @@ +/** @odoo-module **/ + +import {registerPatch} from "@mail/model/model_core"; + +registerPatch({ + name: "ir.model.review", + fields: { + availableWebViews: { + compute() { + return ["list", "form"]; + }, + }, + }, +}); \ No newline at end of file From 9ab164f0fe859e5af1812d86236f08ed028dba7c Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 30 Dec 2024 17:31:22 +0800 Subject: [PATCH 103/147] 1 --- sf_tool_management/models/fixture_material_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_tool_management/models/fixture_material_search.py b/sf_tool_management/models/fixture_material_search.py index ea1212a9..0ada643a 100644 --- a/sf_tool_management/models/fixture_material_search.py +++ b/sf_tool_management/models/fixture_material_search.py @@ -21,7 +21,7 @@ class FixtureMaterialSearch(models.Model): image = fields.Binary('图片', related='product_id.image_1920') number = fields.Integer('总数量', compute='_compute_number') usable_num = fields.Integer('可用数量', compute='_compute_number') - have_been_used_num = fields.Integer('在用数量', compute='_compute_number') + have_been_used_num = fields.Integer('占用数量', compute='_compute_number') scrap_num = fields.Integer('报废数量', compute='_compute_number') barcode_ids = fields.One2many('stock.lot', 'fixture_material_search_id', string='序列号', readonly=True) From 7556c09ac222fe897d66cc4fbaa881f39d6372bc Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 17:59:11 +0800 Subject: [PATCH 104/147] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/src/js/ir_model_extend.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js b/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js index fa61232b..97d6f38c 100644 --- a/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js +++ b/jikimo_purchase_tier_validation/static/src/js/ir_model_extend.js @@ -7,7 +7,7 @@ registerPatch({ fields: { availableWebViews: { compute() { - return ["list", "form"]; + return ["list", "form", "activity"]; }, }, }, From 210eea3b0b04f2f484fa1310cd04915d429e648a Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 19:24:45 +0800 Subject: [PATCH 105/147] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/__manifest__.py | 2 +- jikimo_purchase_tier_validation/models/models.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/__manifest__.py b/jikimo_purchase_tier_validation/__manifest__.py index 83df5447..18a63e80 100644 --- a/jikimo_purchase_tier_validation/__manifest__.py +++ b/jikimo_purchase_tier_validation/__manifest__.py @@ -20,7 +20,7 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['purchase', 'base_tier_validation', 'documents'], + 'depends': ['purchase', 'base_tier_validation', 'documents', 'purchase_request', 'account'], # always loaded 'data': [ diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index b991d393..df2e8894 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -153,3 +153,18 @@ class jikimo_purchase_tier_validation(models.Model): 'sticky': False, } } + + +class jikimo_purchase_request(models.Model): + _inherit = 'purchase.order' + _description = "采购申请" + + +class jikimo_account_payment(models.Model): + _inherit = 'account.payment' + _description = "付款单" + + +class jikimo_account_move(models.Model): + _inherit = 'account.move' + _description = "发票账单" From 4937c3a8120caf9f99f68ac339af8916cfb92b90 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 20:27:57 +0800 Subject: [PATCH 106/147] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index df2e8894..4602eb50 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -156,7 +156,7 @@ class jikimo_purchase_tier_validation(models.Model): class jikimo_purchase_request(models.Model): - _inherit = 'purchase.order' + _inherit = 'purchase.request' _description = "采购申请" From a24279f6e69fe5a625baf5a667f5e207880498d2 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 30 Dec 2024 21:37:10 +0800 Subject: [PATCH 107/147] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E7=9A=84=E9=80=9A=E7=9F=A5=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index 4602eb50..bcc18bb6 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -64,6 +64,15 @@ class jikimo_purchase_tier_validation(models.Model): if error_messages: raise ValidationError('\n'.join(error_messages)) + # 添加通知消息 + if hasattr(record, 'message_post'): + current_user = self.env.user.name + record.message_post( + body=f"{current_user} 提交审批", + message_type='notification', + subtype_xmlid='mail.mt_note' + ) + return super(jikimo_purchase_tier_validation, self).request_validation() # 上传合同文件 From acee32cc3901ca74f249f2d4a8df25a4ee00624d Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 31 Dec 2024 08:47:44 +0800 Subject: [PATCH 108/147] =?UTF-8?q?1=E3=80=81=E9=87=87=E8=B4=AD=E8=AE=A2?= =?UTF-8?q?=E5=8D=95form=E9=A1=B5=E4=B9=B0=E5=AE=B6=E6=94=B9=E5=90=8D?= =?UTF-8?q?=E4=B8=BA=E9=87=87=E8=B4=AD=E5=91=98=EF=BC=9B2=E3=80=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=88=90=E5=93=81=E5=85=A5=E5=BA=93=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E7=9A=84=E5=9D=AF=E6=96=99=E5=A7=94=E5=A4=96=E5=8A=A0?= =?UTF-8?q?=E5=B7=A5=E9=93=BE=E6=8E=A5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/views/purchase_order_view.xml | 3 +++ sf_stock/models/stock_picking.py | 10 +++++----- sf_stock/views/stock_picking.xml | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml index bab28456..dd2c452c 100644 --- a/sf_sale/views/purchase_order_view.xml +++ b/sf_sale/views/purchase_order_view.xml @@ -29,6 +29,9 @@ 1 + + 采购员 + diff --git a/sf_stock/models/stock_picking.py b/sf_stock/models/stock_picking.py index 9b7b22b1..f8105097 100644 --- a/sf_stock/models/stock_picking.py +++ b/sf_stock/models/stock_picking.py @@ -47,23 +47,23 @@ class StockPicking(models.Model): }) return action - pro_out_purchase_count = fields.Integer('坯料外协单数量', compute='_compute_pro_out_purchase_count', store=True) + pro_out_purchase_count = fields.Integer('坯料委外单数量', compute='_compute_pro_out_purchase_count', store=True) @api.depends('name') def _compute_pro_out_purchase_count(self): for sp in self: if sp: po_ids = self.env['purchase.order'].sudo().search([ - ('origin', 'like', sp.name), ('purchase_type', '=', 'consignment')]) + ('origin', 'like', sp.name), ('purchase_type', '=', 'outsourcing')]) if po_ids: sp.pro_out_purchase_count = len(po_ids) def pro_out_purchase_order(self): """ - 坯料外协 + 坯料委外 """ po_ids = self.env['purchase.order'].sudo().search([ - ('origin', 'like', self.name), ('purchase_type', '=', 'consignment')]) + ('origin', 'like', self.name), ('purchase_type', '=', 'outsourcing')]) action = { 'res_model': 'purchase.order', 'type': 'ir.actions.act_window', @@ -75,7 +75,7 @@ class StockPicking(models.Model): }) else: action.update({ - 'name': _("外协订单列表"), + 'name': _("委外订单列表"), 'domain': [('id', 'in', po_ids.ids)], 'view_mode': 'tree,form', }) diff --git a/sf_stock/views/stock_picking.xml b/sf_stock/views/stock_picking.xml index 1ecc0d40..043a4d87 100644 --- a/sf_stock/views/stock_picking.xml +++ b/sf_stock/views/stock_picking.xml @@ -18,7 +18,7 @@ attrs="{'invisible': [('pro_out_purchase_count', '=', 0)]}">
- 坯料外协 + 坯料委外
From 78b0529809060357561bb9b1acf8efa9631d8c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Tue, 31 Dec 2024 08:54:02 +0800 Subject: [PATCH 109/147] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=88=90=E5=93=81?= =?UTF-8?q?=E6=97=B6=E4=BB=8E=E6=A8=A1=E6=9D=BF=E4=B8=8A=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=95=86=E4=BB=B7=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_sale_multiple_supply_methods/models/product_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_sale_multiple_supply_methods/models/product_template.py b/jikimo_sale_multiple_supply_methods/models/product_template.py index 640571f7..cd730998 100644 --- a/jikimo_sale_multiple_supply_methods/models/product_template.py +++ b/jikimo_sale_multiple_supply_methods/models/product_template.py @@ -23,4 +23,4 @@ class ProductTemplate(models.Model): self.is_bfm = product_template_id.is_bfm self.is_manual_processing = product_template_id.is_manual_processing # 复制 seller_ids - self.seller_ids = [(0, 0, {'partner_id': seller.partner_id.id, 'delay': 1.0}) for seller in product_template_id.seller_ids] + self.seller_ids = [(0, 0, {'partner_id': seller.partner_id.id, 'delay': 1.0, 'price': seller.price}) for seller in product_template_id.seller_ids] From 32e3c2f79fe6df18f926ad5323f6447e4af22cd0 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 31 Dec 2024 08:56:41 +0800 Subject: [PATCH 110/147] =?UTF-8?q?=E9=87=87=E8=B4=AD=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=BA=90=E6=96=87=E6=A1=A3=E5=AD=97=E6=AE=B5=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=BA=90=E5=8D=95=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/views/purchase_order_view.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml index dd2c452c..eec616f4 100644 --- a/sf_sale/views/purchase_order_view.xml +++ b/sf_sale/views/purchase_order_view.xml @@ -32,7 +32,9 @@ 采购员 - + + 源单据 + @@ -227,6 +229,9 @@ 采购员 + + 源单据 + hide @@ -284,6 +289,9 @@ 采购员 + + 源单据 + From 1816f1a4972c9a7563e975d42f9734ee12b36496 Mon Sep 17 00:00:00 2001 From: hy <123@qq.com> Date: Tue, 31 Dec 2024 09:45:56 +0800 Subject: [PATCH 111/147] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=AF=B9=E4=B8=8D=E9=BD=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/src/js/custom_form_status_indicator.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jikimo_frontend/static/src/js/custom_form_status_indicator.js b/jikimo_frontend/static/src/js/custom_form_status_indicator.js index 1e39b719..4992872a 100644 --- a/jikimo_frontend/static/src/js/custom_form_status_indicator.js +++ b/jikimo_frontend/static/src/js/custom_form_status_indicator.js @@ -177,9 +177,10 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', { const thead_th_num = thead_tr.children().length const tbody_tr_num = tbody_tr.children().length const num = thead_th_num - tbody_tr_num - console.log('num', num); if(num == -1) { - thead_tr.prepend('序号') + tbody.children('tr').each(function () { + $(this).children('td').eq(0).remove() + }) } } catch (e) { From 78a456849c85cf5d56eab97d0afb7fb1aca34ea8 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Tue, 31 Dec 2024 09:55:16 +0800 Subject: [PATCH 112/147] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=88=90=E5=93=81?= =?UTF-8?q?=E8=B0=83=E6=8B=A8=E5=87=BA=E5=BA=93=E8=AE=A2=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=B2=A1=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 1d880d66..2dcab4be 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -654,11 +654,8 @@ class StockPicking(models.Model): if self.location_id.name == '成品存货区' and self.location_dest_id.name == '客户': sale_id = self.env['sale.order'].sudo().search( [('name', '=', self.origin)]) - check_backorder = self._pre_action_done_hook() - if check_backorder is not True: - return res - if sale_id: - sale_id.write({'state':'delivered'}) + if sale_id and res: + sale_id.write({'state': 'delivered'}) return res # 创建 外协出库入单 @@ -674,12 +671,14 @@ class StockPicking(models.Model): }) move_dest_id = False # 如果当前工单是是制造订单的最后一个工艺外协工单 - if workorder == next((workorder for workorder in reversed(sorted_workorders) if workorder.is_subcontract), None): + if workorder == next((workorder for workorder in reversed(sorted_workorders) if workorder.is_subcontract), + None): move_dest_id = item.move_raw_ids[0].id else: # 从sorted_workorders中找到上一工单的move if len(sorted_workorders) > 1: - move_dest_id = sorted_workorders[sorted_workorders.index(workorder)+1].move_subcontract_workorder_ids[1].id + move_dest_id = \ + sorted_workorders[sorted_workorders.index(workorder) + 1].move_subcontract_workorder_ids[1].id new_picking = True outcontract_picking_type_in = self.env.ref( 'sf_manufacturing.outcontract_picking_in').id, @@ -705,9 +704,6 @@ class StockPicking(models.Model): {'picking_id': picking_out.id, 'state': 'waiting'}) moves_out._assign_picking_post_process(new=new_picking) - - - @api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id') def _compute_state(self): super(StockPicking, self)._compute_state() From 4902fc5d9a777d53a8641511a62d999c566ba78a Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 31 Dec 2024 10:56:07 +0800 Subject: [PATCH 113/147] =?UTF-8?q?1=E3=80=81=E9=87=87=E8=B4=AD=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E5=85=B3=E8=81=94=E9=94=80=E5=94=AE=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=AD=97=E6=AE=B5=E4=BB=8E=E9=94=80=E5=94=AE=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=90=AC=E8=BF=81=E5=88=B0=E5=88=B6=E9=80=A0=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E5=B9=B6=E6=96=B0=E5=A2=9E=E4=B8=80=E4=B8=AA?= =?UTF-8?q?many2many=E7=B1=BB=E5=9E=8B=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=B8=94?= =?UTF-8?q?=E5=AF=B9=E5=AD=97=E6=AE=B5=E7=9A=84=E8=87=AA=E5=8A=A8=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=96=B9=E6=B3=95=E8=BF=9B=E8=A1=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/purchase_order.py | 41 ++++++++++++++++--- .../views/purchase_order_view.xml | 7 ++++ sf_sale/models/sale_order.py | 17 -------- sf_sale/views/purchase_order_view.xml | 5 --- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/sf_manufacturing/models/purchase_order.py b/sf_manufacturing/models/purchase_order.py index fc8a96b1..71e4e045 100644 --- a/sf_manufacturing/models/purchase_order.py +++ b/sf_manufacturing/models/purchase_order.py @@ -10,10 +10,11 @@ from odoo.tools import OrderedSet # _get_surface_technics_purchase_ids class PurchaseOrder(models.Model): _inherit = 'purchase.order' + production_count = fields.Integer( "关联制造订单", compute='_compute_workorder_count', - ) + ) def action_view_production(self): origins = [order.name for order in self.picking_ids] @@ -37,17 +38,17 @@ class PurchaseOrder(models.Model): }) return action - def _compute_workorder_count(self): for purchase in self: origins = [order.name for order in purchase.picking_ids] production_id = self.env['mrp.production'].search([('origin', 'in', origins)]) purchase.production_count = len(production_id) + def button_confirm(self): super().button_confirm() - workorders = self.env['mrp.workorder'].search([('purchase_id', '=', self.id),('state', '!=', 'cancel')]) + workorders = self.env['mrp.workorder'].search([('purchase_id', '=', self.id), ('state', '!=', 'cancel')]) for workorder in workorders: - if workorder.routing_type == '表面工艺' and workorder.is_subcontract is True: + if workorder.routing_type == '表面工艺' and workorder.is_subcontract is True: move_out = workorder.move_subcontract_workorder_ids[1] # move_out = self.env['stock.move'].search( # [('location_id', '=', self.env['stock.location'].search( @@ -61,10 +62,39 @@ class PurchaseOrder(models.Model): if not mo.move_line_ids: self.env['stock.move.line'].create(mo.get_move_line(workorder.production_id, workorder)) return True + + origin_sale_id = fields.Many2one('sale.order', string='销售订单号', store=True, compute='_compute_origin_sale_id') + origin_sale_ids = fields.Many2many('sale.order', string='销售订单号(多个)', store=True, + compute='_compute_origin_sale_id') + + @api.depends('origin') + def _compute_origin_sale_id(self): + for purchase in self: + if not purchase.origin: + continue + elif 'MO' in purchase.origin: + mp_name_list = [name.strip() for name in purchase['origin'].split(',')] + os_ids = list({mp_id.sale_order_id.id for mp_id in self.env['mrp.production'].sudo().search([ + ('name', 'in', mp_name_list)])}) + if len(os_ids) == 1: + purchase.origin_sale_id = os_ids[0] + elif len(os_ids) >= 2: + purchase.origin_sale_ids = os_ids + elif 'S' in purchase.origin: + os_name_list = [name.strip() for name in purchase['origin'].split(',')] + os_ids = self.env['sale.order'].sudo().search([('name', 'in', os_name_list)]) + if len(os_ids) == 1: + purchase.origin_sale_id = os_ids.id + elif len(os_ids) >= 2: + purchase.origin_sale_ids = os_ids.ids + + class PurchaseOrderLine(models.Model): _inherit = 'purchase.order.line' part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True) - related_product = fields.Many2one('product.product',compute='_compute_related_product', string='关联产品',help='经此产品工艺加工成的成品') + related_product = fields.Many2one('product.product', compute='_compute_related_product', string='关联产品', + help='经此产品工艺加工成的成品') + @api.depends('order_id.origin') def _compute_related_product(self): for record in self: @@ -73,4 +103,3 @@ class PurchaseOrderLine(models.Model): record.related_product = production_id.product_id if production_id else False else: record.related_product = False - diff --git a/sf_manufacturing/views/purchase_order_view.xml b/sf_manufacturing/views/purchase_order_view.xml index 83562f2c..3b1518fb 100644 --- a/sf_manufacturing/views/purchase_order_view.xml +++ b/sf_manufacturing/views/purchase_order_view.xml @@ -22,6 +22,13 @@ + + + + + diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index c9c06b9b..ac246da9 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -285,8 +285,6 @@ class RePurchaseOrder(models.Model): [('standard', '标准采购'), ('consignment', '工序外协'), ('outsourcing', '委外加工'), ('outside', '外购订单')], string='采购类型', default='standard', store=True, compute='_compute_purchase_type') - origin_sale_id = fields.Many2one('sale.order', string='销售订单号', compute='_compute_origin_sale_id') - # 合同编号 contract_number = fields.Char(string='合同编号', size=20) # 合同概况 @@ -311,21 +309,6 @@ class RePurchaseOrder(models.Model): purchase.purchase_type = 'outsourcing' break - @api.depends('order_line.move_dest_ids.group_id.mrp_production_ids', - 'order_line.move_ids.move_dest_ids.group_id.mrp_production_ids', 'origin') - def _compute_origin_sale_id(self): - for purchase in self: - productions_ids = purchase._get_mrp_productions() - if productions_ids: - if productions_ids[0].sale_order_id: - purchase.origin_sale_id = productions_ids[0].sale_order_id.id - continue - order_id = self.env['sale.order'].sudo().search([('name', '=', purchase.origin)]) - if order_id: - purchase.origin_sale_id = order_id.id - continue - purchase.origin_sale_id = False - delivery_warning = fields.Selection([('normal', '正常'), ('warning', '预警'), ('overdue', '已逾期')], string='交期状态', default='normal', tracking=True) diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml index eec616f4..ecc061fa 100644 --- a/sf_sale/views/purchase_order_view.xml +++ b/sf_sale/views/purchase_order_view.xml @@ -190,11 +190,6 @@ - - - - - 1 From 2373f333151057d25b120394d22138d27f8d96e6 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 31 Dec 2024 11:34:21 +0800 Subject: [PATCH 114/147] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E6=BA=90?= =?UTF-8?q?=E5=8D=95=E6=8D=AE=E4=B8=BA=E5=85=A5=E5=BA=93=E5=8D=95=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E8=87=AA=E5=8A=A8=E8=AE=A1=E7=AE=97=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E5=8F=82=E8=80=83=E9=94=80=E5=94=AE=E8=AE=A2=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/purchase_order.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sf_manufacturing/models/purchase_order.py b/sf_manufacturing/models/purchase_order.py index 71e4e045..3e20a0a2 100644 --- a/sf_manufacturing/models/purchase_order.py +++ b/sf_manufacturing/models/purchase_order.py @@ -87,6 +87,14 @@ class PurchaseOrder(models.Model): purchase.origin_sale_id = os_ids.id elif len(os_ids) >= 2: purchase.origin_sale_ids = os_ids.ids + elif 'IN' in purchase.origin: + sp_name_list = [name.strip() for name in purchase['origin'].split(',')] + os_ids = list({sp_id.sale_order_id.id for sp_id in self.env['stock.picking'].sudo().search([ + ('name', 'in', sp_name_list)])}) + if len(os_ids) == 1: + purchase.origin_sale_id = os_ids[0] + elif len(os_ids) >= 2: + purchase.origin_sale_ids = os_ids class PurchaseOrderLine(models.Model): From 64eb66c334674dc93bedcb8859175ec7cd211a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Tue, 31 Dec 2024 11:39:36 +0800 Subject: [PATCH 115/147] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=80=80=E5=9B=9E?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E8=AE=BE=E8=AE=A1=E5=90=8E=E5=86=8D=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=EF=BC=8C=E9=87=87=E8=B4=AD=E5=8D=95=E7=BC=96=E7=A8=8B?= =?UTF-8?q?=E8=8D=89=E7=A8=BF=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 25 ++++++++++--------- .../wizard/production_technology_wizard.py | 5 +++- sf_sale/models/sale_order.py | 1 - 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index c63a00b0..b9b3dbbb 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -783,7 +783,7 @@ class MrpProduction(models.Model): workorder.duration_expected = workorder._get_duration_expected() # 外协出入库单处理 - def get_subcontract_pick_purchase(self): + def get_subcontract_pick_purchase(self, special_design_workorder): production_all = self.sorted(lambda x: x.id) product_id_to_production_names = {} grouped_product_ids = {k: list(g) for k, g in @@ -792,18 +792,19 @@ class MrpProduction(models.Model): product_id_to_production_names[product_id] = [p.name for p in pd] sorted_workorders = None for production in production_all: - proc_workorders = [] - process_parameter_workorder = self.env['mrp.workorder'].search( - [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), - ('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') - if process_parameter_workorder: - # 将这些特殊表面工艺工单的采购单与调拨单置为失效 - for workorder in process_parameter_workorder: - workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'}) - workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) - workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'}) + # proc_workorders = [] + # process_parameter_workorder = self.env['mrp.workorder'].search( + # [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), + # ('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') + # need_delete_workorder = process_parameter_workorder - special_design_workorder + # for workorder in need_delete_workorder: + # workorder._get_surface_technics_purchase_ids().write({'active': False}) + # workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) + # workorder.move_subcontract_workorder_ids.picking_id.write({'active': False}) + + if special_design_workorder: consecutive_workorders = [] - sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) + sorted_workorders = sorted(special_design_workorder, key=lambda w: w.sequence) # for i, workorder in enumerate(sorted_workorders): # # 检查当前工作订单和下一个工作订单是否连续,并且供应商相同 # if i == 0: diff --git a/sf_manufacturing/wizard/production_technology_wizard.py b/sf_manufacturing/wizard/production_technology_wizard.py index e16e853c..65e87774 100644 --- a/sf_manufacturing/wizard/production_technology_wizard.py +++ b/sf_manufacturing/wizard/production_technology_wizard.py @@ -57,6 +57,7 @@ class ProductionTechnologyWizard(models.TransientModel): # td_upd = self.env['sf.technology.design'].sudo().search(domain) # if td_upd: # ro.write({'sequence': td_upd.sequence, 'active': td_upd.active}) + # 特殊表面工艺 special_design = self.env['sf.technology.design'].sudo().search( [('routing_tag', '=', 'special'), ('production_id', '=', production.id), ('is_auto', '=', False), ('active', 'in', [True, False])]) @@ -112,7 +113,9 @@ class ProductionTechnologyWizard(models.TransientModel): workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0] productions._create_workorder(False) if self.production_id.product_id.categ_id.type == '成品': - productions.get_subcontract_pick_purchase() + special_design_workorder = self.env['mrp.workorder'].search( + [('technology_design_id', 'in', special_design.ids), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) + productions.get_subcontract_pick_purchase(special_design_workorder) productions.is_adjust = False for item in productions: workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index c9c06b9b..5267725a 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -363,7 +363,6 @@ class RePurchaseOrder(models.Model): server_product_process = [] purchase_order = pp._get_surface_technics_purchase_ids() if purchase_order: - purchase_order.write({'state': 'draft'}) pp.purchase_id = [(6, 0, [purchase_order.id])] else: server_template = self.env['product.template'].search( From 4b7308fdcd9aa079fcf1dfa5978924100a5711fd Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Tue, 31 Dec 2024 12:54:16 +0800 Subject: [PATCH 116/147] =?UTF-8?q?sf-=E5=88=B6=E9=80=A0-=E5=A4=96?= =?UTF-8?q?=E5=8D=8F=E5=B7=A5=E5=8D=95-=E8=B0=83=E6=8B=A8=E5=8D=95?= =?UTF-8?q?=E5=B7=B2=E5=8F=96=E6=B6=88=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 1d880d66..1d1cd991 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -685,7 +685,11 @@ class StockPicking(models.Model): 'sf_manufacturing.outcontract_picking_in').id, outcontract_picking_type_out = self.env.ref( 'sf_manufacturing.outcontract_picking_out').id, - moves_in = self.env['stock.move'].sudo().create( + context = dict(self.env.context) + context.update({ + 'default_production_id': item.id, # 添加额外信息到 context 中 + }) + moves_in = self.env['stock.move'].sudo().with_context(context).create( self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, procurement_group_id.id, move_dest_id)) picking_in = self.create( @@ -694,7 +698,8 @@ class StockPicking(models.Model): moves_in.write( {'picking_id': picking_in.id, 'state': 'waiting'}) moves_in._assign_picking_post_process(new=new_picking) - moves_out = self.env['stock.move'].sudo().create( + # self.env.context.get('default_production_id') + moves_out = self.env['stock.move'].sudo().with_context(context).create( self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, procurement_group_id.id, moves_in.id)) workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]}) @@ -774,6 +779,7 @@ class ReStockMove(models.Model): 'origin': item.name, 'group_id': group_id, 'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False, + # 'production_id': item.id, # 'route_ids': False if not route else [(4, route.id)], 'date_deadline': datetime.now(), 'picking_type_id': picking_type_id, From 39ed32f3e9d04209e6cdfb97c3cdaaab0cd8115e Mon Sep 17 00:00:00 2001 From: guanhuan Date: Tue, 31 Dec 2024 13:08:00 +0800 Subject: [PATCH 117/147] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=88=90=E5=93=81?= =?UTF-8?q?=E8=B0=83=E6=8B=A8=E5=87=BA=E5=BA=93=E8=AE=A2=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=B2=A1=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 2dcab4be..fa723283 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -654,7 +654,10 @@ class StockPicking(models.Model): if self.location_id.name == '成品存货区' and self.location_dest_id.name == '客户': sale_id = self.env['sale.order'].sudo().search( [('name', '=', self.origin)]) - if sale_id and res: + stock_picking_list = self.env['stock.picking'].sudo().search( + [('id', 'in', sale_id.picking_ids.ids)]) + stock_picking = stock_picking_list.filtered(lambda p: p.state not in ("done", "cancel")) + if sale_id and not stock_picking: sale_id.write({'state': 'delivered'}) return res @@ -678,7 +681,7 @@ class StockPicking(models.Model): # 从sorted_workorders中找到上一工单的move if len(sorted_workorders) > 1: move_dest_id = \ - sorted_workorders[sorted_workorders.index(workorder) + 1].move_subcontract_workorder_ids[1].id + sorted_workorders[sorted_workorders.index(workorder) + 1].move_subcontract_workorder_ids[1].id new_picking = True outcontract_picking_type_in = self.env.ref( 'sf_manufacturing.outcontract_picking_in').id, From 37476bcc88f3e530d04214c1e649a3b4e3b2639f Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Tue, 31 Dec 2024 14:03:15 +0800 Subject: [PATCH 118/147] =?UTF-8?q?=E5=9B=9E=E9=80=80=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 64 ++++--------------- .../wizard/production_technology_wizard.py | 4 +- 2 files changed, 13 insertions(+), 55 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index b9b3dbbb..057530d0 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -783,7 +783,7 @@ class MrpProduction(models.Model): workorder.duration_expected = workorder._get_duration_expected() # 外协出入库单处理 - def get_subcontract_pick_purchase(self, special_design_workorder): + def get_subcontract_pick_purchase(self): production_all = self.sorted(lambda x: x.id) product_id_to_production_names = {} grouped_product_ids = {k: list(g) for k, g in @@ -792,57 +792,17 @@ class MrpProduction(models.Model): product_id_to_production_names[product_id] = [p.name for p in pd] sorted_workorders = None for production in production_all: - # proc_workorders = [] - # process_parameter_workorder = self.env['mrp.workorder'].search( - # [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), - # ('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') - # need_delete_workorder = process_parameter_workorder - special_design_workorder - # for workorder in need_delete_workorder: - # workorder._get_surface_technics_purchase_ids().write({'active': False}) - # workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) - # workorder.move_subcontract_workorder_ids.picking_id.write({'active': False}) - - if special_design_workorder: - consecutive_workorders = [] - sorted_workorders = sorted(special_design_workorder, key=lambda w: w.sequence) - # for i, workorder in enumerate(sorted_workorders): - # # 检查当前工作订单和下一个工作订单是否连续,并且供应商相同 - # if i == 0: - # consecutive_workorders.append(workorder) - # elif workorder.sequence == sorted_workorders[ - # i - 1].sequence + 1 and workorder.supplier_id.id == sorted_workorders[i - 1].supplier_id.id: - # consecutive_workorders.append(workorder) - # else: - # # 处理连续组,如果它不为空 - # if consecutive_workorders: - # proc_workorders.append(consecutive_workorders) - # # 创建外协出入库单和采购订单 - # # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders) - # # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - # # product_id_to_production_names) - # if i < len(sorted_workorders) - 1: - # # 重置连续组,并添加当前工作订单 - # consecutive_workorders = [workorder] - # else: - # # 判断最后一笔: - # if workorder.sequence == sorted_workorders[ - # i - 1].sequence and workorder.supplier_id.id == sorted_workorders[ - # i - 1].supplier_id.id: - # consecutive_workorders = [workorder] - # else: - # proc_workorders.append([workorder]) - # # 立即创建外协出入库单和采购订单 - # # self.env['stock.picking'].create_outcontract_picking(workorder, production) - # # self.env['purchase.order'].get_purchase_order(workorder, production, - # # product_id_to_production_names) - # consecutive_workorders = [] - # - # # 处理最后一个组,即使它可能只有一个工作订单 - # if consecutive_workorders: - # proc_workorders.append(consecutive_workorders) - # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - # product_id_to_production_names) + proc_workorders = [] + process_parameter_workorder = self.env['mrp.workorder'].search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), + ('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') + if process_parameter_workorder: + # 将这些特殊表面工艺工单的采购单与调拨单置为失效 + for workorder in process_parameter_workorder: + workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'}) + workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) + workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'}) + sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) if not sorted_workorders: return for workorders in reversed(sorted_workorders): diff --git a/sf_manufacturing/wizard/production_technology_wizard.py b/sf_manufacturing/wizard/production_technology_wizard.py index 65e87774..1feee749 100644 --- a/sf_manufacturing/wizard/production_technology_wizard.py +++ b/sf_manufacturing/wizard/production_technology_wizard.py @@ -113,9 +113,7 @@ class ProductionTechnologyWizard(models.TransientModel): workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0] productions._create_workorder(False) if self.production_id.product_id.categ_id.type == '成品': - special_design_workorder = self.env['mrp.workorder'].search( - [('technology_design_id', 'in', special_design.ids), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) - productions.get_subcontract_pick_purchase(special_design_workorder) + productions.get_subcontract_pick_purchase() productions.is_adjust = False for item in productions: workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( From 94b1c7d258771af92617caf281c67899885e32b6 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 31 Dec 2024 15:50:51 +0800 Subject: [PATCH 119/147] =?UTF-8?q?=E5=85=B3=E9=97=AD=E6=8A=A5=E5=BA=9F?= =?UTF-8?q?=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 2 +- sf_quality/models/quality_cnc_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index d121bae8..f11de84b 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -129,7 +129,7 @@ class ResMrpWorkOrder(models.Model): Y10_axis = fields.Float(default=0) Z10_axis = fields.Float(default=0) X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) - test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格', + test_results = fields.Selection([("合格", "合格"), ("返工", "返工")], default='合格', string="检测结果", tracking=True) cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序") cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序") diff --git a/sf_quality/models/quality_cnc_test.py b/sf_quality/models/quality_cnc_test.py index 9c73715d..9810b0e0 100644 --- a/sf_quality/models/quality_cnc_test.py +++ b/sf_quality/models/quality_cnc_test.py @@ -25,7 +25,7 @@ class SfQualityCncTest(models.Model): ('pass', '合格'), ('fail', '不合格')], string='判定结果') number = fields.Integer('数量', default=1) - test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果") + test_results = fields.Selection([("合格", "合格"), ("返工", "返工")], string="检测结果") reason = fields.Selection( [("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"), ("operate computer", "操机"), ("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因") From 281f3c67c34895d99c3e116bf3738a90f3f619cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Tue, 31 Dec 2024 16:00:24 +0800 Subject: [PATCH 120/147] =?UTF-8?q?=E7=89=B9=E6=AE=8A=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E5=A4=96=E5=8D=8F=E9=87=87=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E4=BA=BA=E4=BF=AE=E6=94=B9=E4=B8=BA=E4=BE=9B?= =?UTF-8?q?=E5=BA=94=E5=95=86=E7=9A=84=E9=87=87=E8=B4=AD=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 5267725a..be5098b8 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -373,12 +373,16 @@ class RePurchaseOrder(models.Model): 'product_qty': 1, 'product_uom': server_template.uom_id.id })) + # 获取服务商品最后一个供应商的采购员 + purchase_user_id = server_template.seller_ids[-1].partner_id.purchase_user_id purchase_order = self.env['purchase.order'].sudo().create({ 'partner_id': server_template.seller_ids[0].partner_id.id, 'origin': production.name, 'state': 'draft', 'purchase_type': 'consignment', - 'order_line': server_product_process}) + 'order_line': server_product_process, + 'user_id': purchase_user_id.id + }) pp.purchase_id = [(6, 0, [purchase_order.id])] # self.env.cr.commit() From 247bebbd75467ff6006111cef1989fdc089af795 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Tue, 31 Dec 2024 16:39:09 +0800 Subject: [PATCH 121/147] =?UTF-8?q?=E8=AF=A2=E4=BB=B7=E5=8D=95=E5=AE=A1?= =?UTF-8?q?=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/models.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index bcc18bb6..e5a80f7b 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -72,8 +72,30 @@ class jikimo_purchase_tier_validation(models.Model): message_type='notification', subtype_xmlid='mail.mt_note' ) + res = super(jikimo_purchase_tier_validation, self).request_validation() + self.state = 'to approve' + return res - return super(jikimo_purchase_tier_validation, self).request_validation() + def restart_validation(self): + res = super(jikimo_purchase_tier_validation, self).restart_validation() + self.state = 'draft' + return res + + def _validate_tier(self, tiers=False): + res = super(jikimo_purchase_tier_validation, self)._validate_tier(tiers) + self.state = 'approved' + return res + + def _rejected_tier(self, tiers=False): + res = super(jikimo_purchase_tier_validation, self)._rejected_tier(tiers) + self.state = 'draft' + return res + + @api.model + def _get_under_validation_exceptions(self): + res = super(jikimo_purchase_tier_validation, self)._get_under_validation_exceptions() + res.append("state") + return res # 上传合同文件 def upload_contract_file(self): From 701decb38f3872ac9b3f3660b12ee0a9b045b206 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Tue, 31 Dec 2024 17:08:38 +0800 Subject: [PATCH 122/147] =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E7=A1=AE=E8=AE=A4=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 118 +--------------------- sf_manufacturing/models/purchase_order.py | 6 -- sf_sale/models/sale_order.py | 18 ++++ 3 files changed, 19 insertions(+), 123 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index d121bae8..d6de3408 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1035,49 +1035,6 @@ class ResMrpWorkOrder(models.Model): 'production_id.tool_state', 'production_id.schedule_state', 'sequence', 'production_id.programming_state') def _compute_state(self): - # super()._compute_state() - # for workorder in self: - # if workorder.sequence != 1: - # previous_workorder = self.env['mrp.workorder'].search( - # [('production_id', '=', workorder.production_id.id), - # ('sequence', '=', workorder.sequence - 1)]) - # if workorder.state == 'pending': - # if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): - # if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': - # if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) - # or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel') - # and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) - # or (previous_workorder.state in ('done', 'cancel') - # and not workorder.blocked_by_workorder_ids - # and previous_workorder.test_results not in ['报废', '返工']) - # ): - # workorder.state = 'ready' - # continue - # if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): - # if workorder.sequence != 1: - # workorder.state = 'pending' - # continue - # if workorder.state not in ('waiting', 'ready'): - # continue - # if workorder.state in ( - # 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排': - # workorder.state = 'ready' - # continue - # if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): - # workorder.state = 'pending' - # if workorder.state in ['waiting']: - # if previous_workorder.state == 'waiting': - # workorder.state = 'pending' - # if workorder.sequence == 1 and workorder.state == 'pending': - # workorder.state = 'waiting' - # continue - # if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): - # continue - # if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排': - # workorder.state = 'ready' - # elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': - # workorder.state = 'waiting' - for workorder in self: # 如果工单的工序没有进行排序则跳出循环 if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0): @@ -1119,7 +1076,7 @@ class ResMrpWorkOrder(models.Model): if workorder.state != 'waiting': workorder.state = 'waiting' continue - if workorder.production_id.programming_state == '已编程': + if workorder.production_id.programming_state == '已编程' and workorder.technology_design_id.routing_tag != 'special': workorder.state = 'ready' elif workorder.state != 'waiting': workorder.state = 'waiting' @@ -1134,85 +1091,12 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: - # production_programming = self.env['mrp.production'].search( - # [('origin', '=', self.production_id.origin)], order='name asc') - # production_no_remanufacture = production_programming.filtered( - # lambda a: a.is_remanufacture is False) - # production_list = [production.name for production in production_programming] - # purchase_orders = self.env['purchase.order'].search( - # [('origin', 'ilike', ','.join(production_list))]) - # for line in purchase_orders.order_line: - # if ( - # line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id - # and line.product_qty == len(production_no_remanufacture)): - # if all(pur_order.state == 'purchase' for pur_order in purchase_orders): - # workorder.state = 'ready' - # else: - # workorder.state = 'waiting' purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id: workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' else: workorder.state = 'waiting' - # re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), - # ('processing_panel', '=', workorder.processing_panel), - # ('is_rework', '=', True), ('state', 'in', ['done', 'rework'])]) - # cnc_workorder = self.env['mrp.workorder'].search( - # [('production_id', '=', workorder.production_id.id), - # ('processing_panel', '=', workorder.processing_panel), - # ('routing_type', '=', 'CNC加工'), ('state', 'in', ['done', 'rework']), - # ('test_results', '=', '返工')]) - # cnc_workorder_pending = self.env['mrp.workorder'].search( - # [('production_id', '=', workorder.production_id.id), - # ('processing_panel', '=', workorder.processing_panel), - # ('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])]) - # unclamp_workorder = self.env['mrp.workorder'].search( - # [('production_id', '=', workorder.production_id.id), - # ('sequence', '=', workorder.sequence - 1), - # ('state', 'in', ['done'])]) - # if workorder.state not in ['cancel', 'progress', 'rework']: - # if workorder.production_id.state == 'rework': - # if workorder.routing_type == '装夹预调': - # # # 有返工工单 - # # if re_work: - # # 新工单 - # if workorder.is_rework is False: - # if (workorder.production_id.programming_state == '已编程' - # and workorder.production_id.is_rework is False): - # if re_work or cnc_workorder: - # workorder.state = 'ready' - # else: - # if workorder.production_id.is_rework is True: - # if re_work or cnc_workorder: - # workorder.state = 'waiting' - # - # elif workorder.routing_type == 'CNC加工': - # pre_workorder = self.env['mrp.workorder'].search( - # [('production_id', '=', workorder.production_id.id), - # ('processing_panel', '=', workorder.processing_panel), - # ('routing_type', '=', '装夹预调'), ('state', '=', 'done')]) - # if pre_workorder: - # if re_work: - # workorder.state = 'waiting' - # elif workorder.routing_type == '解除装夹': - # if cnc_workorder: - # if not cnc_workorder_pending or unclamp_workorder.test_results == '报废': - # workorder.state = 'waiting' - # # else: - # # if workorder.production_id.is_rework is True: - # # workorder.state = 'waiting' - # elif workorder.production_id.state == 'progress': - # if (workorder.routing_type == '装夹预调' and workorder.production_id.programming_state == '已编程' - # and workorder.is_rework is False and workorder.state not in ['done', 'rework', 'cancel']): - # if workorder.production_id.is_rework is False: - # if re_work or cnc_workorder or unclamp_workorder: - # workorder.state = 'ready' - # # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: - # # workorder.state = 'ready' - # elif workorder.production_id.state == 'scrap': - # if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废': - # workorder.state = 'waiting' # 重写工单开始按钮方法 def button_start(self): diff --git a/sf_manufacturing/models/purchase_order.py b/sf_manufacturing/models/purchase_order.py index 3e20a0a2..2813883e 100644 --- a/sf_manufacturing/models/purchase_order.py +++ b/sf_manufacturing/models/purchase_order.py @@ -50,12 +50,6 @@ class PurchaseOrder(models.Model): for workorder in workorders: if workorder.routing_type == '表面工艺' and workorder.is_subcontract is True: move_out = workorder.move_subcontract_workorder_ids[1] - # move_out = self.env['stock.move'].search( - # [('location_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - # ('location_dest_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'VL-SPOC')]).id), - # ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])]) for mo in move_out: if mo.state != 'done': mo.write({'state': 'assigned', 'production_id': False}) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 44899d05..24f689d4 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -391,6 +391,23 @@ class RePurchaseOrder(models.Model): production = self.env['mrp.production'].search([('name', '=', production_name)]) for workorder in production.workorder_ids.filtered( lambda wd: wd.routing_type == '表面工艺' and wd.state == 'waiting' and line.product_id.server_product_process_parameters_id == wd.surface_technics_parameters_id): + work_ids = workorder.production_id.workorder_ids.filtered( + lambda wk: wk.state not in ['done', 'rework', 'cancel']) + min_sequence_wk = min(work_ids, key=lambda wk: wk.sequence) + artificial_offline = ( + workorder.production_id.production_type == '人工线下加工' and workorder.production_id.schedule_state != '已排') + auto_production = ( + workorder.production_id.production_type == '自动化产线加工' and workorder.production_id.schedule_state != '已编程') + if workorder.sequence == min_sequence_wk.sequence: + if artificial_offline or auto_production: + raise UserError('等待组件') + else: + sorted_work_ids = work_ids.sorted(key=lambda w: w.sequence) + previous_workorder = self.env['mrp.workorder'].search([('sequence', '<', workorder.sequence), + ('production_id', '=', workorder.production_id.id), + ('state', '=', 'done')], order='sequence desc', limit=1) + if not previous_workorder: + raise UserError('等待组件') workorder.state = 'ready' return result @@ -423,6 +440,7 @@ class PurchaseOrderLine(models.Model): part_name = fields.Char('零件名称', related='product_id.part_name', readonly=True) # part_number = fields.Char('零件图号',related='product_id.part_number', readonly=True) + class ResPartnerToSale(models.Model): _inherit = 'res.partner' From 614447d56e1e7de1b7e55f8e17bc8031b9bffc03 Mon Sep 17 00:00:00 2001 From: hy <123@qq.com> Date: Thu, 2 Jan 2025 10:28:40 +0800 Subject: [PATCH 123/147] =?UTF-8?q?=E8=A7=A3=E5=BC=80=E5=B1=8F=E8=94=BD?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_frontend/static/src/js/custom_form_status_indicator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_frontend/static/src/js/custom_form_status_indicator.js b/jikimo_frontend/static/src/js/custom_form_status_indicator.js index 79702f84..4992872a 100644 --- a/jikimo_frontend/static/src/js/custom_form_status_indicator.js +++ b/jikimo_frontend/static/src/js/custom_form_status_indicator.js @@ -139,7 +139,7 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', { owl.onMounted(() => { this.activeElement = this.uiService.activeElement; this.setRequired() - // this.listherHeaderBodyNum() + this.listherHeaderBodyNum() }) return this._super(...arguments); }, From 81bebf836d725fe49650431bd85c2850f6209988 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Thu, 2 Jan 2025 10:59:03 +0800 Subject: [PATCH 124/147] =?UTF-8?q?sf-=E9=87=87=E8=B4=AD-=E8=AF=A2?= =?UTF-8?q?=E4=BB=B7=E5=8D=95=E7=8A=B6=E6=80=81=E6=B5=81=E8=BD=AC=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E6=8C=89=E9=92=AE=E5=BD=B1=E5=93=8D=E7=8E=B0=E6=9C=89?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/__manifest__.py | 2 +- jikimo_purchase_tier_validation/models/models.py | 4 ++++ jikimo_purchase_tier_validation/views/views.xml | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/__manifest__.py b/jikimo_purchase_tier_validation/__manifest__.py index 18a63e80..91dcbb49 100644 --- a/jikimo_purchase_tier_validation/__manifest__.py +++ b/jikimo_purchase_tier_validation/__manifest__.py @@ -20,7 +20,7 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['purchase', 'base_tier_validation', 'documents', 'purchase_request', 'account'], + 'depends': ['purchase', 'base_tier_validation', 'documents', 'purchase_request', 'account', 'purchase_order_approved'], # always loaded 'data': [ diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index e5a80f7b..5a581980 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -23,6 +23,10 @@ class jikimo_purchase_tier_validation(models.Model): for record in self: if record.need_validation and record.validation_status != 'validated': raise ValidationError(_('此操作需要至少对一条记录进行审批。\n请发起审批申请。')) + if record.state in ['to approve']: + raise ValidationError(_('请先完成审批。')) + if record.state == 'approved': + record.state = 'purchase' return super().button_confirm() # def button_confirm(self): diff --git a/jikimo_purchase_tier_validation/views/views.xml b/jikimo_purchase_tier_validation/views/views.xml index ca82e729..b651e914 100644 --- a/jikimo_purchase_tier_validation/views/views.xml +++ b/jikimo_purchase_tier_validation/views/views.xml @@ -1,11 +1,23 @@ + + tier_validation_view_approved_purchase_order_form_inherit + purchase.order + + + + + + + tier_validation_view_purchase_order_form_inherit purchase.order + + From a1bf997d516b88e12e30d350310aca9e4669e932 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:49:05 +0800 Subject: [PATCH 125/147] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=B2=97=E4=B8=8E?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E6=80=BB=E7=9B=91=E5=B2=97=E4=BD=8D=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E5=8D=95=E6=93=8D=E4=BD=9C=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/security/ir.model.access.csv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index f096b449..b8862b8d 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -183,4 +183,7 @@ access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0 access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1 -access_mrp_workorder_batch_replan_wizard_group_plan_dispatch,mrp_workorder_batch_replan_wizard_group_plan_dispatch,model_mrp_workorder_batch_replan_wizard,sf_base.group_plan_dispatch,1,1,1,0 \ No newline at end of file +access_mrp_workorder_batch_replan_wizard_group_plan_dispatch,mrp_workorder_batch_replan_wizard_group_plan_dispatch,model_mrp_workorder_batch_replan_wizard,sf_base.group_plan_dispatch,1,1,1,0 + +access_mrp_workorder_group_purchase_director,mrp_workorder,model_mrp_workorder,sf_base.group_purchase_director,1,1,0,0 +access_mrp_workorder_group_purchase,mrp_workorder,model_mrp_workorder,sf_base.group_purchase,1,1,0,0 \ No newline at end of file From 0ce51a4a66a320191c1ed81e3e7082dc52231d5a Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:49:46 +0800 Subject: [PATCH 126/147] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E7=BA=BF=E4=B8=8B=E5=8A=A0=E5=B7=A5=E5=B7=A5=E5=8D=95=E6=8E=92?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 2 + .../production_technology_re_adjust_wizard.py | 49 ------------------- .../wizard/production_technology_wizard.py | 30 ------------ 3 files changed, 2 insertions(+), 79 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 057530d0..af0f0aa9 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -941,6 +941,8 @@ class MrpProduction(models.Model): and item.process_parameters_id == work.surface_technics_parameters_id) or (item.route_id.name == work.name and item.panel and item.panel == work.processing_panel)) + if work.name == '人工线下加工': + td_ids = technology_design_ids.filtered(lambda item: (item.route_id.name in work.name)) if td_ids: work.sequence = td_ids[0].sequence cancel_work_ids = workorder_ids.filtered(lambda item: item.state in ('已取消', 'cancel')) diff --git a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py index 5bd32b8c..fe90f66a 100644 --- a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py +++ b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py @@ -25,38 +25,6 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): # 该制造订单的其他同一销售订单的制造订单的工艺设计处理 if production_item != self.production_id: self.env['sf.technology.design'].sudo().unified_procedure_multiple_work_orders(technology_designs, production_item) - # for td_other in production_item.technology_design_ids: - # # if td_other.is_auto is False: - # # td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id) - # # if not td_del or td_del.active is False: - # # td_other.write({'active': False}) - # for td_main in technology_designs: - # route_other = production_item.technology_design_ids.filtered( - # lambda td: td.route_id.id == td_main.route_id.id) - # if not route_other and td_main.active is True: - # production_item.write({'technology_design_ids': [(0, 0, { - # 'route_id': td_main.route_id.id, - # 'process_parameters_id': False if td_main.process_parameters_id is False else - # self.env[ - # 'sf.production.process.parameter'].search( - # [('id', '=', td_main.process_parameters_id.id)]).id, - # 'sequence': td_main.sequence, - # 'is_auto': td_main.is_auto})]}) - # else: - # for ro in route_other: - # domain = [('production_id', '=', self.production_id.id), - # ('active', 'in', [True, False]), - # ('route_id', '=', ro.route_id.id)] - # if ro.route_id.routing_type == '表面工艺': - # domain += [('process_parameters_id', '=', ro.process_parameters_id.id)] - # elif ro.route_id.routing_tag == 'special' and ro.is_auto is False: - # # display_name = ro.route_id.display_name - # domain += [('id', '=', ro.id)] - # elif ro.panel is not False: - # domain += [('panel', '=', ro.panel)] - # td_upd = self.env['sf.technology.design'].sudo().search(domain) - # if td_upd: - # ro.write({'sequence': td_upd.sequence, 'active': td_upd.active}) special_design = self.env['sf.technology.design'].sudo().search( [('routing_tag', '=', 'special'), ('production_id', '=', production_item.id), ('is_auto', '=', False), ('active', 'in', [True, False])]) @@ -71,23 +39,6 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): else: domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')] workorder = self.env['mrp.workorder'].search(domain) - # previous_workorder = self.env['mrp.workorder'].search( - # [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), - # ('production_id', '=', workorder.production_id.id)]) - # if previous_workorder: - # if previous_workorder.supplier_id != workorder.supplier_id: - # is_cancel = True - # else: - # is_cancel = True - # if workorder.state != 'cancel' and is_cancel is True: - # workorder.write({'state': 'cancel'}) - # workorder.picking_ids.write({'state': 'cancel'}) - # workorder.picking_ids.move_ids.write({'state': 'cancel'}) - # purchase_order = self.env['purchase.order'].search( - # [('origin', '=', workorder.production_id.name)]) - # for line in purchase_order.order_line: - # if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: - # purchase_order.write({'state': 'cancel'}) else: workorder = self.env['mrp.workorder'].search( [('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) diff --git a/sf_manufacturing/wizard/production_technology_wizard.py b/sf_manufacturing/wizard/production_technology_wizard.py index 1feee749..0415d1fd 100644 --- a/sf_manufacturing/wizard/production_technology_wizard.py +++ b/sf_manufacturing/wizard/production_technology_wizard.py @@ -27,36 +27,6 @@ class ProductionTechnologyWizard(models.TransientModel): if production != self.production_id: self.env['sf.technology.design'].sudo().unified_procedure_multiple_work_orders(technology_designs, production) - # for td_other in production.technology_design_ids: - # if td_other.is_auto is False: - # td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id) - # if not td_del or td_del.active is False: - # td_other.write({'active': False}) - # for td_main in technology_designs: - # route_other = production.technology_design_ids.filtered( - # lambda td: td.route_id.id == td_main.route_id.id) - # if not route_other and td_main.active is True: - # production.write({'technology_design_ids': [(0, 0, { - # 'route_id': td_main.route_id.id, - # 'process_parameters_id': False if td_main.process_parameters_id is False else self.env[ - # 'sf.production.process.parameter'].search( - # [('id', '=', td_main.process_parameters_id.id)]).id, - # 'sequence': td_main.sequence})]}) - # else: - # for ro in route_other: - # domain = [('production_id', '=', self.production_id.id), - # ('active', 'in', [True, False]), - # ('route_id', '=', ro.route_id.id)] - # if ro.route_id.routing_type == '表面工艺': - # domain += [('process_parameters_id', '=', ro.process_parameters_id.id)] - # elif ro.route_id.routing_tag == 'special' and ro.is_auto is False: - # # display_name = ro.route_id.display_name - # domain += [('id', '=', ro.id)] - # elif ro.panel is not False: - # domain += [('panel', '=', ro.panel)] - # td_upd = self.env['sf.technology.design'].sudo().search(domain) - # if td_upd: - # ro.write({'sequence': td_upd.sequence, 'active': td_upd.active}) # 特殊表面工艺 special_design = self.env['sf.technology.design'].sudo().search( [('routing_tag', '=', 'special'), ('production_id', '=', production.id), From 2f3e12e3af4bd9b123bc73b537b65e2e8bec30fb Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:50:39 +0800 Subject: [PATCH 127/147] =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E7=A1=AE=E8=AE=A4=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E9=99=90=E5=88=B6=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=8C=96=E4=BA=A7?= =?UTF-8?q?=E7=BA=BF=E5=8A=A0=E5=B7=A5=E8=B7=AF=E7=BA=BF=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E7=9F=AB=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 95999611..b03d761a 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -401,7 +401,7 @@ class RePurchaseOrder(models.Model): artificial_offline = ( workorder.production_id.production_type == '人工线下加工' and workorder.production_id.schedule_state != '已排') auto_production = ( - workorder.production_id.production_type == '自动化产线加工' and workorder.production_id.schedule_state != '已编程') + workorder.production_id.production_type == '自动化产线加工' and workorder.production_id.programming_state != '已编程') if workorder.sequence == min_sequence_wk.sequence: if artificial_offline or auto_production: raise UserError('等待组件') From f884963abc8c4748c61cd1d29bd98d42bddfa443 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 13:34:09 +0800 Subject: [PATCH 128/147] =?UTF-8?q?=E5=B7=A5=E8=89=BA=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E5=85=B3=E8=81=94=E9=87=87=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E4=B8=BA=E8=8D=89=E7=A8=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index b03d761a..1b282c8e 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -346,6 +346,7 @@ class RePurchaseOrder(models.Model): server_product_process = [] purchase_order = pp._get_surface_technics_purchase_ids() if purchase_order: + purchase_order.write({'state': 'draft'}) pp.purchase_id = [(6, 0, [purchase_order.id])] else: server_template = self.env['product.template'].search( From f92bd8263ca03b1eb1e2bc529c2fd369fae33fa7 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 2 Jan 2025 14:20:31 +0800 Subject: [PATCH 129/147] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quality_control/views/quality_views.xml | 1 + sf_message/__manifest__.py | 2 +- sf_message/data/bussiness_node.xml | 5 +++ sf_message/data/template_data.xml | 12 +++++++ sf_message/models/__init__.py | 1 + sf_message/models/sf_message_product.py | 14 +++++++- sf_message/models/sf_message_quality_check.py | 34 +++++++++++++++++++ 7 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 sf_message/models/sf_message_quality_check.py diff --git a/quality_control/views/quality_views.xml b/quality_control/views/quality_views.xml index 790f8cef..c40d42b2 100644 --- a/quality_control/views/quality_views.xml +++ b/quality_control/views/quality_views.xml @@ -519,6 +519,7 @@ Quality Checks quality.check tree,kanban,form,pivot,graph + {'is_web_request': True}

No quality check found diff --git a/sf_message/__manifest__.py b/sf_message/__manifest__.py index 6796a50b..8c769d60 100644 --- a/sf_message/__manifest__.py +++ b/sf_message/__manifest__.py @@ -12,7 +12,7 @@ 'category': 'sf', 'website': 'https://www.sf.jikimo.com', 'depends': ['sale', 'purchase', 'sf_plan', 'jikimo_message_notify', 'stock', 'sf_quality', 'mrp', - 'sf_manufacturing','product'], + 'sf_manufacturing','product','quality'], 'data': [ 'data/bussiness_node.xml', 'data/cron_data.xml', diff --git a/sf_message/data/bussiness_node.xml b/sf_message/data/bussiness_node.xml index e7c3b0ba..b429d766 100644 --- a/sf_message/data/bussiness_node.xml +++ b/sf_message/data/bussiness_node.xml @@ -150,5 +150,10 @@ 采购单已逾期提醒 purchase.order + + + 待质检提醒 + product.product + \ No newline at end of file diff --git a/sf_message/data/template_data.xml b/sf_message/data/template_data.xml index 52b226e3..11f05a3c 100644 --- a/sf_message/data/template_data.xml +++ b/sf_message/data/template_data.xml @@ -389,5 +389,17 @@ 事项:[共有{{num}}个采购订单已逾期]({{url}}) + + + 待质检提醒 + + product.product + + markdown + normal + ### 待质检提醒: +单号:产品[{{name}}]({{url}}) +事项:有{{num}}个质检单需要处理。 + \ No newline at end of file diff --git a/sf_message/models/__init__.py b/sf_message/models/__init__.py index 8c215042..f8f6fcf1 100644 --- a/sf_message/models/__init__.py +++ b/sf_message/models/__init__.py @@ -13,3 +13,4 @@ from . import sf_message_maintenance_logs from . import sf_message_mrp_production_wizard from . import sf_message_mrp_production_adjust_wizard from . import sf_message_product +from . import sf_message_quality_check \ No newline at end of file diff --git a/sf_message/models/sf_message_product.py b/sf_message/models/sf_message_product.py index 85ac4ce2..0f2cfd7e 100644 --- a/sf_message/models/sf_message_product.py +++ b/sf_message/models/sf_message_product.py @@ -3,7 +3,7 @@ from odoo import models, fields, api, _ from urllib.parse import urlencode -class SFMessagePlan(models.Model): +class SFMessageProduct(models.Model): _name = 'product.product' _inherit = ['product.product', 'jikimo.message.dispatch'] @@ -28,6 +28,18 @@ class SFMessagePlan(models.Model): '{{number}}', str(production_num)).replace( '{{request_url}}', url) contents.append(content) + if message_queue_id.message_template_id.name == '待质检提醒': + content = message_queue_id.message_template_id.content + product_product = self.env['product.product'].sudo().search([('id', '=', int(message_queue_id.res_id))]) + quality_check_num = self.env['quality.check'].sudo().search_count( + [('product_id', '=', product_product.id), ('quality_state', '=', 'none')]) + if quality_check_num >= 1: + url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + action_id = self.env.ref('quality_control.quality_check_action_report').id + url_with_id = f"{url}/web#view_type=list&action={action_id}" + content = content.replace('{{name}}', product_product.name).replace('{{url}}', url_with_id).replace( + '{{num}}', str(quality_check_num)) + contents.append(content) return contents, message_queue_ids def get_request_url(self): diff --git a/sf_message/models/sf_message_quality_check.py b/sf_message/models/sf_message_quality_check.py new file mode 100644 index 00000000..c53adda9 --- /dev/null +++ b/sf_message/models/sf_message_quality_check.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +import logging +from odoo import models, fields, api, _ + + +class SFMessageQualityCheck(models.Model): + _name = 'quality.check' + _inherit = ['quality.check', 'jikimo.message.dispatch'] + + @api.model_create_multi + def create(self, vals_list): + result = super().create(vals_list) + try: + # 判断是否为web页面创建请求 + is_web_request = self.env.context.get('is_web_request', False) + if not is_web_request: + for obj in result: + jikimo_message_queue = self.get_message_queue(obj.product_id.id) + if not jikimo_message_queue: + obj.product_id.add_queue('待质检提醒') + except Exception as e: + logging.info('add_queue待质检提醒 error:%s' % e) + return result + + def get_message_queue(self, res_id): + business_node_id = self.env.ref('sf_message.bussiness_quality_check').id + message_template = self.env["jikimo.message.template"].sudo().search([ + ("model", "=", self._name), + ("bussiness_node_id", "=", business_node_id) + ], limit=1) + jikimo_message_queue = self.env['jikimo.message.queue'].sudo().search( + [('res_id', '=', res_id), ("message_status", "in", ("pending", "sent")), + ('message_template_id', '=', message_template.id)]) + return jikimo_message_queue From eaaa13fb9aa2db1be8ec4fc126815b35d7d5e5a7 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 2 Jan 2025 14:21:18 +0800 Subject: [PATCH 130/147] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_message/models/__init__.py b/sf_message/models/__init__.py index f8f6fcf1..18c6b873 100644 --- a/sf_message/models/__init__.py +++ b/sf_message/models/__init__.py @@ -13,4 +13,4 @@ from . import sf_message_maintenance_logs from . import sf_message_mrp_production_wizard from . import sf_message_mrp_production_adjust_wizard from . import sf_message_product -from . import sf_message_quality_check \ No newline at end of file +from . import sf_message_quality_check From 170309b3c006329e07a5bb1cf070ba05cc909034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Fri, 3 Jan 2025 10:01:52 +0800 Subject: [PATCH 131/147] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/__manifest__.py b/jikimo_purchase_tier_validation/__manifest__.py index 91dcbb49..a7bdbddf 100644 --- a/jikimo_purchase_tier_validation/__manifest__.py +++ b/jikimo_purchase_tier_validation/__manifest__.py @@ -20,7 +20,7 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['purchase', 'base_tier_validation', 'documents', 'purchase_request', 'account', 'purchase_order_approved'], + 'depends': ['purchase', 'purchase_tier_validation', 'documents', 'purchase_request', 'account', 'purchase_order_approved'], # always loaded 'data': [ From c6aeff2006cccfa21c82d53c139fe617ce77d131 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 3 Jan 2025 10:17:33 +0800 Subject: [PATCH 132/147] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/models/sf_message_quality_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_message/models/sf_message_quality_check.py b/sf_message/models/sf_message_quality_check.py index c53adda9..15713791 100644 --- a/sf_message/models/sf_message_quality_check.py +++ b/sf_message/models/sf_message_quality_check.py @@ -25,7 +25,7 @@ class SFMessageQualityCheck(models.Model): def get_message_queue(self, res_id): business_node_id = self.env.ref('sf_message.bussiness_quality_check').id message_template = self.env["jikimo.message.template"].sudo().search([ - ("model", "=", self._name), + ("name", "=", '待质检提醒'), ("bussiness_node_id", "=", business_node_id) ], limit=1) jikimo_message_queue = self.env['jikimo.message.queue'].sudo().search( From 1936b512c237b6a75818573d9e75671397d906e4 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 3 Jan 2025 11:32:24 +0800 Subject: [PATCH 133/147] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=A4=9A=E5=B1=82?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index 5a581980..32eca4f0 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -87,7 +87,17 @@ class jikimo_purchase_tier_validation(models.Model): def _validate_tier(self, tiers=False): res = super(jikimo_purchase_tier_validation, self)._validate_tier(tiers) - self.state = 'approved' + tier_reviews = tiers or self.review_ids + + # 检查是否所有审批都已通过 + all_approved = all( + tier_review.review_status == 'approved' + for tier_review in tier_reviews + ) + + if all_approved and tier_reviews: # 确保有审批记录 + self.state = 'approved' + return res def _rejected_tier(self, tiers=False): From aa4b73e406d3ff29d5a70e8827a85b895932b20d Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 3 Jan 2025 11:43:27 +0800 Subject: [PATCH 134/147] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index 32eca4f0..d90ed257 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -91,7 +91,7 @@ class jikimo_purchase_tier_validation(models.Model): # 检查是否所有审批都已通过 all_approved = all( - tier_review.review_status == 'approved' + tier_review.status == 'approved' for tier_review in tier_reviews ) From d182641d8193c1ce3f231edbf2e71f15e40d895c Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 3 Jan 2025 12:52:24 +0800 Subject: [PATCH 135/147] =?UTF-8?q?=E5=A4=96=E8=B4=AD=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/models/sf_message_sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_message/models/sf_message_sale.py b/sf_message/models/sf_message_sale.py index 4e8679f8..f4712f67 100644 --- a/sf_message/models/sf_message_sale.py +++ b/sf_message/models/sf_message_sale.py @@ -32,7 +32,7 @@ class SFMessageSale(models.Model): for purchase_order_id in purchase_order_ids: if purchase_order_id.purchase_type == 'outsourcing': purchase_order_id.add_queue('委外加工采购单提醒') - if purchase_order_id.purchase_type == 'standard': + if purchase_order_id.purchase_type == 'outside': purchase_order_id.add_queue('外购订单采购单提醒') except Exception as e: logging.info('add_queue error:%s' % e) From 0d28df04151e9cc80d4981b7099461090e18c42e Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 3 Jan 2025 12:52:27 +0800 Subject: [PATCH 136/147] =?UTF-8?q?=E9=80=82=E9=85=8D=E5=A4=9A=E5=B1=82?= =?UTF-8?q?=E5=AE=A1=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_purchase_tier_validation/models/models.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/jikimo_purchase_tier_validation/models/models.py b/jikimo_purchase_tier_validation/models/models.py index 5a581980..d90ed257 100644 --- a/jikimo_purchase_tier_validation/models/models.py +++ b/jikimo_purchase_tier_validation/models/models.py @@ -87,7 +87,17 @@ class jikimo_purchase_tier_validation(models.Model): def _validate_tier(self, tiers=False): res = super(jikimo_purchase_tier_validation, self)._validate_tier(tiers) - self.state = 'approved' + tier_reviews = tiers or self.review_ids + + # 检查是否所有审批都已通过 + all_approved = all( + tier_review.status == 'approved' + for tier_review in tier_reviews + ) + + if all_approved and tier_reviews: # 确保有审批记录 + self.state = 'approved' + return res def _rejected_tier(self, tiers=False): From 6b61df9d507d3c6915ca50d3119ee5286f5a749c Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 3 Jan 2025 15:04:22 +0800 Subject: [PATCH 137/147] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=A4=96=E5=8D=8F?= =?UTF-8?q?=E5=8F=91=E6=96=99=E9=80=9A=E7=9F=A5=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/__manifest__.py | 3 +- .../models/sf_message_mrp_production.py | 5 ++- sf_message/views/stock_picking_view.xml | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 sf_message/views/stock_picking_view.xml diff --git a/sf_message/__manifest__.py b/sf_message/__manifest__.py index 8c769d60..42f1ad13 100644 --- a/sf_message/__manifest__.py +++ b/sf_message/__manifest__.py @@ -12,7 +12,7 @@ 'category': 'sf', 'website': 'https://www.sf.jikimo.com', 'depends': ['sale', 'purchase', 'sf_plan', 'jikimo_message_notify', 'stock', 'sf_quality', 'mrp', - 'sf_manufacturing','product','quality'], + 'sf_manufacturing', 'product', 'quality'], 'data': [ 'data/bussiness_node.xml', 'data/cron_data.xml', @@ -20,6 +20,7 @@ 'security/ir.model.access.csv', 'views/mrp_workorder_views.xml', 'views/purchase_order_view.xml', + 'views/stock_picking_view.xml', ], 'test': [ ], diff --git a/sf_message/models/sf_message_mrp_production.py b/sf_message/models/sf_message_mrp_production.py index b0689b81..9fd21e9e 100644 --- a/sf_message/models/sf_message_mrp_production.py +++ b/sf_message/models/sf_message_mrp_production.py @@ -63,8 +63,9 @@ class SFMessageMrpProduction(models.Model): [('origin', 'in', mrp_production_names), ('state', '=', 'assigned')]) if stock_picking_num >= 1: url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - action_id = self.env.ref('stock.action_picking_tree_ready').id - url_with_id = f"{url}/web#view_type=list&action={action_id}" + action_id = self.env.ref('sf_message.action_picking_outsourced_tree_ready').id + menu_id = self.env.ref('stock.menu_stock_root').id + url_with_id = f"{url}/web#view_type=list&action={action_id}&menu_id={menu_id}" content = content.replace('{{name}}', mrp_production.product_id.name).replace('{{url}}', url_with_id).replace( '{{num}}', str(stock_picking_num)) diff --git a/sf_message/views/stock_picking_view.xml b/sf_message/views/stock_picking_view.xml new file mode 100644 index 00000000..9087aa18 --- /dev/null +++ b/sf_message/views/stock_picking_view.xml @@ -0,0 +1,37 @@ + + + + + stock.picking.search + stock.picking + + + + + + + + + + + + 待办 + stock.picking + ir.actions.act_window + tree,kanban,form,calendar + + {'search_default_outsourced': 1,'contact_display': 'partner_address', + 'search_default_available': 1} + + + +

+ 没有仓库调拨。 让我们创建一个! +

+

+ 移动允许您将产品从一个位置移动到另外一个位置。 +

+
+
+
\ No newline at end of file From b3f56754cdae93627b3c162c53368fe7fbebb9d7 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 3 Jan 2025 15:09:03 +0800 Subject: [PATCH 138/147] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_plan_management/i18n/zh_CN.po | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sf_plan_management/i18n/zh_CN.po b/sf_plan_management/i18n/zh_CN.po index b811963b..dde8ccfd 100644 --- a/sf_plan_management/i18n/zh_CN.po +++ b/sf_plan_management/i18n/zh_CN.po @@ -2023,6 +2023,11 @@ msgstr "损失" msgid "Maintenance" msgstr "" +#. module: sf_manufacturing +#: model:ir.model.fields.selection,name:sf_manufacturing.selection__mrp_production__state__confirmed +msgid "待排程" +msgstr "待排程" + #. module: mrp #: model_terms:ir.ui.view,arch_db:mrp.product_product_form_view_bom_button #: model_terms:ir.ui.view,arch_db:mrp.product_template_form_view_bom_button From 5cff411aafa74adde0b2b4b3d4c7a61721d318a4 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 3 Jan 2025 15:25:47 +0800 Subject: [PATCH 139/147] =?UTF-8?q?r=E7=8E=AF=E5=A2=83=E5=AE=A1=E6=89=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wizards/__init__.py | 3 ++- .../wizards/comment_wizard.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 jikimo_purchase_tier_validation/wizards/comment_wizard.py diff --git a/jikimo_purchase_tier_validation/wizards/__init__.py b/jikimo_purchase_tier_validation/wizards/__init__.py index e134fb87..43edb50d 100644 --- a/jikimo_purchase_tier_validation/wizards/__init__.py +++ b/jikimo_purchase_tier_validation/wizards/__init__.py @@ -1 +1,2 @@ -from . import upload_file_wizard \ No newline at end of file +from . import upload_file_wizard +from . import comment_wizard \ No newline at end of file diff --git a/jikimo_purchase_tier_validation/wizards/comment_wizard.py b/jikimo_purchase_tier_validation/wizards/comment_wizard.py new file mode 100644 index 00000000..f45ecde6 --- /dev/null +++ b/jikimo_purchase_tier_validation/wizards/comment_wizard.py @@ -0,0 +1,15 @@ +from odoo import models, fields + + +class CommentWizard(models.TransientModel): + _inherit = "comment.wizard" + + def add_comment(self): + + rec = self.env[self.res_model].browse(self.res_id) + + self.review_ids = rec.review_ids + + result = super(CommentWizard, self).add_comment() + + return result From aaded331cdd8ca23ec1eb329f55579b9bb7080f9 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Mon, 6 Jan 2025 10:11:44 +0800 Subject: [PATCH 140/147] =?UTF-8?q?=E8=A7=A3=E9=99=A4=E8=A3=85=E5=A4=B9?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A2=9E=E5=8A=A0=E5=89=8D=E7=BD=AE=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/wizard/workpiece_delivery_wizard.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sf_manufacturing/wizard/workpiece_delivery_wizard.py b/sf_manufacturing/wizard/workpiece_delivery_wizard.py index 10171806..6a13fc08 100644 --- a/sf_manufacturing/wizard/workpiece_delivery_wizard.py +++ b/sf_manufacturing/wizard/workpiece_delivery_wizard.py @@ -207,8 +207,9 @@ class WorkpieceDeliveryWizard(models.TransientModel): workorder.production_line_id.id != self.production_ids[0].production_line_id.id): raise UserError(f'该rfid对应的制造订单号为{workorder.production_id.name}的目的生产线不一致') - # 调用打印成品条码方法 - workorder.print_method() + if workorder.routing_type == '解除装夹': + # 调用打印成品条码方法 + workorder.print_method() # 将对象添加到对应的同模型且是多对多类型里 self.production_ids |= workorder.production_id From 403e64a9570ecb4d2b9f73b2e1336ce730e789e0 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Mon, 6 Jan 2025 11:09:22 +0800 Subject: [PATCH 141/147] =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E5=A4=96=E5=8D=8F=E5=85=B3=E8=81=94=E9=87=87=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 31 +++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 8b34feb8..447c6da1 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -330,7 +330,7 @@ class ResMrpWorkOrder(models.Model): return result def _get_surface_technics_purchase_ids(self): - domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')] + domain = [('origin', 'like', '%' + self.production_id.name + '%'), ('purchase_type', '=', 'consignment')] purchase_orders = self.env['purchase.order'].search(domain) purchase_orders_id = self.env['purchase.order'] for po in purchase_orders: @@ -1058,16 +1058,18 @@ class ResMrpWorkOrder(models.Model): and workorder.production_id.schedule_state == '已排' and len(workorder.production_id.picking_ids.filtered( lambda w: w.state not in ['done', 'cancel'])) == 0): + workorder.state = 'ready' if workorder.is_subcontract is True: purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id.state == 'purchase': - workorder.state = 'ready' + move_out = workorder.move_subcontract_workorder_ids[1] + for mo in move_out: + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) continue - else: - workorder.state = 'waiting' - continue - else: - workorder.state = 'ready' + continue + else: + workorder.state = 'waiting' continue # ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]========================== if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework' @@ -1076,7 +1078,7 @@ class ResMrpWorkOrder(models.Model): if workorder.state != 'waiting': workorder.state = 'waiting' continue - if workorder.production_id.programming_state == '已编程' and workorder.technology_design_id.routing_tag != 'special': + if workorder.production_id.programming_state == '已编程': workorder.state = 'ready' elif workorder.state != 'waiting': workorder.state = 'waiting' @@ -1091,12 +1093,17 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: + if len(workorder.production_id.picking_ids.filtered( + lambda w: w.state not in ['done', + 'cancel'])) == 0 and workorder.production_id.programming_state == '已编程': + workorder.state = 'ready' purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id: - workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' - else: - workorder.state = 'waiting' - + if purchase_orders_id.state == 'purchase': + move_out = workorder.move_subcontract_workorder_ids[1] + for mo in move_out: + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) # 重写工单开始按钮方法 def button_start(self): From 9f1514bd1475a938af8979d240ccaa323c1fef19 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 6 Jan 2025 11:44:33 +0800 Subject: [PATCH 142/147] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=80=E5=94=AE?= =?UTF-8?q?=E5=8D=95=E5=8F=B7=E5=92=8C=E8=BF=BD=E6=BA=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index fa723283..72581d8c 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -605,10 +605,10 @@ class StockPicking(models.Model): sale_info = self.env['sale.order'].sudo().search( [('name', '=', sale_name)]) else: - production_list = self.env['mrp.production'].sudo().search( + sale_order_line = self.env['sale.order.line'].sudo().search( [('product_id', '=', product_id.id)]) - if production_list: - sale_info = production_list[0].sale_order_id + if sale_order_line: + sale_info = sale_order_line[0].order_id if sale_info: item.sale_order_id = sale_info.id item.retrospect_ref = sale_info.order_code From 0bd65b5da8fd3a860fad21f76bfe7c71a49baf05 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Mon, 6 Jan 2025 13:03:15 +0800 Subject: [PATCH 143/147] =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 26 ++++++++---------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 447c6da1..6cb177dc 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1058,18 +1058,16 @@ class ResMrpWorkOrder(models.Model): and workorder.production_id.schedule_state == '已排' and len(workorder.production_id.picking_ids.filtered( lambda w: w.state not in ['done', 'cancel'])) == 0): - workorder.state = 'ready' if workorder.is_subcontract is True: purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id.state == 'purchase': - move_out = workorder.move_subcontract_workorder_ids[1] - for mo in move_out: - if mo.state != 'done': - mo.write({'state': 'assigned', 'production_id': False}) + workorder.state = 'ready' continue - continue - else: - workorder.state = 'waiting' + else: + workorder.state = 'waiting' + continue + else: + workorder.state = 'ready' continue # ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]========================== if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework' @@ -1093,17 +1091,11 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: - if len(workorder.production_id.picking_ids.filtered( - lambda w: w.state not in ['done', - 'cancel'])) == 0 and workorder.production_id.programming_state == '已编程': - workorder.state = 'ready' purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id: - if purchase_orders_id.state == 'purchase': - move_out = workorder.move_subcontract_workorder_ids[1] - for mo in move_out: - if mo.state != 'done': - mo.write({'state': 'assigned', 'production_id': False}) + workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' + else: + workorder.state = 'waiting' # 重写工单开始按钮方法 def button_start(self): From bc475441a2e572cef85b4e1103dd33b696a8729c Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 6 Jan 2025 13:11:22 +0800 Subject: [PATCH 144/147] =?UTF-8?q?1=E3=80=81=E5=8E=BB=E9=99=A4=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E5=BC=80=E5=A7=8B=E6=8C=89=E9=92=AE=E7=9A=84=E4=BA=8C?= =?UTF-8?q?=E6=AC=A1=E7=A1=AE=E8=AE=A4=EF=BC=9B2=E3=80=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=89=98=E7=9B=98=E5=85=A5=E5=BA=93=E5=90=8E=E5=A4=B9?= =?UTF-8?q?=E5=85=B7=E7=89=A9=E6=96=99=E6=9F=A5=E8=AF=A2=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=BF=98=E6=98=AF=E6=9C=AA=E5=85=A5=E5=BA=93?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 26 ++++++++++++------- sf_manufacturing/views/mrp_workorder_view.xml | 2 +- .../models/maintenance_equipment.py | 4 +++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 6cb177dc..447c6da1 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1058,16 +1058,18 @@ class ResMrpWorkOrder(models.Model): and workorder.production_id.schedule_state == '已排' and len(workorder.production_id.picking_ids.filtered( lambda w: w.state not in ['done', 'cancel'])) == 0): + workorder.state = 'ready' if workorder.is_subcontract is True: purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id.state == 'purchase': - workorder.state = 'ready' + move_out = workorder.move_subcontract_workorder_ids[1] + for mo in move_out: + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) continue - else: - workorder.state = 'waiting' - continue - else: - workorder.state = 'ready' + continue + else: + workorder.state = 'waiting' continue # ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]========================== if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework' @@ -1091,11 +1093,17 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: + if len(workorder.production_id.picking_ids.filtered( + lambda w: w.state not in ['done', + 'cancel'])) == 0 and workorder.production_id.programming_state == '已编程': + workorder.state = 'ready' purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id: - workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' - else: - workorder.state = 'waiting' + if purchase_orders_id.state == 'purchase': + move_out = workorder.move_subcontract_workorder_ids[1] + for mo in move_out: + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) # 重写工单开始按钮方法 def button_start(self): diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 1e47b873..d5cba300 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -172,7 +172,7 @@ -