feat: implement route assignment management and sequencing module with interactive data visualization and editing capabilities
This commit is contained in:
@@ -52,6 +52,13 @@ export class ExcelPreviewService {
|
||||
missingHeaders.push(displayRequired[i]);
|
||||
}
|
||||
}
|
||||
if (type === 'PDV') {
|
||||
const hasVisitsFormat = normalizedHeaders.includes('visitas_semanales') && normalizedHeaders.includes('duracion_visitahoras');
|
||||
const hasWeeklyHours = normalizedHeaders.includes('minimo_horas_semana');
|
||||
if (!hasVisitsFormat && !hasWeeklyHours) {
|
||||
missingHeaders.push('Mínimo horas semana o Visitas semanales + Duración visita(horas)');
|
||||
}
|
||||
}
|
||||
|
||||
const errors: FieldError[] = [];
|
||||
const repeatedHeaders = normalizedHeaders.filter((header, index) => header && normalizedHeaders.indexOf(header) !== index);
|
||||
@@ -92,6 +99,7 @@ export class ExcelPreviewService {
|
||||
coerced['longitud'] = this.coerceNum(row['longitud']);
|
||||
coerced['visitas_semanales'] = this.coerceNum(row['visitas_semanales']);
|
||||
coerced['duracion_visitahoras'] = this.coerceNum(row['duracion_visitahoras']);
|
||||
coerced['minimo_horas_semana'] = this.coerceNum(row['minimo_horas_semana']);
|
||||
coerced['prioridad'] = this.coerceNum(row['prioridad']);
|
||||
if (typeof coerced['segmentacion'] === 'string') {
|
||||
coerced['segmentacion'] = String(coerced['segmentacion']).trim().toUpperCase();
|
||||
@@ -139,6 +147,33 @@ export class ExcelPreviewService {
|
||||
return Number.isNaN(n) ? value : n;
|
||||
}
|
||||
|
||||
async preparePdvForOptimizer(file: File): Promise<File> {
|
||||
const buffer = await file.arrayBuffer();
|
||||
const workbook = XLSX.read(buffer, { type: 'array', cellDates: true });
|
||||
const sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
const rows = XLSX.utils.sheet_to_json(sheet, { defval: null, raw: true })
|
||||
.map(row => normalizeRow(row as Record<string, unknown>));
|
||||
const normalized = rows.map(row => {
|
||||
const weeklyHours = cleanNum(row['minimo_horas_semana']);
|
||||
const visits = cleanNum(row['visitas_semanales']);
|
||||
const duration = cleanNum(row['duracion_visitahoras']);
|
||||
return {
|
||||
'ID': row['id'],
|
||||
'Nombre del PDV': row['nombre_del_pdv'],
|
||||
'Segmentación': row['segmentacion'],
|
||||
'Latitud': cleanNum(row['latitud']),
|
||||
'Longitud': cleanNum(row['longitud']),
|
||||
'Visitas semanales': Number.isFinite(visits) ? visits : 1,
|
||||
'Duración visita(horas)': Number.isFinite(duration) ? duration : weeklyHours,
|
||||
'Prioridad': cleanNum(row['prioridad'])
|
||||
};
|
||||
});
|
||||
const output = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(output, XLSX.utils.json_to_sheet(normalized), 'PDV');
|
||||
const data = XLSX.write(output, { bookType: 'xlsx', type: 'array' });
|
||||
return new File([data], file.name, { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
}
|
||||
|
||||
private extractHeaders(sheet: XLSX.WorkSheet): string[] {
|
||||
const range = XLSX.utils.decode_range(sheet['!ref'] || 'A1');
|
||||
const headers: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user