73 lines
4.4 KiB
Python
73 lines
4.4 KiB
Python
# -*- 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)])
|