diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml
index 87dbd94c..b90d1a5c 100644
--- a/sf_base/views/tool_views.xml
+++ b/sf_base/views/tool_views.xml
@@ -80,10 +80,10 @@
sf.cutter.function.tree
sf.functional.cutting.tool.model
-
-
-
-
+
+
+
+
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index aefa2ac5..7cada1be 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/sf_mrs_connect/models/res_config_setting.py b/sf_mrs_connect/models/res_config_setting.py
index 159e8d48..04693fa7 100644
--- a/sf_mrs_connect/models/res_config_setting.py
+++ b/sf_mrs_connect/models/res_config_setting.py
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
# Part of SmartGo. See LICENSE file for full copyright and licensing details.
import logging
+
+import requests
+
from odoo import api, fields, models
-from odoo.exceptions import ValidationError
+from odoo.exceptions import ValidationError, UserError
_logger = logging.getLogger(__name__)
@@ -86,7 +89,7 @@ class ResConfigSettings(models.TransientModel):
_logger.info("同步刀具物料每齿走刀量完成")
except Exception as e:
- _logger.info("捕获错误信息:%s" % e)
+ _logger.info("sf_all_sync error: %s" % e)
raise ValidationError("数据错误导致同步失败,请联系管理员")
@api.model
@@ -144,3 +147,68 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("ftp_user", self.ftp_user or "")
ir_config.set_param("ftp_password", self.ftp_password or "")
ir_config.set_param("enable_tool_presetter", self.enable_tool_presetter or False)
+
+ def sync_sale_price(self):
+ self.get_page_all_records(self.sale_order_price_process)
+
+ def sale_order_price_process(self, datas):
+ if not datas:
+ return
+ try:
+ convert_sale_data = map(lambda data:
+ {'name': data.name, 'order_lines': {
+ str(i): str(value.price_unit) for i, value in enumerate(data.order_line)
+ }
+ },
+ datas)
+ config = self.env['res.config.settings'].get_values()
+ url = config['bfm_url_new'] + '/api/sync/order/price'
+ json_data = {
+ 'params': {
+ 'data': list(convert_sale_data),
+ },
+ }
+ response = requests.post(url, json=json_data, data=None)
+ response = response.json()
+ if not response.get('error'):
+ result = response.get('result')
+ for need_change_sale_data in result:
+ res_order_lines_map = need_change_sale_data.get('order_lines')
+ if not res_order_lines_map:
+ continue
+ need_change_sale_order = self.env['sale.order'].sudo().search([('name', '=', need_change_sale_data.get('name'))])
+ for index,need_change_sale_order_line in enumerate(need_change_sale_order.order_line):
+ if not res_order_lines_map.get(str(index)):
+ continue
+ order_line = self.env['sale.order.line'].browse(need_change_sale_order_line.id)
+ new_price = res_order_lines_map.get(str(index))
+ if order_line:
+ # 修改单价
+ order_line.write({'remark': new_price})
+ else:
+ logging.error('同步销售订单价格失败 {}'.format(response.text))
+ raise UserError('同步销售订单价格失败')
+ except Exception as e:
+ raise UserError(e)
+
+ def get_page_all_records(self, func, page_size=100):
+ # 获取模型对象
+ model = self.env['sale.order'].sudo()
+
+ # 初始化分页参数
+ page_number = 1
+ while True:
+ # 计算偏移量
+ offset = (page_number - 1) * page_size
+
+ # 获取当前页的数据
+ records = model.search([], limit=page_size, offset=offset)
+
+ # 如果没有更多记录,退出循环
+ if not records:
+ break
+
+ # 将当前页的数据添加到结果列表
+ func(records)
+ # 增加页码
+ page_number += 1
\ No newline at end of file
diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py
index e812bd03..e106bbf2 100644
--- a/sf_mrs_connect/models/sync_common.py
+++ b/sf_mrs_connect/models/sync_common.py
@@ -2,6 +2,8 @@
import logging
import json
import base64
+import traceback
+
import requests
from odoo import models
from odoo.exceptions import ValidationError
@@ -73,7 +75,8 @@ class MrStaticResourceDataSync(models.Model):
self.env['sf.feed.per.tooth'].sync_feed_per_tooth_yesterday()
_logger.info("同步刀具物料每齿走刀量完成")
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ traceback_error = traceback.format_exc()
+ logging.error("同步静态资源库失败:%s" % traceback_error)
raise ValidationError("数据错误导致同步失败,请联系管理员")
@@ -2759,8 +2762,9 @@ class CuttingToolBasicParameters(models.Model):
if result['status'] == 1:
if 'basic_parameters_integral_tool' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_integral_tool']:
- basic_parameters_integral_tool_list = json.loads(
- result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_integral_tool'])
+ cutting_tool_basic_parameters_yesterday_list= result['cutting_tool_basic_parameters_yesterday_list']
+ basic_parameters_integral_tool_list = cutting_tool_basic_parameters_yesterday_list['basic_parameters_integral_tool']
+
if basic_parameters_integral_tool_list:
for integral_tool_item in basic_parameters_integral_tool_list:
integral_tool = self.search(
diff --git a/sf_mrs_connect/views/res_config_settings_views.xml b/sf_mrs_connect/views/res_config_settings_views.xml
index 05e5be41..651e6f15 100644
--- a/sf_mrs_connect/views/res_config_settings_views.xml
+++ b/sf_mrs_connect/views/res_config_settings_views.xml
@@ -129,6 +129,21 @@
+
diff --git a/sf_tool_management/__manifest__.py b/sf_tool_management/__manifest__.py
index a1a88fb0..97c26e40 100644
--- a/sf_tool_management/__manifest__.py
+++ b/sf_tool_management/__manifest__.py
@@ -10,7 +10,7 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
- 'depends': ['sf_manufacturing'],
+ 'depends': ['sf_manufacturing', 'sf_base'],
'data': [
'security/group_security.xml',
'security/ir.model.access.csv',
@@ -24,6 +24,11 @@
'views/menu_view.xml',
'views/stock.xml',
'data/tool_data.xml',
+ 'wizard/jikimo_bom_wizard.xml',
+ 'views/tool_inventory.xml',
+ 'views/jikimo_bom.xml',
+ 'views/tool_views.xml',
+
],
'demo': [
],
diff --git a/sf_tool_management/models/__init__.py b/sf_tool_management/models/__init__.py
index 90776ca7..e4f2a622 100644
--- a/sf_tool_management/models/__init__.py
+++ b/sf_tool_management/models/__init__.py
@@ -8,4 +8,6 @@ from . import fixture_material_search
from . import fixture_enroll
from . import temporary_data_processing_methods
from . import stock
-
+from . import jikimo_bom
+from . import tool_inventory
+from . import functional_cutting_tool_model
\ No newline at end of file
diff --git a/sf_tool_management/models/functional_cutting_tool_model.py b/sf_tool_management/models/functional_cutting_tool_model.py
new file mode 100644
index 00000000..9b5a5002
--- /dev/null
+++ b/sf_tool_management/models/functional_cutting_tool_model.py
@@ -0,0 +1,6 @@
+from odoo import models, fields
+
+
+class SyncFunctionalCuttingToolModel(models.Model):
+ _inherit = 'sf.functional.cutting.tool.model'
+ cutting_tool_type_ids = fields.Many2many('sf.cutting.tool.type', string='整体式刀具物料')
\ No newline at end of file
diff --git a/sf_tool_management/models/functional_tool_enroll.py b/sf_tool_management/models/functional_tool_enroll.py
index ba3553e1..ab391511 100644
--- a/sf_tool_management/models/functional_tool_enroll.py
+++ b/sf_tool_management/models/functional_tool_enroll.py
@@ -50,7 +50,7 @@ class ToolDatasync(models.Model):
# self.env['sf.real.time.distribution.of.functional.tools'].sudo().sync_enroll_functional_tool_real_time_distribution_all()
# logging.info("功能刀具安全库存每日同步成功")
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ logging.info("刀具物料、刀具信息同步失败:%s" % e)
raise ValidationError("数据错误导致同步失败,请联系管理员")
@@ -312,7 +312,7 @@ class FunctionalToolWarning(models.Model):
else:
logging.info('没有注册功能刀具预警信息')
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ logging.info("功能刀具预警同步失败:%s" % e)
class StockMoveLine(models.Model):
@@ -373,7 +373,7 @@ class StockMoveLine(models.Model):
else:
logging.info('没有注册功能刀具出入库记录信息')
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ logging.info("出入库记录信息同步失败:%s" % e)
class RealTimeDistributionFunctionalTools(models.Model):
@@ -446,4 +446,4 @@ class RealTimeDistributionFunctionalTools(models.Model):
else:
logging.info('没有注册功能刀具出入库记录信息')
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ logging.info("实时功能刀具同步失败:%s" % e)
diff --git a/sf_tool_management/models/jikimo_bom.py b/sf_tool_management/models/jikimo_bom.py
new file mode 100644
index 00000000..5272d4f0
--- /dev/null
+++ b/sf_tool_management/models/jikimo_bom.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+from xml import etree
+
+from odoo import models, fields, api, Command
+from odoo.http import request
+
+
+class jikimo_bom(models.Model):
+ _name = 'jikimo.bom'
+ _description = '功能刀具物料清单'
+ tool_inventory_id = fields.Many2one('sf.tool.inventory', '功能刀具清单')
+ tool_name = fields.Char(related="tool_inventory_id.name", string='功能刀具名称')
+ functional_cutting_tool_model_id = fields.Many2one(related='tool_inventory_id.functional_cutting_tool_model_id',
+ string='功能刀具类型')
+ tool_groups_id = fields.Many2one(related='tool_inventory_id.tool_groups_id', string='刀具组')
+ tool_length = fields.Float(related='tool_inventory_id.tool_length', string='刀具总长(mm)')
+ diameter = fields.Float(related='tool_inventory_id.diameter', string='直径(mm)')
+ angle = fields.Float(related='tool_inventory_id.angle', string='R角(mm)')
+ extension = fields.Float(related='tool_inventory_id.extension', string='伸出长度(mm)')
+ product_ids = fields.Many2many('product.product', string='产品')
+ knife_handle_model = fields.Selection(related='tool_inventory_id.knife_handle_model', string='使用刀柄型号')
+ options = fields.Char('产品清单')
+
+ def name_get(self):
+ result = []
+ for bom in self:
+ result.append((bom.id, '功能刀具物料清单'))
+ return result
+ def bom_product_domains(self, assembly_options):
+ self.options = assembly_options
+ cutting_tool_materials = self.env['sf.cutting.tool.material'].search(
+ [('name', 'in', assembly_options.split('+'))])
+ domains = []
+ for index, option in enumerate(cutting_tool_materials):
+ domain = ['&',('cutting_tool_material_id', '=', option.id),
+ ("cutting_tool_type_id", "in",
+ self.tool_inventory_id.functional_cutting_tool_model_id.cutting_tool_type_ids.ids)]
+ if option.name == '刀柄':
+ domain = ['&']+domain+[ ("cutting_tool_taper_shank_model", "=", self.tool_inventory_id.knife_handle_model)]
+
+ if option.name == '整体式刀具':
+ domain=['&']+domain+[
+ '|',
+ # 刀具直径
+ ('cutting_tool_blade_diameter', '=', self.tool_inventory_id.diameter),
+
+ # r角
+ ('cutting_tool_blade_tip_working_size', '=', self.tool_inventory_id.angle)]
+ if option.name == '刀杆':
+ domain = ['&'] + domain + [
+ ("cutting_tool_cutter_arbor_diameter", "=", self.tool_inventory_id.diameter)]
+ if option.name == '刀片':
+ domain = ['&'] + domain + [
+ ("cutting_tool_blade_tip_circular_arc_radius", "=", self.tool_inventory_id.angle)]
+ if option.name == '刀盘':
+ domain = ['&'] + domain + [
+ ("cutting_tool_cutter_head_diameter", "=", self.tool_inventory_id.diameter)]
+ domains=domains+domain
+ if index != 0:
+ domains = ['|'] + domains
+ # wqwqwe = self.env['product.product'].search(ddd)
+ # product = self.env['product.product'].search(domain)
+ # if product:
+ # products = products + product
+ return domains
+
+ def generate_bill_materials(self, assembly_options):
+ domains=self.bom_product_domains(assembly_options)
+ products = self.env['product.product'].search(domains)
+ if products:
+ self.product_ids = [Command.set(products.ids)]
+ # if option.name == '刀盘':
+ # hilt = self.env['product.product'].search(
+ # [('cutting_tool_blade_diameter', '=', self.tool_inventory_id.diameter),
+ # ('cutting_tool_material_id', '=', option.id)])
+ # self.product_ids = [Command.set(hilt.ids)]k
+
+
+class jikimo_bom_line(models.Model):
+ _name = 'jikimo.bom.line'
+ _description = 'jikimo.bom.line'
+
+ name = fields.Char()
+
+
+class ProductProduct(models.Model):
+ _inherit = 'product.product'
+
+ def search(self, args, offset=0, limit=None, order=None, count=False):
+ # 你可以在这里修改 `args` 以调整搜索条件
+ # 例如,添加额外的搜索条件
+ if self.env.context.get('jikimo_bom_product'):
+ bom_id = self.env['jikimo.bom'].browse(request.session.get('jikimo_bom_product').get('bom_id'))
+ domains = bom_id.bom_product_domains(bom_id.options)
+ args=args+domains
+ return super(ProductProduct, self).search(args, offset=offset, limit=limit, order=order, count=count)
diff --git a/sf_tool_management/models/tool_inventory.py b/sf_tool_management/models/tool_inventory.py
new file mode 100644
index 00000000..db15834a
--- /dev/null
+++ b/sf_tool_management/models/tool_inventory.py
@@ -0,0 +1,34 @@
+from odoo import models, fields
+from odoo.http import request
+
+
+class ToolInventory(models.Model):
+ _inherit = 'sf.tool.inventory'
+ _description = '功能刀具清单'
+ knife_handle_model = fields.Selection([('BT30', 'BT30'), ('BT40', 'BT40'), ('BT50', 'BT50'), ('GSK30', 'GSK30'), ('GSK40', 'GSK40'), ('GSK50', 'GSK50')], string='使用刀柄型号')
+ jikimo_bom_ids = fields.One2many('jikimo.bom','tool_inventory_id', 'bom单')
+ def bom_mainfest(self):
+
+ jikimo_bom_ids = self.mapped('jikimo_bom_ids')
+ if not jikimo_bom_ids:
+ self._bom_mainfest()
+ return self.bom_mainfest()
+ request.session['jikimo_bom_product'] = {'bom_id': int(self.jikimo_bom_ids)}
+ # context = dict(self.env.context)
+ # context.update({'jikimo_bom_product': self.jikimo_bom_ids.options})
+ # if self.functional_cutting_tool_model_id.cutting_tool_type_ids:
+ # context.update({'jikimo_bom_product_cutting_tool_type': self.functional_cutting_tool_model_id.cutting_tool_type_ids.ids})
+ return {
+ 'type': 'ir.actions.act_window',
+ 'name': '刀具组装清单',
+ 'res_model': 'jikimo.bom',
+ 'view_mode': 'form',
+ 'view_id': self.env.ref('sf_tool_management.view_jikimo_bom_form').id,
+ 'res_id': int(self.jikimo_bom_ids),
+ 'target': 'current', # Use 'new' to open in a new window/tab
+ # {'jikimo_bom_product': self.jikimo_bom_ids.options}
+ }
+
+ # 创建bom单
+ def _bom_mainfest(self):
+ self.env['jikimo.bom'].create({'tool_inventory_id':self.id})
\ No newline at end of file
diff --git a/sf_tool_management/security/ir.model.access.csv b/sf_tool_management/security/ir.model.access.csv
index 26b45aeb..8c188464 100644
--- a/sf_tool_management/security/ir.model.access.csv
+++ b/sf_tool_management/security/ir.model.access.csv
@@ -38,3 +38,6 @@ access_sf_fixture_material_search_group_plan_dispatch,sf.fixture.material.search
access_sf_functional_tool_dismantle,sf.functional.tool.dismantle,model_sf_functional_tool_dismantle,base.group_user,1,1,1,0
access_sf_functional_tool_dismantle_group_sf_tool_user,sf.functional.tool.dismantle_group_sf_tool_user,model_sf_functional_tool_dismantle,sf_base.group_sf_tool_user,1,1,1,0
access_sf_functional_tool_dismantle_group_plan_dispatch,sf.functional.tool.dismantle_group_plan_dispatch,model_sf_functional_tool_dismantle,sf_base.group_plan_dispatch,1,0,0,0
+
+access_jikimo_bom,jikimo.bom,model_jikimo_bom,base.group_user,1,1,1,1
+access_jikimo_bom_wizard,jikimo.bom.wizard,model_jikimo_bom_wizard,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/sf_tool_management/views/jikimo_bom.xml b/sf_tool_management/views/jikimo_bom.xml
new file mode 100644
index 00000000..bb1454df
--- /dev/null
+++ b/sf_tool_management/views/jikimo_bom.xml
@@ -0,0 +1,51 @@
+
+
+
+ bom物料清单
+ jikimo.bom
+ tree,form
+
+
+ jikimo.bom.form
+ jikimo.bom
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_tool_management/views/tool_inventory.xml b/sf_tool_management/views/tool_inventory.xml
new file mode 100644
index 00000000..f7fbc6b5
--- /dev/null
+++ b/sf_tool_management/views/tool_inventory.xml
@@ -0,0 +1,15 @@
+
+
+
+ sf.tool.inventory.inherit.tree
+ sf.tool.inventory
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_tool_management/views/tool_views.xml b/sf_tool_management/views/tool_views.xml
new file mode 100644
index 00000000..24379b9a
--- /dev/null
+++ b/sf_tool_management/views/tool_views.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ sf.cutter.function.inherit.tree
+ sf.functional.cutting.tool.model
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_tool_management/wizard/__init__.py b/sf_tool_management/wizard/__init__.py
index 40272379..6fb6c20e 100644
--- a/sf_tool_management/wizard/__init__.py
+++ b/sf_tool_management/wizard/__init__.py
@@ -1 +1,2 @@
from . import wizard
+from . import jikimo_bom_wizard
\ No newline at end of file
diff --git a/sf_tool_management/wizard/jikimo_bom_wizard.py b/sf_tool_management/wizard/jikimo_bom_wizard.py
new file mode 100644
index 00000000..f86a7a09
--- /dev/null
+++ b/sf_tool_management/wizard/jikimo_bom_wizard.py
@@ -0,0 +1,28 @@
+import logging
+
+from datetime import timedelta, datetime, date
+
+from odoo import fields, models, api
+from odoo.exceptions import ValidationError, UserError
+
+
+class JikimoBomWizard(models.TransientModel):
+ _name = 'jikimo.bom.wizard'
+ _description = '组装方式选择'
+ bom_id = fields.Many2one('jikimo.bom', '刀具组装清单')
+ assembly_options = fields.Selection([
+ ('刀柄+整体式刀具', '刀柄+整体式刀具'),
+ ('刀柄+刀杆+刀片', '刀柄+刀杆+刀片'),
+ ('刀柄+刀盘+刀片', '刀柄+刀盘+刀片')
+ ], string='组装方式', required=True)
+ # assembly_options_ids = fields.Many2many('sf.cutting.tool.material', string="组装方式")
+ is_ok = fields.Boolean('确认上述信息正确无误。')
+
+ def submit(self):
+ if not self.bom_id:
+ raise UserError('缺少bom信息')
+ if self.bom_id.tool_inventory_id.functional_cutting_tool_model_id.name == '飞刀' and self.assembly_options == '刀柄+整体式刀具':
+ raise UserError('飞刀只可选 刀柄+刀杆+刀片 或 刀柄+刀盘+刀片')
+ if self.bom_id.tool_inventory_id.functional_cutting_tool_model_id.name in['中心钻','合金钻','合金刀','整体刀','倒角刀','丝锥'] and self.assembly_options != '刀柄+整体式刀具':
+ raise UserError('此功能刀具只可选 刀柄+整体式刀具')
+ self.bom_id.generate_bill_materials(self.assembly_options)
\ No newline at end of file
diff --git a/sf_tool_management/wizard/jikimo_bom_wizard.xml b/sf_tool_management/wizard/jikimo_bom_wizard.xml
new file mode 100644
index 00000000..5d6d2e82
--- /dev/null
+++ b/sf_tool_management/wizard/jikimo_bom_wizard.xml
@@ -0,0 +1,33 @@
+
+
+
+ 组装方式..
+ jikimo.bom.wizard
+ form
+ new
+
+
+ jikimo.bom.wizard.form.view
+ jikimo.bom.wizard
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_warehouse/models/sync_common.py b/sf_warehouse/models/sync_common.py
index aaa186f9..d8f075dd 100644
--- a/sf_warehouse/models/sync_common.py
+++ b/sf_warehouse/models/sync_common.py
@@ -139,5 +139,5 @@ class MrsShelfLocationDataSync(models.Model):
location_id.product_sn_id = False
except Exception as e:
- logging.info("捕获错误信息:%s" % e)
+ logging.info("库区信息同步失败:%s" % e)
raise ValidationError("数据错误导致同步失败,请联系管理员")