diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py
index 1bfdd356..09fecfae 100644
--- a/sf_bf_connect/models/process_status.py
+++ b/sf_bf_connect/models/process_status.py
@@ -36,6 +36,7 @@ class StatusChange(models.Model):
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
try:
res = super(StatusChange, self).action_confirm()
+ logging.info('原生方法返回结果:%s' % res)
# 原有方法执行后,进行额外的操作(如调用外部API)
process_start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
config = self.env['res.config.settings'].get_values()
@@ -61,6 +62,7 @@ class StatusChange(models.Model):
traceback_error = traceback.format_exc()
logging.error("工厂加工同步订单状态失败:%s " % traceback_error)
raise UserError(e)
+ logging.info('最终返回值:%s' % res)
return res
def action_cancel(self):
diff --git a/sf_bf_connect/views/view.xml b/sf_bf_connect/views/view.xml
index 184d0e71..f4245343 100644
--- a/sf_bf_connect/views/view.xml
+++ b/sf_bf_connect/views/view.xml
@@ -58,7 +58,7 @@
-
+
diff --git a/sf_dlm_management/__manifest__.py b/sf_dlm_management/__manifest__.py
index a5c894d4..9a94082a 100644
--- a/sf_dlm_management/__manifest__.py
+++ b/sf_dlm_management/__manifest__.py
@@ -9,7 +9,7 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
- 'depends': ['sf_sale', 'sf_dlm', 'sf_manufacturing'],
+ 'depends': ['sf_sale', 'sf_dlm', 'sf_manufacturing','jikimo_attachment_viewer'],
'data': [
'data/stock_data.xml',
'views/product_template_management_view.xml',
diff --git a/sf_hr/models/__init__.py b/sf_hr/models/__init__.py
index ffe76391..9744f0cc 100644
--- a/sf_hr/models/__init__.py
+++ b/sf_hr/models/__init__.py
@@ -2,3 +2,4 @@
from . import hr_employee
from . import res_config_setting
+from . import res_users
diff --git a/sf_hr/models/hr_employee.py b/sf_hr/models/hr_employee.py
index e9826f29..5d37f199 100644
--- a/sf_hr/models/hr_employee.py
+++ b/sf_hr/models/hr_employee.py
@@ -11,6 +11,42 @@ class JkmPracticeEmployee(models.Model):
we_id = fields.Char(string='企微ID', index=True)
+ @api.model_create_multi
+ def create(self, vals_list):
+ for val in vals_list:
+ if 'work_email' in val:
+ val["we_id"] = self._get_we_id(val.get('work_email'))
+ return super(JkmPracticeEmployee, self).create(vals_list)
+
+ def write(self, vals):
+ if 'work_email' in vals:
+ vals["we_id"] = self._get_we_id(vals.get('work_email'))
+ return super(JkmPracticeEmployee, self).write(vals)
+
+ @api.depends('work_contact_id', 'work_contact_id.mobile', 'work_contact_id.email')
+ def _compute_work_contact_details(self):
+ for employee in self:
+ if employee.work_contact_id:
+ employee.mobile_phone = employee.work_contact_id.mobile
+ employee.work_email = employee.work_contact_id.email
+ if employee.work_contact_id.email:
+ employee.we_id = self._get_we_id(employee.work_contact_id.email)
+
+ def _get_we_id(self, work_email):
+ json1 = {
+ 'params': {
+ 'work_email': work_email
+ }
+ }
+ url = '/api/get/we_id/info'
+ config = self.env['res.config.settings'].get_values()
+ ret = requests.post((config['ims_url'] + url), json=json1, data={})
+ result = ret.json()['result']
+ if result['code'] == 200:
+ if result['we_id']:
+ return result['we_id']
+ return None
+
def _employee_info_sync(self):
url = '/api/get/organization'
config = self.env['res.config.settings'].get_values()
diff --git a/sf_hr/models/res_users.py b/sf_hr/models/res_users.py
new file mode 100644
index 00000000..7ced81bc
--- /dev/null
+++ b/sf_hr/models/res_users.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+import random
+from odoo import models, fields, api
+from odoo.http import request
+from odoo.exceptions import AccessDenied
+
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class ResUsers(models.Model):
+ _inherit = 'res.users'
+
+ we_employee_id = fields.Char(string=u'企业微信账号', related='employee_id.we_id', default="")
diff --git a/sf_maintenance/models/sf_maintenance_oee.py b/sf_maintenance/models/sf_maintenance_oee.py
index 0889fdb5..eef42a60 100644
--- a/sf_maintenance/models/sf_maintenance_oee.py
+++ b/sf_maintenance/models/sf_maintenance_oee.py
@@ -62,22 +62,22 @@ class SfMaintenanceEquipmentOEE(models.Model):
("封存(报废)", "封存(报废)")],
default='正常', string="机床状态", related='equipment_id.state')
- online_time = fields.Char('开机时长(小时)', reaonly='True')
+ online_time = fields.Char('开机时长(小时)', readonly='True')
- offline_time = fields.Char('关机时长(小时)', reaonly='True')
- idle_nums = fields.Integer('待机次数', reaonly='True')
+ offline_time = fields.Char('关机时长(小时)', readonly='True')
+ idle_nums = fields.Integer('待机次数', readonly='True')
# 待机时长
- idle_time = fields.Char('待机时长(小时)', reaonly='True')
+ idle_time = fields.Char('待机时长(小时)', readonly='True')
# 待机率
- idle_rate = fields.Char('待机率(%)', reaonly='True')
+ idle_rate = fields.Char('待机率(%)', readonly='True')
- work_time = fields.Char('加工时长(小时)', reaonly='True')
- work_rate = fields.Char('可用率(%)', reaonly='True')
- fault_time = fields.Char('故障时长(小时)', reaonly='True')
- fault_rate = fields.Char('故障率(%)', reaonly='True')
- fault_nums = fields.Integer('故障次数', reaonly='True')
+ work_time = fields.Char('加工时长(小时)', readonly='True')
+ work_rate = fields.Char('可用率(%)', readonly='True')
+ fault_time = fields.Char('故障时长(小时)', readonly='True')
+ fault_rate = fields.Char('故障率(%)', readonly='True')
+ fault_nums = fields.Integer('故障次数', readonly='True')
# 设备故障日志
sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_oee_id', '设备故障日志',
@@ -367,25 +367,25 @@ class SfMaintenanceEquipmentOEELog(models.Model):
[("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")],
default="", string="功能类型")
machine_tool_picture = fields.Binary('设备图片')
- type_id = fields.Many2one('sf.machine_tool.type', '品牌型号', reaonly='True')
+ type_id = fields.Many2one('sf.machine_tool.type', '品牌型号', readonly='True')
state = fields.Selection([("加工", "加工"), ("关机", "关机"), ("待机", "待机"), ("故障", "故障"),
("检修", "检修"), ("保养", "保养")], default="", string="实时状态")
- online_time = fields.Char('开机时长', reaonly='True')
+ online_time = fields.Char('开机时长', readonly='True')
- offline_time = fields.Char('关机时长', reaonly='True')
- offline_nums = fields.Integer('关机次数', reaonly='True')
+ offline_time = fields.Char('关机时长', readonly='True')
+ offline_nums = fields.Integer('关机次数', readonly='True')
# 待机时长
- idle_time = fields.Char('待机时长', reaonly='True')
+ idle_time = fields.Char('待机时长', readonly='True')
# 待机率
- idle_rate = fields.Char('待机率', reaonly='True')
+ idle_rate = fields.Char('待机率', readonly='True')
- work_time = fields.Char('加工时长', reaonly='True')
- work_rate = fields.Char('可用率', reaonly='True')
- fault_time = fields.Char('故障时长', reaonly='True')
- fault_rate = fields.Char('故障率', reaonly='True')
- fault_nums = fields.Integer('故障次数', reaonly='True')
+ work_time = fields.Char('加工时长', readonly='True')
+ work_rate = fields.Char('可用率', readonly='True')
+ fault_time = fields.Char('故障时长', readonly='True')
+ fault_rate = fields.Char('故障率', readonly='True')
+ fault_nums = fields.Integer('故障次数', readonly='True')
detail_ids = fields.One2many('maintenance.equipment.oee.log.detail', 'log_id', string='日志详情')
diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py
index 71f4027a..5106dcb1 100644
--- a/sf_manufacturing/__manifest__.py
+++ b/sf_manufacturing/__manifest__.py
@@ -10,7 +10,7 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
- 'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse'],
+ 'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse','jikimo_attachment_viewer'],
'data': [
'data/stock_data.xml',
'data/empty_racks_data.xml',
@@ -29,6 +29,7 @@
'views/production_line_view.xml',
'views/mrp_workcenter_views.xml',
'views/mrp_workorder_view.xml',
+ 'views/stock_picking_view.xml',
'views/model_type_view.xml',
'views/agv_setting_views.xml',
'views/sf_maintenance_equipment.xml',
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 573bb73f..571971bc 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -141,12 +141,12 @@ class MrpProduction(models.Model):
], string='工序状态', default='待装夹')
# 零件图号
- part_number = fields.Char('零件图号', readonly=True)
+ part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True)
# 上传零件图纸
- part_drawing = fields.Binary('零件图纸', readonly=True)
+ part_drawing = fields.Binary('零件图纸', related='product_id.machining_drawings', readonly=True)
- quality_standard = fields.Binary('质检标准', readonly=True)
+ quality_standard = fields.Binary('质检标准', related='product_id.quality_standard', readonly=True)
@api.depends('product_id.manual_quotation')
def _compute_manual_quotation(self):
@@ -806,6 +806,8 @@ class MrpProduction(models.Model):
'date_to': date_planned_end,
})
# work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end})
+ # 设置一个较大的结束时间,防止在设置开始时间时,结束时间小于开始时间
+ work.date_planned_finished = datetime.datetime.today() + datetime.timedelta(days=100)
work.date_planned_start = date_planned_start
work.date_planned_finished = date_planned_end
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index d2613b9a..37d42b42 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -306,6 +306,7 @@ class ResMrpWorkOrder(models.Model):
is_delivery = fields.Boolean('是否配送完成', default=False)
rfid_code = fields.Char('RFID码')
rfid_code_old = fields.Char('RFID码(已解除)')
+ is_test_env = fields.Boolean('测试环境', default=False)
production_line_id = fields.Many2one('sf.production.line', related='production_id.production_line_id',
string='生产线', store=True, tracking=True)
@@ -321,6 +322,9 @@ class ResMrpWorkOrder(models.Model):
detailed_reason = fields.Text('详细原因')
is_rework = fields.Boolean(string='是否返工', default=False)
+ def button_change_env(self):
+ self.is_test_env = not self.is_test_env
+
@api.constrains('blocked_by_workorder_ids')
def _check_no_cyclic_dependencies(self):
if self.production_id.state not in ['rework'] and self.state not in ['rework']:
diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py
index 0b512c36..71aa05f8 100644
--- a/sf_manufacturing/models/product_template.py
+++ b/sf_manufacturing/models/product_template.py
@@ -141,11 +141,11 @@ class ResProductMo(models.Model):
cutting_tool_coarse_medium_fine = fields.Selection(related='cutting_tool_model_id.integral_coarse_medium_fine', string='粗/中/精')
# cutting_tool_model_id.integral_coarse_medium_fine
# cutting_tool_run_out_accuracy_max = fields.Float('端跳精度max', digits=(6, 1))
- cutting_tool_run_out_accuracy_max = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_max', string='端跳精度max', digits=(6, 1))
+ cutting_tool_run_out_accuracy_max = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_max', string='端跳精度max')
# cutting_tool_model_id.integral_run_out_accuracy_max
# cutting_tool_run_out_accuracy_min = fields.Float('端跳精度min', digits=(6, 1))
cutting_tool_run_out_accuracy_min = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_min',
- string='端跳精度min', digits=(6, 1))
+ string='端跳精度min')
# cutting_tool_model_id.integral_run_out_accuracy_min
# cutting_tool_blade_tip_working_size = fields.Char('刀尖倒角度(°)', size=20)
cutting_tool_blade_tip_working_size = fields.Char(related='specification_id.blade_tip_working_size',
@@ -777,8 +777,6 @@ class ResProductMo(models.Model):
part_number = fields.Char(string='零件图号', readonly=True)
machining_drawings = fields.Binary('2D加工图纸', readonly=True)
quality_standard = fields.Binary('质检标准', readonly=True)
- machining_drawings_name = fields.Char('2D加工图纸名', readonly=True)
- quality_standard_name = fields.Char('质检标准名', readonly=True)
@api.constrains('tool_length')
def _check_tool_length_size(self):
@@ -840,10 +838,10 @@ class ResProductMo(models.Model):
else:
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
- def attachment_update(self, name, res_id, res_field):
+ def attachment_update(self, name, res_id, res_field, mimetype):
attachment_info = self.env['ir.attachment'].sudo().search(
[('res_id', '=', res_id), ('res_field', '=', res_field)], limit=1)
- attachment_info.write({'name': name})
+ attachment_info.write({'name': name, 'mimetype': mimetype})
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
def product_create(self, product_id, item, order_id, order_number, i):
@@ -883,8 +881,6 @@ class ResProductMo(models.Model):
'manual_quotation': item['manual_quotation'] or False,
'part_number': item.get('part_number') or '',
'active': True,
- 'machining_drawings_name': item['machining_drawings_name'],
- 'quality_standard_name': item['quality_standard_name'],
'machining_drawings': '' if not item['machining_drawings'] else base64.b64decode(
item['machining_drawings']),
'quality_standard': '' if not item['quality_standard'] else base64.b64decode(item['quality_standard']),
@@ -895,12 +891,12 @@ class ResProductMo(models.Model):
vals.update({'taxes_id': [(6, 0, [int(tax_id)])]})
copy_product_id.sudo().write(vals)
product_id.product_tmpl_id.active = False
- if item['machining_drawings'] and item['machining_drawings_name']:
+ if item['machining_drawings'] and item['machining_drawings_name'] and item['machining_drawings_mimetype']:
self.attachment_update(item['machining_drawings_name'], copy_product_id.product_tmpl_id.id,
- 'machining_drawings')
- if item['quality_standard'] and item['quality_standard_name']:
+ 'machining_drawings', item['machining_drawings_mimetype'])
+ if item['quality_standard'] and item['quality_standard_name'] and item['quality_standard_mimetype']:
self.attachment_update(item['quality_standard_name'], copy_product_id.product_tmpl_id.id,
- 'quality_standard')
+ 'quality_standard', item['quality_standard_mimetype'])
return copy_product_id
def _get_ids(self, param):
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 02161b4a..fb678fd3 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -272,21 +272,6 @@ class StockRule(models.Model):
workorder_duration += workorder.duration_expected
sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
- # 根据销售订单号查询快速订单
- quick_easy_order = self.env['quick.easy.order'].sudo().search([('sale_order_id', '=', sale_order.id)])
- if quick_easy_order:
- production.write({'part_number': quick_easy_order.part_drawing_number,
- 'part_drawing': quick_easy_order.machining_drawings})
- else:
- production.write({'part_number': production.product_id.part_number,
- 'part_drawing': production.product_id.machining_drawings,
- 'quality_standard': production.product_id.quality_standard})
- if production.product_id.machining_drawings and production.product_id.machining_drawings_name:
- self.attachment_update(production.product_id.machining_drawings_name, production.id,
- 'part_drawing')
- if production.product_id.quality_standard and production.product_id.quality_standard_name:
- self.attachment_update(production.product_id.quality_standard_name, production.id,
- 'quality_standard')
if sale_order:
# sale_order.write({'schedule_status': 'to schedule'})
self.env['sf.production.plan'].sudo().with_company(company_id).create({
@@ -563,6 +548,35 @@ class StockPicking(models.Model):
_inherit = 'stock.picking'
surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数")
+ person_of_delivery = fields.Char('收货人', compute='_compute_origin', store=True)
+ telephone_of_delivery = fields.Char('电话号码', compute='_compute_origin', store=True)
+ address_of_delivery = fields.Char('联系地址', compute='_compute_origin')
+
+ retrospect_ref = fields.Char('追溯参考', compute='_compute_origin', store=True)
+
+ @api.depends('origin')
+ def _compute_origin(self):
+ """
+ 计算带料入库单对应销售单
+ """
+ for item in self:
+ if item.picking_type_id.sequence_code == 'DL' and item.origin:
+ if 'WH/IN/' in item.origin:
+ picking_id = self.env['stock.picking'].search([('name', '=', item.origin)])
+ if picking_id and picking_id.origin:
+ purchase_id = self.env['purchase.order'].sudo().search([('name', '=', picking_id.origin)])
+ if purchase_id and purchase_id.origin:
+ sale_id = self.env['sale.order'].sudo().search([('name', '=', purchase_id.origin)])
+ item.person_of_delivery = sale_id.person_of_delivery
+ item.telephone_of_delivery = sale_id.telephone_of_delivery
+ item.address_of_delivery = sale_id.address_of_delivery
+
+ bom = self.env['mrp.bom'].sudo().search([('bom_line_ids.product_id', '=', self.move_ids.product_id.id)])
+ if bom:
+ if item.picking_type_id.sequence_code == 'DL':
+ item.retrospect_ref = bom.product_tmpl_id.default_code
+ elif item.picking_type_id.sequence_code in ['INT', 'PC']:
+ item.retrospect_ref = bom.product_tmpl_id.name
# 设置外协出入单的名称
def _get_name_Res(self, rescode):
@@ -756,6 +770,8 @@ class ReStockMove(models.Model):
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
elif self.product_id.tracking == "lot":
self._put_tool_lot(self.company_id, self.product_id, self.origin)
+ if not self.move_line_nosuggest_ids:
+ self._generate_serial_numbers()
return {
'name': _('Detailed Operations'),
diff --git a/sf_manufacturing/security/group_security.xml b/sf_manufacturing/security/group_security.xml
index fdbc3ae5..040e7b92 100644
--- a/sf_manufacturing/security/group_security.xml
+++ b/sf_manufacturing/security/group_security.xml
@@ -1,5 +1,9 @@
-
-
+
+
+ 演示模式
+
+
-
\ No newline at end of file
+
+
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index 76c7ff4d..bb06fa04 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -197,7 +197,7 @@
-
+
+
+
+
+
+
+
+
diff --git a/sf_manufacturing/views/stock_picking_view.xml b/sf_manufacturing/views/stock_picking_view.xml
index 13bb12c2..356059c2 100644
--- a/sf_manufacturing/views/stock_picking_view.xml
+++ b/sf_manufacturing/views/stock_picking_view.xml
@@ -1,22 +1,51 @@
-
- stock.move.operations.form.inherit.sf
- stock.move
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
stock.picking.form.inherit.sf
stock.picking
+
+
+
+
+
+
+
+
+
+
+ sf.vpicktree.1
+ stock.picking
+
+
+
+
+
+
+
+
+
+ stock.picking.search
+ stock.picking
+
+
+
+
+
diff --git a/sf_message/models/sf_message_sale.py b/sf_message/models/sf_message_sale.py
index 91be525e..58d1a021 100644
--- a/sf_message/models/sf_message_sale.py
+++ b/sf_message/models/sf_message_sale.py
@@ -34,18 +34,19 @@ class SFMessageSale(models.Model):
picking_id.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id).ids
purchase_order_id.extend(purchase_order_ids)
if purchase_order_id:
- purchase_order_list = self.env['purchase.order'].search([('id', 'in', purchase_order_id)])
+ purchase_order_list = self.env['purchase.order'].sudo().search([('id', 'in', purchase_order_id)])
for purchase_order_info in purchase_order_list:
purchase_order_info.add_queue('坯料采购提醒')
except Exception as e:
logging.info('add_queue error:%s' % e)
+ logging.info('action_confirm res:%s' % res)
return res
# 继承并重写jikimo.message.dispatch的_get_message()
def _get_message(self, message_queue_ids):
contents = []
bussiness_node = None
- url = self.env['ir.config_parameter'].get_param('web.base.url')
+ url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
current_time_strf = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_strf)
current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
@@ -60,7 +61,7 @@ class SFMessageSale(models.Model):
contents.append(content)
elif item.message_template_id.bussiness_node_id.name == '确认接单':
content = super(SFMessageSale, self)._get_message(item)
- sale_order_line = self.env['sale.order.line'].search([('order_id', '=', int(item.res_id))])
+ sale_order_line = self.env['sale.order.line'].sudo().search([('order_id', '=', int(item.res_id))])
product = sale_order_line[0].product_id.name if len(sale_order_line) == 1 else '%s...' % \
sale_order_line[
0].product_id.name
@@ -112,7 +113,7 @@ class SFMessageSale(models.Model):
sale_order = self.sudo().search(
[('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False), ('delivery_status', '!=', 'full')])
for item in sale_order:
- production = self.env['mrp.production'].search([('origin', '=', item.name)])
+ production = self.env['mrp.production'].sudo().search([('origin', '=', item.name)])
production_not_done = production.filtered(lambda p: p.state not in ['done', 'scrap', 'cancel'])
production_done_count = len(production.filtered(lambda p: p.state in ['done', 'scrap', 'cancel']))
deadline_of_delivery = item.deadline_of_delivery.strftime("%Y-%m-%d")
@@ -153,11 +154,11 @@ class SFMessageSale(models.Model):
for wo in overdue_orders:
business_node_id = business_node_ids.get(wo.delivery_warning)
if business_node_id:
- message_template = self.env["jikimo.message.template"].search([
+ message_template = self.env["jikimo.message.template"].sudo().search([
("model", "=", self._name),
("bussiness_node_id", "=", business_node_id)
], limit=1)
- sale_order_has = self.env['jikimo.message.queue'].search([
+ sale_order_has = self.env['jikimo.message.queue'].sudo().search([
('res_id', '=', wo.id),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template.id)
diff --git a/sf_message/models/sf_message_stock_picking.py b/sf_message/models/sf_message_stock_picking.py
index 9d7c7f0e..6e80c670 100644
--- a/sf_message/models/sf_message_stock_picking.py
+++ b/sf_message/models/sf_message_stock_picking.py
@@ -29,14 +29,14 @@ class SFMessageStockPicking(models.Model):
[('origin', '=', record.origin), ('state', '!=', 'done'),
('picking_type_id.sequence_code', '=', 'SFP')])
if not stock_picking_sfp:
- stock_picking_send = self.env["jikimo.message.queue"].search([('res_id', '=', record.id)])
+ stock_picking_send = self.env["jikimo.message.queue"].sudo().search([('res_id', '=', record.id)])
if not stock_picking_send:
record.add_queue('订单发货提醒')
def deal_stock_picking_sfp(self, message_queue_id): # 处理订单发货提醒
content = None
- stock_picking = self.env['stock.picking'].search([('id', '=', int(message_queue_id.res_id))])
- stock_picking_out = self.env['stock.picking'].search(
+ stock_picking = self.env['stock.picking'].sudo().search([('id', '=', int(message_queue_id.res_id))])
+ stock_picking_out = self.env['stock.picking'].sudo().search(
[('origin', '=', stock_picking.origin), ('state', '=', 'assigned'),
('picking_type_id.sequence_code', '=', 'OUT')])
if stock_picking_out and len(stock_picking_out) > 0:
@@ -54,10 +54,10 @@ class SFMessageStockPicking(models.Model):
i = 0
if message_queue_id.message_template_id.name == '坯料发料提醒':
content = message_queue_id.message_template_id.content
- stock_picking_line = self.env['stock.picking'].search([('id', '=', int(message_queue_id.res_id))])
- mrp_production_info = self.env['mrp.production'].search(
+ stock_picking_line = self.env['stock.picking'].sudo().search([('id', '=', int(message_queue_id.res_id))])
+ mrp_production_info = self.env['mrp.production'].sudo().search(
[('name', '=', stock_picking_line.origin)])
- mrp_production_list = self.env['mrp.production'].search(
+ mrp_production_list = self.env['mrp.production'].sudo().search(
[('product_id', '=', mrp_production_info.product_id.id)])
for mrp_production_line in mrp_production_list:
picking_ids = mrp_production_line.picking_ids
@@ -87,9 +87,9 @@ class SFMessageStockPicking(models.Model):
return super(SFMessageStockPicking, self).get_special_url(id, tmplate_name, special_name, model_id)
def request_url(self):
- url = self.env['ir.config_parameter'].get_param('web.base.url')
+ url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
action_id = self.env.ref('stock.stock_picking_type_action').id
- menu_id = self.env['ir.model.data'].search([('name', '=', 'module_theme_treehouse')]).id
+ menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_theme_treehouse')]).id
# 查询参数
params = {'menu_id': menu_id, 'action': action_id, 'model': 'stock.picking',
'view_type': 'kanban'}
@@ -100,9 +100,9 @@ class SFMessageStockPicking(models.Model):
return full_url
def request_url1(self, id):
- url = self.env['ir.config_parameter'].get_param('web.base.url')
+ url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
action_id = self.env.ref('stock.action_picking_tree_all').id
- menu_id = self.env['ir.model.data'].search([('name', '=', 'module_theme_treehouse')]).id
+ menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_theme_treehouse')]).id
# 查询参数
params = {'id': id, 'menu_id': menu_id, 'action': action_id, 'model': 'stock.picking',
'view_type': 'form'}
diff --git a/sf_message/models/sf_message_workorder.py b/sf_message/models/sf_message_workorder.py
index 6d1cff77..d5186797 100644
--- a/sf_message/models/sf_message_workorder.py
+++ b/sf_message/models/sf_message_workorder.py
@@ -26,7 +26,7 @@ class SFMessageWork(models.Model):
contents = []
product_id = []
bussiness_node = None
- url = self.env['ir.config_parameter'].get_param('web.base.url')
+ url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
current_time_strf = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_strf)
current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
@@ -39,8 +39,8 @@ class SFMessageWork(models.Model):
for message_queue_id in message_queue_ids:
if message_queue_id.message_template_id.name == '工单已下发通知':
content = message_queue_id.message_template_id.content
- mrp_workorder_line = self.env['mrp.workorder'].search([('id', '=', int(message_queue_id.res_id))])
- mrp_workorder_list = self.env['mrp.workorder'].search(
+ mrp_workorder_line = self.env['mrp.workorder'].sudo().search([('id', '=', int(message_queue_id.res_id))])
+ mrp_workorder_list = self.env['mrp.workorder'].sudo().search(
[('product_id', '=', mrp_workorder_line.product_id.id), ('state', '=', 'ready'),
('routing_type', '=', '装夹预调')])
if len(mrp_workorder_list) > 0 and mrp_workorder_line.product_id.id not in product_id:
@@ -96,10 +96,10 @@ class SFMessageWork(models.Model):
return contents
def request_url(self):
- url = self.env['ir.config_parameter'].get_param('web.base.url')
+ url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
action_id = self.env.ref('sf_message.mrp_workorder_issued_action').id
- menu_id = self.env['ir.model.data'].search([('name', '=', 'module_stock_dropshipping')]).id
- active_id = self.env['mrp.workcenter'].search([('name', '=', '工件装夹中心')]).id
+ menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_stock_dropshipping')]).id
+ active_id = self.env['mrp.workcenter'].sudo().search([('name', '=', '工件装夹中心')]).id
# 查询参数
params = {'menu_id': menu_id, 'action': action_id, 'model': 'mrp.workorder',
'view_type': 'list', 'active_id': active_id}
diff --git a/sf_message/security/ir.model.access.csv b/sf_message/security/ir.model.access.csv
index 05a7366c..4aa153e6 100644
--- a/sf_message/security/ir.model.access.csv
+++ b/sf_message/security/ir.model.access.csv
@@ -5,24 +5,28 @@ access_jikimo_message_template_group_purchase,jikimo_message_template,jikimo_mes
access_jikimo_message_template_group_sf_stock_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_template_group_sf_order_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_template_group_sf_tool_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_tool_user,1,1,1,0
+access_jikimo_message_template_group_purchase_director,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_bussiness_node_group_sale_salemanager,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_bussiness_node_group_purchase,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_purchase,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_stock_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_order_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_tool_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_tool_user,1,1,1,0
+access_jikimo_message_bussiness_node_group_purchase_director,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_queue_group_sale_salemanager,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_queue_group_purchase,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_purchase,1,1,1,0
access_jikimo_message_queue_group_sf_stock_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_queue_group_sf_order_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_queue_group_sf_tool_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_tool_user,1,1,1,0
+access_jikimo_message_queue_group_purchase_director,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_reminder_time_group_sale_salemanager,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_reminder_time_group_purchase,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_purchase,1,1,1,0
access_jikimo_message_reminder_time_group_sf_stock_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_reminder_time_group_sf_order_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_reminder_time_group_sf_tool_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_tool_user,1,1,1,0
+access_jikimo_message_reminder_time_group_purchase_director,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_purchase_director,1,1,1,0
diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py
index 492ef525..bdf916ce 100644
--- a/sf_plan/models/custom_plan.py
+++ b/sf_plan/models/custom_plan.py
@@ -246,26 +246,27 @@ class sf_production_plan(models.Model):
record.date_planned_finished = item.date_planned_finished
# 计算下一个cnc工单的开始时间
last_cnc_start = workorder_list[-1].date_planned_finished + timedelta(minutes=pre_duration)
- record.state = 'done'
- # record.production_id.schedule_state = '已排'
- record.sudo().production_id.schedule_state = '已排'
- record.sudo().production_id.process_state = '待装夹'
- # self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
- # sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
- # if 'S' in sale_obj.name:
- # sale_obj.schedule_status = 'to process'
- mrp_production_ids = record.production_id._get_children().ids
- print('mrp_production_ids', mrp_production_ids)
- for i in mrp_production_ids:
- record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
- # record.production_id.date_planned_start = record.date_planned_start
- # record.production_id.date_planned_finished = record.date_planned_finished
- record.sudo().production_id.production_line_id = record.production_line_id.id
- if record.production_id.workorder_ids:
- record.sudo().production_id.workorder_ids.filtered(
- lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
- {'production_line_id': record.production_line_id.id,
- 'plan_start_processing_time': record.date_planned_start})
+ # 没有工单也能排程
+ record.state = 'done'
+ # record.production_id.schedule_state = '已排'
+ record.sudo().production_id.schedule_state = '已排'
+ record.sudo().production_id.process_state = '待装夹'
+ # self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
+ # sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
+ # if 'S' in sale_obj.name:
+ # sale_obj.schedule_status = 'to process'
+ mrp_production_ids = record.production_id._get_children().ids
+ print('mrp_production_ids', mrp_production_ids)
+ for i in mrp_production_ids:
+ record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
+ # record.production_id.date_planned_start = record.date_planned_start
+ # record.production_id.date_planned_finished = record.date_planned_finished
+ record.sudo().production_id.production_line_id = record.production_line_id.id
+ if record.production_id.workorder_ids:
+ record.sudo().production_id.workorder_ids.filtered(
+ lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
+ {'production_line_id': record.production_line_id.id,
+ 'plan_start_processing_time': record.date_planned_start})
# record.date_planned_finished = record.date_planned_start + timedelta(days=3)
# record.state = 'done'
diff --git a/sf_plan/wizard/action_plan_some.py b/sf_plan/wizard/action_plan_some.py
index 1c08ff0f..86b3f1ac 100644
--- a/sf_plan/wizard/action_plan_some.py
+++ b/sf_plan/wizard/action_plan_some.py
@@ -37,52 +37,4 @@ class Action_Plan_All_Wizard(models.TransientModel):
# 判断能否排成
self.plan_ids.deal_processing_schedule(self.date_planned_start)
self.plan_ids.do_production_schedule()
- # for plan in temp_plan_ids:
- # # 处理每个计划
- # # 比如更新计划状态、分配资源等
- # # 示例:plan.state = 'scheduled'
- # print('处理计划:', plan.id)
- # # 拿到计划对象
- # plan_obj = self.env['sf.production.plan'].browse(plan.id)
- # plan_obj.production_line_id = self.production_line_id.id
- # plan.date_planned_start = self.date_planned_start
- # plan_obj.do_production_schedule()
- # plan_obj.state = 'done'
_logger.info('处理计划: %s 完成', self.plan_ids.ids)
-
- # # 获取当前生产线
- # production_line_id = self.production_line_id
- # # 获取当前生产线的所有生产订单
- # production_order_ids = self.env['mrp.production'].search([('production_line_id', '=', production_line_id.id)])
- # # 获取当前生产线的所有生产订单的id
- # production_order_id_list = []
- # for production_order_id in production_order_ids:
- # production_order_id_list.append(production_order_id.id)
- # # 获取当前生产线的所有生产订单的排程状态
- # production_order_plan_state_list = []
- # for production_order_id in production_order_ids:
- # production_order_plan_state_list.append(production_order_id.plan_state)
- # # 如果当前生产线的所有生产订单的排程状态都是已排程,则报错
- # if all(production_order_plan_state == '已排程' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已排程,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是未排程,则报错
- # if all(production_order_plan_state == '未排程' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都未排程,请先排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已完成,则报错
- # if all(production_order_plan_state == '已完成' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已完成,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已取消,则报错
- # if all(production_order_plan_state == '已取消' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已取消,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已暂停,则报错
- # if all(production_order_plan_state == '已暂停' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已暂停,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已完成,则报错
- # if all(production_order_plan_state == '已完成' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已完成,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已取消,则报错
- # if all(production_order_plan_state == '已取消' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已取消,请勿重复排程!')
- # # 如果当前生产线的所有生产订单的排程状态都是已暂停,则报错
- # if all(production_order_plan_state == '已暂停' for production_order_plan_state in production_order_plan_state_list):
- # raise UserError('当前生产线的所有生产订单都已暂停,请勿重复排程!')
diff --git a/sf_quality/__manifest__.py b/sf_quality/__manifest__.py
index b1151b6d..582e306a 100644
--- a/sf_quality/__manifest__.py
+++ b/sf_quality/__manifest__.py
@@ -13,7 +13,7 @@
'author': 'jikimo',
'website': 'https://sf.cs.jikimo.com',
# 此处依赖sf_manufacturing是因为我要重写其中的一个字段operation_id的string,故需要sf_manufacturing先安装
- 'depends': ['quality_control', 'web_widget_model_viewer', 'sf_manufacturing'],
+ 'depends': ['quality_control', 'web_widget_model_viewer', 'sf_manufacturing','jikimo_attachment_viewer'],
'data': [
'security/ir.model.access.csv',
'views/view.xml',
diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py
index 1c62b782..e974c5d4 100644
--- a/sf_sale/models/quick_easy_order_old.py
+++ b/sf_sale/models/quick_easy_order_old.py
@@ -220,7 +220,14 @@ class QuickEasyOrder(models.Model):
'total_amount': item.price,
'remark': '',
'manual_quotation': True,
- 'barcode': barcode
+ 'barcode': barcode,
+ 'part_number': item.part_drawing_number,
+ 'machining_drawings_name': '',
+ 'quality_standard_name': '',
+ 'machining_drawings_mimetype': '',
+ 'quality_standard_mimetype': '',
+ 'machining_drawings': item.machining_drawings,
+ 'quality_standard': '',
})
# res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
product_id = self.env.ref('sf_dlm.product_template_sf').sudo()
diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py
index acd1d60c..bc34c134 100644
--- a/sf_sale/models/sale_order.py
+++ b/sf_sale/models/sale_order.py
@@ -32,9 +32,9 @@ class ReSaleOrder(models.Model):
tracking=3,
default='draft')
deadline_of_delivery = fields.Date('订单交期', tracking=True)
- person_of_delivery = fields.Char('交货人')
- telephone_of_delivery = fields.Char('交货人电话号码')
- address_of_delivery = fields.Char('交货人地址')
+ person_of_delivery = fields.Char('收货人')
+ telephone_of_delivery = fields.Char('电话号码')
+ address_of_delivery = fields.Char('联系地址')
payments_way = fields.Selection([('现结', '现结'), ('月结', '月结')], '结算方式', default='现结', tracking=True)
pay_way = fields.Selection([('转账', '转账'), ('微信', '微信'), ('支付宝', '支付宝')], '支付方式')
check_status = fields.Selection([('pending', '待审核'), ('approved', '已审核'), ('fail', '不通过')], '审核状态')
@@ -118,12 +118,16 @@ class ReSaleOrder(models.Model):
# 业务平台分配工厂时在创建完产品后再创建销售明细信息
def sale_order_create_line(self, product, item):
+ machining_accuracy_name = ''
+ if product.model_machining_precision:
+ machining_accuracy_name = self.env['sf.machining.accuracy'].sudo().search(
+ [('sync_id', '=', product.model_machining_precision)]).name
vals = {
'order_id': self.id,
'product_id': product.id,
- 'name': '%s/%s/%s/%s/±%s/%s' % (
+ 'name': '%s/%s/%s/%s/%s/%s' % (
product.model_long, product.model_width, product.model_height, product.model_volume,
- product.model_machining_precision,
+ machining_accuracy_name,
product.materials_id.name),
'price_unit': product.list_price,
'product_uom_qty': item['number'],
@@ -204,6 +208,8 @@ class RePurchaseOrder(models.Model):
compute='_compute_user_id',
store=True)
+ purchase_type = fields.Selection([('standard', '标准采购'), ('consignment', '委外加工')], string='采购类型', default='standard')
+
@api.depends('partner_id')
def _compute_user_id(self):
if not self.user_id:
diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml
index f721d515..0a66287f 100644
--- a/sf_sale/views/purchase_order_view.xml
+++ b/sf_sale/views/purchase_order_view.xml
@@ -158,6 +158,11 @@
{'readonly': [('state', 'in', ['purchase'])]}
+
+
+
+
+
diff --git a/sf_sale/views/quick_easy_order_view.xml b/sf_sale/views/quick_easy_order_view.xml
index 9111403d..aebb4e97 100644
--- a/sf_sale/views/quick_easy_order_view.xml
+++ b/sf_sale/views/quick_easy_order_view.xml
@@ -80,8 +80,8 @@
-
-
+
+
diff --git a/sf_sale/views/sale_order_view.xml b/sf_sale/views/sale_order_view.xml
index a84a2b44..16ae9c4c 100644
--- a/sf_sale/views/sale_order_view.xml
+++ b/sf_sale/views/sale_order_view.xml
@@ -96,8 +96,8 @@
-
-
+
+
@@ -181,17 +181,27 @@
下单日期
-
-
-
+
+ view_order_form_inherit_sale_stock.sf
+ sale.order
+
+
+
+
+
+
+
+
+
+
sale.order.quotation.tree.inherit.sf
sale.order
diff --git a/sf_tool_management/models/mrp_workorder.py b/sf_tool_management/models/mrp_workorder.py
index 267dbe60..8fe9748e 100644
--- a/sf_tool_management/models/mrp_workorder.py
+++ b/sf_tool_management/models/mrp_workorder.py
@@ -200,6 +200,8 @@ class MrpProduction(models.Model):
self[0].write({'is_rework': False})
# 修改制造订单 编程状态变为“编程中” 制造订单状态为‘返工’
self.write({'programming_state': '编程中', 'work_state': '编程中', 'state': 'rework'})
+ self[0].workorder_ids.filtered(
+ lambda a: a.name == '装夹预调' and a.state not in ['rework', 'done', 'cancel'])._compute_state()
if missing_tool_1:
logging.info(f'线边、机内缺刀:{missing_tool_1}')
# 修改 修改cnc程序的‘刀具状态’ 为 ‘缺刀’
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 371e4a54..341ec60f 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -1119,6 +1119,8 @@ class SfPickingType(models.Model):
action = super(SfPickingType, self)._get_action(action_xmlid)
if not self.env.user.has_group('base.group_system'):
action['context']['create'] = False
+ if self.sequence_code in ['DL', 'INT', 'PC']:
+ action['context']['search_default_retrospect_ref'] = 1
return action