Agregar El Salvador y actualizar dist validado
This commit is contained in:
@@ -65,8 +65,9 @@ export default function BambooCorrectionModal({
|
||||
|
||||
const recipientLabel = useMemo(() => {
|
||||
if (country.code === 'TT') return 'Laurele Nicome-Jack';
|
||||
if (country.code === 'PA') return 'Delarys Peñalba y Ariadne Cortéz';
|
||||
return 'Pablo Gamboa Cú, Sara Meyer Lima y María Morales Adler';
|
||||
if (country.code === 'PA') return 'Delarys Peñalba';
|
||||
if (country.code === 'SV') return 'Carlos Antonio Malta Méndez';
|
||||
return 'haguirre@gomezleemarketing.com';
|
||||
}, [country.code]);
|
||||
|
||||
const sourceNames = useMemo(
|
||||
|
||||
@@ -36,7 +36,7 @@ export default function CountrySelector({ onSelect }: CountrySelectorProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{COUNTRIES.map((country) => (
|
||||
<button
|
||||
key={country.code}
|
||||
|
||||
@@ -84,6 +84,13 @@ function getReconciliationUrl(countryCode: string) {
|
||||
);
|
||||
}
|
||||
|
||||
if (countryCode === 'SV') {
|
||||
return (
|
||||
(import.meta.env.VITE_N8N_EL_SALVADOR_WEBHOOK_URL as string | undefined) ||
|
||||
'https://agenteit.digitalcompass.agency/webhook/nominasv-bamboo-test'
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
(import.meta.env.VITE_N8N_GUATEMALA_WEBHOOK_URL as string | undefined) ||
|
||||
(import.meta.env.VITE_N8N_WEBHOOK_URL as string | undefined) ||
|
||||
@@ -787,6 +794,8 @@ export default function Dashboard({
|
||||
}: DashboardProps) {
|
||||
const defaultPeriod = useMemo(() => readStoredPeriod(country.code), [country.code]);
|
||||
const isPanama = country.code === 'PA';
|
||||
const isElSalvador = country.code === 'SV';
|
||||
const isMultiPayrollCountry = isPanama || isElSalvador;
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
const [processingStep, setProcessingStep] = useState('');
|
||||
const [filterMode, setFilterMode] = useState<
|
||||
@@ -1000,11 +1009,11 @@ export default function Dashboard({
|
||||
}
|
||||
};
|
||||
|
||||
const addPanamaPayrollFiles = async (files: File[]) => {
|
||||
const addMultiPayrollFiles = async (files: File[]) => {
|
||||
const excelFiles = files.filter(isExcelFile);
|
||||
|
||||
if (excelFiles.length === 0) {
|
||||
onShowToast('Formato inválido. Panamá requiere uno o varios archivos Excel (.xlsx, .xls).', 'error');
|
||||
onShowToast(`Formato inválido. ${country.name} requiere uno o varios archivos Excel (.xlsx, .xls).`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1027,7 +1036,7 @@ export default function Dashboard({
|
||||
const detected = await applyDetectedPayrollPeriod(detectionFile, combined.length);
|
||||
|
||||
if (!detected) {
|
||||
onShowToast(`${newFiles.length} archivo(s) de nómina de Panamá cargado(s) con éxito.`, 'success');
|
||||
onShowToast(`${newFiles.length} archivo(s) de nómina de ${country.name} cargado(s) con éxito.`, 'success');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1040,8 +1049,8 @@ export default function Dashboard({
|
||||
const files = Array.from(e.dataTransfer.files) as File[];
|
||||
if (files.length === 0) return;
|
||||
|
||||
if (isPanama) {
|
||||
await addPanamaPayrollFiles(files);
|
||||
if (isMultiPayrollCountry) {
|
||||
await addMultiPayrollFiles(files);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1072,8 +1081,8 @@ export default function Dashboard({
|
||||
const files = Array.from(e.target.files || []) as File[];
|
||||
if (files.length === 0) return;
|
||||
|
||||
if (isPanama) {
|
||||
await addPanamaPayrollFiles(files);
|
||||
if (isMultiPayrollCountry) {
|
||||
await addMultiPayrollFiles(files);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1085,7 +1094,7 @@ export default function Dashboard({
|
||||
}
|
||||
};
|
||||
|
||||
const removePanamaPayrollFile = (indexToRemove: number) => {
|
||||
const removeMultiPayrollFile = (indexToRemove: number) => {
|
||||
setUploadedPayrollFiles(
|
||||
uploadedPayrollFiles.filter((_, index) => index !== indexToRemove)
|
||||
);
|
||||
@@ -1117,7 +1126,7 @@ export default function Dashboard({
|
||||
onShowToast('Planilla de banco removida.', 'info');
|
||||
};
|
||||
|
||||
const clearPanamaUploadedFiles = () => {
|
||||
const clearUploadedFiles = () => {
|
||||
setUploadedPayroll(null);
|
||||
setUploadedPayrollFiles([]);
|
||||
setUploadedBankFiles([]);
|
||||
@@ -1208,7 +1217,7 @@ export default function Dashboard({
|
||||
return;
|
||||
}
|
||||
|
||||
const payrollFilesForRun = isPanama
|
||||
const payrollFilesForRun = isMultiPayrollCountry
|
||||
? uploadedPayrollFiles
|
||||
: (uploadedPayroll ? [uploadedPayroll] : []);
|
||||
|
||||
@@ -1217,8 +1226,8 @@ export default function Dashboard({
|
||||
payrollFilesForRun.some((file) => !file.rawFile)
|
||||
) {
|
||||
onShowToast(
|
||||
isPanama
|
||||
? 'Debes cargar la nómina principal y los suplementos de Panamá antes de ejecutar el cruce.'
|
||||
isMultiPayrollCountry
|
||||
? `Debes cargar todos los archivos de nómina de ${country.name} correspondientes al período antes de ejecutar el cruce.`
|
||||
: 'Debes cargar la nómina antes de ejecutar el cruce.',
|
||||
'error'
|
||||
);
|
||||
@@ -1297,7 +1306,7 @@ export default function Dashboard({
|
||||
Object.entries(metadata).forEach(([key, value]) => {
|
||||
formData.append(key, Array.isArray(value) ? JSON.stringify(value) : String(value));
|
||||
});
|
||||
if (isPanama) {
|
||||
if (isMultiPayrollCountry) {
|
||||
payrollFilesForRun.forEach((file, index) => {
|
||||
if (!file.rawFile) return;
|
||||
formData.append('payroll_files', file.rawFile, file.name);
|
||||
@@ -1639,11 +1648,11 @@ export default function Dashboard({
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{isPanama && (uploadedPayrollFiles.length > 0 || uploadedBankFiles.length > 0) && (
|
||||
{isMultiPayrollCountry && (uploadedPayrollFiles.length > 0 || uploadedBankFiles.length > 0) && (
|
||||
<div className="flex justify-end" style={{ marginBottom: '-20px' }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={clearPanamaUploadedFiles}
|
||||
onClick={clearUploadedFiles}
|
||||
className="inline-flex items-center gap-2 border border-red-100 bg-white px-3 py-2 text-[10px] font-black text-red-600 hover:bg-red-50 transition-colors uppercase tracking-wide shadow-sm"
|
||||
aria-label="Borrar todos los archivos cargados"
|
||||
title="Eliminar de una vez todas las nóminas y planillas del banco cargadas"
|
||||
@@ -1668,11 +1677,11 @@ export default function Dashboard({
|
||||
ref={payrollInputRef}
|
||||
onChange={handlePayrollSelect}
|
||||
accept=".xlsx,.xls"
|
||||
multiple={isPanama}
|
||||
multiple={isMultiPayrollCountry}
|
||||
className="hidden"
|
||||
/>
|
||||
|
||||
{isPanama ? (
|
||||
{isMultiPayrollCountry ? (
|
||||
uploadedPayrollFiles.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
<div className="border border-[#4F758B]/20 bg-[#4F758B]/5 px-4 py-3">
|
||||
@@ -1680,7 +1689,9 @@ export default function Dashboard({
|
||||
{uploadedPayrollFiles.length} archivo(s) de nómina cargado(s)
|
||||
</p>
|
||||
<p className="text-[10px] text-neutral-500 mt-1">
|
||||
Incluye la quincenal y todas las planillas extraordinarias, vacaciones o XIII Mes que correspondan al período.
|
||||
{isPanama
|
||||
? 'Incluye la quincenal y todas las planillas extraordinarias, vacaciones o XIII Mes que correspondan al período.'
|
||||
: 'Incluye todos los archivos de nómina de El Salvador que correspondan a la quincena seleccionada (General, Karla Elias, Nestlé, Motorola u otros del mismo formato).'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1697,7 +1708,7 @@ export default function Dashboard({
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => removePanamaPayrollFile(index)}
|
||||
onClick={() => removeMultiPayrollFile(index)}
|
||||
className="p-1.5 text-neutral-400 hover:text-red-500 hover:bg-neutral-100 transition-all rounded"
|
||||
aria-label={`Remover ${file.name}`}
|
||||
>
|
||||
|
||||
@@ -40,6 +40,13 @@ function getHistoryUrl(countryCode: string) {
|
||||
);
|
||||
}
|
||||
|
||||
if (countryCode === 'SV') {
|
||||
return (
|
||||
(import.meta.env.VITE_HISTORICOS_SV_URL as string | undefined) ||
|
||||
'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-historicos'
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
(import.meta.env.VITE_HISTORICOS_GT_URL as string | undefined) ||
|
||||
'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-historicos'
|
||||
@@ -58,6 +65,13 @@ function getMarkResolvedUrl(countryCode: string) {
|
||||
);
|
||||
}
|
||||
|
||||
if (countryCode === 'SV') {
|
||||
return (
|
||||
(import.meta.env.VITE_MARCAR_RESUELTO_SV_URL as string | undefined) ||
|
||||
'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-sv-marcar-resuelto'
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
(import.meta.env.VITE_MARCAR_RESUELTO_GT_URL as string | undefined) ||
|
||||
'https://agenteit.digitalcompass.agency/webhook/cruce-cuentas-gt-marcar-resuelto'
|
||||
@@ -143,7 +157,7 @@ function normalizeReports(input: unknown, country: CountryConfig): HistoricalRep
|
||||
|
||||
return {
|
||||
id: String(report.id ?? `reporte-${index + 1}`),
|
||||
country: (rawCountry === 'TT' ? 'TT' : rawCountry === 'PA' ? 'PA' : 'GT') as HistoricalReport['country'],
|
||||
country: (rawCountry === 'TT' ? 'TT' : rawCountry === 'PA' ? 'PA' : rawCountry === 'SV' ? 'SV' : 'GT') as HistoricalReport['country'],
|
||||
date: formatDate(report.fecha ?? report.period_end ?? rawExecutionDate, country.locale),
|
||||
executionDate: formatDateTime(rawExecutionDate, country.locale),
|
||||
period: String(report.periodo ?? report.period_label ?? report.period ?? 'Período no especificado'),
|
||||
@@ -457,7 +471,7 @@ export default function History({
|
||||
if (!isCurrentRequest()) return;
|
||||
|
||||
// Respaldo temporal: webhook histórico existente. También se envía el país
|
||||
// para impedir que se mezclen reportes de Guatemala, Trinidad y Tobago y Panamá.
|
||||
// para impedir que se mezclen reportes de Guatemala, Trinidad y Tobago, Panamá y El Salvador.
|
||||
const historyUrl = getHistoryUrl(country.code);
|
||||
if (!historyUrl) {
|
||||
throw new Error(`No está configurado el origen histórico de ${country.name}.`);
|
||||
|
||||
@@ -25,6 +25,14 @@ export const COUNTRIES: CountryConfig[] = [
|
||||
locale: 'es-PA',
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
code: 'SV',
|
||||
name: 'El Salvador',
|
||||
flag: 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_El_Salvador.svg.webp',
|
||||
currency: 'USD',
|
||||
locale: 'es-SV',
|
||||
enabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_COUNTRY_CODE: CountryCode = 'GT';
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ export type ViewType = 'cruce' | 'historial';
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'info';
|
||||
|
||||
export type CountryCode = 'GT' | 'TT' | 'PA';
|
||||
export type CountryCode = 'GT' | 'TT' | 'PA' | 'SV';
|
||||
|
||||
export interface CountryConfig {
|
||||
code: CountryCode;
|
||||
|
||||
Reference in New Issue
Block a user