From dfba055019c7b91725dc8f88f8da9b9bf6b8064b Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 19 Jul 2024 16:45:46 +0800 Subject: [PATCH 01/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0bfm=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=97=B6=E4=BA=A7=E5=93=81=E5=88=9B=E5=BB=BA=E5=A1=AB=E5=85=85?= =?UTF-8?q?=E7=A8=8E=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 70 ++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index f47f8c8d..f2d4073e 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -56,7 +56,7 @@ class ReSaleOrder(models.Model): deadline_of_delivery, payments_way, pay_way): now_time = datetime.datetime.now() partner = self.get_customer() - order_id = self.env['sale.order'].sudo().create({ + data ={ 'company_id': company_id.id, 'date_order': now_time, 'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time), @@ -67,10 +67,18 @@ class ReSaleOrder(models.Model): 'person_of_delivery': delivery_name, 'telephone_of_delivery': delivery_telephone, 'address_of_delivery': delivery_address, - 'deadline_of_delivery': deadline_of_delivery, 'payments_way': payments_way, 'pay_way': pay_way, - }) + } + if deadline_of_delivery: + # deadline_of_delivery字段存在为false字符串情况 + if not isinstance(deadline_of_delivery, str): + data.update({'deadline_of_delivery': deadline_of_delivery}) + else: + if deadline_of_delivery!="False": + data.update({'deadline_of_delivery': deadline_of_delivery}) + + order_id = self.env['sale.order'].sudo().create(data) return order_id def write(self, vals): @@ -113,6 +121,7 @@ class ReSaleOrder(models.Model): 'price_unit': product.list_price, 'product_uom_qty': item['number'], 'model_glb_file': base64.b64decode(item['model_file']), + 'remark': item.get('remark') } return self.env['sale.order.line'].with_context(skip_procurement=True).create(vals) @@ -151,6 +160,7 @@ class ResaleOrderLine(models.Model): # # without modifying the related product_id when updated. # domain=[('sale_ok', '=', True), ('categ_type', '=', '成品')]) check_status = fields.Selection(related='order_id.check_status') + remark = fields.Char('备注') @api.depends('product_template_id') def _compute_model_glb_file(self): @@ -256,33 +266,33 @@ class ResPartnerToSale(models.Model): # if obj: # raise UserError('该邮箱已存在,请重新输入') - @api.model - def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): - if self._context.get('is_customer'): - if self.env.user.has_group('sf_base.group_sale_director'): - domain = [('customer_rank', '>', 0)] - elif self.env.user.has_group('sf_base.group_sale_salemanager'): - customer = self.env['res.partner'].search( - [('customer_rank', '>', 0), ('user_id', '=', self.env.user.id)]) - if customer: - ids = [t.id for t in customer] - domain = [('id', 'in', ids)] - else: - domain = [('id', '=', False)] - return self._search(domain, limit=limit, access_rights_uid=name_get_uid) - elif self._context.get('is_supplier') or self.env.user.has_group('sf_base.group_purchase_director'): - if self.env.user.has_group('sf_base.group_purchase_director'): - domain = [('supplier_rank', '>', 0)] - elif self.env.user.has_group('sf_base.group_purchase'): - supplier = self.env['res.partner'].search( - [('supplier_rank', '>', 0), ('purchase_user_id', '=', self.env.user.id)]) - if supplier: - ids = [t.id for t in supplier] - domain = [('id', 'in', ids)] - else: - domain = [('id', '=', False)] - return self._search(domain, limit=limit, access_rights_uid=name_get_uid) - return super()._name_search(name, args, operator, limit, name_get_uid) + # @api.model + # def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): + # if self._context.get('is_customer'): + # if self.env.user.has_group('sf_base.group_sale_director'): + # domain = [('customer_rank', '>', 0)] + # elif self.env.user.has_group('sf_base.group_sale_salemanager'): + # customer = self.env['res.partner'].search( + # [('customer_rank', '>', 0), ('user_id', '=', self.env.user.id)]) + # if customer: + # ids = [t.id for t in customer] + # domain = [('id', 'in', ids)] + # else: + # domain = [('id', '=', False)] + # return self._search(domain, limit=limit, access_rights_uid=name_get_uid) + # elif self._context.get('is_supplier') or self.env.user.has_group('sf_base.group_purchase_director'): + # if self.env.user.has_group('sf_base.group_purchase_director'): + # domain = [('supplier_rank', '>', 0)] + # elif self.env.user.has_group('sf_base.group_purchase'): + # supplier = self.env['res.partner'].search( + # [('supplier_rank', '>', 0), ('purchase_user_id', '=', self.env.user.id)]) + # if supplier: + # ids = [t.id for t in supplier] + # domain = [('id', 'in', ids)] + # else: + # domain = [('id', '=', False)] + # return self._search(domain, limit=limit, access_rights_uid=name_get_uid) + # return super()._name_search(name, args, operator, limit, name_get_uid) @api.onchange('user_id') def _get_salesman(self): From a0d3b40548b1f2bce5054290e73dffe556335e54 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 19 Jul 2024 16:46:31 +0800 Subject: [PATCH 02/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=92=8C=E4=BA=A7=E5=93=81=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=94=99=E8=AF=AF=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/quick_easy_order.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index e3bf3002..5272d7a5 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -371,6 +371,7 @@ class QuickEasyOrder(models.Model): product_bom_purchase.bom_create_line_has(purchase_embryo) order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item) except Exception as e: + logging.error('工厂创建销售订单和产品失败,请联系管理员'.format(e)) # self.cr.rollback() return UserError('工厂创建销售订单和产品失败,请联系管理员') From 03fe730c50fb1552a86ff00463bb833c400392be Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 19 Jul 2024 16:46:53 +0800 Subject: [PATCH 03/24] =?UTF-8?q?=E4=BA=A7=E5=93=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=A8=8E=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d05de81..400cf0d6 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -640,6 +640,10 @@ class ResProductMo(models.Model): 'part_number': item.get('part_number') or '', 'active': True, } + tax_id = self.env['account.tax'].sudo().search( + [('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')]) + if tax_id: + vals.update({'taxes_id':[(6,0,[int(tax_id)])]}) copy_product_id.sudo().write(vals) product_id.product_tmpl_id.active = False return copy_product_id @@ -947,6 +951,7 @@ class SfMaintenanceEquipmentAndProductTemplate(models.Model): raise ValidationError("机床基坐标获取失败") +sf_man class SfMaintenanceEquipmentTool(models.Model): _name = 'maintenance.equipment.tool' _description = '机床刀位' From ef1c7b6b25105717bf5a68b649e70cee39b082cc Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Fri, 19 Jul 2024 17:23:01 +0800 Subject: [PATCH 04/24] =?UTF-8?q?=E5=A4=9A=E4=BD=99=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 400cf0d6..7f67adc5 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -951,7 +951,7 @@ class SfMaintenanceEquipmentAndProductTemplate(models.Model): raise ValidationError("机床基坐标获取失败") -sf_man + class SfMaintenanceEquipmentTool(models.Model): _name = 'maintenance.equipment.tool' _description = '机床刀位' From a5d8e88f1d44d7393ae45ae529206c684a558633 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 24 Jul 2024 16:33:47 +0800 Subject: [PATCH 05/24] =?UTF-8?q?=E6=B3=A8=E9=87=8AOCC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 4 +- sf_mrs_connect/controllers/controllers.py | 80 ++++++++++----------- sf_sale/models/quick_easy_order.py | 4 +- sf_sale/models/quick_easy_order_old.py | 4 +- sf_sale/models/sale_order.py | 1 + 5 files changed, 47 insertions(+), 46 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d05de81..f292d694 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 8267fdac..72b5d026 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -29,21 +29,21 @@ class Sf_Mrs_Connect(http.Controller): [('programming_no', '=', ret['programming_no'])]) if productions: # # 拉取所有加工面的程序文件 - for r in ret['processing_panel'].split(','): - program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) - if os.path.exists(program_path_tmp_r): - files_r = os.listdir(program_path_tmp_r) - if files_r: - for file_name in files_r: - file_path = os.path.join(program_path_tmp_r, file_name) - os.remove(file_path) - download_state = request.env['sf.cnc.processing'].with_user( - request.env.ref("base.user_admin")).download_file_tmp( - ret['folder_name'], r) - if download_state is False: - res['status'] = -2 - res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no']) - return json.JSONEncoder().encode(res) + # for r in ret['processing_panel'].split(','): + # program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) + # if os.path.exists(program_path_tmp_r): + # files_r = os.listdir(program_path_tmp_r) + # if files_r: + # for file_name in files_r: + # file_path = os.path.join(program_path_tmp_r, file_name) + # os.remove(file_path) + # download_state = request.env['sf.cnc.processing'].with_user( + # request.env.ref("base.user_admin")).download_file_tmp( + # ret['folder_name'], r) + # if download_state is False: + # res['status'] = -2 + # res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no']) + # return json.JSONEncoder().encode(res) for production in productions: if not production.workorder_ids: production.product_id.model_processing_panel = ret['processing_panel'] @@ -82,31 +82,31 @@ class Sf_Mrs_Connect(http.Controller): # if pre_workorder: # pre_workorder.write( # {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) - for panel in ret['processing_panel'].split(','): - # 查询状态为进行中且工序类型为CNC加工的工单 - cnc_workorder = productions.workorder_ids.filtered( - lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', - 'cancel'] and ac.processing_panel == panel) - if cnc_workorder: - # program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test', - # panel) - program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) - logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel) - files_panel = os.listdir(program_path_tmp_panel) - if files_panel: - for file in files_panel: - file_extension = os.path.splitext(file)[1] - logging.info('file_extension:%s' % file_extension) - if file_extension.lower() == '.pdf': - panel_file_path = os.path.join(program_path_tmp_panel, file) - logging.info('panel_file_path:%s' % panel_file_path) - cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) - pre_workorder = productions.workorder_ids.filtered( - lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', - 'cancel'] and ap.processing_panel == panel) - if pre_workorder: - pre_workorder.write( - {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) + # for panel in ret['processing_panel'].split(','): + # # 查询状态为进行中且工序类型为CNC加工的工单 + # cnc_workorder = productions.workorder_ids.filtered( + # lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', + # 'cancel'] and ac.processing_panel == panel) + # if cnc_workorder: + # program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test', + # panel) + # program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) + # logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel) + # files_panel = os.listdir(program_path_tmp_panel) + # if files_panel: + # for file in files_panel: + # file_extension = os.path.splitext(file)[1] + # logging.info('file_extension:%s' % file_extension) + # if file_extension.lower() == '.pdf': + # panel_file_path = os.path.join(program_path_tmp_panel, file) + # logging.info('panel_file_path:%s' % panel_file_path) + # cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) + # pre_workorder = productions.workorder_ids.filtered( + # lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', + # 'cancel'] and ap.processing_panel == panel) + # if pre_workorder: + # pre_workorder.write( + # {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) productions.write({'programming_state': '已编程', 'work_state': '已编程'}) cnc_program_ids = [item.id for item in productions] workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index e3bf3002..11acc06f 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 3ae65db3..92f6cda2 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index b7dae97f..0455c4f0 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -237,6 +237,7 @@ class ResPartnerToSale(models.Model): _inherit = 'res.partner' purchase_user_id = fields.Many2one('res.users', '采购员') + translated_display_name = fields.Char('11') @api.constrains('name') def _check_name(self): From 121861863f6d457e90399a64784acc6e85b348c8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 24 Jul 2024 16:57:50 +0800 Subject: [PATCH 06/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=94=80=E5=94=AE?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=A1=AE=E8=AE=A4=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_bf_connect/models/process_status.py | 19 ++++++++++++++++ sf_manufacturing/models/mrp_workorder.py | 29 ++++++------------------ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index d79b3369..735bc531 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -14,6 +14,25 @@ class StatusChange(models.Model): def action_confirm(self): # 在原有方法执行前记录日志和执行其他操作 logging.info('函数已经执行=============') + for order in self.order_lines: + for item in order.product_template_id.model_process_parameters_ids: + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), + ('detailed_type', '=', 'service')]) + logging.info('server_product:%s' % server_product.name) + if server_product: + order_line_ids.append((0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': 1, + 'product_uom': server_product.uom_id.id + })) + self.env['purchase.order'].sudo().create({ + 'partner_id': server_product.seller_ids.partner_id.id, + 'origin': record.production_id.name, + 'state': 'draft', + 'order_line': order_line_ids, + }) + # 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法) res = super(StatusChange, self).action_confirm() diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 520af4f4..b54113b4 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -989,28 +989,13 @@ class ResMrpWorkOrder(models.Model): picking_out = record.env['stock.move.line'].search( [('picking_id', '=', record.picking_ids[0].id)]) logging.info('picking_out:%s' % picking_out.picking_id.name) - if picking_out: - order_line_ids = [] - logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name) - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', record.surface_technics_parameters_id.id), - ('detailed_type', '=', 'service')]) - logging.info('server_product:%s' % server_product.name) - if server_product: - order_line_ids.append((0, 0, { - 'product_id': server_product.product_variant_id.id, - 'product_qty': 1, - 'product_uom': server_product.uom_id.id - })) - self.env['purchase.order'].sudo().create({ - 'partner_id': server_product.seller_ids.partner_id.id, - 'origin': record.production_id.name, - 'state': 'draft', - 'order_line': order_line_ids, - }) - else: - raise UserError( - '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name) + # if picking_out: + # order_line_ids = [] + # logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name) + # + # else: + # raise UserError( + # '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name) tem_date_planned_finished = record.date_planned_finished tem_date_finished = record.date_finished logging.info('routing_type:%s' % record.routing_type) From 96c22a5d4649faf54eb6a184a8a95e330cbf9ca4 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 24 Jul 2024 17:30:59 +0800 Subject: [PATCH 07/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E6=9C=8D=E5=8A=A1=E4=BA=A7=E5=93=81=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_bf_connect/models/process_status.py | 53 +++++++++++++++----------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index 735bc531..5ef558f0 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -14,25 +14,34 @@ class StatusChange(models.Model): def action_confirm(self): # 在原有方法执行前记录日志和执行其他操作 logging.info('函数已经执行=============') + server_product_none = [] for order in self.order_lines: for item in order.product_template_id.model_process_parameters_ids: - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), - ('detailed_type', '=', 'service')]) - logging.info('server_product:%s' % server_product.name) - if server_product: - order_line_ids.append((0, 0, { - 'product_id': server_product.product_variant_id.id, - 'product_qty': 1, - 'product_uom': server_product.uom_id.id - })) - self.env['purchase.order'].sudo().create({ - 'partner_id': server_product.seller_ids.partner_id.id, - 'origin': record.production_id.name, - 'state': 'draft', - 'order_line': order_line_ids, - }) + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), + ('detailed_type', '=', 'service')]) + if not server_product: + server_product_none.append(item.surface_technics_parameters_id.name) + if server_product_none: + raise UserError(_("请先至产品中创建表面工艺为%s的服务产品", ", ".join(server_product_none))) + # if not server_product_none: + # for st_item in order.product_template_id.model_process_parameters_ids: + # server_product = self.env['product.template'].search( + # [('server_product_process_parameters_id', '=', st_item.surface_technics_parameters_id.id), + # ('detailed_type', '=', 'service')]) + # if server_product: + # order_line_ids.append((0, 0, { + # 'product_id': server_product.product_variant_id.id, + # 'product_qty': 1, + # 'product_uom': server_product.uom_id.id + # })) + # self.env['purchase.order'].sudo().create({ + # 'partner_id': server_product.seller_ids.partner_id.id, + # 'origin': record.production_id.name, + # 'state': 'draft', + # 'order_line': order_line_ids, + # }) # 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法) res = super(StatusChange, self).action_confirm() @@ -221,12 +230,12 @@ class FinishStatusChange(models.Model): [('id', 'child_of', self.picking_type_id.warehouse_id.view_location_id.id), ('usage', '!=', 'supplier')]) if self.env['stock.move'].search([ - ('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']), - ('product_qty', '>', 0), - ('location_id', 'in', wh_location_ids), - ('move_orig_ids', '=', False), - ('picking_id', 'not in', self.ids), - ('product_id', 'in', lines.product_id.ids)], limit=1): + ('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']), + ('product_qty', '>', 0), + ('location_id', 'in', wh_location_ids), + ('move_orig_ids', '=', False), + ('picking_id', 'not in', self.ids), + ('product_id', 'in', lines.product_id.ids)], limit=1): action = self.action_view_reception_report() action['context'] = {'default_picking_ids': self.ids} return action From 2deaffb4eb87a0543aa3190d55011e371ed2d02a Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jul 2024 14:07:36 +0800 Subject: [PATCH 08/24] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E4=BA=A7=E5=93=81=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_bf_connect/models/process_status.py | 11 ++++++----- sf_manufacturing/models/stock.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index 5ef558f0..b2b8cacd 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -1,7 +1,8 @@ from datetime import datetime import logging import requests -from odoo import fields, models +from odoo.exceptions import UserError +from odoo import fields, models, _ _logger = logging.getLogger(__name__) @@ -15,15 +16,15 @@ class StatusChange(models.Model): # 在原有方法执行前记录日志和执行其他操作 logging.info('函数已经执行=============') server_product_none = [] - for order in self.order_lines: + for order in self.order_line: for item in order.product_template_id.model_process_parameters_ids: server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), + [('server_product_process_parameters_id', '=', item.id), ('detailed_type', '=', 'service')]) if not server_product: - server_product_none.append(item.surface_technics_parameters_id.name) + server_product_none.append(item.name) if server_product_none: - raise UserError(_("请先至产品中创建表面工艺为%s的服务产品", ", ".join(server_product_none))) + raise UserError(_("请先至产品中创建表面工艺参数为%s的服务产品", ", ".join(server_product_none))) # if not server_product_none: # for st_item in order.product_template_id.model_process_parameters_ids: diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 4bf7cc72..67829ef2 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -272,6 +272,25 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: + for st_item in production_item.product_id.model_process_parameters_ids: + purchase_order = self.env['purchase.order'].search([('state','=','draft'),('origin','ilike',production_item.name)]) + for po in purchase_order.order_line: + for pp in po.product_id.model_process_parameters_ids: + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', pp.id), + ('detailed_type', '=', 'service')]) + order_line_ids.append((0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': "同一个产品的制造订单数量", + 'product_uom': server_product.uom_id.id + })) + self.env['purchase.order'].sudo().create({ + 'partner_id': server_product.seller_ids.partner_id.id, + 'origin': "同一个产品的制造订单名称", + 'state': 'draft', + 'order_line': order_line_ids, + }) + # # 同一个产品多个制造订单对应一个编程单和模型库 # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 if not production_item.programming_no: From 19c4b99baec22f744b0b09db4943048eefda3372 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jul 2024 17:21:44 +0800 Subject: [PATCH 09/24] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=90=8E=E7=94=9F=E6=88=90=E8=AF=A2=E4=BB=B7?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_bf_connect/models/process_status.py | 30 ++++++-------------------- sf_manufacturing/models/stock.py | 18 ++++++++++------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index b2b8cacd..0bc99bdc 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -18,32 +18,14 @@ class StatusChange(models.Model): server_product_none = [] for order in self.order_line: for item in order.product_template_id.model_process_parameters_ids: - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', item.id), - ('detailed_type', '=', 'service')]) - if not server_product: - server_product_none.append(item.name) + if item.gain_way == '外协': + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', item.id), + ('detailed_type', '=', 'service')]) + if not server_product: + server_product_none.append(item.name) if server_product_none: raise UserError(_("请先至产品中创建表面工艺参数为%s的服务产品", ", ".join(server_product_none))) - - # if not server_product_none: - # for st_item in order.product_template_id.model_process_parameters_ids: - # server_product = self.env['product.template'].search( - # [('server_product_process_parameters_id', '=', st_item.surface_technics_parameters_id.id), - # ('detailed_type', '=', 'service')]) - # if server_product: - # order_line_ids.append((0, 0, { - # 'product_id': server_product.product_variant_id.id, - # 'product_qty': 1, - # 'product_uom': server_product.uom_id.id - # })) - # self.env['purchase.order'].sudo().create({ - # 'partner_id': server_product.seller_ids.partner_id.id, - # 'origin': record.production_id.name, - # 'state': 'draft', - # 'order_line': order_line_ids, - # }) - # 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法) res = super(StatusChange, self).action_confirm() diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 67829ef2..76036a54 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -272,21 +272,27 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: - for st_item in production_item.product_id.model_process_parameters_ids: - purchase_order = self.env['purchase.order'].search([('state','=','draft'),('origin','ilike',production_item.name)]) - for po in purchase_order.order_line: - for pp in po.product_id.model_process_parameters_ids: + purchase_order = self.env['purchase.order'].search( + [('state', '=', 'draft'), ('origin', 'ilike', production_item.name)]) + # for po in purchase_order.order_line: + for pp in production_item.product_id.model_process_parameters_ids: + if pp.gain_way == '外协': + purchase_order_line = self.env['purchase.order.line'].search( + [('order_id', '=', po.order_id)]) + if not purchase_order_line: server_product = self.env['product.template'].search( [('server_product_process_parameters_id', '=', pp.id), ('detailed_type', '=', 'service')]) + production_process = product_id_to_production_names.get( + production_item.product_id.id) order_line_ids.append((0, 0, { 'product_id': server_product.product_variant_id.id, - 'product_qty': "同一个产品的制造订单数量", + 'product_qty': len(production_process), 'product_uom': server_product.uom_id.id })) self.env['purchase.order'].sudo().create({ 'partner_id': server_product.seller_ids.partner_id.id, - 'origin': "同一个产品的制造订单名称", + 'origin': ','.join(production_process), 'state': 'draft', 'order_line': order_line_ids, }) From 36a2bcca6e58d5f286f9658868843c84e2240ab2 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 26 Jul 2024 15:49:25 +0800 Subject: [PATCH 10/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5yi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_bf_connect/models/process_status.py | 1 + sf_dlm/models/product_supplierinfo.py | 4 ++ sf_manufacturing/models/mrp_production.py | 1 + sf_manufacturing/models/product_template.py | 13 +++- sf_manufacturing/models/stock.py | 69 +++++++++++++++++---- 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index 0bc99bdc..6b773f5d 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -26,6 +26,7 @@ class StatusChange(models.Model): server_product_none.append(item.name) if server_product_none: raise UserError(_("请先至产品中创建表面工艺参数为%s的服务产品", ", ".join(server_product_none))) + # 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法) res = super(StatusChange, self).action_confirm() diff --git a/sf_dlm/models/product_supplierinfo.py b/sf_dlm/models/product_supplierinfo.py index 05191b44..cd5ad9a0 100644 --- a/sf_dlm/models/product_supplierinfo.py +++ b/sf_dlm/models/product_supplierinfo.py @@ -135,3 +135,7 @@ class ResSupplierInfo(models.Model): boms |= supplier.product_tmpl_id.bom_ids.filtered(lambda b: not b.product_id or b.product_id in ( supplier.product_id or supplier.product_tmpl_id.product_variant_ids)) supplier.is_subcontractor = supplier.partner_id in boms.subcontractor_id + + + + diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 65c3ebec..f0c006ea 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -904,6 +904,7 @@ class MrpProduction(models.Model): if pre_workorder: pre_workorder.write( {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) + logging.info('更新程序完成:%s' % production.name) else: diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index f292d694..f4f11dd4 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -5,8 +5,10 @@ import base64 import hashlib import os from odoo import models, fields, api, _ -from odoo.exceptions import ValidationError +from odoo.exceptions import ValidationError, UserError from odoo.modules import get_resource_path + + # from OCC.Extend.DataExchange import read_step_file # from OCC.Extend.DataExchange import write_stl_file @@ -106,6 +108,15 @@ class ResProductMo(models.Model): name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False) + @api.constrains('seller_ids') + def _check_seller_ids(self): + if self.categ_type == '表面工艺': + if self.seller_ids: + if self.seller_ids[0].price == 0.0: + raise UserError("请在该产品【采购】中的【价格】进行输入") + else: + raise UserError("请在【采购】中输入供应商信息") + @api.depends('cutting_tool_model_id', 'specification_id') def _compute_tool_name(self): for item in self: diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 76036a54..fc0b7814 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -272,29 +272,72 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: - purchase_order = self.env['purchase.order'].search( - [('state', '=', 'draft'), ('origin', 'ilike', production_item.name)]) - # for po in purchase_order.order_line: + sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, key=lambda w: w.id) + consecutive_process_parameters = [] + m = 0 + for i in range(len(sorted_workorders) - 1): + if m == 0: + is_pick = False + if sorted_process_parameters[i].supplier_id.id == sorted_process_parameters[i + 1].supplier_id.id : + if sorted_process_parameters[i] not in consecutive_process_parameters: + consecutive_process_parameters.append(sorted_process_parameters[i]) + consecutive_process_parameters.append(sorted_process_parameters[i + 1]) + m += 1 + continue + else: + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, + production_item) + if sorted_process_parameters[i] in consecutive_workorders: + is_pick = True + consecutive_process_parameters = [] + m = 0 + # 当前面的连续工序生成对应的采购单再生成当前工序的外协采购单 + if is_pick is False: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], + production_item) + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, + production_item) + if sorted_process_parameters[i] in consecutive_process_parameters: + is_pick = True + consecutive_process_parameters = [] + m = 0 + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, production_item) + if is_pick is False and m == 0: + if len(sorted_process_parameters) == 1: + self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters, production_item) + else: + self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters[i], production_item) for pp in production_item.product_id.model_process_parameters_ids: if pp.gain_way == '外协': + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', pp.id), + ('detailed_type', '=', 'service')]) purchase_order_line = self.env['purchase.order.line'].search( - [('order_id', '=', po.order_id)]) + [('product_id', '=', server_product.id)]) if not purchase_order_line: - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', pp.id), - ('detailed_type', '=', 'service')]) + is_exist = False + else: + for item in purchase_order_line: + purchase_order = self.env['purchase.order'].search( + [('state', '=', 'draft'), ('origin', 'ilike', production_item.name), + ('id', '=', item.order_id)]) + if not purchase_order: + is_exist = False + if is_exist is False: production_process = product_id_to_production_names.get( production_item.product_id.id) - order_line_ids.append((0, 0, { - 'product_id': server_product.product_variant_id.id, - 'product_qty': len(production_process), - 'product_uom': server_product.uom_id.id - })) self.env['purchase.order'].sudo().create({ 'partner_id': server_product.seller_ids.partner_id.id, 'origin': ','.join(production_process), 'state': 'draft', - 'order_line': order_line_ids, + 'order_line': [(0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': len(production_process), + 'product_uom': server_product.uom_id.id + })] }) # # 同一个产品多个制造订单对应一个编程单和模型库 From 39214e53521149b200d28dbe250c9b20ecf65c01 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Sun, 28 Jul 2024 11:47:12 +0800 Subject: [PATCH 11/24] =?UTF-8?q?=E6=B3=A8=E9=87=8A=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 | 4 +- sf_manufacturing/models/mrp_workorder.py | 14 ++- sf_manufacturing/models/stock.py | 104 +++++++++--------- .../views/mrp_production_addional_change.xml | 4 +- 4 files changed, 65 insertions(+), 61 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index f0c006ea..fd9e3e2e 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -184,8 +184,8 @@ class MrpProduction(models.Model): production.workorder_ids): production.state = 'rework' # 如果制造订单的功能刀具为【无效刀】则制造订单状态改为返工 - if production.tool_state == '2': - production.state = 'rework' + # if production.tool_state == '2': + # production.state = 'rework' def action_check(self): """ diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index e60d56c2..a7142ea4 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -827,14 +827,18 @@ class ResMrpWorkOrder(models.Model): ('sequence', '=', workorder.sequence - 1), ('state', 'in', ['done'])]) if unclamp_workorder: - workorder.state = 'ready' + if workorder.is_subcontract is False: + workorder.state = 'ready' + # else: + + # else: # if workorder.state not in ['cancel', 'rework']: # workorder.state = 'rework' - if workorder.production_id.state == 'pending_cam': - if workorder.routing_type == '装夹预调' and workorder.state in ['ready', 'waiting']: - if workorder.production_id.tool_state in ['1', '2']: - workorder.state = 'waiting' + # if workorder.production_id.state == 'pending_cam': + # if workorder.routing_type == '装夹预调' and workorder.state in ['ready', 'waiting']: + # if workorder.production_id.tool_state in ['1', '2']: + # workorder.state = 'waiting' logging.info('工序:%s' % workorder.sequence) logging.info('工单最终状态:%s' % workorder.state) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index fc0b7814..f6d35b54 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -272,44 +272,44 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: - sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, key=lambda w: w.id) - consecutive_process_parameters = [] - m = 0 - for i in range(len(sorted_workorders) - 1): - if m == 0: - is_pick = False - if sorted_process_parameters[i].supplier_id.id == sorted_process_parameters[i + 1].supplier_id.id : - if sorted_process_parameters[i] not in consecutive_process_parameters: - consecutive_process_parameters.append(sorted_process_parameters[i]) - consecutive_process_parameters.append(sorted_process_parameters[i + 1]) - m += 1 - continue - else: - if m == len(consecutive_process_parameters) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, - production_item) - if sorted_process_parameters[i] in consecutive_workorders: - is_pick = True - consecutive_process_parameters = [] - m = 0 - # 当前面的连续工序生成对应的采购单再生成当前工序的外协采购单 - if is_pick is False: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], - production_item) - if m == len(consecutive_process_parameters) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, - production_item) - if sorted_process_parameters[i] in consecutive_process_parameters: - is_pick = True - consecutive_process_parameters = [] - m = 0 - if m == len(consecutive_process_parameters) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, production_item) - if is_pick is False and m == 0: - if len(sorted_process_parameters) == 1: - self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters, production_item) - else: - self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters[i], production_item) + # sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, key=lambda w: w.id) + # consecutive_process_parameters = [] + # m = 0 + # for i in range(len(sorted_process_parameters) - 1): + # if m == 0: + # is_pick = False + # if sorted_process_parameters[i].supplier_id.id == sorted_process_parameters[i + 1].supplier_id.id and : + # if sorted_process_parameters[i] not in consecutive_process_parameters: + # consecutive_process_parameters.append(sorted_process_parameters[i]) + # consecutive_process_parameters.append(sorted_process_parameters[i + 1]) + # m += 1 + # continue + # else: + # if m == len(consecutive_process_parameters) - 1 and m != 0: + # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, + # production_item) + # if sorted_process_parameters[i] in consecutive_workorders: + # is_pick = True + # consecutive_process_parameters = [] + # m = 0 + # # 当前面的连续工序生成对应的采购单再生成当前工序的外协采购单 + # if is_pick is False: + # self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], + # production_item) + # if m == len(consecutive_process_parameters) - 1 and m != 0: + # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, + # production_item) + # if sorted_process_parameters[i] in consecutive_process_parameters: + # is_pick = True + # consecutive_process_parameters = [] + # m = 0 + # if m == len(consecutive_process_parameters) - 1 and m != 0: + # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, production_item) + # if is_pick is False and m == 0: + # if len(sorted_process_parameters) == 1: + # self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters, production_item) + # else: + # self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters[i], production_item) for pp in production_item.product_id.model_process_parameters_ids: if pp.gain_way == '外协': server_product = self.env['product.template'].search( @@ -567,26 +567,26 @@ class StockPicking(models.Model): [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), ('location_id', '=', self.env['stock.location'].search( [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.origin)]) + ('origin', '=', self.origin), ('picking_id', '=', self.id)]) if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id: if move_out.origin == move_in.origin: if move_out.picking_id.state != 'done': raise UserError( _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name)) res = super().button_validate() - if res is True: - if self.id == move_out.picking_id.id: - # if move_out.move_line_ids.workorder_id.state == 'progress': - move_in = self.env['stock.move'].search( - [('location_dest_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - ('location_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.origin)]) - production = self.env['mrp.production'].search([('name', '=', self.origin)]) - if move_in: - move_in.write({'state': 'assigned'}) - self.env['stock.move.line'].create(move_in.get_move_line(production, None)) + # if res is True: + # if self.id == move_out.picking_id.id: + # # if move_out.move_line_ids.workorder_id.state == 'progress': + # move_in = self.env['stock.move'].search( + # [('location_dest_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + # ('location_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'VL-SPOC')]).id), + # ('origin', '=', self.origin)]) + # production = self.env['mrp.production'].search([('name', '=', self.origin)]) + # if move_in: + # move_in.write({'state': 'assigned'}) + # self.env['stock.move.line'].create(move_in.get_move_line(production, None)) return res diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index fdbec99f..53df7491 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -285,7 +285,7 @@ - + @@ -566,7 +566,7 @@
- +
From f49557090a4c967d01f21a59af30f8b3ea647994 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 1 Aug 2024 10:40:25 +0800 Subject: [PATCH 12/24] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80?= =?UTF-8?q?=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=E6=8B=86=E8=A7=A3=E6=97=B6?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E8=B0=83=E6=8B=A8=E5=8D=95=E5=8D=95?= =?UTF-8?q?=E6=8D=AE=E9=AA=8C=E8=AF=81=E5=87=BA=E7=8E=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 83fa3b36..65475333 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -1103,7 +1103,7 @@ class StockMove(models.Model): move_line_ids = picking_id.move_line_ids for move_line_id in move_line_ids: for res in data: - if move_line_id.lot_id.product_id == res['lot_id'].product_id: + if move_line_id.product_id == res['lot_id'].product_id: move_line_id.write({ 'destination_location_id': res.get('destination').id, 'lot_id': res.get('lot_id').id From 510e8d49fb788180c87b56d59ccbd1dc468a744e Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 1 Aug 2024 10:46:14 +0800 Subject: [PATCH 13/24] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7?= =?UTF-8?q?=E6=8B=86=E8=A7=A3=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 83fa3b36..65475333 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -1103,7 +1103,7 @@ class StockMove(models.Model): move_line_ids = picking_id.move_line_ids for move_line_id in move_line_ids: for res in data: - if move_line_id.lot_id.product_id == res['lot_id'].product_id: + if move_line_id.product_id == res['lot_id'].product_id: move_line_id.write({ 'destination_location_id': res.get('destination').id, 'lot_id': res.get('lot_id').id From a5da18bbc7ad59f745264dea75794947ddb7b1d0 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 1 Aug 2024 11:34:20 +0800 Subject: [PATCH 14/24] =?UTF-8?q?1=E3=80=81=E4=BF=AE=E6=94=B9=E5=A4=B9?= =?UTF-8?q?=E5=85=B7=E9=87=8D=E9=87=8F=E5=8D=95=E4=BD=8D=E4=B8=BAkg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/basic_parameters_fixture.py | 2 +- sf_manufacturing/models/product_template.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sf_base/models/basic_parameters_fixture.py b/sf_base/models/basic_parameters_fixture.py index e9469355..868114e8 100644 --- a/sf_base/models/basic_parameters_fixture.py +++ b/sf_base/models/basic_parameters_fixture.py @@ -13,7 +13,7 @@ class BasicParametersFixture(models.Model): diameter = fields.Float('直径(mm)', digits=(16, 2)) # '零点卡盘' 字段 - weight = fields.Float('重量(mm)', digits=(16, 2)) + weight = fields.Float('重量(kg)', digits=(16, 2)) orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2)) clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2)) clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数') diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d05de81..496f3372 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -800,7 +800,7 @@ class ResProductFixture(models.Model): diameter = fields.Float('直径(mm)', digits=(16, 2)) # '零点卡盘' 字段 - weight = fields.Float('重量(mm)', digits=(16, 2)) + weight = fields.Float('重量(kg)', digits=(16, 2)) orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2)) clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2)) clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数') From 070890e3b64582f68542edf64edf1dde741646c4 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 5 Aug 2024 16:26:54 +0800 Subject: [PATCH 15/24] =?UTF-8?q?=E8=A7=A3=E5=86=B3=20=20SF=EF=BC=8C?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=E9=87=87=E8=B4=AD=E5=8D=95=E5=9D=AF=E6=96=99?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=97=B6=E5=88=B0=E5=8E=9F=E6=9D=90=E6=96=99?= =?UTF-8?q?=E5=BA=93BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 4bf7cc72..c202fc71 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -217,6 +217,23 @@ class StockRule(models.Model): ( p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() + # 处理 根据制造订单生成的采购单坯料入库时到原材料库,手动将原材料位置该为坯料存货区 + for production in productions: + if production.picking_ids: + product_type_id = production.picking_ids[0].move_ids[0].product_id.categ_id + if product_type_id.name == '坯料': + location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')]) + if not location_id: + logging.info(f'没有搜索到【坯料存货区】: {location_id}') + break + for picking_id in production.picking_ids: + if picking_id.picking_type_id.name == '内部调拨': + if picking_id.location_dest_id.product_type != product_type_id: + picking_id.location_dest_id = location_id.id + elif picking_id.picking_type_id.name == '生产发料': + if picking_id.location_id.product_type != product_type_id: + picking_id.location_id = location_id.id + for production in productions: ''' 创建制造订单时生成序列号 From e92c9675b6aeb235cf2ad32aed7b24060e4dab58 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 5 Aug 2024 17:18:54 +0800 Subject: [PATCH 16/24] =?UTF-8?q?1=E3=80=81=20=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E5=86=85=E9=83=A8=E8=B0=83=E6=8B=A8=E5=8D=95=EF=BC=8C=E5=9C=A8?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E7=9B=AE=E6=A0=87=E8=B4=A7=E4=BD=8D=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E9=9A=90=E8=97=8F=E5=B8=A6=E5=BE=AA=E7=8E=AF=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E6=A0=87=E7=AD=BE=E7=9A=84=E8=B4=A7=E4=BD=8D=E4=B8=8D?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/views/fixture_view.xml | 14 +++++++------- sf_warehouse/views/change_stock_move_views.xml | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sf_base/views/fixture_view.xml b/sf_base/views/fixture_view.xml index 0e86738d..07dadd33 100644 --- a/sf_base/views/fixture_view.xml +++ b/sf_base/views/fixture_view.xml @@ -171,7 +171,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -220,7 +220,7 @@ - + @@ -248,7 +248,7 @@ - + @@ -278,7 +278,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -335,7 +335,7 @@ - + diff --git a/sf_warehouse/views/change_stock_move_views.xml b/sf_warehouse/views/change_stock_move_views.xml index c5df0881..9e1073c9 100644 --- a/sf_warehouse/views/change_stock_move_views.xml +++ b/sf_warehouse/views/change_stock_move_views.xml @@ -21,7 +21,8 @@ + '=', there_is_no_sn), ('rotative_Boolean', '=', False)]" + options="{'no_create': True,'no_create_edit':True}"/> From 5393ef686a2215df8598ba69a2e3dfe9b39f67b8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Mon, 5 Aug 2024 17:28:48 +0800 Subject: [PATCH 17/24] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 2 +- sf_manufacturing/models/stock.py | 164 +++++++++--------- .../views/mrp_production_addional_change.xml | 2 +- sf_sale/models/sale_order.py | 32 +++- 4 files changed, 118 insertions(+), 82 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 5f7c04b6..880db242 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -940,7 +940,7 @@ class ResMrpWorkOrder(models.Model): if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready': workorder.state = 'waiting' continue ->>>>>>> 3f27ae0f35c7054b2e6583cc60502d6faef3fc92 + # elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'cancel', 'progress', # 'rework']: diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index f6d35b54..f1289261 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -272,73 +272,79 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: - # sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, key=lambda w: w.id) - # consecutive_process_parameters = [] - # m = 0 - # for i in range(len(sorted_process_parameters) - 1): - # if m == 0: - # is_pick = False - # if sorted_process_parameters[i].supplier_id.id == sorted_process_parameters[i + 1].supplier_id.id and : - # if sorted_process_parameters[i] not in consecutive_process_parameters: - # consecutive_process_parameters.append(sorted_process_parameters[i]) - # consecutive_process_parameters.append(sorted_process_parameters[i + 1]) - # m += 1 - # continue - # else: - # if m == len(consecutive_process_parameters) - 1 and m != 0: - # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, - # production_item) - # if sorted_process_parameters[i] in consecutive_workorders: - # is_pick = True - # consecutive_process_parameters = [] - # m = 0 - # # 当前面的连续工序生成对应的采购单再生成当前工序的外协采购单 - # if is_pick is False: - # self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], - # production_item) - # if m == len(consecutive_process_parameters) - 1 and m != 0: - # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, - # production_item) - # if sorted_process_parameters[i] in consecutive_process_parameters: - # is_pick = True - # consecutive_process_parameters = [] - # m = 0 - # if m == len(consecutive_process_parameters) - 1 and m != 0: - # self.env['stock.picking'].create_outcontract_picking(consecutive_process_parameters, production_item) - # if is_pick is False and m == 0: - # if len(sorted_process_parameters) == 1: - # self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters, production_item) - # else: - # self.env['stock.picking'].create_outcontract_picking(sorted_process_parameters[i], production_item) - for pp in production_item.product_id.model_process_parameters_ids: - if pp.gain_way == '外协': - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', pp.id), - ('detailed_type', '=', 'service')]) - purchase_order_line = self.env['purchase.order.line'].search( - [('product_id', '=', server_product.id)]) - if not purchase_order_line: - is_exist = False - else: - for item in purchase_order_line: - purchase_order = self.env['purchase.order'].search( - [('state', '=', 'draft'), ('origin', 'ilike', production_item.name), - ('id', '=', item.order_id)]) - if not purchase_order: - is_exist = False - if is_exist is False: - production_process = product_id_to_production_names.get( - production_item.product_id.id) - self.env['purchase.order'].sudo().create({ - 'partner_id': server_product.seller_ids.partner_id.id, - 'origin': ','.join(production_process), - 'state': 'draft', - 'order_line': [(0, 0, { - 'product_id': server_product.product_variant_id.id, - 'product_qty': len(production_process), - 'product_uom': server_product.uom_id.id - })] - }) + sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, + key=lambda w: w.id) + consecutive_process_parameters = [] + m = 0 + for i in range(len(sorted_process_parameters) - 1): + if m == 0: + is_purchase = False + if sorted_process_parameters[i].supplier_id.id == sorted_process_parameters[ + i + 1].supplier_id.id and sorted_process_parameters[i].gain_way == '外协': + if sorted_process_parameters[i] not in consecutive_process_parameters: + consecutive_process_parameters.append(sorted_process_parameters[i]) + consecutive_process_parameters.append(sorted_process_parameters[i + 1]) + m += 1 + continue + else: + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, + production_item, + product_id_to_production_names) + if sorted_process_parameters[i] in consecutive_workorders: + is_purchase = True + consecutive_process_parameters = [] + m = 0 + # 当前面的连续采购单生成再生成当前工序的外协采购单 + if is_purchase is False: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters[i], + production_item, product_id_to_production_names) + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, + production_item, product_id_to_production_names) + if sorted_process_parameters[i] in consecutive_process_parameters: + is_purchase = True + consecutive_process_parameters = [] + m = 0 + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, production_item, + product_id_to_production_names) + if is_purchase is False and m == 0: + if len(sorted_process_parameters) == 1: + self.env['purchase.order'].get_purchase_order(sorted_process_parameters, production_item, + product_id_to_production_names) + else: + self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i], production_item, + product_id_to_production_names) + # for pp in production_item.product_id.model_process_parameters_ids: + # if pp.gain_way == '外协': + # server_product = self.env['product.template'].search( + # [('server_product_process_parameters_id', '=', pp.id), + # ('detailed_type', '=', 'service')]) + # purchase_order_line = self.env['purchase.order.line'].search( + # [('product_id', '=', server_product.id)]) + # if not purchase_order_line: + # is_exist = False + # else: + # for item in purchase_order_line: + # purchase_order = self.env['purchase.order'].search( + # [('state', '=', 'draft'), ('origin', 'ilike', production_item.name), + # ('id', '=', item.order_id)]) + # if not purchase_order: + # is_exist = False + # if is_exist is False: + # production_process = product_id_to_production_names.get( + # production_item.product_id.id) + # self.env['purchase.order'].sudo().create({ + # 'partner_id': server_product.seller_ids.partner_id.id, + # 'origin': ','.join(production_process), + # 'state': 'draft', + # 'order_line': [(0, 0, { + # 'product_id': server_product.product_variant_id.id, + # 'product_qty': len(production_process), + # 'product_uom': server_product.uom_id.id + # })] + # }) # # 同一个产品多个制造订单对应一个编程单和模型库 # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 @@ -575,18 +581,18 @@ class StockPicking(models.Model): _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name)) res = super().button_validate() # if res is True: - # if self.id == move_out.picking_id.id: - # # if move_out.move_line_ids.workorder_id.state == 'progress': - # move_in = self.env['stock.move'].search( - # [('location_dest_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - # ('location_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'VL-SPOC')]).id), - # ('origin', '=', self.origin)]) - # production = self.env['mrp.production'].search([('name', '=', self.origin)]) - # if move_in: - # move_in.write({'state': 'assigned'}) - # self.env['stock.move.line'].create(move_in.get_move_line(production, None)) + # if self.id == move_out.picking_id.id: + # # if move_out.move_line_ids.workorder_id.state == 'progress': + # move_in = self.env['stock.move'].search( + # [('location_dest_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + # ('location_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'VL-SPOC')]).id), + # ('origin', '=', self.origin)]) + # production = self.env['mrp.production'].search([('name', '=', self.origin)]) + # if move_in: + # move_in.write({'state': 'assigned'}) + # self.env['stock.move.line'].create(move_in.get_move_line(production, None)) return res diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index a39a3d07..69aed55e 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -122,7 +122,7 @@ groups="sf_base.group_sf_mrp_user"/>
- + diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index e8a9faad..9a668e88 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -211,36 +211,46 @@ class RePurchaseOrder(models.Model): if not line.taxes_id: raise UserError('请对【产品】中的【税】进行选择') - def get_purchase_order(self, production, product_id_to_production_names): - for pp in production.product_id.model_process_parameters_ids: + def get_purchase_order(self, consecutive_process_parameters, production, product_id_to_production_names): + is_exist = True + server_product_process = [] + production_process = product_id_to_production_names.get( + production.product_id.id) + for pp in consecutive_process_parameters: if pp.gain_way == '外协': server_product = self.env['product.template'].search( [('server_product_process_parameters_id', '=', pp.id), ('detailed_type', '=', 'service')]) purchase_order_line = self.env['purchase.order.line'].search( - [('product_id', '=', server_product.id)]) + [('product_id', '=', server_product.id), ('product_qty', '=', len(production_process))]) if not purchase_order_line: is_exist = False + server_product_process.append((0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': len(production_process), + 'product_uom': server_product.uom_id.id + })) else: for item in purchase_order_line: purchase_order = self.env['purchase.order'].search( [('state', '=', 'draft'), ('origin', 'ilike', production.name), - ('id', '=', item.order_id)]) + ('id', '=', item.order_id.id)]) if not purchase_order: is_exist = False - if is_exist is False: - production_process = product_id_to_production_names.get( - production.product_id.id) - self.env['purchase.order'].sudo().create({ - 'partner_id': server_product.seller_ids.partner_id.id, - 'origin': ','.join(production_process), - 'state': 'draft', - 'order_line': [(0, 0, { - 'product_id': server_product.product_variant_id.id, - 'product_qty': len(production_process), - 'product_uom': server_product.uom_id.id - })] - }) + server_product_process.append((0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': len(production_process), + 'product_uom': server_product.uom_id.id + })) + if is_exist is False: + purchase_order = self.env['purchase.order'].search( + [('state', '=', 'draft'), ('origin', '=', ','.join(production_process))]) + if not purchase_order: + self.env['purchase.order'].sudo().create({ + 'partner_id': server_product.seller_ids.partner_id.id, + 'origin': ','.join(production_process), + 'state': 'draft', + 'order_line': server_product_process}) @api.onchange('order_line') def _onchange_order_line(self): From aaa19b96fd31b4a5dd7f519f8d27bcd49eb84a88 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 8 Aug 2024 14:57:55 +0800 Subject: [PATCH 21/24] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=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_workorder.py | 2 +- sf_manufacturing/models/product_template.py | 4 +- sf_manufacturing/models/stock.py | 26 +++--- sf_manufacturing/views/mrp_workorder_view.xml | 11 ++- sf_mrs_connect/controllers/controllers.py | 80 +++++++++---------- sf_sale/models/quick_easy_order.py | 4 +- sf_sale/models/quick_easy_order_old.py | 4 +- sf_sale/models/sale_order.py | 8 ++ 8 files changed, 73 insertions(+), 66 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 44fe8c92..ed4786cd 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -933,7 +933,7 @@ class ResMrpWorkOrder(models.Model): purchase_orders = self.env['purchase.order'].search( [('origin', '=', ','.join(production_list))]) for line in purchase_orders.order_line: - if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len( + if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len( production_programming): if purchase_orders.state == 'purchase': workorder.state = 'ready' diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 721aa0a9..d4bdc1f2 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -9,8 +9,8 @@ from odoo.exceptions import ValidationError, UserError from odoo.modules import get_resource_path -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index f338924d..03dd861e 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -554,19 +554,19 @@ class StockPicking(models.Model): raise UserError( _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name)) res = super().button_validate() - # if res is True: - # if self.id == move_out.picking_id.id: - # # if move_out.move_line_ids.workorder_id.state == 'progress': - # move_in = self.env['stock.move'].search( - # [('location_dest_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - # ('location_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'VL-SPOC')]).id), - # ('origin', '=', self.origin)]) - # production = self.env['mrp.production'].search([('name', '=', self.origin)]) - # if move_in: - # move_in.write({'state': 'assigned'}) - # self.env['stock.move.line'].create(move_in.get_move_line(production, None)) + if res is True: + if self.id == move_out.picking_id.id: + # if move_out.move_line_ids.workorder_id.state == 'progress': + move_in = self.env['stock.move'].search( + [('location_dest_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + ('location_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'VL-SPOC')]).id), + ('origin', '=', self.origin)]) + production = self.env['mrp.production'].search([('name', '=', self.origin)]) + if move_in: + move_in.write({'state': 'assigned'}) + self.env['stock.move.line'].create(move_in.get_move_line(production, None)) return res diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 23b61c66..0c4fcd38 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -118,11 +118,6 @@ statusbar_visible="pending,waiting,ready,progress,to be detected,done,rework"/> - + diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 72b5d026..ce342d4a 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -29,21 +29,21 @@ class Sf_Mrs_Connect(http.Controller): [('programming_no', '=', ret['programming_no'])]) if productions: # # 拉取所有加工面的程序文件 - # for r in ret['processing_panel'].split(','): - # program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) - # if os.path.exists(program_path_tmp_r): - # files_r = os.listdir(program_path_tmp_r) - # if files_r: - # for file_name in files_r: - # file_path = os.path.join(program_path_tmp_r, file_name) - # os.remove(file_path) - # download_state = request.env['sf.cnc.processing'].with_user( - # request.env.ref("base.user_admin")).download_file_tmp( - # ret['folder_name'], r) - # if download_state is False: - # res['status'] = -2 - # res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no']) - # return json.JSONEncoder().encode(res) + for r in ret['processing_panel'].split(','): + program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) + if os.path.exists(program_path_tmp_r): + files_r = os.listdir(program_path_tmp_r) + if files_r: + for file_name in files_r: + file_path = os.path.join(program_path_tmp_r, file_name) + os.remove(file_path) + download_state = request.env['sf.cnc.processing'].with_user( + request.env.ref("base.user_admin")).download_file_tmp( + ret['folder_name'], r) + if download_state is False: + res['status'] = -2 + res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no']) + return json.JSONEncoder().encode(res) for production in productions: if not production.workorder_ids: production.product_id.model_processing_panel = ret['processing_panel'] @@ -82,31 +82,31 @@ class Sf_Mrs_Connect(http.Controller): # if pre_workorder: # pre_workorder.write( # {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) - # for panel in ret['processing_panel'].split(','): - # # 查询状态为进行中且工序类型为CNC加工的工单 - # cnc_workorder = productions.workorder_ids.filtered( - # lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', - # 'cancel'] and ac.processing_panel == panel) - # if cnc_workorder: - # program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test', - # panel) - # program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) - # logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel) - # files_panel = os.listdir(program_path_tmp_panel) - # if files_panel: - # for file in files_panel: - # file_extension = os.path.splitext(file)[1] - # logging.info('file_extension:%s' % file_extension) - # if file_extension.lower() == '.pdf': - # panel_file_path = os.path.join(program_path_tmp_panel, file) - # logging.info('panel_file_path:%s' % panel_file_path) - # cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) - # pre_workorder = productions.workorder_ids.filtered( - # lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', - # 'cancel'] and ap.processing_panel == panel) - # if pre_workorder: - # pre_workorder.write( - # {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) + for panel in ret['processing_panel'].split(','): + # 查询状态为进行中且工序类型为CNC加工的工单 + cnc_workorder = productions.workorder_ids.filtered( + lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', + 'cancel'] and ac.processing_panel == panel) + if cnc_workorder: + program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test', + panel) + program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) + logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel) + files_panel = os.listdir(program_path_tmp_panel) + if files_panel: + for file in files_panel: + file_extension = os.path.splitext(file)[1] + logging.info('file_extension:%s' % file_extension) + if file_extension.lower() == '.pdf': + panel_file_path = os.path.join(program_path_tmp_panel, file) + logging.info('panel_file_path:%s' % panel_file_path) + cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) + pre_workorder = productions.workorder_ids.filtered( + lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', + 'cancel'] and ap.processing_panel == panel) + if pre_workorder: + pre_workorder.write( + {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) productions.write({'programming_state': '已编程', 'work_state': '已编程'}) cnc_program_ids = [item.id for item in productions] workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index e8807707..b4ed6f31 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 92f6cda2..3ae65db3 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 9a668e88..424f9bb5 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -271,6 +271,14 @@ class RePurchaseOrder(models.Model): if picking_id.move_ids: for move_id in picking_id.move_ids: move_id.put_move_line() + for line in item.order_line: + if line.product_id.categ_type == '表面工艺': + for production_name in item.origin.split(','): + 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): + workorder.state = 'ready' + return result From 3d2c7425c42033eded868b2374c80f0d802703f5 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 8 Aug 2024 15:03:45 +0800 Subject: [PATCH 22/24] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_dlm/models/product_supplierinfo.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sf_dlm/models/product_supplierinfo.py b/sf_dlm/models/product_supplierinfo.py index cd5ad9a0..05191b44 100644 --- a/sf_dlm/models/product_supplierinfo.py +++ b/sf_dlm/models/product_supplierinfo.py @@ -135,7 +135,3 @@ class ResSupplierInfo(models.Model): boms |= supplier.product_tmpl_id.bom_ids.filtered(lambda b: not b.product_id or b.product_id in ( supplier.product_id or supplier.product_tmpl_id.product_variant_ids)) supplier.is_subcontractor = supplier.partner_id in boms.subcontractor_id - - - - From 563023fa3c754a75a354596fc12afadc9616a51f Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 8 Aug 2024 15:07:22 +0800 Subject: [PATCH 23/24] =?UTF-8?q?=E4=B8=AD=E6=8E=A7=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=BA=AB=E4=BB=BD=E9=AA=8C=E8=AF=81=E6=94=BE=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/controllers/controllers.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index babda164..072cd222 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -145,7 +145,7 @@ class Manufacturing_Connect(http.Controller): logging.info('get_qcCheck error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def button_Work_START(self, **kw): """ @@ -193,7 +193,7 @@ class Manufacturing_Connect(http.Controller): logging.info('button_Work_START error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def button_Work_End(self, **kw): """ @@ -244,7 +244,7 @@ class Manufacturing_Connect(http.Controller): logging.info('button_Work_End error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def PartQualityInspect(self, **kw): """ @@ -290,7 +290,7 @@ class Manufacturing_Connect(http.Controller): logging.info('PartQualityInspect error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/CMMProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/CMMProgDolod', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def CMMProgDolod(self, **kw): """ @@ -330,7 +330,7 @@ class Manufacturing_Connect(http.Controller): logging.info('CMMProgDolod error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/NCProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/NCProgDolod', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def NCProgDolod(self, **kw): """ From 112efccb7cb5ba75d6b0c1138da8a3fb4ffe2f43 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 8 Aug 2024 16:21:15 +0800 Subject: [PATCH 24/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/controllers/controllers.py | 4 +- sf_manufacturing/models/stock.py | 83 +++++++++++---------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 072cd222..f3597093 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -429,7 +429,7 @@ class Manufacturing_Connect(http.Controller): logging.info('LocationChange error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def AGVToProduct(self, **kw): """ @@ -490,7 +490,7 @@ class Manufacturing_Connect(http.Controller): logging.info('AGVToProduct error:%s' % e) return json.JSONEncoder().encode(res) - @http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def AGVDownProduct(self, **kw): """ diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index aea42c6f..b71db731 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -289,25 +289,40 @@ class StockRule(models.Model): product_id_to_production_names[product_id] = [production.name for production in all_production] for production_item in productions: if production_item.product_id.id in product_id_to_production_names: - sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, - key=lambda w: w.id) + if production_item.product_id.model_process_parameters_ids: + is_purchase = False + sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids, + key=lambda w: w.id) - consecutive_process_parameters = [] - m = 0 - for i in range(len(sorted_process_parameters) - 1): - if m == 0: - is_purchase = False - if self.env['product.template']._get_process_parameters_product( - sorted_process_parameters[i]).partner_id == self.env[ - 'product.template']._get_process_parameters_product(sorted_process_parameters[ - i + 1]).partner_id and \ - sorted_process_parameters[i].gain_way == '外协': - if sorted_process_parameters[i] not in consecutive_process_parameters: - consecutive_process_parameters.append(sorted_process_parameters[i]) - consecutive_process_parameters.append(sorted_process_parameters[i + 1]) - m += 1 - continue - else: + consecutive_process_parameters = [] + m = 0 + for i in range(len(sorted_process_parameters) - 1): + if m == 0: + is_purchase = False + if self.env['product.template']._get_process_parameters_product( + sorted_process_parameters[i]).partner_id == self.env[ + 'product.template']._get_process_parameters_product(sorted_process_parameters[ + i + 1]).partner_id and \ + sorted_process_parameters[i].gain_way == '外协': + if sorted_process_parameters[i] not in consecutive_process_parameters: + consecutive_process_parameters.append(sorted_process_parameters[i]) + consecutive_process_parameters.append(sorted_process_parameters[i + 1]) + m += 1 + continue + else: + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, + production_item, + product_id_to_production_names) + if sorted_process_parameters[i] in consecutive_process_parameters: + is_purchase = True + consecutive_process_parameters = [] + m = 0 + # 当前面的连续外协采购单生成再生成当前外协采购单 + if is_purchase is False: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, + production_item, + product_id_to_production_names) if m == len(consecutive_process_parameters) - 1 and m != 0: self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, production_item, @@ -316,27 +331,19 @@ class StockRule(models.Model): is_purchase = True consecutive_process_parameters = [] m = 0 - # 当前面的连续采购单生成再生成当前工序的外协采购单 - if is_purchase is False: - self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, - production_item, product_id_to_production_names) - if m == len(consecutive_process_parameters) - 1 and m != 0: - self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, - production_item, product_id_to_production_names) - if sorted_process_parameters[i] in consecutive_process_parameters: - is_purchase = True - consecutive_process_parameters = [] - m = 0 - if m == len(consecutive_process_parameters) - 1 and m != 0: - self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, production_item, - product_id_to_production_names) - if is_purchase is False and m == 0: - if len(sorted_process_parameters) == 1: - self.env['purchase.order'].get_purchase_order(sorted_process_parameters, production_item, - product_id_to_production_names) - else: - self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i], production_item, + if m == len(consecutive_process_parameters) - 1 and m != 0: + self.env['purchase.order'].get_purchase_order(consecutive_process_parameters, + production_item, product_id_to_production_names) + if is_purchase is False and m == 0: + if len(sorted_process_parameters) == 1: + self.env['purchase.order'].get_purchase_order(sorted_process_parameters, + production_item, + product_id_to_production_names) + else: + self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i], + production_item, + product_id_to_production_names) # # 同一个产品多个制造订单对应一个编程单和模型库 # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 if not production_item.programming_no: