diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss index eddf019b..2b1c6cfc 100644 --- a/jikimo_frontend/static/src/scss/custom_style.scss +++ b/jikimo_frontend/static/src/scss/custom_style.scss @@ -132,11 +132,11 @@ td.o_required_modifier { //font-weight: bold; } -//.text-truncate { -// overflow: unset !important; -// text-overflow: unset !important; -// white-space: nowrap!important; -//} +.text-truncate { + overflow: unset !important; + text-overflow: unset !important; + //white-space: nowrap!important; +} .o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove) { white-space: nowrap !important; @@ -425,7 +425,13 @@ div:has(.o_required_modifier) > label::before { .o_list_renderer .o_list_table thead .o_list_number_th { text-align:left; } - +.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector).o_list_number { + text-align: left; +} .o_list_renderer .flex-row-reverse { flex-direction: unset!important; +} + +.o_list_renderer .flex-row-reverse > .text-end { + text-align: left!important; } \ No newline at end of file diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 809462a9..f6e58855 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -17,9 +17,32 @@ class MrpProduction(models.Model): maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests") request_ids = fields.One2many('maintenance.request', 'production_id') model_file = fields.Binary('模型文件', related='product_id.model_file') - schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排')], + schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排'), ('已完成', '已完成')], 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) active = fields.Boolean(string='已归档', default=True) programming_no = fields.Char('编程单号') @@ -27,6 +50,45 @@ class MrpProduction(models.Model): programming_state = fields.Char('编程状态') 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): """ 审核启用 diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index bddb5236..509cf473 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -28,9 +28,9 @@ - - - + + + @@ -58,6 +58,9 @@ mrp.production + + draft,confirmed,progress,pending_processing,completed,done + diff --git a/sf_plan/__init__.py b/sf_plan/__init__.py index 8134f974..52497701 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 wizard diff --git a/sf_plan/__manifest__.py b/sf_plan/__manifest__.py index 257400d3..6059e3bd 100644 --- a/sf_plan/__manifest__.py +++ b/sf_plan/__manifest__.py @@ -17,8 +17,10 @@ 'data': [ 'security/ir.model.access.csv', # 'security/rules.xml', + 'wizard/action_plan_some.xml', 'views/view.xml', - 'views/change_manufactuing.xml' + 'views/change_manufactuing.xml', + ], 'assets': { diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index a60af7f3..03117a3a 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -12,14 +12,30 @@ class sf_production_plan(models.Model): _name = 'sf.production.plan' _description = 'sf_production_plan' _inherit = ['mail.thread'] - _order = 'create_date desc' + # _order = 'state desc, write_date desc' state = fields.Selection([ ('draft', '待排程'), ('done', '已排程'), - ('processing', '已加工'), + ('processing', '加工中'), ('finished', '已完成') ], 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='工单编号') active = fields.Boolean(string='已归档', default=True) # 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) 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 # 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): self.date_planned_finished = False self.state = 'draft' + self.production_line_id = False aa = self.env['mrp.production'].sudo().search([('name', '=', self.name)]) aa.schedule_state = '未排' return self.date_planned_finished diff --git a/sf_plan/security/ir.model.access.csv b/sf_plan/security/ir.model.access.csv index 3123afe9..be1708f7 100644 --- a/sf_plan/security/ir.model.access.csv +++ b/sf_plan/security/ir.model.access.csv @@ -1,3 +1,5 @@ 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_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 \ No newline at end of file diff --git a/sf_plan/views/view.xml b/sf_plan/views/view.xml index c1bdf5fe..7f5a1969 100644 --- a/sf_plan/views/view.xml +++ b/sf_plan/views/view.xml @@ -5,11 +5,13 @@ sf.production.plan.tree sf.production.plan - + +
-
- + diff --git a/sf_plan/wizard/__init__.py b/sf_plan/wizard/__init__.py new file mode 100644 index 00000000..1dd0edf6 --- /dev/null +++ b/sf_plan/wizard/__init__.py @@ -0,0 +1 @@ +from . import action_plan_some diff --git a/sf_plan/wizard/action_plan_some.py b/sf_plan/wizard/action_plan_some.py new file mode 100644 index 00000000..7078efae --- /dev/null +++ b/sf_plan/wizard/action_plan_some.py @@ -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 diff --git a/sf_plan/wizard/action_plan_some.xml b/sf_plan/wizard/action_plan_some.xml new file mode 100644 index 00000000..2c52658a --- /dev/null +++ b/sf_plan/wizard/action_plan_some.xml @@ -0,0 +1,31 @@ + + + + 选择生产线 + sf.action.plan.all.wizard + +
+ + + +
+
+
+
+
+ + 请选择要排程的生产线 + ir.actions.act_window + + sf.action.plan.all.wizard + form + + new + {'default_plan_ids': active_ids} + + + +
\ No newline at end of file diff --git a/sf_plan_management/i18n/zh_CN.po b/sf_plan_management/i18n/zh_CN.po index 1b311da9..ac175e4e 100644 --- a/sf_plan_management/i18n/zh_CN.po +++ b/sf_plan_management/i18n/zh_CN.po @@ -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_control.quality_check_view_search msgid "In Progress" -msgstr "进行中" +msgstr "待排程" #. module: stock #: 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.ui.menu,name:sf_plan.mrp_custom_menu msgid "制造订单" -msgstr "生产订单" +msgstr "制造订单" #. module: sf_plan #: model:ir.actions.act_window,name:sf_plan.sf_production_plan_action diff --git a/sf_sale/static/js/setTableWidth.js b/sf_sale/static/js/setTableWidth.js index 7cae3950..6e494214 100644 --- a/sf_sale/static/js/setTableWidth.js +++ b/sf_sale/static/js/setTableWidth.js @@ -11,15 +11,16 @@ function setTableWidth() { const tbody_tr = dom.find('tbody').children('tr') dom.find('thead').children('tr').children().each(function () { $('#widthTest').text($(this).text()) - const width = $('#widthTest').width() + const width = $('#widthTest').width() + 10 const i = $(this).index() - console.log(111) tbody_tr.each(function () { if($(this).children().length > 2) { $(this).children().eq(i).css('min-width', width + 'px') } }) }) + const resizeEvent = new Event('resize'); + window.dispatchEvent(resizeEvent); } $(function () { diff --git a/sf_tool_management/static/src/change.scss b/sf_tool_management/static/src/change.scss index a4e64f97..4c857c8c 100644 --- a/sf_tool_management/static/src/change.scss +++ b/sf_tool_management/static/src/change.scss @@ -11,11 +11,7 @@ } .o_form_view .o_field_widget .o_list_renderer { - width: calc(100% - 64px) !important; + width: 100%!important; margin:0 auto; overflow: auto; } - -.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector).o_list_number { - text-align: left; -} \ No newline at end of file