Installation
P.FLEX is a web-based application that can be deployed on-premises or in the cloud. Follow these steps to get started.
Prerequisites
Before installation, ensure you have:
Node.js 18+ installed on your server
Modern web browser (Chrome, Edge, Firefox)
Network access to your plant’s machines (for IoT integration)
User credentials from your systems administrator
Clone and Install Dependencies
Download the P.FLEX application and install required packages: # Install dependencies
npm install
This installs Angular 19, RxJS, TailwindCSS, and all required libraries.
Configure Environment
Set up your environment configuration in .env.local: # API Configuration
API_URL = http://localhost:3000
# Plant Configuration
PLANT_NAME = "Planta Central - Zona Industrial"
SHIFT_1_START = 06:00
SHIFT_2_START = 18:00
# Optional: Gemini API for AI features
GEMINI_API_KEY = your_api_key_here
The Gemini API key is optional and only required if you want to enable AI-powered production insights.
Start the Development Server
Launch P.FLEX in development mode: The application will be available at http://localhost:4200
Build for Production
When ready to deploy, create a production build: Deploy the contents of the dist/ folder to your web server.
First Login
After installation, access the system through your web browser.
Login Screen
The login interface provides secure access with shift selection:
Enter Your Credentials
Use your assigned username (employee ID or username): src/features/access/login.component.ts
// Example login implementation
onLogin () {
if ( this . username && this . selectedShift ) {
this . state . login ( this . username , this . selectedShift );
this . router . navigate ([ '/operator' ]);
}
}
Default Demo Accounts:
admin - Full system access (Systems role)
jefe - Management dashboard (Jefatura role)
jperez - Supervisor access
operario - Operator interface
Select Your Shift
Choose between Day Shift or Night Shift:
Turno Día : 06:00 - 18:00
Turno Noche : 18:00 - 06:00
Shift times are configurable in the system settings by administrators.
Authenticate
Click AUTENTICAR SISTEMA to log in. The system will:
Validate your credentials
Log the access event to the audit trail
Redirect you to your role-appropriate dashboard
Role-Based Dashboards
Depending on your role, you’ll see different interfaces:
Operator View Simplified interface for machine operators to register production, report issues, and view assigned work orders.
Supervisor Dashboard Full control center with KPIs, machine status, active orders, and incident management.
First Tasks
Let’s perform common operations to familiarize yourself with P.FLEX.
1. View the Dashboard
The main dashboard provides a real-time overview of your plant:
src/features/dashboard/dashboard.component.ts
// Dashboard calculates live statistics
get stats () {
const all = this . ordersService . ots ;
let totalMeters = 0 ;
all . forEach ( ot => {
const mtl = parseFloat ( String ( ot . total_mtl || '0' ). replace ( /,/ g , '' ));
if ( ! isNaN ( mtl )) totalMeters += mtl ;
});
return {
pending: all . filter ( ot => ot . Estado_pedido === 'PENDIENTE' ). length ,
totalMeters: Math . round ( totalMeters )
};
}
Key Metrics Displayed:
OEE Global : Overall Equipment Effectiveness (target: >80%)
Active Work Orders : Currently in production
Active Incidents : Quality or machine issues requiring attention
Volume (meters) : Total production output
Energy Efficiency : Power consumption vs. output
Sync Queue : Pending offline synchronizations
2. Create a Work Order
Add a new production order to the system:
Access Order Management
Navigate to Orders → OT List from the sidebar
Click 'Nueva OT'
This opens the work order creation form with fields:
OT Number (unique identifier)
Client / Razon Social
Product Description
Total Meters
Machine Assignment
Status (Pendiente, En Proceso, Finalizada)
Save the Order
The order is immediately available for production scheduling: handleOtSave ( formData : Partial < OT > ) {
const currentOts = this . ordersService . ots ;
const existingIndex = currentOts . findIndex (
o => String ( o . OT ) === String ( formData . OT )
);
let updatedOts = [ ... currentOts ];
if ( existingIndex !== - 1 ) {
updatedOts [ existingIndex ] = { ... updatedOts [ existingIndex ], ... formData };
} else {
updatedOts . push ( formData );
}
this . ordersService . updateOts ( updatedOts );
alert ( `OT ${ formData . OT } guardada correctamente.` );
}
Work orders can also be imported in bulk from Excel files. See the Orders Management guide for details.
3. Schedule Production
Assign work orders to machines using the visual Gantt chart:
Open Production Planning
Navigate to Planning → Schedule to see the Gantt chart view
Select Area and Shift
Choose Impresión , Troquelado , or Rebobinado
Select Día or Noche shift
Drag to Schedule
Click ASIGNAR to create a new production slot: src/features/planning/schedule.component.ts
saveJob () {
if ( this . tempStartDateTime ) {
const d = new Date ( this . tempStartDateTime );
this . currentJob . start =
` ${ d . getHours (). toString (). padStart ( 2 , '0' ) } : ${ d . getMinutes (). toString (). padStart ( 2 , '0' ) } ` ;
}
this . currentJob . duration = Math . round ( this . tempDurationHours * 60 );
if ( this . isEditing ) {
this . _jobs = this . _jobs . map ( j =>
j . id === this . currentJob . id ? this . currentJob : j
);
} else {
this . currentJob . id = Math . random (). toString ( 36 ). substr ( 2 , 9 );
this . _jobs . push ( this . currentJob );
}
this . showJobModal = false ;
}
Validate Resources
P.FLEX checks tooling availability:
Are required clichés in inventory?
Is the die available and in good condition?
Is substrate material in stock?
4. Register Production Output
Operators log production results:
Select Machine
From the operator interface, choose your assigned machine (e.g., IMP-01, TRQ-03)
Enter Production Data
Record:
Meters produced
Quality status (OK, Defects, Scrap)
Downtime reasons (if any)
Tooling condition (Cliché and Die status)
Submit Report
Data is logged with timestamp and operator ID: // Production report includes tooling status
const report = {
ot: '45001' ,
machine: 'IMP-01' ,
operator: 'Juan Martinez' ,
totalMeters: 15000 ,
activities: [
{ type: 'Setup' , startTime: '07:00' , endTime: '08:30' , meters: 0 },
{ type: 'Impresión' , startTime: '08:30' , endTime: '11:00' , meters: 6000 },
{ type: 'Impresión' , startTime: '11:15' , endTime: '13:00' , meters: 9000 }
],
clise: { code: 'CL-45001-01' , status: 'OK' },
die: { status: 'OK' }
};
5. Manage Inventory
Track tooling and materials:
Clichés (Printing Plates) Upload Excel inventory with item codes, client, dimensions, location, and accumulated meters.
Dies (Troqueles) Track series, dimensions, cavities, material, and wear status.
Finished Goods Monitor completed production with OT number, rolls, millares, location, and quality status (Liberado, Cuarentena, Retenido).
Visual Warehouse Map See rack locations with capacity indicators and quick item lookup.
src/features/inventory/services/inventory.service.ts
// Import and normalize inventory data
normalizeCliseData ( rawData : any []): { valid: CliseItem [], conflicts: CliseItem [] } {
const normalized = this . excelService . normalizeData ( rawData , this . CLISE_MAPPING );
const mapped : CliseItem [] = normalized . map ( row => ({
id: Math . random (). toString ( 36 ). substr ( 2 , 9 ),
item: String ( row . item || '' ). trim (),
ubicacion: String ( row . ubicacion || '' ). trim (),
descripcion: String ( row . descripcion || '' ). trim (),
cliente: String ( row . cliente || '' ). trim (),
ancho: this . excelService . parseNumber ( row . ancho ),
avance: this . excelService . parseNumber ( row . avance ),
mtl_acum: this . excelService . parseNumber ( row . mtl_acum )
}));
const valid = mapped . filter (( i : CliseItem ) => i . item && i . cliente );
const conflicts = mapped . filter (( i : CliseItem ) => ! i . item || ! i . cliente );
return { valid , conflicts };
}
6. Report an Incident
When issues occur, log them in the quality system:
Click 'Falla' Button
From the dashboard or quick actions menu
Fill Incident Details
Title and description
Priority (Alta, Media, Baja)
Type (Maquinaria, Material, Calidad, Otro)
Related OT and machine
Assign CAPA Actions
Add corrective and preventive actions: src/features/quality/services/quality.service.ts
addCapaAction ( incidentId : string , action : Partial < CapaAction > ) {
const newAction : CapaAction = {
id: Math . random (). toString ( 36 ). substr ( 2 , 9 ),
description: action . description || '' ,
type: action . type || 'Correctiva' ,
responsible: action . responsible || '' ,
deadline: action . deadline || new Date (). toISOString (). split ( 'T' )[ 0 ],
completed: false
};
// Update incident status to 'Acción Correctiva'
this . audit . log ( this . state . userName (), this . state . userRole (),
'CALIDAD' , 'Agregar Acción CAPA' ,
`Acción ${ newAction . type } agregada` );
}
Common Workflows
Daily Shift Startup
Log in with your credentials and select shift
Review dashboard for pending orders and alerts
Check machine status - update any machines in maintenance
Verify tooling availability for scheduled jobs
Start production and register outputs as you complete work
Excel Import Workflow
Bulk data import from spreadsheets:
// Handle Excel file upload
handleImport ( data : any []) {
const currentData = this . ordersService . ots ;
const importedData = data ;
let updatedData = [ ... currentData ];
importedData . forEach (( row : any ) => {
if ( ! row . OT ) return ;
const rowOtStr = String ( row . OT ). trim ();
const index = updatedData . findIndex (
item => String ( item . OT ). trim () === rowOtStr
);
if ( index !== - 1 ) {
// Update existing
const currentStatus = updatedData [ index ]. Estado_pedido ;
updatedData [ index ] = { ... updatedData [ index ], ... row };
if ( currentStatus ) updatedData [ index ]. Estado_pedido = currentStatus ;
} else {
// Add new
updatedData . push ({ ... row , Estado_pedido: 'PENDIENTE' });
}
});
this . ordersService . updateOts ( updatedData );
alert ( `Importación completada. ${ importedData . length } registros procesados.` );
}
Supported Formats : Excel (.xlsx), CSV. The system intelligently maps column headers to internal fields.
Export and Reporting
P.FLEX includes powerful export capabilities:
PDF Export Generate visual snapshots of dashboards, schedules, and reports with html2canvas and jsPDF.
Excel Export Export tabular data (orders, inventory, production logs) to Excel for further analysis.
// Export dashboard to Excel
exportToExcel () {
const wb = XLSX . utils . book_new ();
const dateStr = new Date (). toISOString (). split ( 'T' )[ 0 ];
// Sheet 1: KPIs
const statsData = [
[ 'REPORTE GENERAL DE PLANTA' , dateStr ],
[ '' ],
[ 'METRICAS PRINCIPALES' ],
[ 'OEE Global' , '82.4%' ],
[ 'OTs Activas' , this . activeProduction . length ],
[ 'Metros Totales' , '45.2k' ]
];
const wsStats = XLSX . utils . aoa_to_sheet ( statsData );
XLSX . utils . book_append_sheet ( wb , wsStats , "KPIs" );
// Sheet 2: Active Orders
const activeOTsData = this . activeProduction . map ( ot => ({
OT: ot . OT ,
Cliente: ot [ 'Razon Social' ],
Producto: ot . descripcion ,
Maquina: ot . maquina ,
Metros: ot . total_mtl
}));
const wsOTs = XLSX . utils . json_to_sheet ( activeOTsData );
XLSX . utils . book_append_sheet ( wb , wsOTs , "Producción" );
XLSX . writeFile ( wb , `Dashboard_Data_ ${ dateStr } .xlsx` );
}
Next Steps
Explore Key Features Learn about all 10+ modules and advanced capabilities
User Management Configure roles, permissions, and plant-specific settings
Machine Configuration Set up your production lines and equipment registry
Quality System Implement CAPA and incident management workflows
Getting Stuck? Check the detailed feature guides or consult your systems administrator for plant-specific configurations.