Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修改机床参数bug
# Conflicts: # sf_manufacturing/models/product_template.py
This commit is contained in:
@@ -17,9 +17,32 @@ class MrpProduction(models.Model):
|
|||||||
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
|
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
|
||||||
request_ids = fields.One2many('maintenance.request', 'production_id')
|
request_ids = fields.One2many('maintenance.request', 'production_id')
|
||||||
model_file = fields.Binary('模型文件', related='product_id.model_file')
|
model_file = fields.Binary('模型文件', related='product_id.model_file')
|
||||||
schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排')],
|
schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排'), ('已完成', '已完成')],
|
||||||
string='排程状态', default='未排')
|
string='排程状态', default='未排')
|
||||||
|
|
||||||
|
# state = fields.Selection(selection_add=[
|
||||||
|
# ('pending_scheduling', '待排程'),
|
||||||
|
# ('pending_processing', '待加工'),
|
||||||
|
# ('completed', '已完工')
|
||||||
|
# ])
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('confirmed', 'Confirmed'),
|
||||||
|
('progress', '待排程'),
|
||||||
|
('pending_processing', '待加工'),
|
||||||
|
('completed', '已完工'),
|
||||||
|
('to_close', 'To Close'),
|
||||||
|
('done', 'Done'),
|
||||||
|
('cancel', 'Cancelled')], string='State',
|
||||||
|
compute='_compute_state', copy=False, index=True, readonly=True,
|
||||||
|
store=True, tracking=True,
|
||||||
|
help=" * Draft: The MO is not confirmed yet.\n"
|
||||||
|
" * Confirmed: The MO is confirmed, the stock rules and the reordering of the components are trigerred.\n"
|
||||||
|
" * In Progress: The production has started (on the MO or on the WO).\n"
|
||||||
|
" * To Close: The production is done, the MO has to be closed.\n"
|
||||||
|
" * Done: The MO is closed, the stock moves are posted. \n"
|
||||||
|
" * Cancelled: The MO has been cancelled, can't be confirmed anymore.")
|
||||||
|
|
||||||
check_status = fields.Boolean(string='启用状态', default=False, readonly=True)
|
check_status = fields.Boolean(string='启用状态', default=False, readonly=True)
|
||||||
active = fields.Boolean(string='已归档', default=True)
|
active = fields.Boolean(string='已归档', default=True)
|
||||||
programming_no = fields.Char('编程单号')
|
programming_no = fields.Char('编程单号')
|
||||||
@@ -27,6 +50,45 @@ class MrpProduction(models.Model):
|
|||||||
programming_state = fields.Char('编程状态')
|
programming_state = fields.Char('编程状态')
|
||||||
glb_file = fields.Binary("glb模型文件")
|
glb_file = fields.Binary("glb模型文件")
|
||||||
|
|
||||||
|
@api.depends(
|
||||||
|
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state',
|
||||||
|
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state')
|
||||||
|
def _compute_state(self):
|
||||||
|
for production in self:
|
||||||
|
if not production.state or not production.product_uom_id:
|
||||||
|
production.state = 'draft'
|
||||||
|
elif production.state == 'cancel' or (production.move_finished_ids and all(
|
||||||
|
move.state == 'cancel' for move in production.move_finished_ids)):
|
||||||
|
production.state = 'cancel'
|
||||||
|
elif (
|
||||||
|
production.state == 'done'
|
||||||
|
or (production.move_raw_ids and all(
|
||||||
|
move.state in ('cancel', 'done') for move in production.move_raw_ids))
|
||||||
|
and all(move.state in ('cancel', 'done') for move in production.move_finished_ids)
|
||||||
|
):
|
||||||
|
production.state = 'done'
|
||||||
|
elif production.workorder_ids and all(
|
||||||
|
wo_state in ('done', 'cancel') for wo_state in production.workorder_ids.mapped('state')):
|
||||||
|
production.state = 'to_close'
|
||||||
|
elif not production.workorder_ids and float_compare(production.qty_producing, production.product_qty,
|
||||||
|
precision_rounding=production.product_uom_id.rounding) >= 0:
|
||||||
|
production.state = 'to_close'
|
||||||
|
elif any(wo_state in ('progress', 'done') for wo_state in production.workorder_ids.mapped('state')):
|
||||||
|
production.state = 'progress'
|
||||||
|
elif production.product_uom_id and not float_is_zero(production.qty_producing,
|
||||||
|
precision_rounding=production.product_uom_id.rounding):
|
||||||
|
production.state = 'progress'
|
||||||
|
elif any(not float_is_zero(move.quantity_done,
|
||||||
|
precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding)
|
||||||
|
for move in production.move_raw_ids):
|
||||||
|
production.state = 'progress'
|
||||||
|
|
||||||
|
# 新添加的状态逻辑
|
||||||
|
if production.state == 'progress' and production.schedule_state == '已排':
|
||||||
|
production.state = 'pending_processing'
|
||||||
|
elif production.state == 'progress' and production.schedule_state == '已完成':
|
||||||
|
production.state = 'completed'
|
||||||
|
|
||||||
def action_check(self):
|
def action_check(self):
|
||||||
"""
|
"""
|
||||||
审核启用
|
审核启用
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ class ResProductMo(models.Model):
|
|||||||
tool_thickness = fields.Float('厚度(mm)')
|
tool_thickness = fields.Float('厚度(mm)')
|
||||||
tool_weight = fields.Float('重量(kg)')
|
tool_weight = fields.Float('重量(kg)')
|
||||||
tool_hardness = fields.Integer('硬度(hrc)')
|
tool_hardness = fields.Integer('硬度(hrc)')
|
||||||
|
|
||||||
coating_material = fields.Char('涂层材质')
|
coating_material = fields.Char('涂层材质')
|
||||||
# 整体式刀具特有字段
|
# 整体式刀具特有字段
|
||||||
cutting_tool_total_length = fields.Float('总长度(mm)', digits=(6, 1))
|
cutting_tool_total_length = fields.Float('总长度(mm)', digits=(6, 1))
|
||||||
@@ -263,7 +262,18 @@ class ResProductMo(models.Model):
|
|||||||
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
||||||
self.cutting_tool_main_included_angle = self.specification_id.main_included_angle
|
self.cutting_tool_main_included_angle = self.specification_id.main_included_angle
|
||||||
self.cutting_tool_top_angle = self.specification_id.top_angle
|
self.cutting_tool_top_angle = self.specification_id.top_angle
|
||||||
|
|
||||||
self.cutting_tool_blade_tip_dip_angle = self.specification_id.blade_tip_dip_angle
|
self.cutting_tool_blade_tip_dip_angle = self.specification_id.blade_tip_dip_angle
|
||||||
|
|
||||||
|
self.cutting_tool_screw = self.specification_id.screw
|
||||||
|
self.cutting_tool_wrench = self.specification_id.wrench
|
||||||
|
self.cutting_tool_blade_id = self.specification_id.blade_id.id
|
||||||
|
self.cutting_tool_is_cooling_hole = self.specification_id.is_cooling_hole
|
||||||
|
self.cutting_tool_locating_slot_code = self.specification_id.locating_slot_code
|
||||||
|
self.cutting_tool_install_blade_tip_num = self.specification_id.install_blade_tip_num
|
||||||
|
self.cutting_tool_installing_structure = self.specification_id.installing_structure
|
||||||
|
self.cutting_tool_cut_depth_max = self.specification_id.cut_depth_max
|
||||||
|
|
||||||
if self.cutting_tool_type == '刀盘':
|
if self.cutting_tool_type == '刀盘':
|
||||||
self.cutting_tool_blade_length = self.specification_id.blade_length
|
self.cutting_tool_blade_length = self.specification_id.blade_length
|
||||||
self.cutting_tool_cutter_head_diameter = self.specification_id.cutter_head_diameter
|
self.cutting_tool_cutter_head_diameter = self.specification_id.cutter_head_diameter
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
<xpath expr="//field[@name='production_real_duration']" position="after">
|
<xpath expr="//field[@name='production_real_duration']" position="after">
|
||||||
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'" decoration-success="reservation_state == 'assigned'"/>
|
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'" decoration-success="reservation_state == 'assigned'"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='state']" position="before">
|
<!-- <xpath expr="//field[@name='state']" position="before"> -->
|
||||||
<field name="schedule_state" optional="show"/>
|
<!-- <field name="schedule_state" optional="show"/> -->
|
||||||
</xpath>
|
<!-- </xpath> -->
|
||||||
<xpath expr="//field[@name='activity_ids']" position="replace">
|
<xpath expr="//field[@name='activity_ids']" position="replace">
|
||||||
<field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/>
|
<field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
@@ -58,6 +58,9 @@
|
|||||||
<field name="model">mrp.production</field>
|
<field name="model">mrp.production</field>
|
||||||
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
|
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='state']" position="attributes">
|
||||||
|
<attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done</attribute>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//form//header//button[@name='action_confirm']" position="after">
|
<xpath expr="//form//header//button[@name='action_confirm']" position="after">
|
||||||
<field name="active" invisible="1"/>
|
<field name="active" invisible="1"/>
|
||||||
<field name="check_status" invisible="1"/>
|
<field name="check_status" invisible="1"/>
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
|||||||
@@ -17,8 +17,10 @@
|
|||||||
'data': [
|
'data': [
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
# 'security/rules.xml',
|
# 'security/rules.xml',
|
||||||
|
'wizard/action_plan_some.xml',
|
||||||
'views/view.xml',
|
'views/view.xml',
|
||||||
'views/change_manufactuing.xml'
|
'views/change_manufactuing.xml',
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'assets': {
|
'assets': {
|
||||||
|
|||||||
@@ -12,14 +12,30 @@ class sf_production_plan(models.Model):
|
|||||||
_name = 'sf.production.plan'
|
_name = 'sf.production.plan'
|
||||||
_description = 'sf_production_plan'
|
_description = 'sf_production_plan'
|
||||||
_inherit = ['mail.thread']
|
_inherit = ['mail.thread']
|
||||||
_order = 'create_date desc'
|
# _order = 'state desc, write_date desc'
|
||||||
|
|
||||||
state = fields.Selection([
|
state = fields.Selection([
|
||||||
('draft', '待排程'),
|
('draft', '待排程'),
|
||||||
('done', '已排程'),
|
('done', '已排程'),
|
||||||
('processing', '已加工'),
|
('processing', '加工中'),
|
||||||
('finished', '已完成')
|
('finished', '已完成')
|
||||||
], string='工单状态', tracking=True)
|
], string='工单状态', tracking=True)
|
||||||
|
|
||||||
|
state_order = fields.Integer(compute='_compute_state_order', store=True)
|
||||||
|
|
||||||
|
@api.depends('state')
|
||||||
|
def _compute_state_order(self):
|
||||||
|
order_mapping = {
|
||||||
|
'draft': 1,
|
||||||
|
'done': 2,
|
||||||
|
'processing': 3,
|
||||||
|
'finished': 4
|
||||||
|
}
|
||||||
|
for record in self:
|
||||||
|
record.state_order = order_mapping.get(record.state, 0)
|
||||||
|
|
||||||
|
_order = 'state_order asc, write_date desc'
|
||||||
|
|
||||||
name = fields.Char(string='工单编号')
|
name = fields.Char(string='工单编号')
|
||||||
active = fields.Boolean(string='已归档', default=True)
|
active = fields.Boolean(string='已归档', default=True)
|
||||||
# selected = fields.Boolean(default=False)
|
# selected = fields.Boolean(default=False)
|
||||||
@@ -51,6 +67,11 @@ class sf_production_plan(models.Model):
|
|||||||
sequence = fields.Integer(string='序号', 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='生产计划')
|
current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划')
|
||||||
|
|
||||||
|
@api.onchange('state')
|
||||||
|
def _onchange_state(self):
|
||||||
|
if self.state == 'finished':
|
||||||
|
self.production_id.schedule_state = '已完成'
|
||||||
|
|
||||||
# @api.model
|
# @api.model
|
||||||
# def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
|
# def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
|
||||||
# """
|
# """
|
||||||
@@ -252,6 +273,7 @@ class sf_production_plan(models.Model):
|
|||||||
def cancel_production_schedule(self):
|
def cancel_production_schedule(self):
|
||||||
self.date_planned_finished = False
|
self.date_planned_finished = False
|
||||||
self.state = 'draft'
|
self.state = 'draft'
|
||||||
|
self.production_line_id = False
|
||||||
aa = self.env['mrp.production'].sudo().search([('name', '=', self.name)])
|
aa = self.env['mrp.production'].sudo().search([('name', '=', self.name)])
|
||||||
aa.schedule_state = '未排'
|
aa.schedule_state = '未排'
|
||||||
return self.date_planned_finished
|
return self.date_planned_finished
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
access_sf_production_plan,sf.production.plan,model_sf_production_plan,base.group_user,1,0,0,0
|
access_sf_production_plan,sf.production.plan,model_sf_production_plan,base.group_user,1,0,0,0
|
||||||
access_sf_production_plan_for_dispatch,sf.production.plan for dispatch,model_sf_production_plan,sf_base.group_plan_dispatch,1,1,1,0
|
access_sf_production_plan_for_dispatch,sf.production.plan for dispatch,model_sf_production_plan,sf_base.group_plan_dispatch,1,1,1,0
|
||||||
|
|
||||||
|
access_sf_action_plan_all_wizard,sf.action.plan.all.wizard,model_sf_action_plan_all_wizard,base.group_user,1,1,1,1
|
||||||
|
@@ -5,11 +5,13 @@
|
|||||||
<field name="name">sf.production.plan.tree</field>
|
<field name="name">sf.production.plan.tree</field>
|
||||||
<field name="model">sf.production.plan</field>
|
<field name="model">sf.production.plan</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="订单计划" editable="bottom">
|
<!-- <tree string="订单计划" editable="bottom"> -->
|
||||||
|
<tree string="订单计划">
|
||||||
<header>
|
<header>
|
||||||
<button name="do_production_schedule" type="object" string="批量排程"/>
|
<!-- <button name="do_production_schedule" type="object" string="批量排程"/> -->
|
||||||
|
<button string="批量排程" name="%(sf_plan.action_plan_some)d" type="action" class="btn-primary"/>
|
||||||
</header>
|
</header>
|
||||||
<field name="state" widget="badge" decoration-warning="state == 'draft'" decoration-success="state == 'done'"/>
|
<field name="state" widget="badge" decoration-warning="state == 'draft'" decoration-success="state == 'done'" decoration-info="state == 'processing'" decoration-danger="state == 'finished'"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="origin"/>
|
<field name="origin"/>
|
||||||
<field name="order_deadline"/>
|
<field name="order_deadline"/>
|
||||||
|
|||||||
1
sf_plan/wizard/__init__.py
Normal file
1
sf_plan/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import action_plan_some
|
||||||
65
sf_plan/wizard/action_plan_some.py
Normal file
65
sf_plan/wizard/action_plan_some.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import base64
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo import fields, models
|
||||||
|
# from odoo.exceptions import ValidationError
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Action_Plan_All_Wizard(models.TransientModel):
|
||||||
|
_name = 'sf.action.plan.all.wizard'
|
||||||
|
_description = u'排程向导'
|
||||||
|
|
||||||
|
# 选择生产线
|
||||||
|
production_line_id = fields.Many2one('sf.production.line', string=u'生产线', required=True)
|
||||||
|
|
||||||
|
# 接收传递过来的计划ID
|
||||||
|
plan_ids = fields.Many2many('sf.production.plan', string=u'计划ID')
|
||||||
|
|
||||||
|
# 确认排程按钮
|
||||||
|
def action_plan_all(self):
|
||||||
|
# 使用传递过来的计划ID
|
||||||
|
temp_plan_ids = self.plan_ids
|
||||||
|
# 在这里添加您的逻辑来处理这些ID
|
||||||
|
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_obj.do_production_schedule()
|
||||||
|
# plan_obj.state = 'done'
|
||||||
|
print('处理计划:', plan.id, '完成')
|
||||||
|
|
||||||
|
# # 获取当前生产线
|
||||||
|
# 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
|
||||||
31
sf_plan/wizard/action_plan_some.xml
Normal file
31
sf_plan/wizard/action_plan_some.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="action_plan_some_form" model="ir.ui.view">
|
||||||
|
<field name="name">选择生产线</field>
|
||||||
|
<field name="model">sf.action.plan.all.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<group>
|
||||||
|
<field name="production_line_id"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button string="确认排程" name="action_plan_all" type="object" class="btn-primary"/>
|
||||||
|
<!-- <button string="取消" class="btn-secondary" special="cancel"/> -->
|
||||||
|
<button string="取消" class="btn-primary" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="action_plan_some" model="ir.actions.act_window">
|
||||||
|
<field name="name">请选择要排程的生产线</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<!-- <field name="res_model">up.select.wizard</field>-->
|
||||||
|
<field name="res_model">sf.action.plan.all.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="action_plan_some_form"/>
|
||||||
|
<field name="target">new</field>
|
||||||
|
<field name="context">{'default_plan_ids': active_ids}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -39704,7 +39704,7 @@ msgstr "付款中"
|
|||||||
#: model_terms:ir.ui.view,arch_db:quality.quality_alert_view_search
|
#: model_terms:ir.ui.view,arch_db:quality.quality_alert_view_search
|
||||||
#: model_terms:ir.ui.view,arch_db:quality_control.quality_check_view_search
|
#: model_terms:ir.ui.view,arch_db:quality_control.quality_check_view_search
|
||||||
msgid "In Progress"
|
msgid "In Progress"
|
||||||
msgstr "进行中"
|
msgstr "待排程"
|
||||||
|
|
||||||
#. module: stock
|
#. module: stock
|
||||||
#: model:ir.model.fields,field_description:stock.field_stock_warehouse__in_type_id
|
#: model:ir.model.fields,field_description:stock.field_stock_warehouse__in_type_id
|
||||||
@@ -112590,7 +112590,7 @@ msgstr ""
|
|||||||
#: model:ir.model,name:sf_manufacturing.model_mrp_production
|
#: model:ir.model,name:sf_manufacturing.model_mrp_production
|
||||||
#: model:ir.ui.menu,name:sf_plan.mrp_custom_menu
|
#: model:ir.ui.menu,name:sf_plan.mrp_custom_menu
|
||||||
msgid "制造订单"
|
msgid "制造订单"
|
||||||
msgstr "生产订单"
|
msgstr "制造订单"
|
||||||
|
|
||||||
#. module: sf_plan
|
#. module: sf_plan
|
||||||
#: model:ir.actions.act_window,name:sf_plan.sf_production_plan_action
|
#: model:ir.actions.act_window,name:sf_plan.sf_production_plan_action
|
||||||
|
|||||||
@@ -81,6 +81,25 @@ class ReSaleOrder(models.Model):
|
|||||||
}
|
}
|
||||||
return self.env['sale.order.line'].create(vals)
|
return self.env['sale.order.line'].create(vals)
|
||||||
|
|
||||||
|
@api.constrains('order_line')
|
||||||
|
def check_order_line(self):
|
||||||
|
for item in self:
|
||||||
|
if not item.order_line:
|
||||||
|
raise UserError('请选择【订单行】中的【产品】')
|
||||||
|
for line in item.order_line:
|
||||||
|
if not line.product_template_id:
|
||||||
|
raise UserError('请对【订单行】中的【产品】进行选择')
|
||||||
|
if not line.name:
|
||||||
|
raise UserError('请对【订单行】中的【说明】进行输入')
|
||||||
|
if line.product_qty == 0:
|
||||||
|
raise UserError('请对【订单行】中的【数量】进行输入')
|
||||||
|
if not line.product_uom:
|
||||||
|
raise UserError('请对【订单行】中的【计量单位】进行选择')
|
||||||
|
if line.price_unit == 0:
|
||||||
|
raise UserError('请对【订单行】中的【单价】进行输入')
|
||||||
|
if not line.taxes_id:
|
||||||
|
raise UserError('请对【订单行】中的【税】进行选择')
|
||||||
|
|
||||||
|
|
||||||
class ResaleOrderLine(models.Model):
|
class ResaleOrderLine(models.Model):
|
||||||
_inherit = 'sale.order.line'
|
_inherit = 'sale.order.line'
|
||||||
@@ -95,6 +114,28 @@ class RePurchaseOrder(models.Model):
|
|||||||
check_status = fields.Selection([('pending', '待审核'), ('approved', '已审核'), ('fail', '不通过')], '审核状态')
|
check_status = fields.Selection([('pending', '待审核'), ('approved', '已审核'), ('fail', '不通过')], '审核状态')
|
||||||
remark = fields.Text('备注')
|
remark = fields.Text('备注')
|
||||||
|
|
||||||
|
def button_confirming(self):
|
||||||
|
self.write({'state': 'purchase', 'check_status': 'pending'})
|
||||||
|
|
||||||
|
@api.constrains('order_line')
|
||||||
|
def check_order_line(self):
|
||||||
|
for item in self:
|
||||||
|
if not item.order_line:
|
||||||
|
raise UserError('该询价单未添加【产品】,请进行添加')
|
||||||
|
for line in item.order_line:
|
||||||
|
if not line.product_id:
|
||||||
|
raise UserError('【产品】未添加,请进行添加')
|
||||||
|
if not line.name:
|
||||||
|
raise UserError('请对【产品】中的【说明】进行输入')
|
||||||
|
if line.product_qty == 0:
|
||||||
|
raise UserError('请对【产品】中的【数量】进行输入')
|
||||||
|
if not line.product_uom:
|
||||||
|
raise UserError('请对【产品】中的【计量单位】进行选择')
|
||||||
|
if line.price_unit == 0:
|
||||||
|
raise UserError('请对【产品】中的【单价】进行输入')
|
||||||
|
if not line.taxes_id:
|
||||||
|
raise UserError('请对【产品】中的【税】进行选择')
|
||||||
|
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
if self.env.user.has_group('sf_base.group_purchase_director'):
|
if self.env.user.has_group('sf_base.group_purchase_director'):
|
||||||
if vals.get('check_status'):
|
if vals.get('check_status'):
|
||||||
@@ -103,9 +144,19 @@ class RePurchaseOrder(models.Model):
|
|||||||
return super().write(vals)
|
return super().write(vals)
|
||||||
|
|
||||||
def button_confirm(self):
|
def button_confirm(self):
|
||||||
self.check_status = 'pending'
|
for order in self:
|
||||||
res = super().button_confirm()
|
if order.state not in ['draft', 'sent', 'purchase']:
|
||||||
return res
|
continue
|
||||||
|
order.order_line._validate_analytic_distribution()
|
||||||
|
order._add_supplier_to_product()
|
||||||
|
# Deal with double validation process
|
||||||
|
if order._approval_allowed():
|
||||||
|
order.button_approve()
|
||||||
|
else:
|
||||||
|
order.write({'state': 'to approve'})
|
||||||
|
if order.partner_id not in order.message_partner_ids:
|
||||||
|
order.message_subscribe([order.partner_id.id])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class ResPartnerToSale(models.Model):
|
class ResPartnerToSale(models.Model):
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ access_uom_category_group_purchase,uom_category_group_purchase,uom.model_uom_cat
|
|||||||
access_uom_category_group_purchase_director,uom_category_group_purchase_director,uom.model_uom_category,sf_base.group_purchase_director,1,0,0,0
|
access_uom_category_group_purchase_director,uom_category_group_purchase_director,uom.model_uom_category,sf_base.group_purchase_director,1,0,0,0
|
||||||
access_sale_order_check_wizard_group_sale_salemanager,sale_order_check_wizard_group_sale_salemanager,model_sale_order_check_wizard,sf_base.group_sale_salemanager,1,1,1,0
|
access_sale_order_check_wizard_group_sale_salemanager,sale_order_check_wizard_group_sale_salemanager,model_sale_order_check_wizard,sf_base.group_sale_salemanager,1,1,1,0
|
||||||
access_sale_order_check_wizard_group_sale_director,sale_order_check_wizard_group_sale_director,model_sale_order_check_wizard,sf_base.group_sale_director,1,1,1,0
|
access_sale_order_check_wizard_group_sale_director,sale_order_check_wizard_group_sale_director,model_sale_order_check_wizard,sf_base.group_sale_director,1,1,1,0
|
||||||
|
access_account_move_line_group_sale_salemanager,account_move_line_group_sale_salemanager,account.model_account_move_line,sf_base.group_sale_salemanager,1,1,1,0
|
||||||
|
access_account_move_line_group_sale_director,account_move_line_group_sale_director,account.model_account_move_line,sf_base.group_sale_director,1,1,1,0
|
||||||
access_account_move_line_group_purchase,account_move_line_group_purchase,account.model_account_move_line,sf_base.group_purchase,1,1,1,0
|
access_account_move_line_group_purchase,account_move_line_group_purchase,account.model_account_move_line,sf_base.group_purchase,1,1,1,0
|
||||||
access_account_move_line_group_purchase_director,account_move_line_group_purchase_director,account.model_account_move_line,sf_base.group_purchase_director,1,1,1,0
|
access_account_move_line_group_purchase_director,account_move_line_group_purchase_director,account.model_account_move_line,sf_base.group_purchase_director,1,1,1,0
|
||||||
access_res_users_group_purchase,res_user_group_purchase,model_res_users,sf_base.group_purchase,1,1,1,0
|
access_res_users_group_purchase,res_user_group_purchase,model_res_users,sf_base.group_purchase,1,1,1,0
|
||||||
@@ -71,9 +73,13 @@ access_crm_tag_group_sale_salemanager,crm_tag_group_sale_salemanager,sales_team.
|
|||||||
access_crm_tag_group_sale_director,crm_tag_group_sale_director,sales_team.model_crm_tag,sf_base.group_sale_director,1,1,1,0
|
access_crm_tag_group_sale_director,crm_tag_group_sale_director,sales_team.model_crm_tag,sf_base.group_sale_director,1,1,1,0
|
||||||
|
|
||||||
access_sale_order,sale.order,sale.model_sale_order,sf_base.group_plan_dispatch,1,0,0,0
|
access_sale_order,sale.order,sale.model_sale_order,sf_base.group_plan_dispatch,1,0,0,0
|
||||||
access_res_partner_group_purchase,res_partner_group_purchase,base.model_res_partner,sf_base.group_purchase,1,1,1,0
|
access_res_partner_group_sale_salemanager,res_partner_group_sale_salemanager,base.model_res_partner,sf_base.group_sale_salemanager,1,0,1,0
|
||||||
access_res_partner_group_purchase_director,res_partner_group_purchase_director,base.model_res_partner,sf_base.group_purchase_director,1,1,1,0
|
access_res_partner_group_sale_director,res_partner_group_sale_director,base.model_res_partner,sf_base.group_sale_director,1,0,1,0
|
||||||
|
access_res_partner_group_purchase,res_partner_group_purchase,base.model_res_partner,sf_base.group_purchase,1,0,1,0
|
||||||
|
access_res_partner_group_purchase_director,res_partner_group_purchase_director,base.model_res_partner,sf_base.group_purchase_director,1,0,1,0
|
||||||
access_sale_advance_payment_inv_group_sale_salemanager,sale_advance_payment_inv_group_sale_salemanager,sale.model_sale_advance_payment_inv,sf_base.group_sale_salemanager,1,1,1,0
|
access_sale_advance_payment_inv_group_sale_salemanager,sale_advance_payment_inv_group_sale_salemanager,sale.model_sale_advance_payment_inv,sf_base.group_sale_salemanager,1,1,1,0
|
||||||
access_sale_advance_payment_inv_group_sale_director,sale_advance_payment_inv_group_sale_director,sale.model_sale_advance_payment_inv,sf_base.group_sale_director,1,1,1,0
|
access_sale_advance_payment_inv_group_sale_director,sale_advance_payment_inv_group_sale_director,sale.model_sale_advance_payment_inv,sf_base.group_sale_director,1,1,1,0
|
||||||
|
access_sale_report_group_sale_salemanager,sale_report_group_sale_salemanager,sale.model_sale_report,sf_base.group_sale_salemanager,1,0,1,0
|
||||||
|
access_sale_report_group_sale_director,sale_report_group_sale_director,sale.model_sale_report,sf_base.group_sale_director,1,0,1,0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
@@ -18,13 +18,17 @@
|
|||||||
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="after">
|
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="after">
|
||||||
<button name="sf_sale.action_purchase_order_check_wizard" string="审核" type="action"
|
<button name="sf_sale.action_purchase_order_check_wizard" string="审核" type="action"
|
||||||
context="{'default_order_id':active_id}" groups="sf_base.group_purchase_director"
|
context="{'default_order_id':active_id}" groups="sf_base.group_purchase_director"
|
||||||
attrs="{'invisible': ['&',('check_status','in', ['approved']),('state', 'in', ['draft','send','purchase'])]}"
|
attrs="{'invisible': ['&',('check_status','in', ['approved',False]),('state', 'in', ['purchase'])]}"
|
||||||
class="oe_highlight"/>
|
class="oe_highlight"/>
|
||||||
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='button_confirm'][2]" position="replace">
|
<xpath expr="//form/header/button[@name='button_confirm'][2]" position="replace">
|
||||||
<button name="button_confirm" type="object" context="{'validate_analytic': True}"
|
<button name="button_confirm" type="object" context="{'validate_analytic': True}"
|
||||||
string="确认订单" id="draft_confirm"
|
string="确认订单" id="draft_confirm"
|
||||||
attrs="{'invisible': ['|','&',('check_status','in', ['approved','fail','pending']),('state', 'in', ['draft','purchase']),('state', 'in', ['purchase'])]}"
|
/>
|
||||||
|
<button name="button_confirming" type="object"
|
||||||
|
string="确认"
|
||||||
|
attrs="{'invisible': ['&',('check_status','!=', False),('state', 'not in', ['draft','send'])]}"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
@@ -129,12 +133,15 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="view_purchase_order_kpis_tree_inherit_sf" model="ir.ui.view">
|
<record id="view_purchase_order_view_tree_inherit_sf" model="ir.ui.view">
|
||||||
<field name="name">purchase.order.tree.inherit.sf</field>
|
<field name="name">purchase.order.tree.inherit.sf</field>
|
||||||
<field name="model">purchase.order</field>
|
<field name="model">purchase.order</field>
|
||||||
<field name="inherit_id" ref="purchase.purchase_order_kpis_tree"/>
|
<field name="inherit_id" ref="purchase.purchase_order_view_tree"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="state" position="after">
|
<tree position="attributes">
|
||||||
|
<attribute name="default_order">check_status desc,date_approve asc</attribute>
|
||||||
|
</tree>
|
||||||
|
<field name="amount_total" position="after">
|
||||||
<field name="check_status" widget="badge"
|
<field name="check_status" widget="badge"
|
||||||
decoration-success="check_status == 'approved'"
|
decoration-success="check_status == 'approved'"
|
||||||
decoration-warning="check_status == 'pending'"
|
decoration-warning="check_status == 'pending'"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form position="attributes">
|
<form position="attributes">
|
||||||
<attribute name="delete">false</attribute>
|
<attribute name="delete">false</attribute>
|
||||||
|
<attribute name="edit">false</attribute>
|
||||||
</form>
|
</form>
|
||||||
<field name="vat" position="after">
|
<field name="vat" position="after">
|
||||||
<field name="customer_rank" invisible="1"/>
|
<field name="customer_rank" invisible="1"/>
|
||||||
|
|||||||
@@ -1,6 +1,54 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<data>
|
||||||
|
<record id="sale_order_view_search_inherit_sf" model="ir.ui.view">
|
||||||
|
<field name="name">sale.order.search.inherit.sf</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="mode">primary</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_sales_order_filter"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<filter name="my_sale_orders_filter" position="replace">
|
||||||
|
<field name="campaign_id"/>
|
||||||
|
<separator/>
|
||||||
|
<filter string="报价" name="draft" domain="[('state','in',('draft', 'sent'))]"/>
|
||||||
|
<filter string="销售订单" name="sales" domain="[('state','in',('sale','done'))]"/>
|
||||||
|
<separator/>
|
||||||
|
<filter string="创建日期" name="filter_create_date" date="create_date"/>
|
||||||
|
</filter>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_quotations_with_onboarding_inherit_sf" model="ir.actions.act_window">
|
||||||
|
<field name="name">报价</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">sale.order</field>
|
||||||
|
<field name="view_id" ref="sale.view_quotation_tree_with_onboarding"/>
|
||||||
|
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
|
||||||
|
<field name="search_view_id" ref="sale_order_view_search_inherit_sf"/>
|
||||||
|
<field name="context">{'search_default_my_quotation': 1}</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Create a new quotation, the first step of a new sale!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Once the quotation is confirmed by the customer, it becomes a sales order.
|
||||||
|
<br/>
|
||||||
|
You will be able to create an invoice and collect the payment.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <menuitem id="menu_sale_quotations">-->
|
||||||
|
<!-- <field name="active" eval="False"/>-->
|
||||||
|
<!-- </menuitem>-->
|
||||||
|
|
||||||
|
<menuitem id="menu_sale_quotations_inherit_sf"
|
||||||
|
action="action_quotations_with_onboarding_inherit_sf"
|
||||||
|
groups="sales_team.group_sale_salesman,sf_base.group_sale_salemanager,sf_base.group_sale_director"
|
||||||
|
parent="sale.sale_order_menu"
|
||||||
|
sequence="10"/>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_sale_order_form_inherit_sf">
|
<record model="ir.ui.view" id="view_sale_order_form_inherit_sf">
|
||||||
<field name="name">sale.order.form.inherit.sf</field>
|
<field name="name">sale.order.form.inherit.sf</field>
|
||||||
<field name="model">sale.order</field>
|
<field name="model">sale.order</field>
|
||||||
@@ -36,7 +84,8 @@
|
|||||||
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel'])]}"/>
|
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel'])]}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
|
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
|
||||||
<attribute name="attrs">{'invisible': [('check_status', '=', False)]}
|
<attribute name="attrs">{'invisible': ['|',('state', 'in', ['cancel']),('check_status', 'in',
|
||||||
|
[False,'approved'])]}
|
||||||
</attribute>
|
</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
||||||
@@ -119,7 +168,6 @@
|
|||||||
<field name="model">sale.order</field>
|
<field name="model">sale.order</field>
|
||||||
<field name="inherit_id" ref="sale_management.sale_order_form_quote"/>
|
<field name="inherit_id" ref="sale_management.sale_order_form_quote"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
|
||||||
<field name="date_order" position="attributes">
|
<field name="date_order" position="attributes">
|
||||||
<attribute name="string">下单日期</attribute>
|
<attribute name="string">下单日期</attribute>
|
||||||
</field>
|
</field>
|
||||||
@@ -141,6 +189,7 @@
|
|||||||
<field name="inherit_id" ref="sale.view_quotation_tree_with_onboarding"/>
|
<field name="inherit_id" ref="sale.view_quotation_tree_with_onboarding"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree position="attributes">
|
<tree position="attributes">
|
||||||
|
<attribute name="default_order">check_status desc,create_date asc</attribute>
|
||||||
<attribute name="delete">False</attribute>
|
<attribute name="delete">False</attribute>
|
||||||
</tree>
|
</tree>
|
||||||
<field name="name" position="attributes">
|
<field name="name" position="attributes">
|
||||||
@@ -164,6 +213,7 @@
|
|||||||
<field name="inherit_id" ref="sale.view_order_tree"/>
|
<field name="inherit_id" ref="sale.view_order_tree"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree position="attributes">
|
<tree position="attributes">
|
||||||
|
<attribute name="default_order">schedule_status desc,date_order asc</attribute>
|
||||||
<attribute name="create">False</attribute>
|
<attribute name="create">False</attribute>
|
||||||
</tree>
|
</tree>
|
||||||
<field name="name" position="attributes">
|
<field name="name" position="attributes">
|
||||||
|
|||||||
Reference in New Issue
Block a user