diff --git a/sf_demand_plan/__manifest__.py b/sf_demand_plan/__manifest__.py
index dc772ab2..c7df6fab 100644
--- a/sf_demand_plan/__manifest__.py
+++ b/sf_demand_plan/__manifest__.py
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '机企猫智能工厂 需求计划',
- 'version': '1.0',
+ 'version': '1.1',
'summary': '智能工厂计划管理',
'sequence': 1,
'description': """
@@ -13,7 +13,7 @@
'depends': ['sf_plan','jikimo_printing'],
'data': [
'security/ir.model.access.csv',
- 'views/demand_plan_info.xml.xml',
+ 'views/demand_plan_info.xml',
'views/demand_plan.xml',
'wizard/sf_demand_plan_print_wizard_view.xml',
],
diff --git a/sf_demand_plan/migrations/1.1/post-migrate.py b/sf_demand_plan/migrations/1.1/post-migrate.py
new file mode 100644
index 00000000..5f2a0286
--- /dev/null
+++ b/sf_demand_plan/migrations/1.1/post-migrate.py
@@ -0,0 +1,25 @@
+# migrations/1.1.0/post-migrate.py
+import os
+import csv
+import logging
+from odoo import api, SUPERUSER_ID
+
+_logger = logging.getLogger(__name__)
+
+
+def migrate(cr, version):
+ # 获取环境
+ env = api.Environment(cr, SUPERUSER_ID, {})
+
+ ProductionLine = env['sf.production.demand.plan']
+ DemandPlan = env['sf.demand.plan']
+
+ lines = ProductionLine.search([('demand_plan_id', '=', False)])
+ for line in lines:
+ vals = {
+ 'sale_order_id': line.sale_order_id.id,
+ 'sale_order_line_id': line.sale_order_line_id.id,
+ 'line_ids': line.ids
+ }
+ new_plan = DemandPlan.create(vals)
+ line.write({'demand_plan_id': new_plan.id})
diff --git a/sf_demand_plan/models/sale_order.py b/sf_demand_plan/models/sale_order.py
index 620bc3b3..c7ece36d 100644
--- a/sf_demand_plan/models/sale_order.py
+++ b/sf_demand_plan/models/sale_order.py
@@ -17,9 +17,9 @@ class ReSaleOrder(models.Model):
'sale_order_line_id': ret.id,
}
demand_plan_info = self.env['sf.demand.plan'].sudo().create(vals)
- vals.update({'demand_plan_id': demand_plan_info.id})
+ vals.update({'demand_plan_id': demand_plan_info.id, 'plan_uom_qty': ret.product_uom_qty})
demand_plan = self.env['sf.production.demand.plan'].sudo().create(vals)
- demand_plan_info.write({'line_ids': demand_plan.id})
+ demand_plan_info.write({'line_ids': demand_plan.ids})
if demand_plan.product_id.machining_drawings_name:
filename_url = demand_plan.product_id.machining_drawings_name.rsplit('.', 1)[0]
wizard_vals = {
diff --git a/sf_demand_plan/models/sf_demand_plan.py b/sf_demand_plan/models/sf_demand_plan.py
index 14c6a9de..b57ed713 100644
--- a/sf_demand_plan/models/sf_demand_plan.py
+++ b/sf_demand_plan/models/sf_demand_plan.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
+from odoo.tools import float_compare
class SfDemandPlan(models.Model):
@@ -17,7 +18,8 @@ class SfDemandPlan(models.Model):
('20', '待工艺设计'),
('30', '部分下达'),
('40', '已下达'),
- ], string='状态')
+ ('50', '取消'),
+ ], string='状态', default='10', compute='_compute_state', store=True)
line_ids = fields.One2many(comodel_name='sf.production.demand.plan',
inverse_name='demand_plan_id', string="需求计划", copy=True)
@@ -40,12 +42,12 @@ class SfDemandPlan(models.Model):
related='product_id.blank_type')
embryo_long = fields.Char('坯料尺寸(mm)', compute='_compute_embryo_long', store=True)
is_incoming_material = fields.Boolean('客供料', related='sale_order_line_id.is_incoming_material', store=True)
- # product_uom_qty = fields.Float(
- # string="待计划",
- # related='sale_order_line_id.product_uom_qty', store=True)
- # product_uom_qty = fields.Float(
- # string="已计划",
- # related='sale_order_line_id.product_uom_qty', store=True)
+ pending_qty = fields.Float(
+ string="待计划",
+ compute='_compute_pending_qty', store=True)
+ planned_qty = fields.Float(
+ string="已计划",
+ compute='_compute_planned_qty', store=True)
model_id = fields.Char('模型ID', related='product_id.model_id')
customer_name = fields.Char('客户', related='sale_order_id.customer_name')
product_uom_qty = fields.Float(
@@ -56,7 +58,7 @@ class SfDemandPlan(models.Model):
contract_code = fields.Char('合同号', related='sale_order_id.contract_code', store=True)
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
- 'plan_process_parameter_rel',
+ 'demand_plan_process_parameter_rel',
string='表面工艺',
compute='_compute_model_process_parameters_ids'
, store=True
@@ -76,7 +78,11 @@ class SfDemandPlan(models.Model):
('4', '低'),
], string='优先级', default='3')
- remark = fields.Char('备注')
+ hide_button_release_plan = fields.Boolean(
+ string='显示下达计划按钮',
+ compute='_compute_hide_button_release_plan',
+ default=False
+ )
@api.depends('product_id.part_number', 'product_id.model_name')
def _compute_part_number(self):
@@ -134,3 +140,41 @@ class SfDemandPlan(models.Model):
line.inventory_quantity_auto_apply = quantity_map.get(line.product_id.id, 0.0)
else:
line.inventory_quantity_auto_apply = 0.0
+
+ @api.depends('product_uom_qty', 'line_ids.plan_uom_qty')
+ def _compute_pending_qty(self):
+ for line in self:
+ sum_plan_uom_qty = sum(line.line_ids.mapped('plan_uom_qty'))
+ pending_qty = line.product_uom_qty - sum_plan_uom_qty
+ if float_compare(pending_qty, 0,
+ precision_rounding=line.product_id.uom_id.rounding) == -1:
+ line.pending_qty = 0
+ else:
+ line.pending_qty = pending_qty
+
+ @api.depends('line_ids.plan_uom_qty')
+ def _compute_planned_qty(self):
+ for line in self:
+ line.planned_qty = sum(line.line_ids.mapped('plan_uom_qty'))
+
+ @api.depends('line_ids.status')
+ def _compute_hide_button_release_plan(self):
+ for line in self:
+ line.hide_button_release_plan = bool(line.line_ids.filtered(
+ lambda p: p.status != '60'))
+
+ def button_release_plan(self):
+ pass
+
+ @api.depends('line_ids.status', 'sale_order_id.state')
+ def _compute_state(self):
+ for line in self:
+ status_line = line.line_ids.filtered(lambda p: p.status == '60')
+ if line.sale_order_id.state == 'cancel':
+ line.state = '50'
+ elif len(line.line_ids) == len(status_line):
+ line.state = '40'
+ elif bool(status_line):
+ line.state = '30'
+ else:
+ line.state = '10'
diff --git a/sf_demand_plan/models/sf_production_demand_plan.py b/sf_demand_plan/models/sf_production_demand_plan.py
index 6c745f3b..99b1d1ef 100644
--- a/sf_demand_plan/models/sf_production_demand_plan.py
+++ b/sf_demand_plan/models/sf_production_demand_plan.py
@@ -5,7 +5,6 @@ from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo.tools import float_compare
from datetime import datetime, timedelta
-from odoo.exceptions import UserError
class SfProductionDemandPlan(models.Model):
@@ -22,7 +21,7 @@ class SfProductionDemandPlan(models.Model):
('2', '高'),
('3', '中'),
('4', '低'),
- ], string='优先级', default='3')
+ ], string='优先级', related='demand_plan_id.priority')
status = fields.Selection([
('10', '草稿'),
('20', '待确认'),
@@ -30,7 +29,7 @@ class SfProductionDemandPlan(models.Model):
('50', '待下达生产'),
('60', '已下达'),
('100', '取消'),
- ], string='状态', compute='_compute_status', store=True)
+ ], string='状态', compute='_compute_status', store=True, readonly=False)
demand_plan_id = fields.Many2one(comodel_name="sf.demand.plan",
string="物料需求", readonly=True)
sale_order_id = fields.Many2one(comodel_name="sale.order",
@@ -58,7 +57,7 @@ class SfProductionDemandPlan(models.Model):
('manual', "人工线下加工"),
('purchase', "外购"),
('outsourcing', "委外加工"),
- ], string='供货方式', related='sale_order_line_id.supply_method', store=True)
+ ], string='供货方式')
product_uom_qty = fields.Float(
string="需求数量",
related='sale_order_line_id.product_uom_qty', store=True)
@@ -78,12 +77,8 @@ class SfProductionDemandPlan(models.Model):
materials_id = fields.Char('材料', related='demand_plan_id.materials_id')
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='精度',
related='product_id.model_machining_precision')
- model_process_parameters_ids = fields.Many2many('sf.production.process.parameter',
- 'plan_process_parameter_rel',
- string='表面工艺',
- related='demand_plan_id.model_process_parameters_ids'
- , store=True
- )
+ model_process_parameters_ids = fields.Many2many(related='demand_plan_id.model_process_parameters_ids',
+ string='表面工艺', )
product_remark = fields.Char("产品备注", related='product_id.model_remark')
order_code = fields.Char('E-SHOP订单号', related='sale_order_id.order_code')
order_state = fields.Selection(
@@ -137,6 +132,16 @@ class SfProductionDemandPlan(models.Model):
outsourcing_purchase_request = fields.Char('委外采购申请单')
+ plan_uom_qty = fields.Float(string="计划量")
+ procurement_reason = fields.Selection([
+ ('销售订单', "销售订单"),
+ ('需求预测', "需求预测"),
+ ('生产报废', "生产报废"),
+ ], string='补货原因', default='销售订单')
+
+ blank_arrival_date = fields.Date('采购计划到货(坯料)')
+ finished_product_arrival_date = fields.Date('采购计划到货(成品)')
+
@api.depends('sale_order_id.state', 'sale_order_id.mrp_production_ids.schedule_state', 'sale_order_id.order_line',
'sale_order_id.mrp_production_ids.state')
def _compute_status(self):
@@ -271,14 +276,18 @@ class SfProductionDemandPlan(models.Model):
self._do_production_schedule(pro_plan_list)
def edit_button(self):
- return {
- 'res_model': 'sf.demand.plan',
- 'type': 'ir.actions.act_window',
+ self.ensure_one()
+ action = {
'name': _("需求计划"),
- 'domain': [('line_ids', 'in', self.demand_plan_id.ids)],
- 'views': [[self.env.ref('sf_demand_plan.view_sf_demand_plan_list').id, 'list']],
- 'target': 'new',
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'views': [[self.env.ref('sf_demand_plan.view_sf_demand_plan_form').id, 'form']],
+ 'res_model': 'sf.demand.plan',
+ 'res_id': self.demand_plan_id.id,
}
+ if self.demand_plan_id.state == '40':
+ action.update({'flags': {'mode': 'readonly'}})
+ return action
def _do_production_schedule(self, pro_plan_list):
for pro_plan in pro_plan_list:
@@ -502,3 +511,9 @@ class SfProductionDemandPlan(models.Model):
programming_no = list(set(programming_mrp_production_ids))
numbers_str = "、".join(programming_no)
raise ValidationError(f"编程单号:{numbers_str},请去云平台处理")
+
+ def button_delete(self):
+ self.ensure_one()
+ if len(self.demand_plan_id.line_ids) == 1:
+ raise ValidationError(f"最后一条计划,不能删除!")
+ self.unlink()
diff --git a/sf_demand_plan/security/ir.model.access.csv b/sf_demand_plan/security/ir.model.access.csv
index 106f6fc9..b588c8b6 100644
--- a/sf_demand_plan/security/ir.model.access.csv
+++ b/sf_demand_plan/security/ir.model.access.csv
@@ -1,6 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_production_demand_plan,sf.production.demand.plan,model_sf_production_demand_plan,base.group_user,1,0,0,0
-access_sf_production_demand_plan_for_dispatch,sf.production.demand.plan for dispatch,model_sf_production_demand_plan,sf_base.group_plan_dispatch,1,1,0,0
+access_sf_production_demand_plan_for_dispatch,sf.production.demand.plan for dispatch,model_sf_production_demand_plan,sf_base.group_plan_dispatch,1,1,1,1
access_sf_demand_plan_print_wizard,sf.demand.plan.print.wizard,model_sf_demand_plan_print_wizard,base.group_user,1,0,0,0
access_sf_demand_plan_print_wizard_for_dispatch,sf.demand.plan.print.wizard for dispatch,model_sf_demand_plan_print_wizard,sf_base.group_plan_dispatch,1,1,0,0
diff --git a/sf_demand_plan/views/demand_plan.xml b/sf_demand_plan/views/demand_plan.xml
index b4c643ce..8dff8149 100644
--- a/sf_demand_plan/views/demand_plan.xml
+++ b/sf_demand_plan/views/demand_plan.xml
@@ -4,7 +4,7 @@
sf.production.demand.plan
+ class="demand_plan_tree" create="false" delete="false">
@@ -93,7 +93,8 @@
-
+
-
- sf.demand.plan.list
+
+ sf.demand.plan.form
sf.demand.plan
@@ -32,6 +36,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+