坯料排程基本功能完成

This commit is contained in:
mgw
2023-08-11 12:18:47 +08:00
parent d971cbd5f1
commit fc490f1612
6 changed files with 303 additions and 0 deletions

4
sf_plan/__init__.py Normal file
View File

@@ -0,0 +1,4 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models

35
sf_plan/__manifest__.py Normal file
View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '机企猫智能工厂 订单排程',
'version': '1.0',
'summary': 'sf_plan',
'sequence': 19,
'description': """
这是一个用于机企猫生产订单排程的模块
====================
""",
'category': 'sf',
'author': 'jikimo',
'website': 'https://sf.cs.jikimo.com',
# 此处依赖sf_manufacturing是因为我要重写其中的一个字段operation_id的string故需要sf_manufacturing先安装
'depends': ['mrp', 'mrp_workorder'],
'data': [
'security/ir.model.access.csv',
'views/view.xml'
],
'assets': {
'web.assets_qweb': [
],
'web.assets_backend': [
],
},
'installable': True,
'application': True,
# 'auto_install': False,
'license': 'LGPL-3',
}

View File

@@ -0,0 +1,4 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import custom_plan

View File

@@ -0,0 +1,135 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from datetime import datetime, timedelta
# sf坯料预制排程
class sf_pl_plan(models.Model):
_name = 'sf.pl.plan'
_description = 'sf_pl_plan'
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='坯料预制')
@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 unlink(self):
sequence_to_reorder = self.mapped('sequence')
res = super().unlink()
records_to_reorder = self.search([('sequence', '>', min(sequence_to_reorder))])
for record in records_to_reorder:
record.sequence -= 1
return res
# 生成编码
def _get_pl_no(self):
sf_pl_no = self.env['sf.pl.plan'].sudo().search(
[('pl_no', '!=', '')],
limit=1,
order="id desc")
today_date = datetime.today().strftime('%y%m%d')
if not sf_pl_no:
# 如果没有找到先前的坯料编码则今天的第一个坯料编码为PL230520-001
num = 'PL' + today_date + '-001'
else:
# 获取最后一个坯料编码
last_pl_no = sf_pl_no.pl_no
last_date = last_pl_no[2:8]
last_seq = int(last_pl_no[-3:])
if last_date == today_date:
# 如果最后一个坯料编码的日期与今天相同则序号加1
new_seq = last_seq + 1
num = 'PL' + today_date + f'-{new_seq:03}'
else:
# 如果最后一个坯料编码的日期与今天不同则今天的第一个坯料编码为PL230520-001
num = 'PL' + today_date + '-001'
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)
# 当不设置计划结束时间时,增加计算计划结束时间的方法,根据采购周期加缓冲期两个值来算就可以了
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
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
# # 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)
# # 当不设置计划结束时间时,增加计算计划结束时间的方法
# @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
#

View File

@@ -0,0 +1,7 @@
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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_pl_plan sf.pl.plan model_sf_pl_plan base.group_user 1 1 1 1

118
sf_plan/views/view.xml Normal file
View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="sf_pl_plan_tree" model="ir.ui.view">
<field name="name">sf.pl.plan.tree</field>
<field name="model">sf.pl.plan</field>
<field name="arch" type="xml">
<tree string="坯料预制计划">
<!-- sequence、pl_no、pl_name、quantity、plan_start_time、plan_end_time、actual_start_time、actual_end_time、state、create_uid、create_date -->
<field name="sequence"/>
<field name="pl_no"/>
<field name="pl_name"/>
<field name="quantity"/>
<field name="plan_start_time"/>
<field name="plan_end_time"/>
<field name="state"/>
<field name="create_uid" string="创建人"/>
<field name="create_date" string="创建时间"/>
</tree>
</field>
</record>
<record id="sf_pl_plan_form" model="ir.ui.view">
<field name="name">sf.pl.plan.form</field>
<field name="model">sf.pl.plan</field>
<field name="arch" type="xml">
<form string="坯料预制计划">
<header>
<button string="执行排程" name="get_plan_end_time" type="object" class="oe_highlight"/>
</header>
<sheet>
<group>
<group string="基本信息">
<field name="pl_no"/>
<field name="pl_name"/>
<field name="quantity"/>
<field name="plan_start_time"/>
<field name="plan_end_time"/>
<field name="state"/>
</group>
<group string="规格信息">
<field name="length"/>
<field name="width"/>
<field name="thickness"/>
<field name="diameter"/>
<field name="material"/>
</group>
<group string="绑定订单">
<field name="customer_name"/>
<field name="order_no"/>
<field name="line_no"/>
<field name="delivery_length"/>
<field name="delivery_width"/>
<field name="delivery_thickness"/>
<field name="delivery_diameter"/>
<field name="delivery_quantity"/>
<field name="delivery_date"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="sf_pl_plan_gantt" model="ir.ui.view">
<field name="name">sf.pl.plan.gantt</field>
<field name="model">sf.pl.plan</field>
<field name="arch" type="xml">
<gantt class="o_mrp_workorder_gantt" date_stop="plan_end_time" date_start="plan_start_time" string="坯料预制计划" default_group_by="current_operation_name" create="0"
delete="0" sample="1"
display_unavailability="1"
color="pl_name"
progress_bar="pl_name"
form_view_id="sf_pl_plan_form">
<field name="pl_no"/>
<field name="pl_name"/>
<field name="quantity"/>
<field name="plan_start_time"/>
<field name="plan_end_time"/>
<field name="state"/>
<templates>
<div t-name="gantt-popover" class="container-fluid">
<div class="row g-0">
<div class="col">
<ul class="ps-1 mb-0 list-unstyled">
<li><strong>开始时间: </strong> <t t-out="userTimezoneStartDate.format('L LTS')"/></li>
<li><strong>结束时间: </strong> <t t-out="userTimezoneStopDate.format('L LTS')"/></li>
<li><strong>坯料编号: </strong> <t t-out="pl_no"/></li>
<li><strong>坯料名称: </strong> <t t-out="pl_name"/></li>
<li><strong>数量: </strong> <t t-out="quantity"/></li>
<li><strong>材质: </strong> <t t-out="material"/></li>
</ul>
</div>
</div>
</div>
</templates>
</gantt>
</field>
</record>
<record id="sf_pl_plan_action" model="ir.actions.act_window">
<field name="name">坯料预制计划</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sf.pl.plan</field>
<field name="view_mode">tree,form,gantt</field>
</record>
<menuitem
id="sf_pl_plan_menu"
name="坯料预制计划"
parent="mrp_workorder.mrp_workorder_menu_planning"
sequence="10"
action="sf_pl_plan_action"
/>
</data>
</odoo>