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 bf92a8f7..ba43169d 100644 --- a/sf_plan/__manifest__.py +++ b/sf_plan/__manifest__.py @@ -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 2a2be736..b07614d3 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -1,19 +1,35 @@ # -*- 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_production_plan(models.Model): _name = 'sf.production.plan' + # _inherit = 'mrp.production' _description = 'sf_production_plan' - name = fields.Char(string='名称', size=64) + 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='来源') + # 序号、坯料编号、坯料名称、材质、数量、长度、宽度、厚度、直径、计划开始时间、计划结束时间、状态(已产出与待产出)、操作、创建人、创建时间、客户名称、订单号、行号、长度、宽度、厚度、直径、交货数量、交货日期 # 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) + 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='生产线') @@ -21,6 +37,24 @@ class sf_production_plan(models.Model): # ('未排程', '未排程'), ('已排程', '已排程')], 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 _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() @@ -40,17 +74,16 @@ class sf_production_plan(models.Model): else: return None - def cancel_plan(self): self.ensure_one() self.date_planned_finished = None - self.state = 'confirmed' + 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) + # @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') @@ -89,18 +122,18 @@ class sf_production_plan(models.Model): # 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) + # 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') + # 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) @@ -113,64 +146,123 @@ class sf_production_plan(models.Model): # 当不设置计划结束时间时,增加计算计划结束时间的方法,根据采购周期加缓冲期两个值来算就可以了 def do_production_schedule(self): - 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 + 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: - raise ValidationError('生产线为空!') + 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.plan_end_time = False + self.date_planned_finished = False self.state = 'draft' - return self.plan_end_time + 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/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 22e72c30..d7f8c59d 100644 --- a/sf_plan/views/view.xml +++ b/sf_plan/views/view.xml @@ -7,14 +7,14 @@ - + - - - - -