From 9660392495aaa4209fd57ced968cfa406ef521fb Mon Sep 17 00:00:00 2001 From: guanhuan Date: Mon, 6 Jan 2025 14:52:24 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=BA=9F?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E7=94=9F=E6=88=90=E8=B0=83=E6=8B=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index af0f0aa9..f065f562 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1378,9 +1378,9 @@ class MrpProduction(models.Model): move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc') for mo in move: domain = [] - if mo.location_id.barcode == 'WH-POSTPRODUCTION' and mo.rule_id.picking_type_id.barcode == 'PC': + if mo.location_id.barcode == 'PL' and mo.rule_id.picking_type_id.sequence_code == 'PC': domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')] - elif mo.location_id.barcode == 'PL' and mo.rule_id.picking_type_id.barcode == 'INT': + elif mo.location_id.barcode == 'WH-INPUT' and mo.rule_id.picking_type_id.sequence_code == 'INT': domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')] if domain: picking_type = self.env['stock.picking.type'].search(domain) @@ -1540,7 +1540,7 @@ class MrpProduction(models.Model): @api.depends('procurement_group_id', 'procurement_group_id.stock_move_ids.group_id') def _compute_picking_ids(self): for order in self: - if order.product_id.product_tmpl_id.single_manufacturing == True: + if order.product_id.product_tmpl_id.single_manufacturing == True and not order.is_remanufacture: first_order = self.env['mrp.production'].search( [('origin', '=', order.origin), ('product_id', '=', order.product_id.id)], limit=1, order='id asc') order.picking_ids = self.env['stock.picking'].search([ From 4fc0eab5130a975356a01b74f42c49f587310e3a Mon Sep 17 00:00:00 2001 From: guanhuan Date: Wed, 8 Jan 2025 10:58:56 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=BA=9F?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E7=94=9F=E6=88=90=E8=B0=83=E6=8B=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 40 +++++-------------- sf_manufacturing/models/mrp_workorder.py | 2 +- sf_manufacturing/models/stock.py | 7 +--- sf_manufacturing/wizard/production_wizard.py | 24 +++++------ .../wizard/production_wizard_views.xml | 2 +- sf_quality/models/quality_cnc_test.py | 2 +- 6 files changed, 26 insertions(+), 51 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index f065f562..d865e208 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1189,7 +1189,8 @@ class MrpProduction(models.Model): 'res_model': 'sf.production.wizard', 'target': 'new', 'context': { - 'default_production_id': self.id, + 'default_mrp_production_id': self.id, + 'is_remanufacture_flag': True, 'default_reprogramming_num': cloud_programming['reprogramming_num'], 'default_programming_states': cloud_programming['programming_state'], 'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False @@ -1348,10 +1349,6 @@ class MrpProduction(models.Model): if self.is_scrap is True: procurement_requests = [] sale_order = self.env['sale.order'].sudo().search([('name', '=', self.origin)]) - values = self.env['mrp.production'].create_production1_values(self) - # productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( - # self.company_id).create( - # values) # 查询出库移动记录 out_picking = self.env['stock.picking'].search( [('origin', '=', sale_order.name), ('name', 'ilike', 'WH/OUT/')]) @@ -1375,31 +1372,14 @@ class MrpProduction(models.Model): productions = self.env['mrp.production'].sudo().search( [('origin', '=', self.origin)], order='id desc', limit=1) productions.write({'programming_no': self.programming_no, 'is_remanufacture': True}) - move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc') - for mo in move: - domain = [] - if mo.location_id.barcode == 'PL' and mo.rule_id.picking_type_id.sequence_code == 'PC': - domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')] - elif mo.location_id.barcode == 'WH-INPUT' and mo.rule_id.picking_type_id.sequence_code == 'INT': - domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')] - if domain: - picking_type = self.env['stock.picking.type'].search(domain) - mo.write({'picking_type_id': picking_type.id}) - mo._assign_picking() - else: - if mo.reference != productions.name: - mo.reference = productions.name - if mo.production_id: - if mo.production_id != productions: - mo.production_id = False - mo_move = self.env['stock.move'].search( - [('origin', '=', sale_order.name), ('reference', 'ilike', 'WH/MO/')]) - if mo_move: - sfp_move = self.env['stock.move'].search( - [('origin', '=', sale_order.name), ('reference', 'ilike', 'WH/SFP/')], limit=1) - mo_move.write({'reference': sfp_move.reference, 'partner_id': sfp_move.partner_id.id, - 'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id, - 'production_id': False}) + # mo_move = self.env['stock.move'].search( + # [('origin', '=', sale_order.name), ('reference', 'ilike', 'WH/MO/')]) + # if mo_move: + # sfp_move = self.env['stock.move'].search( + # [('origin', '=', sale_order.name), ('reference', 'ilike', 'WH/SFP/')], limit=1) + # mo_move.write({'reference': sfp_move.reference, 'partner_id': sfp_move.partner_id.id, + # 'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id, + # 'production_id': False}) # productions.procurement_group_id.mrp_production_ids.move_dest_ids.write( # {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])}) stock_picking_remanufacture = self.env['stock.picking'].search([('origin', '=', productions.name)]) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 8b34feb8..d6de3408 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/models/stock.py b/sf_manufacturing/models/stock.py index a9b08513..d9b5ac2e 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -1031,12 +1031,7 @@ class ReStockMove(models.Model): """ res = super(ReStockMove, self)._get_new_picking_values() ## 制造订单报废生成的新制造订单不走合并 - production_remanufacture = None - if 'origin' in res: - if self.picking_type_id.name in ['生产发料', '内部调拨']: - production_remanufacture = self.env['mrp.production'].search( - [('name', '=', res['origin']), ('is_remanufacture', '=', True)]) - if not production_remanufacture: + if not self.env.context.get('is_remanufacture_flag'): if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨']: production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc') productions = self.env['mrp.production'].search( diff --git a/sf_manufacturing/wizard/production_wizard.py b/sf_manufacturing/wizard/production_wizard.py index 9b7a0e58..238b47ff 100644 --- a/sf_manufacturing/wizard/production_wizard.py +++ b/sf_manufacturing/wizard/production_wizard.py @@ -12,7 +12,7 @@ class ProductionWizard(models.TransientModel): _name = 'sf.production.wizard' _description = '制造订单向导' - production_id = fields.Many2one('mrp.production', string='制造订单号') + mrp_production_id = fields.Many2one('mrp.production', string='制造订单号') reprogramming_num = fields.Integer('重新编程次数', default=0) is_reprogramming = fields.Boolean(string='申请重新编程', default=False) is_remanufacture = fields.Boolean(string='重新生成制造订单', default=True) @@ -27,24 +27,24 @@ class ProductionWizard(models.TransientModel): self.is_reprogramming = False def confirm(self): - self.production_id.detection_result_ids.write({'handle_result': '已处理'}) - self.production_id.write({'state': 'cancel', 'scrap_ids': [(0, 0, { + self.mrp_production_id.detection_result_ids.write({'handle_result': '已处理'}) + self.mrp_production_id.write({'state': 'cancel', 'scrap_ids': [(0, 0, { 'name': self.env['ir.sequence'].next_by_code('stock.scrap') or _('New'), - 'product_id': self.production_id.product_id.id, + 'product_id': self.mrp_production_id.product_id.id, 'scrap_qty': 1, - 'origin': self.production_id.origin, + 'origin': self.mrp_production_id.origin, 'date_done': fields.datetime.now(), 'lot_id': self.env['stock.move.line'].search( - [('move_id', '=', self.production_id.move_raw_ids[0].id)]).lot_id.id, - 'location_id': self.production_id.move_raw_ids.filtered(lambda x: x.state not in ( + [('move_id', '=', self.mrp_production_id.move_raw_ids[0].id)]).lot_id.id, + 'location_id': self.mrp_production_id.move_raw_ids.filtered(lambda x: x.state not in ( 'done', - 'cancel')) and self.production_id.location_src_id.id or self.production_id.location_dest_id.id, + 'cancel')) and self.mrp_production_id.location_src_id.id or self.mrp_production_id.location_dest_id.id, 'scrap_location_id': self.env['stock.scrap']._get_default_scrap_location_id(), 'state': 'done'})]}) - self.production_id.action_cancel() + self.mrp_production_id.action_cancel() if self.is_remanufacture is True: ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming} if self.is_reprogramming is True: - self.production_id.update_programming_state() - new_production = self.production_id.recreateManufacturing(ret) - self.production_id.write({'remanufacture_production_id': new_production.id}) + self.mrp_production_id.update_programming_state() + new_production = self.mrp_production_id.recreateManufacturing(ret) + self.mrp_production_id.write({'remanufacture_production_id': new_production.id}) diff --git a/sf_manufacturing/wizard/production_wizard_views.xml b/sf_manufacturing/wizard/production_wizard_views.xml index a81036f5..609f0254 100644 --- a/sf_manufacturing/wizard/production_wizard_views.xml +++ b/sf_manufacturing/wizard/production_wizard_views.xml @@ -6,7 +6,7 @@
- +
重新生成制造订单 diff --git a/sf_quality/models/quality_cnc_test.py b/sf_quality/models/quality_cnc_test.py index 9810b0e0..9c73715d 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 3ba79d88b5a1ef8c02aca6cbe08d154fed7f9d1c Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Wed, 8 Jan 2025 11:36:28 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= 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 af0f0aa9..59c2ca67 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -459,7 +459,7 @@ class MrpProduction(models.Model): process_parameters.append(special.process_parameters_id.display_name) if account_moves: - raise UserError(_("请联系工厂生产经理对采购订单为%s生成的账单进行取消", ", ".join(account_moves))) + raise UserError(_("请联系工厂生产经理对会计凭证为%s生成的账单进行取消", ", ".join([move.name for move in account_moves]))) if parameters_not: raise UserError(_("【工艺设计】-【工序】为%s未选择参数,请选择", ", ".join(parameters_not))) if process_parameters: From d582604f132dc3015fca8acdef9ecbe95b8c3c5c Mon Sep 17 00:00:00 2001 From: guanhuan Date: Wed, 8 Jan 2025 13:06:01 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=8A=A5=E5=BA=9F=E8=A7=A3=E7=BB=91rfid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/wizard/production_wizard.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sf_manufacturing/wizard/production_wizard.py b/sf_manufacturing/wizard/production_wizard.py index 238b47ff..e3e07f80 100644 --- a/sf_manufacturing/wizard/production_wizard.py +++ b/sf_manufacturing/wizard/production_wizard.py @@ -42,6 +42,12 @@ class ProductionWizard(models.TransientModel): 'scrap_location_id': self.env['stock.scrap']._get_default_scrap_location_id(), 'state': 'done'})]}) self.mrp_production_id.action_cancel() + # 解绑rfid_code + mrp_workorder_list = self.mrp_production_id.workorder_ids.filtered(lambda kw: kw.rfid_code) + for workorder in mrp_workorder_list: + rfid_code = workorder.rfid_code + workorder.write({'rfid_code_old': rfid_code, + 'rfid_code': False}) if self.is_remanufacture is True: ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming} if self.is_reprogramming is True: From 284234adf274c51a384bd7d6eec1472bf39b8c04 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Wed, 8 Jan 2025 13:37:48 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=83=A8=E5=88=86=E8=BF=98=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 35 ++++++++---------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index d26e6c33..114fd2f0 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -275,31 +275,18 @@ class ResMrpWorkOrder(models.Model): def _compute_surface_technics_purchase_ids(self): for order in self: if order.routing_type == '表面工艺' and order.state not in ['cancel']: - # if order.production_id.production_type == '自动化产线加工': - # domain = [('programming_no', '=', order.production_id.programming_no)] - # else:buzhdiao - # domain = [('origin', '=', order.production_id.origin)] - # production_programming = self.env['mrp.production'].search(domain, order='name asc') - # production_list = [production.name for production in production_programming] - # production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False) - # technology_design = self.env['sf.technology.design'].search( - # [('process_parameters_id', '=', order.surface_technics_parameters_id.id), - # ('production_id', '=', order.production_id.id)]) - # if technology_design.is_auto is False: - # domain = [('origin', '=', order.production_id.name)] - # else: - domain = [('purchase_type', '=', 'consignment'), ('origin', '=', order.production_id.name), + domain = [('purchase_type', '=', 'consignment'), + ('origin', 'like', '%' + self.production_id.name + '%'), ('state', '!=', 'cancel')] purchase = self.env['purchase.order'].search(domain) - purchase_num = 0 + order.surface_technics_purchase_count = 0 if not purchase: order.surface_technics_purchase_count = 0 for po in purchase: - for line in po.order_line: - if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id: - if line.product_qty == 1: - purchase_num += 1 - order.surface_technics_purchase_count = purchase_num + if any( + line.product_id and line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id + for line in po.order_line): + order.surface_technics_purchase_count = 1 else: order.surface_technics_purchase_count = 0 @@ -1297,7 +1284,7 @@ class ResMrpWorkOrder(models.Model): raise UserError('请先完成该工单的工艺外协再进行操作') # 表面工艺外协,最后一张工单 workorders = self.production_id.workorder_ids - subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') + subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True and wo.state != 'cancel').sorted('sequence') if self == subcontract_workorders[-1]: # 给下一个库存移动就绪 self.move_subcontract_workorder_ids[0].move_dest_ids._action_done() @@ -1321,8 +1308,10 @@ class ResMrpWorkOrder(models.Model): is_production_id = False rework_workorder = record.production_id.workorder_ids.filtered(lambda p: p.state == 'rework') done_workorder = record.production_id.workorder_ids.filtered(lambda p1: p1.state in ['done']) - if (len(rework_workorder) + len(done_workorder) == len(record.production_id.workorder_ids)) or ( - len(done_workorder) == len(record.production_id.workorder_ids)): + if (len(rework_workorder) + len(done_workorder) == len( + record.production_id.workorder_ids.filtered(lambda wo: wo.state != 'cancel'))) or ( + len(done_workorder) == len( + record.production_id.workorder_ids.filtered(lambda wo: wo.state != 'cancel'))): is_production_id = True if record.routing_type in ['解除装夹'] or ( record.is_rework is True and record.routing_type in ['装夹预调']): From 1a384b990207e724fdadf7e15320c3d4abc38513 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 8 Jan 2025 17:24:58 +0800 Subject: [PATCH 6/7] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=88=B6?= =?UTF-8?q?=E9=80=A0-=E5=B7=A5=E5=BA=8F=E6=A8=A1=E5=9D=97=EF=BC=9B2?= =?UTF-8?q?=E3=80=81=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=BA=8F=E4=B8=AA=E6=80=A7?= =?UTF-8?q?=E5=8C=96=E8=AE=B0=E5=BD=95=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=9F=E6=88=90=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E5=80=BC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/__manifest__.py | 1 + sf_manufacturing/data/sf_work_individuation_page.xml | 8 ++++++++ sf_manufacturing/models/mrp_routing_workcenter.py | 9 +++++++++ sf_manufacturing/security/ir.model.access.csv | 5 ++++- sf_manufacturing/views/mrp_routing_workcenter_view.xml | 2 ++ 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 sf_manufacturing/data/sf_work_individuation_page.xml diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 936afaaf..cffc789a 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -16,6 +16,7 @@ 'data/stock_data.xml', 'data/empty_racks_data.xml', 'data/panel_data.xml', + 'data/sf_work_individuation_page.xml', 'data/agv_scheduling_data.xml', 'security/group_security.xml', 'security/ir.model.access.csv', diff --git a/sf_manufacturing/data/sf_work_individuation_page.xml b/sf_manufacturing/data/sf_work_individuation_page.xml new file mode 100644 index 00000000..89bf333b --- /dev/null +++ b/sf_manufacturing/data/sf_work_individuation_page.xml @@ -0,0 +1,8 @@ + + + + PTD + 后置三元检测 + + + \ No newline at end of file diff --git a/sf_manufacturing/models/mrp_routing_workcenter.py b/sf_manufacturing/models/mrp_routing_workcenter.py index 27c8e9d2..a2a884c9 100644 --- a/sf_manufacturing/models/mrp_routing_workcenter.py +++ b/sf_manufacturing/models/mrp_routing_workcenter.py @@ -25,6 +25,8 @@ class ResMrpRoutingWorkcenter(models.Model): bom_id = fields.Many2one('mrp.bom', required=False) surface_technics_id = fields.Many2one('sf.production.process', string="表面工艺") reserved_duration = fields.Float('预留时长', default=30, tracking=True) + is_outsource = fields.Boolean('外协', default=False) + individuation_page = fields.Many2many('sf.work.individuation.page', string='个性化记录') def get_no(self): international_standards = self.search( @@ -101,3 +103,10 @@ class ResMrpRoutingWorkcenter(models.Model): domain = args + [('id', 'not in', route_workcenter_ids)] return self._search(domain, limit=limit, access_rights_uid=name_get_uid) return super()._name_search(name, args, operator, limit, name_get_uid) + + +class WorkIndividuationPage(models.Model): + _name = 'sf.work.individuation.page' + + code = fields.Char('编号') + name = fields.Char('名称') diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index b8862b8d..4626e3ca 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -186,4 +186,7 @@ access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detectio 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 +access_mrp_workorder_group_purchase,mrp_workorder,model_mrp_workorder,sf_base.group_purchase,1,1,0,0 + +access_sf_work_individuation_page,sf_work_individuation_page,model_sf_work_individuation_page,sf_base.group_sf_mrp_user,1,1,1,0 +access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page_group_plan_dispatch,model_sf_work_individuation_page,sf_base.group_plan_dispatch,1,1,0,0 \ No newline at end of file diff --git a/sf_manufacturing/views/mrp_routing_workcenter_view.xml b/sf_manufacturing/views/mrp_routing_workcenter_view.xml index ddb9558c..b6646dfa 100644 --- a/sf_manufacturing/views/mrp_routing_workcenter_view.xml +++ b/sf_manufacturing/views/mrp_routing_workcenter_view.xml @@ -17,6 +17,8 @@ + + From ebf290fbb38717bade64947b91ed4454daf96258 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 9 Jan 2025 14:32:17 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E5=AE=A2=E4=BE=9B=E6=96=99=E8=B0=83?= =?UTF-8?q?=E6=8B=A8=E5=8D=95=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 12 +---- sf_manufacturing/models/stock.py | 56 ++++++++--------------- 2 files changed, 20 insertions(+), 48 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index fd136048..8a1c9072 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1480,7 +1480,7 @@ class MrpProduction(models.Model): """ 重载创建制造订单的方法,单个制造订单,同一成品只创建一个采购组,用于后续单据的创建 """ - product_group_id = {} + group_id = self.env["procurement.group"].create({'name':vals_list[0].get('origin')}).id for vals in vals_list: if not vals.get('name', False) or vals['name'] == _('New'): picking_type_id = vals.get('picking_type_id') @@ -1489,15 +1489,7 @@ class MrpProduction(models.Model): vals['picking_type_id'] = picking_type_id vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id() if not vals.get('procurement_group_id'): - product_id = self.env['product.product'].browse(vals['product_id']) - if product_id.product_tmpl_id.single_manufacturing: - if product_id.id not in product_group_id.keys(): - procurement_group_vals = self._prepare_procurement_group_vals(vals) - group_id = self.env["procurement.group"].create(procurement_group_vals).id - vals['procurement_group_id'] = group_id - product_group_id[product_id.id] = group_id - else: - vals['procurement_group_id'] = product_group_id[product_id.id] + vals['procurement_group_id'] = group_id return super(MrpProduction, self).create(vals_list) @api.depends('procurement_group_id.stock_move_ids.created_purchase_line_id.order_id', diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index d237a566..d19d7f92 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -72,35 +72,6 @@ class StockRule(models.Model): moves_values_by_company = defaultdict(list) mtso_products_by_locations = defaultdict(list) - # To handle the `mts_else_mto` procure method, we do a preliminary loop to - # isolate the products we would need to read the forecasted quantity, - # in order to to batch the read. We also make a sanitary check on the - # `location_src_id` field. - - # list1 = [] - # for item in procurements: - # num = int(item[0].product_qty) - # if num > 1: - # for no in range(1, num+1): - # - # Procurement = namedtuple('Procurement', ['product_id', 'product_qty', - # 'product_uom', 'location_id', 'name', 'origin', - # 'company_id', - # 'values']) - # s = Procurement(product_id=item[0].product_id,product_qty=1.0,product_uom=item[0].product_uom, - # location_id=item[0].location_id, - # name=item[0].name, - # origin=item[0].origin, - # company_id=item[0].company_id, - # values=item[0].values, - # ) - # item1 = list(item) - # item1[0]=s - # - # list1.append(tuple(item1)) - # else: - # list1.append(item) - for procurement, rule in procurements: if not rule.location_src_id: msg = _('No source location defined on stock rule: %s!') % (rule.name,) @@ -618,15 +589,21 @@ class StockPicking(models.Model): item.address_of_delivery = sale_info.address_of_delivery # 设置外协出入单的名称 - def _get_name_Res(self, rescode): - last_picking = self.sudo().search([('name', 'ilike', rescode)], order='create_date desc,id desc', limit=1) - if not last_picking: - num = "%04d" % 1 + def _get_name_Res(self, rescode,sequence): + last_picking = self.sudo().search([('name', 'ilike', rescode)], order='name desc', limit=1) + sequence_id = sequence.next_by_id() + name_without_prefix = last_picking.name.removeprefix(rescode) + try: + name_value = int(name_without_prefix) # 假设 name 是一个数字字符串 + except ValueError: + name_value = 0 + if name_value >= int(sequence_id.removeprefix(rescode)): + sequence.write({ + 'number_next': name_value + 1, + }) + return sequence.next_by_id() else: - logging.info('编号:' + last_picking.name) - m = int(last_picking.name[-3:]) + 1 - num = "%04d" % m - return '%s%s' % (rescode, num) + return sequence_id def button_validate(self): res = super().button_validate() @@ -787,12 +764,15 @@ class ReStockMove(models.Model): def _get_new_picking_values_Res(self, item, sorted_workorders, rescode): picking_type_id = self.mapped('picking_type_id').id + sequence = False if rescode == 'WH/OCOUT/': picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id + sequence = self.env.ref('sf_manufacturing.sequence_stock_picking_out') elif rescode == 'WH/OCIN/': picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_in').id + sequence = self.env.ref('sf_manufacturing.sequence_stock_picking_in') return { - 'name': self.env['stock.picking']._get_name_Res(rescode), + 'name': self.env['stock.picking']._get_name_Res(rescode,sequence), 'origin': item.name, 'surface_technics_parameters_id': sorted_workorders.surface_technics_parameters_id.id, 'company_id': self.mapped('company_id').id,