diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py
index bcb25c81..5f4c6906 100644
--- a/sf_base/__manifest__.py
+++ b/sf_base/__manifest__.py
@@ -18,6 +18,7 @@
'views/common_view.xml',
'views/fixture_view.xml',
'views/functional_fixture_view.xml',
+ 'views/tool_other_features_view.xml',
'views/menu_view.xml',
"views/tool_views.xml",
"views/tool_menu.xml",
diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py
index 483787eb..93961162 100644
--- a/sf_base/models/__init__.py
+++ b/sf_base/models/__init__.py
@@ -3,6 +3,7 @@ from . import common
from . import tool_base_new
from . import fixture
from . import functional_fixture
+from . import tool_other_features
diff --git a/sf_base/models/tool_other_features.py b/sf_base/models/tool_other_features.py
new file mode 100644
index 00000000..52acf25c
--- /dev/null
+++ b/sf_base/models/tool_other_features.py
@@ -0,0 +1,41 @@
+from odoo import fields, models
+
+
+class SuitableMachiningMethod(models.Model):
+ _name = 'sf.suitable.machining.method'
+ _description = '适合加工方式'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class BladeTipCharacteristics(models.Model):
+ _name = 'sf.blade.tip.characteristics'
+ _description = '刀尖特征'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class HandleType(models.Model):
+ _name = 'sf.handle.type'
+ _description = '柄部类型'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class CuttingDirection(models.Model):
+ _name = 'sf.cutting.direction'
+ _description = '走刀方向'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class SuitableCoolant(models.Model):
+ _name = 'sf.suitable.coolant'
+ _description = '适合冷却液'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
\ No newline at end of file
diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv
index 2cb14006..ba3fb3d0 100644
--- a/sf_base/security/ir.model.access.csv
+++ b/sf_base/security/ir.model.access.csv
@@ -24,6 +24,11 @@ access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,
access_sf_functional_fixture_type,sf_functional_fixture_type,model_sf_functional_fixture_type,base.group_user,1,1,1,1
access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,1
access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,1
+access_sf_suitable_machining_method,sf_suitable_machining_method,model_sf_suitable_machining_method,base.group_user,1,1,1,1
+access_sf_blade_tip_characteristics,sf_blade_tip_characteristics,model_sf_blade_tip_characteristics,base.group_user,1,1,1,1
+access_sf_handle_type,sf_handle_type,model_sf_handle_type,base.group_user,1,1,1,1
+access_sf_cutting_direction,sf_cutting_direction,model_sf_cutting_direction,base.group_user,1,1,1,1
+access_sf_suitable_coolant,sf_suitable_coolant,model_sf_suitable_coolant,base.group_user,1,1,1,1
diff --git a/sf_base/views/base_view.xml b/sf_base/views/base_view.xml
index 5c3fd3ad..8c8e1632 100644
--- a/sf_base/views/base_view.xml
+++ b/sf_base/views/base_view.xml
@@ -159,11 +159,11 @@
-
+
-
+
@@ -210,27 +210,28 @@
-
+
-
+
+
-
+
Φ
-
+
Φ
diff --git a/sf_base/views/common_view.xml b/sf_base/views/common_view.xml
index aab5cf1f..f0ff3a07 100644
--- a/sf_base/views/common_view.xml
+++ b/sf_base/views/common_view.xml
@@ -350,7 +350,7 @@
加工工艺
ir.actions.act_window
sf.processing.technology
- tree,form
+ tree
diff --git a/sf_base/views/tool_other_features_view.xml b/sf_base/views/tool_other_features_view.xml
new file mode 100644
index 00000000..e094a376
--- /dev/null
+++ b/sf_base/views/tool_other_features_view.xml
@@ -0,0 +1,101 @@
+
+
+
+
+ 适合加工方式
+ sf.suitable.machining.method
+
+
+
+
+
+
+
+
+
+ 适合加工方式
+ ir.actions.act_window
+ sf.suitable.machining.method
+ tree
+
+
+
+
+
+ 刀尖特征
+ sf.blade.tip.characteristics
+
+
+
+
+
+
+
+
+
+ 刀尖特征
+ ir.actions.act_window
+ sf.blade.tip.characteristics
+ tree
+
+
+
+
+
+ 柄部类型
+ sf.handle.type
+
+
+
+
+
+
+
+
+
+ 柄部类型
+ ir.actions.act_window
+ sf.handle.type
+ tree
+
+
+
+
+
+ 走刀方向
+ sf.cutting.direction
+
+
+
+
+
+
+
+
+
+ 走刀方向
+ ir.actions.act_window
+ sf.cutting.direction
+ tree
+
+
+
+
+
+ 适合冷却液
+ sf.suitable.coolant
+
+
+
+
+
+
+
+
+
+ 适合冷却液
+ ir.actions.act_window
+ sf.suitable.coolant
+ tree
+
+
\ No newline at end of file
diff --git a/sf_dlm/views/product_template_view.xml b/sf_dlm/views/product_template_view.xml
index 10eef5d6..bfe1e4d5 100644
--- a/sf_dlm/views/product_template_view.xml
+++ b/sf_dlm/views/product_template_view.xml
@@ -83,18 +83,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (mm)
+
+
+ (mm)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀柄'))]}"/>
+
+
+
+
@@ -111,11 +170,11 @@
options="{'format': false}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片','刀杆','刀盘'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片','刀杆','刀盘'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘','刀柄'))]}"/>
@@ -152,24 +211,24 @@
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
-
+ attrs="{'invisible': [('cutting_tool_type', 'in', ('刀柄', '整体式刀具'))]}"/>
+
+ attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 67c1f14c..b6d774a3 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -339,7 +339,7 @@ class MrpProduction(models.Model):
current_sequence += 1
if work.name == '获取CNC加工程序':
work.button_start()
- #work.fetchCNC()
+ # work.fetchCNC()
# 创建工单并进行排序
def _create_workorder(self):
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 8b95c5af..68e45759 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -7,7 +7,7 @@ from odoo.exceptions import ValidationError, UserError
import requests
import json
from re import findall as regex_findall
-from datetime import datetime
+from datetime import datetime, timedelta
from re import split as regex_split
from odoo import SUPERUSER_ID, _, api, fields, models
from odoo.tools import float_compare
@@ -154,6 +154,7 @@ class StockRule(models.Model):
'''创建制造订单'''
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
productions_values)
+
self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
'''
@@ -188,6 +189,30 @@ class StockRule(models.Model):
'mail.message_origin_link',
values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id)
+ '''
+ 创建生产计划
+ '''
+ # 工单耗时
+ workorder_duration = 0
+ for workorder in production.workorder_ids:
+ workorder_duration += workorder.duration_expected
+
+
+ sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
+ if sale_order:
+ bb = sale_order.deadline_of_delivery
+ productions = self.env['sf.production.plan'].with_user(SUPERUSER_ID).sudo().with_company(company_id).\
+ create({
+ 'name': production.name,
+ 'production_id': production.id,
+ 'date_planned_start': production.date_planned_start,
+ 'origin': production.origin,
+ 'product_qty': production.product_qty,
+ 'product_id': production.product_id.id,
+ 'state': 'draft',
+ })
+
+
return True
@@ -472,3 +497,22 @@ class ReStockMove(models.Model):
item.product_id.write({'register_state': '注册失败'})
except Exception as e:
raise UserError("注册刀具到云端失败,请联系管理员!")
+
+
+class ReStockQuant(models.Model):
+ _inherit = 'stock.quant'
+
+ def action_apply_inventory(self):
+ inventory_diff_quantity = self.inventory_diff_quantity
+ super(ReStockQuant, self).action_apply_inventory()
+ if inventory_diff_quantity >= 1:
+ stock = self.env['stock.move'].search([('product_id', '=', self.product_id.id), ('is_inventory', '=', True),
+ ('reference', '=', '更新的产品数量'), ('state', '=', 'done')],
+ limit=1, order='id desc')
+ if self.product_id.categ_type == '夹具':
+ stock._register_fixture()
+ elif self.product_id.categ_type == '刀具':
+ stock._register_cutting_tool()
+ return True
+
+
diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml
index 716cdb76..b326f288 100644
--- a/sf_manufacturing/views/mrp_production_addional_change.xml
+++ b/sf_manufacturing/views/mrp_production_addional_change.xml
@@ -20,8 +20,10 @@
-
-
+
+
+
+
@@ -40,7 +42,64 @@
decoration-warning="reservation_state != 'assigned' and components_availability_state in ('expected', 'available')"
decoration-danger="reservation_state != 'assigned' and components_availability_state == 'late'"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ custom.mrp.production.select
+ mrp.production
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_plan/__init__.py b/sf_plan/__init__.py
index 8134f974..23795ba3 100644
--- a/sf_plan/__init__.py
+++ b/sf_plan/__init__.py
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
+from . import controllers
diff --git a/sf_plan/__manifest__.py b/sf_plan/__manifest__.py
index 80a9d5fb..ba43169d 100644
--- a/sf_plan/__manifest__.py
+++ b/sf_plan/__manifest__.py
@@ -13,7 +13,7 @@
'author': 'jikimo',
'website': 'https://sf.cs.jikimo.com',
# 此处依赖sf_manufacturing是因为我要重写其中的一个字段operation_id的string,故需要sf_manufacturing先安装
- 'depends': ['mrp', 'mrp_workorder'],
+ 'depends': ['mrp', 'mrp_workorder', 'sf_manufacturing'],
'data': [
'security/ir.model.access.csv',
'views/view.xml'
@@ -24,7 +24,8 @@
'web.assets_qweb': [
],
'web.assets_backend': [
- 'sf_plan/static/src/scss/gannt_change.scss'
+ 'sf_plan/static/src/scss/gannt_change.scss',
+ 'sf_plan/static/src/css/button_color.css'
],
},
diff --git a/sf_plan/controllers/__init__.py b/sf_plan/controllers/__init__.py
new file mode 100644
index 00000000..6d07f482
--- /dev/null
+++ b/sf_plan/controllers/__init__.py
@@ -0,0 +1,2 @@
+from .import controllers
+
diff --git a/sf_plan/controllers/controllers.py b/sf_plan/controllers/controllers.py
new file mode 100644
index 00000000..c600d76a
--- /dev/null
+++ b/sf_plan/controllers/controllers.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+import json
+import logging
+from odoo import http
+from odoo.http import request
+
+
+class ProductionPlan(http.Controller):
+
+ @http.route('/api/production/plan', type='http', auth='none', methods=['GET', 'POST'], csrf=False,
+ cors="*")
+ def schedule_orders(self, **kw):
+ """
+ 排程订单
+ """
+ logging.info('schedule_orders', kw)
+
diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py
index b5dad842..b07614d3 100644
--- a/sf_plan/models/custom_plan.py
+++ b/sf_plan/models/custom_plan.py
@@ -1,25 +1,89 @@
# -*- coding: utf-8 -*-
+import base64
+
from odoo import models, fields, api, _
from datetime import datetime, timedelta
+from odoo.exceptions import UserError, ValidationError
+
+import json, requests, logging
-# sf坯料预制排程
-class sf_pl_plan(models.Model):
- _name = 'sf.pl.plan'
- _description = 'sf_pl_plan'
+# sf排程
+class sf_production_plan(models.Model):
+ _name = 'sf.production.plan'
+ # _inherit = 'mrp.production'
+ _description = 'sf_production_plan'
+
+ name = fields.Char(string='名称')
+ production_id = fields.Many2one('mrp.production', '关联制造订单')
+ product_qty = fields.Float(string='数量', digits='Product Unit of Measure', required=True, default=0.0)
+ date_planned_start = fields.Datetime(string='计划开始时间', required=True, index=True, copy=False,
+ default=fields.Datetime.now)
+ date_planned_finished = fields.Datetime(string='计划结束时间')
+ state = fields.Selection([
+ ('draft', '未排程'), ('done', '已排程')], string='状态', copy=False, index=True, readonly=True,
+ store=True, tracking=True)
+ product_id = fields.Many2one('product.product', '关联产品')
+ origin = fields.Char(string='来源')
- name = fields.Char(string='名称', size=64)
# 序号、坯料编号、坯料名称、材质、数量、长度、宽度、厚度、直径、计划开始时间、计划结束时间、状态(已产出与待产出)、操作、创建人、创建时间、客户名称、订单号、行号、长度、宽度、厚度、直径、交货数量、交货日期
# sequence = fields.Integer(string='序号', required=True, copy=False, readonly=True, index=True,
# default=lambda self: self.env['ir.sequence'].sudo().next_by_code('sf.pl.plan'))
- sequence = fields.Integer(string='序号', required=True, copy=False, readonly=True, index=True)
- current_operation_name = fields.Char(string='当前工序名称', size=64, default='坯料预制')
+ sequence = fields.Integer(string='序号', copy=False, readonly=True, index=True)
+ current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划')
+ production_line_id = fields.Many2one('sf.production.line', string='生产线')
+
+ # state = fields.Selection([
+ # ('未排程', '未排程'), ('已排程', '已排程')], string='State', copy=False, index=True, readonly=True,
+ # store=True, tracking=True)
+
+ # orderpoint_id = fields.Many2one('stock.warehouse.orderpoint', compute='_compute_orderpoint_id')
+ # location_src_id = fields.Many2one('stock.location', 'Components Location', compute='_compute_orderpoint_id', active=False)
+ # location_dest_id = fields.Many2one('stock.location', 'Finished Products Location', compute='_compute_orderpoint_id')
+ # picking_type_id = fields.Many2one('stock.picking.type', 'Operation Type', compute='_compute_orderpoint_id')
+ # move_dest_ids = fields.One2many('stock.move', 'created_production_id', compute='_compute_orderpoint_id')
@api.model
- def create(self, vals):
- if 'sequence' not in vals:
- vals['sequence'] = self.env['sf.pl.plan'].search_count([]) + 1
- return super().create(vals)
+ def _compute_orderpoint_id(self):
+ pass
+
+ def test_sale_order(self):
+ company_id = self.env.ref('base.main_company').sudo()
+ date = datetime.today()
+ aaa = self.env['sale.order'].with_user(self.env.ref("base.user_admin")).sale_order_create(
+ company_id, 'delivery_name', 'delivery_telephone', 'delivery_address',
+ date)
+ print('aaa', aaa)
+
+ # 当不设置计划结束时间时,增加计算计划结束时间的方法,根据采购周期加缓冲期两个值来算就可以了
+ def action_view_production_schedule(self):
+ self.ensure_one()
+ if self.date_planned_start and self.date_planned_finished:
+ return None
+ elif self.date_planned_start and not self.date_planned_finished:
+ # 如果没有给出计划结束时间,则计划结束时间为计划开始时间+采购周期+缓冲期
+ # 采购周期
+ purchase_cycle = 3
+ # 缓冲期
+ buffer_period = 1
+ # 计划结束时间 = 计划开始时间 + 采购周期 + 缓冲期
+ self.date_planned_finished = self.date_planned_start + timedelta(days=purchase_cycle) + timedelta(
+ days=buffer_period)
+ self.state = '已排程'
+ return self.date_planned_finished
+ else:
+ return None
+
+ def cancel_plan(self):
+ self.ensure_one()
+ self.date_planned_finished = None
+ self.state = 'draft'
+
+ # @api.model
+ # def create(self, vals):
+ # if 'sequence' not in vals:
+ # vals['sequence'] = self.env['sf.production.plan'].search_count([]) + 1
+ # return super().create(vals)
def unlink(self):
sequence_to_reorder = self.mapped('sequence')
@@ -31,7 +95,7 @@ class sf_pl_plan(models.Model):
# 生成编码
def _get_pl_no(self):
- sf_pl_no = self.env['sf.pl.plan'].sudo().search(
+ sf_pl_no = self.env['sf.production.plan'].sudo().search(
[('pl_no', '!=', '')],
limit=1,
order="id desc")
@@ -55,81 +119,150 @@ class sf_pl_plan(models.Model):
return num
- pl_no = fields.Char(string='坯料编号', required=True, default=_get_pl_no, readonly=True)
- pl_name = fields.Char(string='坯料名称', size=64, required=True)
- material = fields.Many2one('sf.production.materials', string='材质', required=True)
- quantity = fields.Float(string='数量', required=True)
- length = fields.Float(string='长度', required=True)
- width = fields.Float(string='宽度', required=True)
- thickness = fields.Float(string='厚度', required=True)
- diameter = fields.Float(string='直径', required=True)
- plan_start_time = fields.Datetime(string='计划开始时间')
- plan_end_time = fields.Datetime(string='计划结束时间')
- state = fields.Selection([
- ('draft', '待产出'),
- ('produce', '已产出'),
- ], string='状态', copy=False, index=True, default='draft')
- customer_name = fields.Char(string='客户名称', size=64)
- order_no = fields.Char(string='订单号', size=64)
- line_no = fields.Char(string='行号', size=64)
- delivery_length = fields.Float(string='交货长度')
- delivery_width = fields.Float(string='交货宽度')
- delivery_thickness = fields.Float(string='交货厚度')
- delivery_diameter = fields.Float(string='交货直径')
- delivery_quantity = fields.Float(string='交货数量')
- delivery_date = fields.Datetime(string='交货日期', related='plan_end_time', readonly=False, store=True)
+ # pl_no = fields.Char(string='坯料编号', required=True, default=_get_pl_no, readonly=True)
+ # pl_name = fields.Char(string='坯料名称', size=64, required=True)
+ # material = fields.Many2one('sf.production.materials', string='材质', required=True)
+ # quantity = fields.Float(string='数量', required=True)
+ # length = fields.Float(string='长度', required=True)
+ # width = fields.Float(string='宽度', required=True)
+ # thickness = fields.Float(string='厚度', required=True)
+ # diameter = fields.Float(string='直径', required=True)
+ # plan_start_time = fields.Datetime(string='计划开始时间')
+ # plan_end_time = fields.Datetime(string='计划结束时间')
+ # state = fields.Selection([
+ # ('draft', '待排程'),
+ # ('produce', '已排程'),
+ # ('done', '已产出'),
+ # ], string='状态', copy=False, index=True, default='draft')
+ # customer_name = fields.Char(string='客户名称', size=64)
+ # order_no = fields.Char(string='订单号', size=64)
+ # line_no = fields.Char(string='行号', size=64)
+ # delivery_length = fields.Float(string='交货长度')
+ # delivery_width = fields.Float(string='交货宽度')
+ # delivery_thickness = fields.Float(string='交货厚度')
+ # delivery_diameter = fields.Float(string='交货直径')
+ # delivery_quantity = fields.Float(string='交货数量')
+ # delivery_date = fields.Datetime(string='交货日期', related='plan_end_time', readonly=False, store=True)
# 当不设置计划结束时间时,增加计算计划结束时间的方法,根据采购周期加缓冲期两个值来算就可以了
- def get_plan_end_time(self):
- if self.plan_start_time and self.plan_end_time:
- return None
- elif self.plan_start_time and not self.plan_end_time:
- # 如果没有给出计划结束时间,则计划结束时间为计划开始时间+采购周期+缓冲期
- # 采购周期
- purchase_cycle = 3
- # 缓冲期
- buffer_period = 1
- # 计划结束时间 = 计划开始时间 + 采购周期 + 缓冲期
- self.plan_end_time = self.plan_start_time + timedelta(days=purchase_cycle) + timedelta(days=buffer_period)
- return self.plan_end_time
+ def do_production_schedule(self):
+ aa = self.env['mrp.production'].sudo().search([('name', '=', self.name)])
+ workorder_time = 0
+ print(aa.workorder_ids)
+ print(type(aa.workorder_ids))
+ if aa.workorder_ids:
+ for item in aa.workorder_ids:
+ current_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', item.id)])
+ workorder_time += current_workorder.duration_expected
+ print(workorder_time)
+ self.date_planned_finished = self.date_planned_start + timedelta(minutes=workorder_time)
+ self.state = 'done'
else:
- return None
- # 后面要补充计划开始时间的计算方法
- # # 坯料预制时间
- # # pl_time = 0.5
- # # 采购周期
- # purchase_cycle = 3
- # # 缓冲期
- # buffer_period = 1
- # # 计划结束时间 = 计划开始时间 + 坯料预制时间 + 采购周期 + 缓冲期
- # # plan_end_time = plan_start_time + pl_time + purchase_cycle + buffer_period
- # # 计划结束时间 = 计划开始时间(是一个datatime) + 采购周期(Float) + 缓冲期(Float)
- # self.plan_end_time = self.plan_start_time + timedelta(days=purchase_cycle) + timedelta(days=buffer_period)
- # return self.plan_end_time
+ self.date_planned_finished = self.date_planned_start + timedelta(days=3)
+ self.state = 'done'
+ return {
+ 'name': '排程甘特图',
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'sf.production.plan', # 要跳转的模型名称
+ 'view_mode': 'gantt,tree,form', # 要显示的视图类型,可以是'form', 'tree', 'kanban', 'graph', 'calendar', 'pivot'等
+ 'target': 'current', # 跳转的目标窗口,可以是'current'或'new'
+ }
+ # if self.production_line_id:
+ # if self.plan_start_time and self.plan_end_time:
+ # return None
+ # elif self.plan_start_time and not self.plan_end_time:
+ # # 如果没有给出计划结束时间,则计划结束时间为计划开始时间+采购周期+缓冲期
+ # # 采购周期
+ # purchase_cycle = 3
+ # # 缓冲期
+ # buffer_period = 1
+ # # 计划结束时间 = 计划开始时间 + 采购周期 + 缓冲期
+ # self.plan_end_time = self.plan_start_time + timedelta(days=purchase_cycle) + timedelta(
+ # days=buffer_period)
+ # self.state = 'produce'
+ # return self.plan_end_time
+ # else:
+ # return None
+ # # 后面要补充计划开始时间的计算方法
+ # # # 坯料预制时间
+ # # # pl_time = 0.5
+ # # # 采购周期
+ # # purchase_cycle = 3
+ # # # 缓冲期
+ # # buffer_period = 1
+ # # # 计划结束时间 = 计划开始时间 + 坯料预制时间 + 采购周期 + 缓冲期
+ # # # plan_end_time = plan_start_time + pl_time + purchase_cycle + buffer_period
+ # # # 计划结束时间 = 计划开始时间(是一个datatime) + 采购周期(Float) + 缓冲期(Float)
+ # # self.plan_end_time = self.plan_start_time + timedelta(days=purchase_cycle) + timedelta(days=buffer_period)
+ # # return self.plan_end_time
+ # else:
+ # raise ValidationError('生产线为空!')
+
+ def cancel_production_schedule(self):
+ self.date_planned_finished = False
+ self.state = 'draft'
+ return self.date_planned_finished
+
+ def liucheng_cs(self):
+ res = {'order_number': '123', 'delivery_end_date': str(datetime.now()),
+ 'delivery_name': '机企猫', 'delivery_telephone': '18943919239',
+ 'delivery_address': '新时空大厦',
+ 'bfm_process_order_list': []}
+ aa = self.env['ir.attachment'].search([('id', '=', 631)])
+ temp = self.env['product.template'].search([('id', '=', 47)])
+ item = aa.datas.decode('utf-8')
+ val = {
+ 'model_long': 3,
+ 'model_width': 1,
+ 'model_height': 1,
+ 'model_volume': 3,
+ 'model_machining_precision': '0.10',
+ 'model_name': aa.name,
+ 'model_data': base64.b64encode(aa.datas).decode('utf-8'),
+ 'model_file': base64.b64encode(temp.model_file).decode('utf-8'),
+ 'texture_code': '001',
+ 'texture_type_code': '001001',
+ # 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
+ 'process_parameters_code': 'R',
+ 'price': 20,
+ 'number': 2,
+ 'total_amount': 100,
+ 'remark': '这只是测试',
+ 'barcode': 123456789,
+ }
+ res['bfm_process_order_list'].append(val)
+ url = '/api/bfm_process_order/list'
+ res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
+ try:
+ ret = requests.post(('http://localhost:1069' + url), json={}, data=res)
+ # aa = json.loads(ret.text)
+ print(ret)
+ except Exception as e:
+ raise UserError(e)
# # sf生产排程
# class sf_produce_plan(models.Model):
# _name = 'sf.produce.plan'
# _description = 'sf生产排程'
- # # 重写create方法,使得创建坯料预制排程时,如果给出了计划结束时间,则计划开始时间为计划结束时间减去坯料预制时间
- # @api.model
- # def create(self, vals):
- # # 评估结束时间
- # vals['plan_end_time'] = self._get_plan_end_time(vals['plan_start_time'], vals['quantity'])
- # return super(sf_pl_plan, self).create(vals)
+# # 重写create方法,使得创建坯料预制排程时,如果给出了计划结束时间,则计划开始时间为计划结束时间减去坯料预制时间
+# @api.model
+# def create(self, vals):
+# # 评估结束时间
+# vals['plan_end_time'] = self._get_plan_end_time(vals['plan_start_time'], vals['quantity'])
+# return super(sf_pl_plan, self).create(vals)
- # # 当不设置计划结束时间时,增加计算计划结束时间的方法
- # @api.onchange('plan_start_time', 'quantity')
- # def _onchange_plan_start_time(self):
- # if self.plan_start_time and self.quantity:
- # self.plan_end_time = self._get_plan_end_time(self.plan_start_time, self.quantity)
- #
- # # 计算计划结束时间
- # def _get_plan_end_time(self, plan_start_time, quantity):
- # # 坯料预制时间
- # pl_time = 0.5
- # # 计划结束时间 = 计划开始时间 + 坯料预制时间
- # plan_end_time = plan_start_time + pl_time
- # return plan_end_time
- #
+# # 当不设置计划结束时间时,增加计算计划结束时间的方法
+# @api.onchange('plan_start_time', 'quantity')
+# def _onchange_plan_start_time(self):
+# if self.plan_start_time and self.quantity:
+# self.plan_end_time = self._get_plan_end_time(self.plan_start_time, self.quantity)
+#
+# # 计算计划结束时间
+# def _get_plan_end_time(self, plan_start_time, quantity):
+# # 坯料预制时间
+# pl_time = 0.5
+# # 计划结束时间 = 计划开始时间 + 坯料预制时间
+# plan_end_time = plan_start_time + pl_time
+# return plan_end_time
+#
diff --git a/sf_plan/security/ir.model.access.csv b/sf_plan/security/ir.model.access.csv
index 7effd7c3..b1578586 100644
--- a/sf_plan/security/ir.model.access.csv
+++ b/sf_plan/security/ir.model.access.csv
@@ -1,5 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_sf_pl_plan,sf.pl.plan,model_sf_pl_plan,base.group_user,1,1,1,1
+access_sf_production_plan,sf.production.plan,model_sf_production_plan,base.group_user,1,1,1,1
diff --git a/sf_plan/static/src/css/button_color.css b/sf_plan/static/src/css/button_color.css
new file mode 100644
index 00000000..496a94fa
--- /dev/null
+++ b/sf_plan/static/src/css/button_color.css
@@ -0,0 +1,8 @@
+.schedule_done {
+ background-color: #69c17d;
+ color: white;
+}
+.schedule_cancel {
+ background-color: #ffc54d;
+ color: black;
+}
\ No newline at end of file
diff --git a/sf_plan/views/view.xml b/sf_plan/views/view.xml
index 09ba627a..d7f8c59d 100644
--- a/sf_plan/views/view.xml
+++ b/sf_plan/views/view.xml
@@ -1,103 +1,124 @@
-
- sf.pl.plan.tree
- sf.pl.plan
+
+ sf.production.plan.tree
+ sf.production.plan
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
- sf.pl.plan.form
- sf.pl.plan
+
+ sf.production.plan.form
+ sf.production.plan
-
-
- sf.pl.plan.gantt
- sf.pl.plan
+
+
+ sf.production.plan.search
+ sf.production.plan
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sf.production.plan.gantt
+ sf.production.plan
+
+
+ color="production_line_id"
+ decoration-success="state == 'done'"
+ progress_bar="name"
+ form_view_id="sf_production_plan_form">
-
-
-
-
-
+
+
+
+
@@ -113,20 +134,12 @@
- 坯料编号:
-
-
-
- 坯料名称:
-
+ 名称:
+
数量:
-
-
-
- 材质:
-
+
状态:
@@ -142,19 +155,135 @@
-
- 坯料预制计划
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 制造订单生产计划
ir.actions.act_window
- sf.pl.plan
- tree,form,gantt
+ sf.production.plan
+ gantt,tree,form
+
+
+
+
+ 制造订单生产计划
+ ir.actions.act_window
+ sf.production.plan
+ tree,gantt,form
+
+
+
+
+
+
+
+
+ 制造订单
+ ir.actions.act_window
+ mrp.production
+ tree,form
+
+
+
+ 报价单
+ ir.actions.act_window
+ sale.order
+ tree,form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py
index fac229f5..eed2be57 100644
--- a/sf_sale/models/quick_easy_order.py
+++ b/sf_sale/models/quick_easy_order.py
@@ -37,11 +37,11 @@ class QuickEasyOrder(models.Model):
quantity = fields.Integer('数量', default=1)
unit_price = fields.Float('单价')
price = fields.Float('总价')
- model_file = fields.Binary('模型文件')
- upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='模型文件')
+ model_file = fields.Binary('glb模型文件')
+ upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='上传模型文件')
delivery_time = fields.Date('交货日期')
customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
- state = fields.Selection([('草稿', '草稿'), ('待付款', '待付款'), ('待派单', '待派单'),
+ state = fields.Selection([('草稿', '草稿'), ('待派单', '待派单'),
('待接单', '待接单'), ('加工中', '加工中'),
('物流中', '物流中'), ('已交付', '已交付')], string='订单状态', default='草稿',
readonly=True)
@@ -82,6 +82,7 @@ class QuickEasyOrder(models.Model):
obj = super(QuickEasyOrder, self).create(vals)
self.model_coloring(obj)
self.distribute_to_factory(obj)
+ obj.state = '待接单'
return obj
# 将attach的datas内容转为glb文件
diff --git a/sf_sale/views/quick_easy_order_view.xml b/sf_sale/views/quick_easy_order_view.xml
index c140dad7..a5ce9da2 100644
--- a/sf_sale/views/quick_easy_order_view.xml
+++ b/sf_sale/views/quick_easy_order_view.xml
@@ -16,13 +16,16 @@
quick.easy.order
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -33,6 +36,9 @@
quick.easy.order