2025-09-18 23:32:53 +02:00
|
|
|
// frontend/src/utils/enumHelpers.ts
|
|
|
|
|
/**
|
|
|
|
|
* Utilities for working with enums and translations
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
import type { SelectOption } from '../components/ui/Select';
|
|
|
|
|
import {
|
|
|
|
|
SupplierType,
|
|
|
|
|
SupplierStatus,
|
|
|
|
|
PaymentTerms,
|
|
|
|
|
PurchaseOrderStatus,
|
|
|
|
|
DeliveryStatus,
|
|
|
|
|
QualityRating,
|
|
|
|
|
DeliveryRating,
|
|
|
|
|
InvoiceStatus,
|
|
|
|
|
type EnumOption
|
|
|
|
|
} from '../api/types/suppliers';
|
|
|
|
|
|
2025-09-19 11:44:38 +02:00
|
|
|
import {
|
|
|
|
|
CustomerType,
|
|
|
|
|
DeliveryMethod,
|
|
|
|
|
PaymentTerms as OrderPaymentTerms,
|
|
|
|
|
PaymentMethod,
|
|
|
|
|
PaymentStatus,
|
|
|
|
|
CustomerSegment,
|
|
|
|
|
PriorityLevel,
|
|
|
|
|
OrderType,
|
|
|
|
|
OrderStatus,
|
|
|
|
|
OrderSource,
|
|
|
|
|
SalesChannel
|
|
|
|
|
} from '../api/types/orders';
|
|
|
|
|
|
2025-09-18 23:32:53 +02:00
|
|
|
/**
|
|
|
|
|
* Generic function to convert enum to select options with i18n translations
|
|
|
|
|
*/
|
|
|
|
|
export function enumToSelectOptions<T extends Record<string, string | number>>(
|
|
|
|
|
enumObject: T,
|
|
|
|
|
translationKey: string,
|
|
|
|
|
t: (key: string) => string,
|
|
|
|
|
options?: {
|
|
|
|
|
includeDescription?: boolean;
|
|
|
|
|
descriptionKey?: string;
|
|
|
|
|
sortAlphabetically?: boolean;
|
|
|
|
|
}
|
|
|
|
|
): SelectOption[] {
|
|
|
|
|
const selectOptions = Object.entries(enumObject).map(([key, value]) => ({
|
|
|
|
|
value,
|
|
|
|
|
label: t(`${translationKey}.${value}`),
|
|
|
|
|
...(options?.includeDescription && options?.descriptionKey && {
|
|
|
|
|
description: t(`${options.descriptionKey}.${value}`)
|
|
|
|
|
})
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
if (options?.sortAlphabetically) {
|
|
|
|
|
selectOptions.sort((a, b) => a.label.localeCompare(b.label));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return selectOptions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Hook for supplier enum utilities
|
|
|
|
|
*/
|
|
|
|
|
export function useSupplierEnums() {
|
|
|
|
|
const { t } = useTranslation('suppliers');
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
// Supplier Type
|
|
|
|
|
getSupplierTypeOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(SupplierType, 'types', t, {
|
|
|
|
|
includeDescription: true,
|
|
|
|
|
descriptionKey: 'descriptions'
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
getSupplierTypeLabel: (type: SupplierType): string => {
|
|
|
|
|
if (!type) return 'Tipo no definido';
|
|
|
|
|
return t(`types.${type}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Supplier Status
|
|
|
|
|
getSupplierStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(SupplierStatus, 'status', t),
|
|
|
|
|
|
|
|
|
|
getSupplierStatusLabel: (status: SupplierStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Payment Terms
|
|
|
|
|
getPaymentTermsOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(PaymentTerms, 'payment_terms', t, {
|
|
|
|
|
includeDescription: true,
|
|
|
|
|
descriptionKey: 'descriptions'
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
getPaymentTermsLabel: (terms: PaymentTerms): string => {
|
|
|
|
|
if (!terms) return 'Sin términos definidos';
|
|
|
|
|
return t(`payment_terms.${terms}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Purchase Order Status
|
|
|
|
|
getPurchaseOrderStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(PurchaseOrderStatus, 'purchase_order_status', t),
|
|
|
|
|
|
|
|
|
|
getPurchaseOrderStatusLabel: (status: PurchaseOrderStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`purchase_order_status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Delivery Status
|
|
|
|
|
getDeliveryStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(DeliveryStatus, 'delivery_status', t),
|
|
|
|
|
|
|
|
|
|
getDeliveryStatusLabel: (status: DeliveryStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`delivery_status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Quality Rating
|
|
|
|
|
getQualityRatingOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(QualityRating, 'quality_rating', t, {
|
|
|
|
|
includeDescription: true,
|
|
|
|
|
descriptionKey: 'descriptions'
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
getQualityRatingLabel: (rating: QualityRating): string => {
|
|
|
|
|
if (rating === undefined || rating === null) return 'Sin calificación';
|
|
|
|
|
return t(`quality_rating.${rating}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Delivery Rating
|
|
|
|
|
getDeliveryRatingOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(DeliveryRating, 'delivery_rating', t, {
|
|
|
|
|
includeDescription: true,
|
|
|
|
|
descriptionKey: 'descriptions'
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
getDeliveryRatingLabel: (rating: DeliveryRating): string => {
|
|
|
|
|
if (rating === undefined || rating === null) return 'Sin calificación';
|
|
|
|
|
return t(`delivery_rating.${rating}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Invoice Status
|
|
|
|
|
getInvoiceStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(InvoiceStatus, 'invoice_status', t),
|
|
|
|
|
|
|
|
|
|
getInvoiceStatusLabel: (status: InvoiceStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`invoice_status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Field Labels
|
|
|
|
|
getFieldLabel: (field: string): string =>
|
|
|
|
|
t(`labels.${field}`),
|
|
|
|
|
|
|
|
|
|
getFieldDescription: (field: string): string =>
|
|
|
|
|
t(`descriptions.${field}`)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Utility to get enum value from select option value
|
|
|
|
|
*/
|
|
|
|
|
export function getEnumFromValue<T>(
|
|
|
|
|
enumObject: Record<string, T>,
|
|
|
|
|
value: string | number
|
|
|
|
|
): T | undefined {
|
|
|
|
|
return Object.values(enumObject).find(enumValue => enumValue === value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Utility to validate enum value
|
|
|
|
|
*/
|
|
|
|
|
export function isValidEnumValue<T>(
|
|
|
|
|
enumObject: Record<string, T>,
|
|
|
|
|
value: unknown
|
|
|
|
|
): value is T {
|
|
|
|
|
return Object.values(enumObject).includes(value as T);
|
2025-09-19 11:44:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Hook for orders enum utilities
|
|
|
|
|
*/
|
|
|
|
|
export function useOrderEnums() {
|
|
|
|
|
const { t } = useTranslation('orders');
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
// Customer Type
|
|
|
|
|
getCustomerTypeOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(CustomerType, 'customer_types', t),
|
|
|
|
|
|
|
|
|
|
getCustomerTypeLabel: (type: CustomerType): string => {
|
|
|
|
|
if (!type) return 'Tipo no definido';
|
|
|
|
|
const translated = t(`customer_types.${type}`);
|
|
|
|
|
if (translated === `customer_types.${type}`) {
|
|
|
|
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
|
|
|
}
|
|
|
|
|
return translated;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Delivery Method
|
|
|
|
|
getDeliveryMethodOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(DeliveryMethod, 'delivery_methods', t),
|
|
|
|
|
|
|
|
|
|
getDeliveryMethodLabel: (method: DeliveryMethod): string => {
|
|
|
|
|
if (!method) return 'Método no definido';
|
|
|
|
|
const translated = t(`delivery_methods.${method}`);
|
|
|
|
|
if (translated === `delivery_methods.${method}`) {
|
|
|
|
|
return method.charAt(0).toUpperCase() + method.slice(1);
|
|
|
|
|
}
|
|
|
|
|
return translated;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Payment Terms
|
|
|
|
|
getPaymentTermsOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(OrderPaymentTerms, 'payment_terms', t),
|
|
|
|
|
|
|
|
|
|
getPaymentTermsLabel: (terms: OrderPaymentTerms): string => {
|
|
|
|
|
if (!terms) return 'Términos no definidos';
|
|
|
|
|
return t(`payment_terms.${terms}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Payment Method
|
|
|
|
|
getPaymentMethodOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(PaymentMethod, 'payment_methods', t),
|
|
|
|
|
|
|
|
|
|
getPaymentMethodLabel: (method: PaymentMethod): string => {
|
|
|
|
|
if (!method) return 'Método no definido';
|
|
|
|
|
return t(`payment_methods.${method}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Payment Status
|
|
|
|
|
getPaymentStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(PaymentStatus, 'payment_status', t),
|
|
|
|
|
|
|
|
|
|
getPaymentStatusLabel: (status: PaymentStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`payment_status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Customer Segment
|
|
|
|
|
getCustomerSegmentOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(CustomerSegment, 'customer_segments', t),
|
|
|
|
|
|
|
|
|
|
getCustomerSegmentLabel: (segment: CustomerSegment): string => {
|
|
|
|
|
if (!segment) return 'Segmento no definido';
|
|
|
|
|
return t(`customer_segments.${segment}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Priority Level
|
|
|
|
|
getPriorityLevelOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(PriorityLevel, 'priority_levels', t),
|
|
|
|
|
|
|
|
|
|
getPriorityLevelLabel: (level: PriorityLevel): string => {
|
|
|
|
|
if (!level) return 'Prioridad no definida';
|
|
|
|
|
return t(`priority_levels.${level}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Order Type
|
|
|
|
|
getOrderTypeOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(OrderType, 'order_types', t),
|
|
|
|
|
|
|
|
|
|
getOrderTypeLabel: (type: OrderType): string => {
|
|
|
|
|
if (!type) return 'Tipo no definido';
|
|
|
|
|
const translated = t(`order_types.${type}`);
|
|
|
|
|
// If translation failed, return a fallback
|
|
|
|
|
if (translated === `order_types.${type}`) {
|
|
|
|
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
|
|
|
}
|
|
|
|
|
return translated;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Order Status
|
|
|
|
|
getOrderStatusOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(OrderStatus, 'order_status', t),
|
|
|
|
|
|
|
|
|
|
getOrderStatusLabel: (status: OrderStatus): string => {
|
|
|
|
|
if (!status) return 'Estado no definido';
|
|
|
|
|
return t(`order_status.${status}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Order Source
|
|
|
|
|
getOrderSourceOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(OrderSource, 'order_sources', t),
|
|
|
|
|
|
|
|
|
|
getOrderSourceLabel: (source: OrderSource): string => {
|
|
|
|
|
if (!source) return 'Origen no definido';
|
|
|
|
|
return t(`order_sources.${source}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Sales Channel
|
|
|
|
|
getSalesChannelOptions: (): SelectOption[] =>
|
|
|
|
|
enumToSelectOptions(SalesChannel, 'sales_channels', t),
|
|
|
|
|
|
|
|
|
|
getSalesChannelLabel: (channel: SalesChannel): string => {
|
|
|
|
|
if (!channel) return 'Canal no definido';
|
|
|
|
|
return t(`sales_channels.${channel}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Field Labels
|
|
|
|
|
getFieldLabel: (field: string): string =>
|
|
|
|
|
t(`labels.${field}`),
|
|
|
|
|
|
|
|
|
|
getFieldDescription: (field: string): string =>
|
|
|
|
|
t(`descriptions.${field}`)
|
|
|
|
|
};
|
2025-09-18 23:32:53 +02:00
|
|
|
}
|