diff --git a/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx b/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx index ffbd3748..16ed6968 100644 --- a/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx +++ b/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx @@ -359,7 +359,7 @@ export const UploadSalesDataStep: React.FC = ({ const newErrors: Record = {}; if (!stockFormData.current_quantity || Number(stockFormData.current_quantity) <= 0) { - newErrors.current_quantity = 'La cantidad debe ser mayor que cero'; + newErrors.current_quantity = t('setup_wizard:inventory.stock_errors.quantity_required', 'La cantidad debe ser mayor que cero'); } if (stockFormData.expiration_date) { @@ -368,13 +368,13 @@ export const UploadSalesDataStep: React.FC = ({ today.setHours(0, 0, 0, 0); if (expDate < today) { - newErrors.expiration_date = 'La fecha de caducidad está en el pasado'; + newErrors.expiration_date = t('setup_wizard:inventory.stock_errors.expiration_past', 'La fecha de caducidad está en el pasado'); } const threeDaysFromNow = new Date(today); threeDaysFromNow.setDate(threeDaysFromNow.getDate() + 3); if (expDate < threeDaysFromNow) { - newErrors.expiration_warning = '⚠️ Este ingrediente caduca muy pronto!'; + newErrors.expiration_warning = t('setup_wizard:inventory.stock_errors.expiring_soon', '⚠️ Este ingrediente caduca muy pronto!'); } } @@ -385,38 +385,45 @@ export const UploadSalesDataStep: React.FC = ({ const handleSaveStockLot = (addAnother: boolean = false) => { if (!addingStockForId || !validateStockForm()) return; - // Create a temporary stock lot entry (will be saved when ingredients are created) - const newLot: StockResponse = { - id: `temp-${Date.now()}`, - tenant_id: tenantId, - ingredient_id: addingStockForId, - current_quantity: Number(stockFormData.current_quantity), - expiration_date: stockFormData.expiration_date || undefined, - supplier_id: stockFormData.supplier_id || undefined, - batch_number: stockFormData.batch_number || undefined, - production_stage: ProductionStage.RAW_INGREDIENT, - quality_status: 'good', - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - } as StockResponse; + try { + // Create a temporary stock lot entry (will be saved when ingredients are created) + const newLot: StockResponse = { + id: `temp-${Date.now()}`, + tenant_id: tenantId, + ingredient_id: addingStockForId, + current_quantity: Number(stockFormData.current_quantity), + expiration_date: stockFormData.expiration_date || undefined, + supplier_id: stockFormData.supplier_id || undefined, + batch_number: stockFormData.batch_number || undefined, + production_stage: ProductionStage.RAW_INGREDIENT, + quality_status: 'good', + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + } as StockResponse; - // Add to local state - setIngredientStocks(prev => ({ - ...prev, - [addingStockForId]: [...(prev[addingStockForId] || []), newLot], - })); + // Add to local state for display + setIngredientStocks(prev => ({ + ...prev, + [addingStockForId]: [...(prev[addingStockForId] || []), newLot], + })); - if (addAnother) { - // Reset form for adding another lot - setStockFormData({ - current_quantity: '', - expiration_date: '', - supplier_id: stockFormData.supplier_id, // Keep supplier selected - batch_number: '', + if (addAnother) { + // Reset form for adding another lot + setStockFormData({ + current_quantity: '', + expiration_date: '', + supplier_id: stockFormData.supplier_id, // Keep supplier selected + batch_number: '', + }); + setStockErrors({}); + } else { + handleCancelStock(); + } + } catch (error) { + console.error('Error adding stock lot:', error); + setStockErrors({ + submit: t('common:error_saving', 'Error guardando. Por favor, inténtalo de nuevo.') }); - setStockErrors({}); - } else { - handleCancelStock(); } }; @@ -694,25 +701,29 @@ export const UploadSalesDataStep: React.FC = ({ {lots.map((lot) => (
{lot.current_quantity} {item.unit_of_measure} {lot.expiration_date && ( - - 📅 Caduca: {new Date(lot.expiration_date).toLocaleDateString('es-ES')} + + + + + {t('setup_wizard:inventory.expires', 'Exp')}: {new Date(lot.expiration_date).toLocaleDateString('es-ES')} )} {lot.batch_number && ( - Lote: {lot.batch_number} + {t('setup_wizard:inventory.batch', 'Lote')}: {lot.batch_number} )}
+
+
setStockFormData(prev => ({ ...prev, current_quantity: e.target.value }))} - className="w-full px-2 py-1 text-sm border rounded" - placeholder="0" + className={`w-full px-2 py-1 text-sm border ${stockErrors.current_quantity ? 'border-[var(--color-error)]' : 'border-[var(--border-secondary)]'} rounded focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]`} + placeholder="25.0" min="0" step="0.01" /> @@ -747,33 +775,38 @@ export const UploadSalesDataStep: React.FC = ({
setStockFormData(prev => ({ ...prev, expiration_date: e.target.value }))} - className="w-full px-2 py-1 text-sm border rounded" + className={`w-full px-2 py-1 text-sm border ${stockErrors.expiration_date ? 'border-[var(--color-error)]' : 'border-[var(--border-secondary)]'} rounded focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]`} /> {stockErrors.expiration_date && (

{stockErrors.expiration_date}

)} {stockErrors.expiration_warning && ( -

{stockErrors.expiration_warning}

+

+ + + + {stockErrors.expiration_warning} +

)}
setStockFormData(prev => ({ ...prev, batch_number: e.target.value }))} - className="w-full px-2 py-1 text-sm border rounded" - placeholder="Opcional" + className="w-full px-2 py-1 text-sm border border-[var(--border-secondary)] rounded focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]" + placeholder="LOT-2024-11" />
-
- 💡 Los lotes con fecha de caducidad se gestionarán automáticamente con FIFO -
-
+ + {/* Help Text with Icon */} +

+ + + + {t('setup_wizard:inventory.stock_help', 'El seguimiento de caducidad ayuda a prevenir desperdicios y habilita gestión de inventario FIFO')} +

+ + {/* Error Display */} + {stockErrors.submit && ( +
+ {stockErrors.submit} +
+ )} + + {/* Action Buttons */} +
-
@@ -822,7 +867,10 @@ export const UploadSalesDataStep: React.FC = ({ onClick={() => handleAddStockClick(item.id)} className="w-full px-3 py-2 text-xs border-2 border-dashed border-[var(--border-secondary)] hover:border-[var(--color-primary)] hover:bg-[var(--bg-secondary)] rounded-lg transition-colors text-[var(--text-secondary)] hover:text-[var(--color-primary)] font-medium" > - {lots.length === 0 ? '+ Agregar Stock Inicial (Opcional)' : '+ Agregar Otro Lote'} + {lots.length === 0 ? + t('setup_wizard:inventory.add_initial_stock', '+ Agregar Stock Inicial (Opcional)') : + t('setup_wizard:inventory.add_another_lot', '+ Agregar Otro Lote') + } )}