# -*- coding: utf-8 -*- from odoo import models, fields, api, _ class GarmentDashboard(models.Model): _name = 'garment.dashboard' _description = 'Garment Manufacturing Real-Time KPI Dashboard' name = fields.Char(string='Dashboard', default='Tiruppur Factory Control Room') # Executive KPIs total_sales_orders = fields.Integer(string='Active Garment Orders', compute='_compute_kpis') total_ordered_pieces = fields.Integer(string='Total Booked Pieces', compute='_compute_kpis') active_production_plans = fields.Integer(string='Production Orders in Progress', compute='_compute_kpis') avg_production_progress = fields.Float(string='Average Production Progress %', compute='_compute_kpis') # Shop Floor & Sewing KPIs total_sewing_lines = fields.Integer(string='Active Sewing Lines', compute='_compute_kpis') today_target_pieces = fields.Integer(string="Today's Sewing Target", compute='_compute_kpis') today_actual_pieces = fields.Integer(string="Today's Actual Output", compute='_compute_kpis') avg_line_efficiency = fields.Float(string='Factory Efficiency %', compute='_compute_kpis') today_defects = fields.Integer(string="Today's Alteration Count", compute='_compute_kpis') # Material & Inventory KPIs total_fabric_stock_kg = fields.Float(string='Fabric Rolls in Stock (Kg)', compute='_compute_kpis') total_approved_rolls = fields.Integer(string='QC Approved Rolls', compute='_compute_kpis') total_finished_goods_pcs = fields.Integer(string='Finished Goods Stock (Pcs)', compute='_compute_kpis') # Operations & Subcontracting pending_jobwork_dc = fields.Integer(string='Pending Job Work Challans', compute='_compute_kpis') pending_quality_inspections = fields.Integer(string='Pending Quality Inspections', compute='_compute_kpis') active_rework_orders = fields.Integer(string='Open Rework Orders', compute='_compute_kpis') pending_dispatch_cartons = fields.Integer(string='Cartons Ready for Dispatch', compute='_compute_kpis') def _compute_kpis(self): for rec in self: # Sales orders = self.env['sale.order'].search([('is_garment_order', '=', True), ('state', 'in', ['sale', 'done'])]) rec.total_sales_orders = len(orders) rec.total_ordered_pieces = sum(orders.mapped('total_garment_qty')) # Production plans = self.env['garment.production.plan'].search([('state', 'in', ['planned', 'in_progress'])]) rec.active_production_plans = len(plans) rec.avg_production_progress = round(sum(plans.mapped('progress_pct')) / (len(plans) or 1), 1) # Sewing Lines & Today's Hourly lines = self.env['garment.sewing.line'].search([('active', '=', True)]) rec.total_sewing_lines = len(lines) today_logs = self.env['garment.sewing.hourly'].search([('date', '=', fields.Date.today())]) rec.today_target_pieces = sum(today_logs.mapped('total_target')) rec.today_actual_pieces = sum(today_logs.mapped('total_actual')) rec.today_defects = sum(today_logs.mapped('total_defects')) if today_logs: rec.avg_line_efficiency = round(sum(today_logs.mapped('efficiency_pct')) / len(today_logs), 1) else: rec.avg_line_efficiency = 0.0 # Fabric & FG rolls = self.env['garment.fabric.roll'].search([('status', 'in', ['received', 'inspected', 'approved', 'issued'])]) rec.total_fabric_stock_kg = round(sum(rolls.mapped('remaining_weight')), 1) rec.total_approved_rolls = self.env['garment.fabric.roll'].search_count([('status', '=', 'approved')]) fg = self.env['garment.finished.goods'].search([]) rec.total_finished_goods_pcs = sum(fg.mapped('on_hand_qty')) # Job Work & QC rec.pending_jobwork_dc = self.env['garment.jobwork.order'].search_count([('state', 'in', ['sent', 'partial'])]) rec.pending_quality_inspections = self.env['garment.quality.inspection'].search_count([('verdict', '=', 'rework_needed')]) rec.active_rework_orders = self.env['garment.rework.order'].search_count([('state', 'in', ['assigned', 'in_rework', 'ready_recheck'])]) # Packing rec.pending_dispatch_cartons = self.env['garment.carton'].search_count([('dispatch_id', '=', False)])