diff --git a/sf_base/models/base.py b/sf_base/models/base.py index 7565adeb..5762822e 100644 --- a/sf_base/models/base.py +++ b/sf_base/models/base.py @@ -196,8 +196,7 @@ class MachineTool(models.Model): kw = json.dumps(machine_tool_list, ensure_ascii=False) r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers) ret = r.json() - self.code = ret['code'] - print(r) + self.code = ret['message'] if r == 200: return "机床注册成功" else: diff --git a/sf_base/models/common.py b/sf_base/models/common.py index 809b8be0..d576129d 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -31,6 +31,10 @@ class MrsMaterialModel(models.Model): density = fields.Float("密度(kg/m³)") materials_id = fields.Many2one('sf.production.materials', "材料名") remark = fields.Text("备注") + gain_way = fields.Selection( + [("自加工", "自加工"), ("外协", "外协"), ("采购", "采购")], + default="", string="获取方式") + supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商') active = fields.Boolean('有效', default=True) @@ -63,7 +67,6 @@ class MrsProcessingOrder(models.Model): _name = 'sf.processing.order' _description = '工序' sequence = fields.Integer('Sequence') - processing_technology_ids = fields.Many2many('sf.processing.technology', 'sf_associated_processes', index=True, string='加工工艺') production_process_id = fields.Many2one('sf.production.process', string="表面工艺") @@ -79,3 +82,17 @@ class Tray(models.Model): [("空闲", "空闲"), ("占用", "占用"), ("报损", "报损")], default="空闲", string="状态") active = fields.Boolean('有效', default=True) + + +class SupplierSort(models.Model): + _name = 'sf.supplier.sort' + _description = '供应商排序' + + sequence = fields.Integer('Sequence') + partner_id = fields.Many2one('res.partner', domain="[('is_company', '=', True),('supplier_rank', '!=', 0)]") + materials_model_id = fields.Many2one('sf.materials.model') + + _sql_constraints = [ + ('supplier_sort_uniq', 'unique (partner_id,materials_model_id)', '排序不能重复!') + ] + diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index a548d41c..d4441085 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -12,6 +12,7 @@ access_sf_production_materials,sf_production_materials,model_sf_production_mater access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,1 access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,base.group_user,1,1,1,1 access_sf_tray,sf_tray,model_sf_tray,base.group_user,1,1,1,1 +access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,1 diff --git a/sf_base/views/common_view.xml b/sf_base/views/common_view.xml index b0e2a7bc..3b4e7935 100644 --- a/sf_base/views/common_view.xml +++ b/sf_base/views/common_view.xml @@ -6,23 +6,17 @@ sf.processing.technology
- - - - - -
@@ -30,10 +24,8 @@ sf.processing.technology - - @@ -52,13 +44,13 @@ sf.production.process - + sf.production.process @@ -77,9 +69,7 @@
- -
@@ -110,24 +100,28 @@ + + - - - - + + + + + + + + - -
diff --git a/sf_bf_connect/__manifest__.py b/sf_bf_connect/__manifest__.py index eb0e1dfe..fe5a9559 100644 --- a/sf_bf_connect/__manifest__.py +++ b/sf_bf_connect/__manifest__.py @@ -12,7 +12,7 @@ 'website': 'https://www.sf.cs.jikimo.com', 'depends': ['sf_base', 'sf_sale', 'sf_dlm'], 'data': [ - + 'views/res_partner_view.xml' ], 'demo': [ ], diff --git a/sf_bf_connect/controllers/controllers.py b/sf_bf_connect/controllers/controllers.py index c47fd2b8..9e422ca7 100644 --- a/sf_bf_connect/controllers/controllers.py +++ b/sf_bf_connect/controllers/controllers.py @@ -23,6 +23,9 @@ class Sf_Bf_Connect(http.Controller): ret = json.loads(datas) ret = json.loads(ret['result']) product_id = request.env.ref('sf_dlm.product_template_sf').sudo() + self_machining_id = request.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo() + outsource_id = request.env.ref('sf_dlm.product_embryo_sf_outsource').sudo() + purchase_id = request.env.ref('sf_dlm.product_embryo_sf_purchase').sudo() company_id = request.env.ref('base.main_company').sudo() order_id = request.env['sale.order'].with_user(request.env.ref("base.user_admin")).sale_order_create( company_id, ret['delivery_name'], ret['delivery_telephone'], ret['delivery_address'], @@ -32,10 +35,31 @@ class Sf_Bf_Connect(http.Controller): product = request.env['product.template'].sudo().product_create(product_id, item, order_id, ret['order_number'], i) order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item) - bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create(product) - bom.with_user(request.env.ref("base.user_admin")).bom_create_Line(product) - i += 1 - res['factory_order_no'] = order_id.name + bom_data = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).get_bom(product) + if bom_data: + bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create(product, + 'normal') + bom.with_user(request.env.ref("base.user_admin")).bom_create_Line(product) + else: + if product.materials_id.gain_way == '自加工': + self_machining = request.env['product.template'].sudo().no_bom_product_create(self_machining_id, + item, + order_i) + bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create( + self_machining, 'normal') + bom.with_user(request.env.ref("base.user_admin")).bom_create_Line(self_machining) + + elif product.materials_id.gain_way == '外协': + outsource = request.env['product.template'].sudo().no_bom_product_create(outsource_id, item, + order_id) + bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create(outsource) + bom.with_user(request.env.ref("base.user_admin")).bom_create_Line(outsource, 'subcontract') + elif product.materials_id.gain_way == '采购': + purchase = request.env['product.template'].sudo().no_bom_product_create(purchase_id, item, + order_id) + + i += 1 + res['factory_order_no'] = order_id.name return json.JSONEncoder().encode(res) except Exception as e: logging.info('get_bfm_process_order_list error:%s' % e) diff --git a/sf_bf_connect/models/models.py b/sf_bf_connect/models/models.py index 3eeac229..9c9d59a1 100644 --- a/sf_bf_connect/models/models.py +++ b/sf_bf_connect/models/models.py @@ -25,4 +25,5 @@ class ResPartner(models.Model): return ran_str sf_token = fields.Char(u'Token', default=get_token) - sf_secret_key = fields.Char(u'密钥', default=get_secret) \ No newline at end of file + sf_secret_key = fields.Char(u'密钥', default=get_secret) + diff --git a/sf_bf_connect/views/res_partner_view.xml b/sf_bf_connect/views/res_partner_view.xml new file mode 100644 index 00000000..70609554 --- /dev/null +++ b/sf_bf_connect/views/res_partner_view.xml @@ -0,0 +1,20 @@ + + + + + view_partner_form + res.partner + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sf_dlm/data/product_data.xml b/sf_dlm/data/product_data.xml index c3db48ff..5485d1d8 100644 --- a/sf_dlm/data/product_data.xml +++ b/sf_dlm/data/product_data.xml @@ -12,5 +12,48 @@ false + + + 胚料 + 胚料 + + + + 自加工 + + delivery + product + false + + + + false + + + + 外协 + + delivery + product + false + + + + false + + + + 采购 + + delivery + product + false + + + + false + + + \ No newline at end of file diff --git a/sf_dlm/models/product_template.py b/sf_dlm/models/product_template.py index 725ab8e9..6ec7720e 100644 --- a/sf_dlm/models/product_template.py +++ b/sf_dlm/models/product_template.py @@ -35,6 +35,23 @@ class ResProductTemplate(models.Model): # def _compute_volume(self): # self.volume = self.long * self.width * self.height + + single_manufacturing = fields.Boolean(string="单个制造") + + @api.model + def _get_route(self): + route_manufacture = self.env.ref('stock.warehouse0', raise_if_not_found=False).manufacture_pull_id.route_id.id + route_mto = self.env.ref('stock.warehouse0', raise_if_not_found=False).mto_pull_id.route_id.id + if route_manufacture and route_mto: + return [route_manufacture, route_mto] + return [] + + route_ids = fields.Many2many(default=lambda self: self._get_route()) + + # @api.depends('long', 'width', 'height') + # def _compute_volume(self): + # self.volume = self.long * self.width * self.height + # @api.depends('model_long', 'model_width', 'model_height') # def _compute_model_volume(self): # self.model_volume = self.model_long * self.model_width * self.model_height @@ -54,6 +71,12 @@ class ResProductTemplate(models.Model): 'height': item['height'], 'volume': item['long'] * item['width'] * item['height'], 'model_price': item['price'], + 'length': item['model_long'], + 'width': item['model_width'], + 'height': item['model_height'], + 'volume': item['model_long'] * item['model_width'] * item['model_height'], + 'model_price': item['price'], + 'tracking': 'serial', 'single_manufacturing': True, 'list_price': item['price'], 'materials_id': self.env['sf.production.materials'].search( @@ -65,8 +88,44 @@ class ResProductTemplate(models.Model): # 'model_process_parameters_id': self.env['sf.processing.technology'].search( # [('process_encode', '=', item['process_parameters_code'])]).id, 'model_remark': item['remark'], - 'default_code': '%s-%s' % (order_number, i), - 'barcode': item['barcode'], + # 'default_code': '%s-%s' % (order_number, i), + # 'barcode': item['barcode'], + 'active': True + } + logging.info('product_create1:%s' % item) + copy_product_id.sudo().write(vals) + return copy_product_id + + def no_bom_product_create(self, product_id, item, order_id): + copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() + copy_product_id.product_tmpl_id.active = True + logging.info('no_bom_product_create:%s' % item) + materials_id = self.env['sf.production.materials'].search( + [('materials_no', '=', item['texture_code'])]).id + materials_type_id = self.env['sf.materials.model'].search( + [('materials_no', '=', item['texture_type_code'])]).id + vals = { + 'name': '%s %s %s %s * %s * %s' % ( + order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'], + item['model_height']), + 'model_long': item['model_long'], + 'model_width': item['model_width'], + 'model_height': item['model_height'], + 'model_volume': item['model_long'] * item['model_width'] * item['model_height'], + 'length': item['model_long'], + 'width': item['model_width'], + 'height': item['model_height'], + 'volume': item['model_long'] * item['model_width'] * item['model_height'], + 'model_price': item['price'], + 'tracking': 'serial', + 'single_manufacturing': True, + 'list_price': item['price'], + 'materials_id': materials_id.id, + 'materials_type_id': materials_type_id.id, + # 'model_surface_process_id': self.env['sf.production.process'].search( + # [('process_encode', '=', item['surface_process_code'])]).id, + # 'model_process_parameters_id': self.env['sf.processing.technology'].search( + # [('process_encode', '=', item['process_parameters_code'])]).id, 'active': True } logging.info('product_create1:%s' % item) @@ -99,10 +158,10 @@ class ResMrpBom(models.Model): _inherit = 'mrp.bom' # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom - def bom_create(self, product): + def bom_create(self, product, bom_type): bom_id = self.env['mrp.bom'].create({ 'product_tmpl_id': product.product_tmpl_id.id, - 'type': 'normal', + 'type': bom_type, 'product_qty': 1, 'product_uom_id': 1 }) @@ -117,6 +176,24 @@ class ResMrpBom(models.Model): logging.info('bom_create_Line:%s' % product) embryo = self.env['product.product'].search( [('categ_id.is_embryo', '=', True), ('materials_type_id', '=', product.materials_type_id.id), + # 创建新的胚料,根据胚料材料型号的获取方式( + # 自加工,外协,采购) 的配置, 选择不同的库存路线,一种材料型号配置一个路线相关的配置: + # 材料型号配置不同的获取方式: (自加工, 外协, 采购); + # 原材料重量KG(公斤)= 胚料的体积(立方米m³) * 材料密度 * 1000 + def bom_create_Line(self, embryo, materials): + bom_line = self.get_raw_bom(embryo, materials) + vals = { + 'bom_id': self.id, + 'product_id': bom_line.id, + 'product_tmpl_id': bom_line.product_tmpl_id.id, + 'product_qty': bom_line.volume * bom_line.materials_type_id.density * 1000, + 'product_uom_id': bom_line.uom_id.id + } + return self.env['mrp.bom.line'].create(vals) + + def get_bom(self, product): + embryo = self.env['product.product'].search( + [('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id), ('length', '>', product.length), ('width', '>', product.width), ('height', '>', product.height) ], @@ -125,9 +202,32 @@ class ResMrpBom(models.Model): ) logging.info('bom_create_Line1:%s' % product) return self.env['mrp.bom.line'].create(vals) + if embryo: + rate_of_waste = ((embryo.volume - product.model_volume) % embryo.volume) * 100 + if rate_of_waste <= 20: + return embryo + else: + return + + # 查bom的原材料 + def get_raw_bom(self, product): + raw_bom = self.env['product.product'].search( + [('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)]) + return raw_bom class ResProductCategory(models.Model): _inherit = "product.category" - is_embryo = fields.Boolean('胚料') + type = fields.Selection( + [("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料")], + default="", string="类型") + + # @api.constrains('type') + # def _check_type(self): + # category = self.env['product.category'].search( + # [('type', '=', self.type)]) + # if category: + # raise ValidationError("该类别已存在,请选择其他类别") + + diff --git a/sf_dlm/views/product_template_view.xml b/sf_dlm/views/product_template_view.xml index 76cbdb32..e8c28167 100644 --- a/sf_dlm/views/product_template_view.xml +++ b/sf_dlm/views/product_template_view.xml @@ -48,16 +48,16 @@ - - product.category.form.inherit.sf - product.category - - - - - - - + + + + + + + + + + product.template.stock.property.form.inherit diff --git a/sf_manufacturing/models/mrp_routing_workcenter.py b/sf_manufacturing/models/mrp_routing_workcenter.py index 8f533a68..23123d14 100644 --- a/sf_manufacturing/models/mrp_routing_workcenter.py +++ b/sf_manufacturing/models/mrp_routing_workcenter.py @@ -40,24 +40,24 @@ class ResMrpRoutingWorkcenter(models.Model): return self.env.cr.dictfetchall()[0].get('workcenter_id') -class ModelTypeRoutingSort(models.Model): - _name = 'sf.model.type.routing.sort' - _description = '工序排序' - - sequence = fields.Integer('Sequence') - route_workcenter_id = fields.Many2one('mrp.routing.workcenter') - is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') - routing_type = fields.Selection([ - ('获取CNC加工程序', '获取CNC加工程序'), - ('装夹', '装夹'), - ('前置三元定位检测', '前置三元定位检测'), - ('CNC加工', 'CNC加工'), - ('后置三元质量检测', '后置三元质量检测'), - ('解除装夹', '解除装夹'), - ], string="工序类型", related='route_workcenter_id.routing_type') - workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') - model_type_id = fields.Many2one('sf.model.type') - - _sql_constraints = [ - ('route_model_type_uniq', 'unique (route_workcenter_id,model_type_id)', '工序不能重复!') - ] +# class ModelTypeRoutingSort(models.Model): +# _name = 'sf.model.type.routing.sort' +# _description = '工序排序' +# +# sequence = fields.Integer('Sequence') +# route_workcenter_id = fields.Many2one('mrp.routing.workcenter') +# is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') +# routing_type = fields.Selection([ +# ('获取CNC加工程序', '获取CNC加工程序'), +# ('装夹', '装夹'), +# ('前置三元定位检测', '前置三元定位检测'), +# ('CNC加工', 'CNC加工'), +# ('后置三元质量检测', '后置三元质量检测'), +# ('解除装夹', '解除装夹'), +# ], string="工序类型", related='route_workcenter_id.routing_type') +# workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') +# model_type_id = fields.Many2one('sf.model.type') +# +# _sql_constraints = [ +# ('route_model_type_uniq', 'unique (route_workcenter_id,model_type_id)', '工序不能重复!') +# ] diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 23d20d96..a318f6f8 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -242,7 +242,7 @@ class ResMrpWorkOrder(models.Model): 'material_type_code': cnc.env['sf.materials.model'].search( [('id', '=', cnc.product_id.materials_type_id.id)]).materials_no, 'machining_precision': cnc.product_id.model_machining_precision, - 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.long, + 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length, 'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height, 'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width # 'factory_code': self.env.user.company_id.partner_id. diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index f0ada0a3..94e7e2d1 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -29,9 +29,11 @@ class Sf_Mrs_Connect(http.Controller): # # 从ftp拉取对应的文件 model_code = cnc.workorder_id.product_id.barcode processing_panel = cnc.workorder_id.processing_panel + logging.info('model_code:%s' % model_code) server_dir = cnc.with_user(request.env.ref("base.user_admin")).download_file_tmp(model_code, processing_panel) cnc_file_path = os.path.join(server_dir, cnc.program_name + '.NC') + logging.info('cnc_file_path:%s' % cnc_file_path) cnc.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, cnc) # logging.info('get_cnc_processing_create:%s' % '111111111111111') # for root, dirs, files in os.walk(server_dir): diff --git a/sf_mrs_connect/models/ftp_operate.py b/sf_mrs_connect/models/ftp_operate.py index 32c8d32d..a71ee83f 100644 --- a/sf_mrs_connect/models/ftp_operate.py +++ b/sf_mrs_connect/models/ftp_operate.py @@ -19,25 +19,24 @@ class FtpController(): try: self.ftp.connect(host, port) self.ftp.login(username, password) + logging.info("连接成功: ") except: logging.info("连接失败: ") # 下载目录下的文件 - def download_file_tree(self, remotepath, serverdir): + def download_file_tree(self, target_dir, serverdir): + self.ftp.cwd(target_dir) # 切换工作路径 if not os.path.exists(serverdir): os.makedirs(serverdir) - self.ftp.cwd(remotepath) - remotenames = self.ftp.nlst() - for file in remotenames: - server = os.path.join(serverdir, file) - if file.find(".") != -1: - self.download_file(server, file) - else: - return False + remotenames = self.ftp.nlst() + for file in remotenames: + server = os.path.join(serverdir, file) + if file.find(".") != -1: + self.download_file(server, file) + return # 下载指定目录下的指定文件 def download_file(self, serverfile, remotefile): file_handler = open(serverfile, 'wb') self.ftp.retrbinary('RETR ' + remotefile, file_handler.write) file_handler.close() -