Improve the frontend
This commit is contained in:
@@ -5,6 +5,7 @@ import { useSuppliers } from '../../../api/hooks/suppliers';
|
||||
import { useCreatePurchaseOrder } from '../../../api/hooks/suppliers';
|
||||
import { useIngredients } from '../../../api/hooks/inventory';
|
||||
import { useTenantStore } from '../../../stores/tenant.store';
|
||||
import { suppliersService } from '../../../api/services/suppliers';
|
||||
import type { ProcurementRequirementResponse, PurchaseOrderItem } from '../../../api/types/orders';
|
||||
import type { SupplierSummary } from '../../../api/types/suppliers';
|
||||
import type { IngredientResponse } from '../../../api/types/inventory';
|
||||
@@ -31,6 +32,7 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [selectedSupplier, setSelectedSupplier] = useState<string>('');
|
||||
const [formData, setFormData] = useState<Record<string, any>>({});
|
||||
|
||||
// Get current tenant
|
||||
const { currentTenant } = useTenantStore();
|
||||
@@ -44,13 +46,49 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
);
|
||||
const suppliers = (suppliersData || []).filter(supplier => supplier.status === 'active');
|
||||
|
||||
// Fetch ingredients filtered by selected supplier (only when manually adding products)
|
||||
const { data: ingredientsData = [] } = useIngredients(
|
||||
// State for supplier products
|
||||
const [supplierProductIds, setSupplierProductIds] = useState<string[]>([]);
|
||||
const [isLoadingSupplierProducts, setIsLoadingSupplierProducts] = useState(false);
|
||||
|
||||
// Fetch ALL ingredients (we'll filter client-side based on supplier products)
|
||||
const { data: allIngredientsData = [], isLoading: isLoadingIngredients } = useIngredients(
|
||||
tenantId,
|
||||
selectedSupplier ? { supplier_id: selectedSupplier } : {},
|
||||
{ enabled: !!tenantId && isOpen && !requirements?.length && !!selectedSupplier }
|
||||
{},
|
||||
{ enabled: !!tenantId && isOpen && !requirements?.length }
|
||||
);
|
||||
|
||||
// Fetch supplier products when supplier is selected
|
||||
useEffect(() => {
|
||||
const fetchSupplierProducts = async () => {
|
||||
if (!selectedSupplier || !tenantId) {
|
||||
setSupplierProductIds([]);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoadingSupplierProducts(true);
|
||||
try {
|
||||
const products = await suppliersService.getSupplierProducts(tenantId, selectedSupplier);
|
||||
const productIds = products.map(p => p.inventory_product_id);
|
||||
setSupplierProductIds(productIds);
|
||||
} catch (error) {
|
||||
console.error('Error fetching supplier products:', error);
|
||||
setSupplierProductIds([]);
|
||||
} finally {
|
||||
setIsLoadingSupplierProducts(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchSupplierProducts();
|
||||
}, [selectedSupplier, tenantId]);
|
||||
|
||||
// Filter ingredients based on supplier products
|
||||
const ingredientsData = useMemo(() => {
|
||||
if (!selectedSupplier || supplierProductIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return allIngredientsData.filter(ing => supplierProductIds.includes(ing.id));
|
||||
}, [allIngredientsData, supplierProductIds, selectedSupplier]);
|
||||
|
||||
// Create purchase order mutation
|
||||
const createPurchaseOrderMutation = useCreatePurchaseOrder();
|
||||
|
||||
@@ -66,6 +104,14 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
data: ingredient // Store full ingredient data for later use
|
||||
})), [ingredientsData]);
|
||||
|
||||
// Reset selected supplier when modal closes
|
||||
useEffect(() => {
|
||||
if (!isOpen) {
|
||||
setSelectedSupplier('');
|
||||
setFormData({});
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// Unit options for select field
|
||||
const unitOptions = [
|
||||
{ value: 'kg', label: 'Kilogramos' },
|
||||
@@ -80,11 +126,6 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
const handleSave = async (formData: Record<string, any>) => {
|
||||
setLoading(true);
|
||||
|
||||
// Update selectedSupplier if it changed
|
||||
if (formData.supplier_id && formData.supplier_id !== selectedSupplier) {
|
||||
setSelectedSupplier(formData.supplier_id);
|
||||
}
|
||||
|
||||
try {
|
||||
let items: PurchaseOrderItem[] = [];
|
||||
|
||||
@@ -187,8 +228,9 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
};
|
||||
|
||||
|
||||
const sections = [
|
||||
{
|
||||
// Build sections dynamically based on selectedSupplier
|
||||
const sections = useMemo(() => {
|
||||
const supplierSection = {
|
||||
title: 'Información del Proveedor',
|
||||
icon: Building2,
|
||||
fields: [
|
||||
@@ -199,11 +241,19 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
required: true,
|
||||
options: supplierOptions,
|
||||
placeholder: 'Seleccionar proveedor...',
|
||||
span: 2
|
||||
span: 2,
|
||||
validation: (value: any) => {
|
||||
// Update selectedSupplier when supplier changes
|
||||
if (value && value !== selectedSupplier) {
|
||||
setTimeout(() => setSelectedSupplier(value), 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
};
|
||||
|
||||
const orderDetailsSection = {
|
||||
title: 'Detalles de la Orden',
|
||||
icon: Calendar,
|
||||
fields: [
|
||||
@@ -222,8 +272,9 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
helpText: 'Información adicional o instrucciones especiales'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
};
|
||||
|
||||
const ingredientsSection = {
|
||||
title: requirements && requirements.length > 0 ? 'Ingredientes Requeridos' : 'Productos a Comprar',
|
||||
icon: Package,
|
||||
fields: [
|
||||
@@ -281,7 +332,7 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
},
|
||||
helpText: 'Revisa y ajusta las cantidades y precios de los ingredientes requeridos'
|
||||
} : {
|
||||
label: 'Productos a Comprar',
|
||||
label: selectedSupplier ? 'Productos a Comprar' : 'Selecciona un proveedor primero',
|
||||
name: 'manual_products',
|
||||
type: 'list' as const,
|
||||
span: 2,
|
||||
@@ -294,8 +345,8 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: ingredientOptions,
|
||||
placeholder: 'Seleccionar ingrediente...',
|
||||
disabled: false
|
||||
placeholder: isLoadingSupplierProducts || isLoadingIngredients ? 'Cargando ingredientes...' : ingredientOptions.length === 0 ? 'No hay ingredientes disponibles para este proveedor' : 'Seleccionar ingrediente...',
|
||||
disabled: !selectedSupplier || isLoadingIngredients || isLoadingSupplierProducts
|
||||
},
|
||||
{
|
||||
name: 'quantity',
|
||||
@@ -322,16 +373,26 @@ export const CreatePurchaseOrderModal: React.FC<CreatePurchaseOrderModalProps> =
|
||||
}
|
||||
],
|
||||
addButtonLabel: 'Agregar Ingrediente',
|
||||
emptyStateText: 'No hay ingredientes disponibles para este proveedor',
|
||||
emptyStateText: !selectedSupplier
|
||||
? 'Selecciona un proveedor para agregar ingredientes'
|
||||
: isLoadingSupplierProducts || isLoadingIngredients
|
||||
? 'Cargando ingredientes del proveedor...'
|
||||
: ingredientOptions.length === 0
|
||||
? 'Este proveedor no tiene ingredientes asignados en su lista de precios'
|
||||
: 'No hay ingredientes agregados',
|
||||
showSubtotals: true,
|
||||
subtotalFields: { quantity: 'quantity', price: 'unit_price' },
|
||||
disabled: !selectedSupplier
|
||||
},
|
||||
helpText: 'Selecciona ingredientes disponibles del proveedor seleccionado'
|
||||
helpText: !selectedSupplier
|
||||
? 'Primero selecciona un proveedor en la sección anterior'
|
||||
: 'Selecciona ingredientes disponibles del proveedor seleccionado'
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
return [supplierSection, orderDetailsSection, ingredientsSection];
|
||||
}, [requirements, supplierOptions, ingredientOptions, selectedSupplier, isLoadingIngredients, unitOptions]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user