Cadena de valor: Logística, SCM y sistemas ERP
La cadena de valor es el concepto central para analizar y optimizar procesos empresariales. Comprende todas las actividades desde la adquisición de materias primas hasta la entrega al cliente final.
Fundamentos de la cadena de valor
Definición y concepto
La cadena de valor según Porter describe las actividades secuenciales que realiza una empresa para crear productos o servicios y entregarlos al cliente.
Actividades primarias
graph TD
A[Logística de entrada] --> B[Operaciones]
B --> C[Logística de salida]
C --> D[Marketing y ventas]
D --> E[Servicio]
F[Actividades de apoyo] --> A
F --> B
F --> C
F --> D
F --> E
Actividades secundarias
- Infraestructura empresarial: Gestión, planificación, finanzas
- Gestión del personal: Reclutamiento, formación, compensación
- Desarrollo tecnológico: Investigación, mejora de procesos
- Compras: Adquisición de materias primas y servicios
Supply Chain Management (SCM)
Componentes del SCM
// Arquitectura del sistema SCM
public class SupplyChainManagement {
// Gestión de compras
public class ProcurementManagement {
private List<Supplier> suppliers;
private List<PurchaseOrder> orders;
public void createPurchaseOrder(Product product, int quantity, Supplier supplier) {
PurchaseOrder order = new PurchaseOrder(product, quantity, supplier);
orders.add(order);
// Evaluación de proveedores
updateSupplierRating(supplier, calculateDeliveryPerformance(supplier));
// Gestión de inventario
updateInventory(product, quantity);
}
private void updateSupplierRating(Supplier supplier, double performance) {
double currentRating = supplier.getPerformanceRating();
double newRating = (currentRating + performance) / 2;
supplier.setPerformanceRating(newRating);
}
}
// Gestión de almacenes
public class InventoryManagement {
private Map<Product, Integer> stockLevels = new HashMap<>();
private Map<Product, Integer> reorderPoints = new HashMap<>();
public void checkReorderLevels() {
for (Map.Entry<Product, Integer> entry : stockLevels.entrySet()) {
Product product = entry.getKey();
int currentStock = entry.getValue();
int reorderPoint = reorderPoints.getOrDefault(product, 0);
if (currentStock <= reorderPoint) {
triggerReorder(product, calculateOptimalOrderQuantity(product));
}
}
}
private int calculateOptimalOrderQuantity(Product product) {
// Fórmula EOQ: sqrt(2 * D * S / H)
double demand = product.getAnnualDemand();
double setupCost = product.getSetupCost();
double holdingCost = product.getHoldingCostPerUnit();
return (int) Math.sqrt((2 * demand * setupCost) / holdingCost);
}
}
// Gestión de transporte
public class TransportationManagement {
private List<Vehicle> vehicles;
private List<Route> routes;
public Route optimizeRoute(List<Delivery> deliveries) {
// Aproximación del Problema del Viajante
List<Location> locations = deliveries.stream()
.map(Delivery::getLocation)
.collect(Collectors.toList());
return calculateOptimalRoute(locations);
}
private Route calculateOptimalRoute(List<Location> locations) {
// Algoritmo del Vecino Más Cercano
Route route = new Route();
Location current = locations.get(0); // Inicio desde almacén
while (!locations.isEmpty()) {
Location nearest = findNearestLocation(current, locations);
route.addLocation(nearest);
locations.remove(nearest);
current = nearest;
}
return route;
}
}
}
Componentes de software del SCM
-- Modelo de base de datos SCM
CREATE TABLE Suppliers (
supplier_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
contact_person VARCHAR(100),
email VARCHAR(100),
phone VARCHAR(20),
performance_rating DECIMAL(3,2),
delivery_time INT,
quality_score DECIMAL(3,2)
);
CREATE TABLE Products (
product_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
unit_price DECIMAL(10,2),
annual_demand INT,
setup_cost DECIMAL(10,2),
holding_cost_per_unit DECIMAL(10,2),
reorder_point INT,
current_stock INT
);
CREATE TABLE PurchaseOrders (
order_id INT PRIMARY KEY,
supplier_id INT,
product_id INT,
quantity INT,
order_date DATE,
expected_delivery_date DATE,
actual_delivery_date DATE,
status VARCHAR(20),
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
FOREIGN KEY (supplier_id) REFERENCES Suppliers(supplier_id),
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
CREATE TABLE InventoryTransactions (
transaction_id INT PRIMARY KEY,
product_id INT,
transaction_type VARCHAR(20), -- 'IN', 'OUT', 'ADJUSTMENT'
quantity INT,
transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
reference_id INT, -- Purchase Order ID or Sales Order ID
notes TEXT,
FOREIGN KEY (product_id) REFERENCES Products(product_id)
);
CREATE TABLE Shipments (
shipment_id INT PRIMARY KEY,
order_id INT,
carrier VARCHAR(100),
tracking_number VARCHAR(50),
ship_date DATE,
expected_delivery_date DATE,
actual_delivery_date DATE,
status VARCHAR(20),
cost DECIMAL(10,2)
);
Gestión de logística
Logística de transporte y almacenamiento
# Ejemplo en Python para optimización logística
import numpy as np
from scipy.optimize import linear_sum_assignment
from datetime import datetime, timedelta
class LogisticsOptimizer:
def __init__(self):
self.warehouses = []
self.customers = []
self.vehicles = []
def optimize_distribution(self, demand_matrix, cost_matrix):
"""
Optimiza la distribución de mercancías entre almacenes
Utiliza el algoritmo húngaro para problemas de asignación
"""
# Algoritmo húngaro para costes mínimos
row_ind, col_ind = linear_sum_assignment(cost_matrix)
optimal_assignment = []
total_cost = 0
for i, j in zip(row_ind, col_ind):
if demand_matrix[i, j] > 0:
optimal_assignment.append({
'warehouse': i,
'customer': j,
'quantity': demand_matrix[i, j],
'cost': cost_matrix[i, j]
})
total_cost += demand_matrix[i, j] * cost_matrix[i, j]
return optimal_assignment, total_cost
def calculate_transport_costs(self, distance, weight, transport_mode):
"""
Calcula costes de transporte según diversos factores
"""
base_rates = {
'truck': 0.15, # € por km por 100kg
'rail': 0.08, # € por km por 100kg
'air': 0.45, # € por km por 100kg
'ship': 0.05 # € por km por 100kg
}
base_rate = base_rates.get(transport_mode, 0.15)
cost = distance * (weight / 100) * base_rate
# Costes adicionales
if transport_mode == 'air':
cost += 50 # Tarifa de manipulación
elif transport_mode == 'ship':
cost += 25 # Tarifa portuaria
return cost
def optimize_vehicle_loading(self, packages, vehicle_capacity):
"""
Problema de empaquetamiento para carga óptima de vehículos
"""
# Algoritmo codicioso para empaquetamiento
packages_sorted = sorted(packages, key=lambda x: x['weight'], reverse=True)
vehicles = []
for package in packages_sorted:
placed = False
# Intenta colocar el paquete en un vehículo existente
for vehicle in vehicles:
if vehicle['used_capacity'] + package['weight'] <= vehicle_capacity:
vehicle['packages'].append(package)
vehicle['used_capacity'] += package['weight']
placed = True
break
# Crea un vehículo nuevo si no hay espacio
if not placed:
vehicles.append({
'packages': [package],
'used_capacity': package['weight'],
'capacity': vehicle_capacity
})
return vehicles
# Ejemplo de optimización logística
optimizer = LogisticsOptimizer()
# Matriz de demanda (almacenes x clientes)
demand_matrix = np.array([
[100, 150, 200, 0, 50], # Almacén 1
[0, 200, 100, 150, 100], # Almacén 2
[150, 0, 100, 200, 150] # Almacén 3
])
# Matriz de costes (€ por unidad)
cost_matrix = np.array([
[10, 15, 20, 25, 30], # Desde almacén 1
[20, 10, 15, 20, 25], # Desde almacén 2
[15, 20, 10, 15, 20] # Desde almacén 3
])
assignment, total_cost = optimizer.optimize_distribution(demand_matrix, cost_matrix)
print(f"Coste total óptimo: €{total_cost:.2f}")
Planificación de rutas
// JavaScript para planificación de rutas con Google Maps API
class RouteOptimizer {
constructor() {
this.apiKey = 'YOUR_GOOGLE_MAPS_API_KEY';
}
async calculateOptimalRoute(locations, vehicleConstraints) {
// Vehicle Routing Problem con Google Directions API
const waypoints = locations.slice(1, -1).map(loc => ({
location: loc.address,
stopover: true
}));
const request = {
origin: locations[0].address,
destination: locations[locations.length - 1].address,
waypoints: waypoints,
optimize: true, // Optimiza el orden
travelMode: 'DRIVING',
unitSystem: 'METRIC',
vehicleConstraints: vehicleConstraints
};
try {
const response = await this.callDirectionsAPI(request);
return this.processRouteResponse(response);
} catch (error) {
console.error('Cálculo de ruta fallido:', error);
return null;
}
}
async callDirectionsAPI(request) {
const url = `https://routes.googleapis.com/directions/v2:computeRoutes?key=${this.apiKey}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Goog-Api-Key': this.apiKey
},
body: JSON.stringify(request)
});
return response.json();
}
processRouteResponse(response) {
const optimizedRoute = {
totalDistance: response.routes[0].legs.reduce((sum, leg) => sum + leg.distance.value, 0),
totalDuration: response.routes[0].legs.reduce((sum, leg) => sum + leg.duration.value, 0),
waypoints: response.routes[0].waypoint_order,
legs: response.routes[0].legs.map(leg => ({
distance: leg.distance,
duration: leg.duration,
start_address: leg.start_address,
end_address: leg.end_address,
steps: leg.steps
}))
};
return optimizedRoute;
}
calculateFuelConsumption(distance, vehicleType) {
const fuelConsumptionRates = {
'small_truck': 0.12, // Litros por km
'medium_truck': 0.18,
'large_truck': 0.25,
'van': 0.08
};
const rate = fuelConsumptionRates[vehicleType] || 0.15;
return distance * rate;
}
estimateDeliveryTime(distance, trafficConditions) {
const baseSpeed = 80; // km/h
const trafficFactor = trafficConditions === 'heavy' ? 0.6 :
trafficConditions === 'moderate' ? 0.8 : 1.0;
const adjustedSpeed = baseSpeed * trafficFactor;
return distance / adjustedSpeed; // Horas
}
}
// Ejemplo de optimización de rutas
const optimizer = new RouteOptimizer();
const locations = [
{ address: 'Múnich, Alemania', type: 'warehouse' },
{ address: 'Augsburgo, Alemania', type: 'customer' },
{ address: 'Ingolstadt, Alemania', type: 'customer' },
{ address: 'Núremberg, Alemania', type: 'customer' },
{ address: 'Ratisbona, Alemania', type: 'warehouse' }
];
const vehicleConstraints = {
maxWeight: 3500, // kg
maxHeight: 3.0, // metros
hazardousMaterials: false
};
optimizer.calculateOptimalRoute(locations, vehicleConstraints)
.then(route => {
console.log('Ruta optimizada:', route);
});
Sistemas ERP en la cadena de valor
Arquitectura de módulos ERP
-- Modelo de base de datos ERP para la cadena de valor
CREATE TABLE Companies (
company_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
tax_id VARCHAR(50),
address VARCHAR(200),
phone VARCHAR(50),
email VARCHAR(100),
website VARCHAR(100)
);
CREATE TABLE Warehouses (
warehouse_id INT PRIMARY KEY,
company_id INT,
name VARCHAR(100),
address VARCHAR(200),
capacity DECIMAL(10,2),
manager_id INT,
FOREIGN KEY (company_id) REFERENCES Companies(company_id)
);
CREATE TABLE ProductionOrders (
production_order_id INT PRIMARY KEY,
product_id INT,
quantity INT,
start_date DATE,
end_date DATE,
status VARCHAR(20),
priority INT,
assigned_workcenter_id INT,
material_cost DECIMAL(12,2),
labor_cost DECIMAL(12,2),
overhead_cost DECIMAL(12,2)
);
CREATE TABLE WorkCenters (
workcenter_id INT PRIMARY KEY,
name VARCHAR(100),
capacity_per_hour DECIMAL(8,2),
setup_time_minutes INT,
efficiency_rate DECIMAL(3,2),
maintenance_cost_per_hour DECIMAL(8,2)
);
CREATE TABLE QualityChecks (
check_id INT PRIMARY KEY,
production_order_id INT,
check_date TIMESTAMP,
inspector_id INT,
result VARCHAR(20), -- 'PASS', 'FAIL', 'REWORK'
defects_found INT,
corrective_action TEXT,
FOREIGN KEY (production_order_id) REFERENCES ProductionOrders(production_order_id)
);
Funcionalidad similar a SAP
// Sistema ERP con funcionalidad similar a SAP
public class ERPSystem {
// Material Management (MM)
public class MaterialManagement {
private Map<String, Material> materials = new HashMap<>();
private Map<String, MaterialDocument> materialDocuments = new HashMap<>();
public void createMaterial(String materialNumber, String description,
String materialType, String unitOfMeasure) {
Material material = new Material(materialNumber, description,
materialType, unitOfMeasure);
materials.put(materialNumber, material);
}
public MaterialDocument postGoodsMovement(String materialNumber, int quantity,
String movementType, String storageLocation) {
Material material = materials.get(materialNumber);
if (material == null) {
throw new IllegalArgumentException("Material not found: " + materialNumber);
}
// Actualizar existencias
updateStockLevels(materialNumber, quantity, movementType, storageLocation);
// Crear documento de material
MaterialDocument document = new MaterialDocument(
generateDocumentNumber(), materialNumber, quantity,
movementType, storageLocation, new Date()
);
materialDocuments.put(document.getDocumentNumber(), document);
return document;
}
private void updateStockLevels(String materialNumber, int quantity,
String movementType, String storageLocation) {
// Actualizar inventario según el tipo de movimiento
switch (movementType) {
case "101": // Recepción de mercancía
increaseStock(materialNumber, quantity, storageLocation);
break;
case "201": // Salida de almacén
decreaseStock(materialNumber, quantity, storageLocation);
break;
case "301": // Transferencia de almacén
transferStock(materialNumber, quantity, storageLocation);
break;
}
}
}
// Sales and Distribution (SD)
public class SalesDistribution {
private Map<String, SalesOrder> salesOrders = new HashMap<>();
private Map<String, Customer> customers = new HashMap<>();
private Map<String, BillingDocument> billingDocuments = new HashMap<>();
public SalesOrder createSalesOrder(String customerNumber, List<OrderItem> items) {
Customer customer = customers.get(customerNumber);
if (customer == null) {
throw new IllegalArgumentException("Customer not found: " + customerNumber);
}
// Cálculo de precios
BigDecimal totalAmount = calculateTotalAmount(items, customer);
// Verificar disponibilidad
checkAvailability(items);
SalesOrder salesOrder = new SalesOrder(
generateOrderNumber(), customerNumber, items,
new Date(), "OPEN", totalAmount
);
salesOrders.put(salesOrder.getOrderNumber(), salesOrder);
return salesOrder;
}
public BillingDocument createBillingDocument(String salesOrderNumber) {
SalesOrder salesOrder = salesOrders.get(salesOrderNumber);
if (salesOrder == null) {
throw new IllegalArgumentException("Sales order not found: " + salesOrderNumber);
}
BillingDocument billingDocument = new BillingDocument(
generateBillingNumber(), salesOrderNumber,
salesOrder.getItems(), salesOrder.getTotalAmount(), new Date()
);
billingDocuments.put(billingDocument.getBillingNumber(), billingDocument);
return billingDocument;
}
private BigDecimal calculateTotalAmount(List<OrderItem> items, Customer customer) {
BigDecimal total = BigDecimal.ZERO;
for (OrderItem item : items) {
// Considerar precios específicos del cliente
BigDecimal unitPrice = getCustomerSpecificPrice(item.getMaterialNumber(), customer);
BigDecimal itemTotal = unitPrice.multiply(BigDecimal.valueOf(item.getQuantity()));
total = total.add(itemTotal);
}
// Aplicar descuentos y recargos
total = applyDiscountsAndSurcharges(total, customer);
return total;
}
}
// Production Planning (PP)
public class ProductionPlanning {
private Map<String, ProductionOrder> productionOrders = new HashMap<>();
private Map<String, WorkCenter> workCenters = new HashMap<>();
public ProductionOrder createProductionOrder(String materialNumber, int quantity,
Date requiredDate) {
// Planificación de capacidad
WorkCenter suitableWorkCenter = findSuitableWorkCenter(materialNumber);
// Planificación de plazos
Date startDate = calculateStartDate(requiredDate, quantity, suitableWorkCenter);
Date endDate = calculateEndDate(startDate, quantity, suitableWorkCenter);
// Planificación de necesidades de material
List<MaterialRequirement> requirements =
calculateMaterialRequirements(materialNumber, quantity);
ProductionOrder order = new ProductionOrder(
generateProductionOrderNumber(), materialNumber, quantity,
startDate, endDate, suitableWorkCenter.getId(), "CREATED",
requirements
);
productionOrders.add(order);
return order;
}
private List<MaterialRequirement> calculateMaterialRequirements(String materialNumber,
int quantity) {
List<MaterialRequirement> requirements = new ArrayList<>();
// Expandir lista de materiales
BillOfMaterials bom = getBillOfMaterials(materialNumber);
for (BOMItem bomItem : bom.getItems()) {
double requiredQuantity = bomItem.getQuantity() * quantity;
MaterialRequirement requirement = new MaterialRequirement(
bomItem.getMaterialNumber(), requiredQuantity,
bomItem.getUnitOfMeasure(), "OPEN"
);
requirements.add(requirement);
}
return requirements;
}
}
}
Optimización de Procesos
Principios de Lean Management
# Implementación de Lean Management
class LeanManagement:
def __init__(self):
self.waste_types = [
'overproduction', 'waiting', 'transportation',
'inventory', 'motion', 'overprocessing', 'defects'
]
self.value_stream_maps = {}
def analyze_waste(self, process_data):
"""
Análisis de los 7 tipos de desperdicio (Muda)
"""
waste_analysis = {}
for waste_type in self.waste_types:
waste_analysis[waste_type] = self.calculate_waste_metrics(
process_data, waste_type
)
return waste_analysis
def calculate_waste_metrics(self, process_data, waste_type):
"""
Calcula métricas específicas para cada tipo de desperdicio
"""
metrics = {}
if waste_type == 'waiting':
# Analizar tiempos de espera
waiting_times = []
for step in process_data['process_steps']:
waiting_times.append(step.get('waiting_time', 0))
metrics['total_waiting_time'] = sum(waiting_times)
metrics['average_waiting_time'] = sum(waiting_times) / len(waiting_times)
metrics['waiting_percentage'] = (metrics['total_waiting_time'] /
process_data['total_cycle_time']) * 100
elif waste_type == 'inventory':
# Analizar sobrecarga de inventario
current_inventory = process_data.get('current_inventory', 0)
optimal_inventory = process_data.get('optimal_inventory', 0)
excess_inventory = max(0, current_inventory - optimal_inventory)
metrics['excess_inventory'] = excess_inventory
metrics['excess_inventory_value'] = excess_inventory * process_data.get('unit_cost', 0)
elif waste_type == 'defects':
# Analizar tasa de defectos
total_units = process_data.get('total_units', 0)
defective_units = process_data.get('defective_units', 0)
metrics['defect_rate'] = (defective_units / total_units) * 100
metrics['rework_cost'] = defective_units * process_data.get('rework_cost_per_unit', 0)
return metrics
def implement_5s(self, workplace_data):
"""
Implementar la metodología 5S
"""
improvements = []
# 1S - Seiri (Ordenar)
improvements.append(self.implement_sorting(workplace_data))
# 2S - Seiton (Organizar)
improvements.append(self.implement_systematization(workplace_data))
# 3S - Seiso (Limpiar)
improvements.append(self.implement_cleaning(workplace_data))
# 4S - Seiketsu (Estandarizar)
improvements.append(self.implement_standardization(workplace_data))
# 5S - Shitsuke (Disciplina)
improvements.append(self.implement_discipline(workplace_data))
return improvements
def implement_kaizen(self, current_process):
"""
Mejora continua (Kaizen)
"""
kaizen_suggestions = []
# Analizar pasos del proceso
for i, step in enumerate(current_process['steps']):
# Identificar cuellos de botella
if step.get('cycle_time', 0) > current_process.get('target_cycle_time', 0):
kaizen_suggestions.append({
'step': i,
'issue': 'Cycle time exceeds target',
'suggestion': 'Optimize work sequence or reduce setup time',
'potential_improvement': step['cycle_time'] - current_process['target_cycle_time']
})
# Identificar problemas de calidad
if step.get('defect_rate', 0) > current_process.get('target_defect_rate', 0):
kaizen_suggestions.append({
'step': i,
'issue': 'Defect rate exceeds target',
'suggestion': 'Implement error-proofing or improve training',
'potential_improvement': step['defect_rate'] - current_process['target_defect_rate']
})
return kaizen_suggestions
Implementación de Six Sigma
// Metodología Six Sigma DMAIC
public class SixSigmaImplementation {
// Fase Define
public ProjectDefinition defineProject(String problemStatement,
List<String> stakeholders,
Map<String, Object> projectGoals) {
ProjectDefinition definition = new ProjectDefinition();
definition.setProblemStatement(problemStatement);
definition.setStakeholders(stakeholders);
definition.setProjectGoals(projectGoals);
// Definir CTQs (Critical to Quality)
List<CriticalToQuality> ctqs = identifyCriticalToQuality(problemStatement);
definition.setCriticalToQualities(ctqs);
return definition;
}
// Fase Measure
public MeasurementSystem measureCurrentState(ProcessData currentData) {
MeasurementSystem measurement = new MeasurementSystem();
// Analizar capacidad del proceso (Cpk, Ppk)
double cpk = calculateProcessCapabilityIndex(currentData);
double ppk = calculateProcessPerformanceIndex(currentData);
measurement.setCpk(cpk);
measurement.setPpk(ppk);
// Análisis del sistema de medición (MSA)
MeasurementSystemAnalysis msa = performMeasurementSystemAnalysis(currentData);
measurement.setMsaResults(msa);
return measurement;
}
// Fase Analyze
public AnalysisResults analyzeRootCauses(ProcessData data, List<String> potentialCauses) {
AnalysisResults results = new AnalysisResults();
// Análisis estadístico
for (String cause : potentialCauses) {
double correlation = calculateCorrelation(data, cause);
double significance = calculateSignificance(data, cause);
if (significance < 0.05) { // Nivel de significancia 5%
results.addSignificantCause(cause, correlation, significance);
}
}
// Análisis de causa raíz
List<String> rootCauses = performRootCauseAnalysis(results.getSignificantCauses());
results.setRootCauses(rootCauses);
return results;
}
// Fase Improve
public ImprovementPlan developImprovementPlan(List<String> rootCauses) {
ImprovementPlan plan = new ImprovementPlan();
for (String cause : rootCauses) {
List<String> solutions = generateSolutions(cause);
for (String solution : solutions) {
SolutionEvaluation evaluation = evaluateSolution(solution, cause);
if (evaluation.getExpectedBenefit() > evaluation.getImplementationCost()) {
plan.addSolution(solution, evaluation);
}
}
}
// Priorizar soluciones
plan.prioritizeSolutions();
return plan;
}
// Fase Control
public ControlSystem implementControlSystem(ImprovementPlan plan) {
ControlSystem control = new ControlSystem();
// Implementar cartas de control
for (Solution solution : plan.getSelectedSolutions()) {
ControlChart chart = createControlChart(solution);
control.addControlChart(chart);
}
// Configurar sistema de alerta temprana
EarlyWarningSystem warningSystem = setupEarlyWarningSystem(control);
control.setEarlyWarningSystem(warningSystem);
return control;
}
private double calculateProcessCapabilityIndex(ProcessData data) {
double mean = data.getMean();
double stdDev = data.getStandardDeviation();
double upperSpec = data.getUpperSpecificationLimit();
double lowerSpec = data.getLowerSpecificationLimit();
double cpu = (upperSpec - mean) / (3 * stdDev);
double cpl = (mean - lowerSpec) / (3 * stdDev);
return Math.min(cpu, cpl);
}
private ControlChart createControlChart(Solution solution) {
ControlChart chart = new ControlChart();
chart.setProcessParameter(solution.getMonitoredParameter());
chart.setUpperControlLimit(solution.getUpperControlLimit());
chart.setLowerControlLimit(solution.getLowerControlLimit());
chart.setCenterLine(solution.getTargetValue());
return chart;
}
}
Transformación digital en la cadena de valor
Integración Industry 4.0
# IoT y Mantenimiento Predictivo
class Industry40Integration:
def __init__(self):
self.sensors = {}
self.predictive_models = {}
def setup_iot_sensors(self, equipment_id, sensor_types):
"""
Configurar sensores IoT para equipos de producción
"""
sensors = {}
for sensor_type in sensor_types:
sensor = {
'type': sensor_type,
'equipment_id': equipment_id,
'data_points': [],
'thresholds': self.get_sensor_thresholds(sensor_type),
'last_maintenance': datetime.now()
}
sensors[sensor_type] = sensor
self.sensors[equipment_id] = sensors
return sensors
def predict_maintenance_needs(self, equipment_id):
"""
Predecir necesidades de mantenimiento con Machine Learning
"""
if equipment_id not in self.sensors:
return None
sensors = self.sensors[equipment_id]
maintenance_prediction = {
'equipment_id': equipment_id,
'prediction_date': datetime.now(),
'maintenance_needed': False,
'urgency': 'LOW',
'predicted_failure_date': None,
'recommendations': []
}
# Analizar datos de sensores
for sensor_type, sensor_data in sensors.items():
recent_data = sensor_data['data_points'][-100:] # Últimos 100 puntos de datos
if len(recent_data) > 50:
# Análisis de tendencias
trend = self.calculate_trend(recent_data)
# Detección de anomalías
anomalies = self.detect_anomalies(recent_data, sensor_data['thresholds'])
# Aplicar modelo de predicción
failure_probability = self.predict_failure_probability(
recent_data, sensor_type
)
if failure_probability > 0.7: # Alta probabilidad de fallo
maintenance_prediction['maintenance_needed'] = True
maintenance_prediction['urgency'] = 'HIGH'
maintenance_prediction['predicted_failure_date'] = \
self.predict_failure_date(recent_data, failure_probability)
maintenance_prediction['recommendations'].append(
f"Immediate inspection required for {sensor_type} sensor"
)
elif failure_probability > 0.4: # Probabilidad media de fallo
maintenance_prediction['urgency'] = 'MEDIUM'
maintenance_prediction['recommendations'].append(
f"Schedule maintenance for {sensor_type} within 2 weeks"
)
return maintenance_prediction
def optimize_production_schedule(self, production_orders, equipment_status):
"""
Optimizar la planificación de producción con estado en tiempo real
"""
optimized_schedule = []
available_equipment = [eq for eq in equipment_status if eq['status'] == 'AVAILABLE']
for order in production_orders:
# Encontrar equipos adecuados
suitable_equipment = self.find_suitable_equipment(
order, available_equipment
)
if suitable_equipment:
# Pronosticar tiempo de producción
estimated_time = self.estimate_production_time(
order, suitable_equipment
)
# Optimizar consumo de energía
energy_optimization = self.optimize_energy_consumption(
order, suitable_equipment
)
scheduled_order = {
'order_id': order['id'],
'equipment_id': suitable_equipment['id'],
'start_time': self.calculate_start_time(order, optimized_schedule),
'estimated_duration': estimated_time,
'energy_optimization': energy_optimization
}
optimized_schedule.append(scheduled_order)
# Marcar equipo como ocupado
suitable_equipment['status'] = 'BUSY'
return optimized_schedule
def implement_blockchain_supply_chain(self):
"""
Implementar Blockchain para cadenas de suministro transparentes
"""
blockchain = SupplyChainBlockchain()
# Smart Contracts para eventos de cadena de suministro
blockchain.deploy_smart_contract('ProductTracking', '''
contract ProductTracking {
struct Product {
uint256 id;
string currentLocation;
uint256 timestamp;
address currentHolder;
string status;
}
mapping(uint256 => Product) public products;
event ProductMoved(uint256 productId, string newLocation, address newHolder);
function moveProduct(uint256 productId, string memory newLocation, address newHolder) public {
products[productId].currentLocation = newLocation;
products[productId].currentHolder = newHolder;
products[productId].timestamp = block.timestamp;
emit ProductMoved(productId, newLocation, newHolder);
}
}
''')
return blockchain
KPIs y medición de desempeño
Indicadores clave
-- Panel de control KPI para cadena de valor
CREATE TABLE SupplyChainKPIs (
kpi_id INT PRIMARY KEY,
kpi_name VARCHAR(100) NOT NULL,
kpi_category VARCHAR(50), -- 'Efficiency', 'Quality', 'Cost', 'Delivery'
calculation_method TEXT,
target_value DECIMAL(10,2),
current_value DECIMAL(10,2),
measurement_date DATE,
trend VARCHAR(10) -- 'IMPROVING', 'DECLINING', 'STABLE'
);
-- Cálculos de KPI
CREATE VIEW SupplyChainPerformance AS
SELECT
-- Eficiencia de la cadena de suministro
(SELECT COUNT(*) FROM PurchaseOrders WHERE status = 'DELIVERED' AND
DATEDIFF(actual_delivery_date, expected_delivery_date) <= 0) * 100.0 /
(SELECT COUNT(*) FROM PurchaseOrders WHERE status = 'DELIVERED') AS on_time_delivery_rate,
-- Eficiencia de inventario
(SELECT SUM(current_stock * unit_cost) FROM Products) /
(SELECT SUM(annual_demand * unit_cost) FROM Products) * 100 AS inventory_turnover_ratio,
-- Calidad
(SELECT COUNT(*) FROM QualityChecks WHERE result = 'PASS') * 100.0 /
(SELECT COUNT(*) FROM QualityChecks) AS first_pass_yield,
-- Costos
(SELECT SUM(total_amount) FROM PurchaseOrders WHERE
DATE(order_date) >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)) /
(SELECT SUM(quantity) FROM InventoryTransactions WHERE
transaction_type = 'IN' AND
DATE(transaction_date) >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY))
AS average_cost_per_unit;
Monitoreo de rendimiento
# Real-time Performance Monitoring
class SupplyChainMonitor:
def __init__(self):
self.kpi_thresholds = {
'on_time_delivery_rate': 95.0,
'inventory_turnover_ratio': 12.0,
'first_pass_yield': 98.0,
'order_fulfillment_cycle_time': 24.0
}
self.alerts = []
def monitor_real_time_kpis(self):
"""
Supervisión en tiempo real de los KPIs principales
"""
current_kpis = self.calculate_current_kpis()
alerts = []
for kpi_name, threshold in self.kpi_thresholds.items():
current_value = current_kpis.get(kpi_name, 0)
if current_value < threshold:
alert = {
'kpi_name': kpi_name,
'current_value': current_value,
'threshold': threshold,
'severity': self.calculate_alert_severity(current_value, threshold),
'timestamp': datetime.now(),
'recommendations': self.generate_recommendations(kpi_name, current_value)
}
alerts.append(alert)
self.alerts.extend(alerts)
return alerts
def calculate_current_kpis(self):
"""
Calcula los valores de KPI actuales desde la base de datos
"""
kpis = {}
# On-Time Delivery Rate
delivered_orders = self.get_delivered_orders_count()
total_orders = self.get_total_orders_count()
kpis['on_time_delivery_rate'] = (delivered_orders / total_orders) * 100 if total_orders > 0 else 0
# Inventory Turnover Ratio
total_inventory_value = self.get_total_inventory_value()
annual_cost_of_goods_sold = self.get_annual_cogs()
kpis['inventory_turnover_ratio'] = annual_cost_of_goods_sold / total_inventory_value if total_inventory_value > 0 else 0
# First Pass Yield
passed_inspections = self.get_passed_inspections_count()
total_inspections = self.get_total_inspections_count()
kpis['first_pass_yield'] = (passed_inspections / total_inspections) * 100 if total_inspections > 0 else 0
# Order Fulfillment Cycle Time
order_cycles = self.get_order_cycle_times()
kpis['order_fulfillment_cycle_time'] = sum(order_cycles) / len(order_cycles) if order_cycles else 0
return kpis
def generate_dashboard_data(self):
"""
Datos del dashboard para la vista general de la gerencia
"""
kpis = self.calculate_current_kpis()
alerts = self.monitor_real_time_kpis()
dashboard_data = {
'current_kpis': kpis,
'active_alerts': alerts,
'trend_analysis': self.analyze_trends(),
'benchmark_comparison': self.compare_with_benchmarks(kpis),
'improvement_opportunities': self.identify_improvement_opportunities(kpis)
}
return dashboard_data
Conceptos relevantes para el examen
Términos importantes
| Término | Descripción | Significado |
|---|---|---|
| Cadena de valor | Secuencia de actividades para crear valor | Modelo de Porter |
| SCM | Gestión de procesos de la cadena de suministro | Integración y optimización |
| ERP | Enterprise Resource Planning | Procesos empresariales integrados |
| Lean Management | Eliminar desperdicios | 5S, Kaizen, Just-in-Time |
| Six Sigma | Mejora de calidad | DMAIC, Control estadístico de procesos |
Tareas típicas de examen
- Analizar cadenas de valor
- Optimizar procesos de la cadena de suministro
- Implementar módulos ERP
- Aplicar Lean Management
- Calcular KPIs de la cadena de suministro
Resumen
Las cadenas de valor modernas requieren enfoques integrados:
- Los sistemas SCM optimizan los procesos de la cadena de suministro
- La integración ERP crea procesos continuos
- Lean y Six Sigma eliminan desperdicios
- La digitalización permite optimización en tiempo real
- El monitoreo de KPIs garantiza mejora continua
Las cadenas de valor exitosas están impulsadas por datos, orientadas al cliente y continuamente optimizadas.

