refactor(csv): ajusted extract logics
This commit is contained in:
parent
be957d8180
commit
157a7908be
|
|
@ -1,8 +1,8 @@
|
|||
import { Controller, Get, Header, Param, Query } from "@nestjs/common";
|
||||
import { Controller, Get, Param, Query, Res } from "@nestjs/common";
|
||||
import { CsvExportService } from "./csv-exports.service";
|
||||
import { ExportCsvOptionsDto } from "./export-csv-options.dto";
|
||||
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
||||
import { Modules as ModulesEnum } from ".prisma/client";
|
||||
import { Response } from "express";
|
||||
|
||||
@Controller('exports')
|
||||
export class CsvExportController {
|
||||
|
|
@ -10,8 +10,6 @@ export class CsvExportController {
|
|||
|
||||
@Get('csv/:year/:period_no')
|
||||
@ModuleAccessAllowed(ModulesEnum.employee_management)
|
||||
@Header('Content-Type', 'text/csv; charset=utf-8')
|
||||
@Header('Content-Disposition', 'attachment; filename="export.csv"')
|
||||
async exportCsv(
|
||||
@Query('approved') approved: boolean,
|
||||
@Query('shifts') shifts: boolean,
|
||||
|
|
@ -22,7 +20,8 @@ export class CsvExportController {
|
|||
@Query('solucom') solucom: boolean,
|
||||
@Param('year') year: number,
|
||||
@Param('period_no') period_no: number,
|
||||
): Promise<Buffer> {
|
||||
@Res() response: Response,
|
||||
): Promise<void> {
|
||||
const rows = await this.csvService.collectTransaction(
|
||||
year,
|
||||
period_no,
|
||||
|
|
@ -40,7 +39,13 @@ export class CsvExportController {
|
|||
},
|
||||
}
|
||||
);
|
||||
return this.csvService.generateCsv(rows);
|
||||
const csv_buffer = await this.csvService.generateCsv(rows);
|
||||
|
||||
response.set({
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition': 'attachment; filename="export.csv"',
|
||||
});
|
||||
response.send(csv_buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
|
||||
import { Filters, CsvRow } from "src/time-and-attendance/exports/export-csv-options.dto";
|
||||
import { computeHours } from "src/common/utils/date-utils";
|
||||
|
||||
|
||||
|
||||
|
|
@ -35,9 +36,10 @@ export class CsvExportService {
|
|||
}
|
||||
|
||||
const approved_filter = filters.approved ? { is_approved: true } : {};
|
||||
|
||||
const holiday_code = await this.resolveHolidayTypeCode('HOLIDAY');
|
||||
const vacation_code = await this.resolveVacationTypeCode('VACATION');
|
||||
const code_filter = [holiday_code, vacation_code];
|
||||
const leave_code_filter = [holiday_code, vacation_code];
|
||||
|
||||
//Prisma queries
|
||||
const promises: Array<Promise<any[]>> = [];
|
||||
|
|
@ -47,7 +49,7 @@ export class CsvExportService {
|
|||
where: {
|
||||
date: { gte: start, lte: end },
|
||||
...approved_filter,
|
||||
bank_code: { bank_code: { notIn: code_filter } },
|
||||
bank_code: { bank_code: { notIn: leave_code_filter } },
|
||||
timesheet: { employee: { company_code: { in: company_codes } } },
|
||||
},
|
||||
select: {
|
||||
|
|
@ -171,9 +173,9 @@ export class CsvExportService {
|
|||
return {
|
||||
company_code: employee.company_code,
|
||||
external_payroll_id: employee.external_payroll_id,
|
||||
full_name: `${employee.first_name} ${employee.last_name}`,
|
||||
full_name: `${employee.user.first_name} ${employee.user.last_name}`,
|
||||
bank_code: shift.bank_code?.bank_code ?? '',
|
||||
quantity_hours: this.computeHours(shift.start_time, shift.end_time),
|
||||
quantity_hours: computeHours(shift.start_time, shift.end_time),
|
||||
amount: undefined,
|
||||
week_number: week,
|
||||
pay_date: this.formatDate(end),
|
||||
|
|
@ -191,7 +193,7 @@ export class CsvExportService {
|
|||
rows.push({
|
||||
company_code: employee.company_code,
|
||||
external_payroll_id: employee.external_payroll_id,
|
||||
full_name: `${employee.first_name} ${employee.last_name}`,
|
||||
full_name: `${employee.user.first_name} ${employee.user.last_name}`,
|
||||
bank_code: expense.bank_code?.bank_code ?? '',
|
||||
quantity_hours: undefined,
|
||||
amount: Number(expense.amount),
|
||||
|
|
@ -206,13 +208,38 @@ export class CsvExportService {
|
|||
if (a.external_payroll_id !== b.external_payroll_id) {
|
||||
return a.external_payroll_id - b.external_payroll_id;
|
||||
}
|
||||
const bk_code = String(a.bank_code).localeCompare(String(b.bank_code));
|
||||
if (bk_code !== 0) return bk_code;
|
||||
const bank_code = String(a.bank_code).localeCompare(String(b.bank_code));
|
||||
if (bank_code !== 0) return bank_code;
|
||||
if (a.bank_code !== b.bank_code) return a.bank_code.localeCompare(b.bank_code);
|
||||
return 0;
|
||||
});
|
||||
|
||||
return rows;
|
||||
const consolidated_rows = this.consolidateRowHoursAndAmountByType(rows)
|
||||
|
||||
return consolidated_rows;
|
||||
}
|
||||
|
||||
consolidateRowHoursAndAmountByType = (rows: CsvRow[]): CsvRow[] => {
|
||||
type ConsolidateRow = CsvRow & { quantity_hours: number, amount: number };
|
||||
const shifts_map = new Map<string, ConsolidateRow>();
|
||||
|
||||
for (const row of rows) {
|
||||
const key = `${row.company_code}|${row.external_payroll_id}|${row.full_name}|${row.bank_code}|${row.week_number}`;
|
||||
const hours = row.quantity_hours ?? 0;
|
||||
const amounts = row.amount ?? 0;
|
||||
if (!shifts_map.has(key)) {
|
||||
shifts_map.set(key, {
|
||||
...row,
|
||||
quantity_hours: hours,
|
||||
amount: amounts,
|
||||
});
|
||||
} else {
|
||||
const existing = shifts_map.get(key)!;
|
||||
existing.quantity_hours += hours;
|
||||
existing.amount += amounts;
|
||||
}
|
||||
}
|
||||
return Array.from(shifts_map.values());
|
||||
}
|
||||
|
||||
resolveHolidayTypeCode = async (holiday: string): Promise<string> => {
|
||||
|
|
@ -241,13 +268,11 @@ export class CsvExportService {
|
|||
resolveCompanyCodes(companies: { targo: boolean; solucom: boolean; }): number[] {
|
||||
const out: number[] = [];
|
||||
if (companies.targo) {
|
||||
const code_no = parseInt(process.env.TARGO_NO ?? '', 10);
|
||||
if (!Number.isFinite(code_no) || code_no <= 0) throw new BadRequestException('Invalid Targo code in env');
|
||||
const code_no = 271583;
|
||||
out.push(code_no);
|
||||
}
|
||||
if (companies.solucom) {
|
||||
const code_no = parseInt(process.env.SOLUCOM_NO ?? '', 10);
|
||||
if (!Number.isFinite(code_no) || code_no <= 0) throw new BadRequestException('Invalid Solucom code in env');
|
||||
const code_no = 251585;
|
||||
out.push(code_no);
|
||||
}
|
||||
return out;
|
||||
|
|
@ -286,12 +311,6 @@ export class CsvExportService {
|
|||
return Buffer.from('\uFEFF' + header + body, 'utf8');
|
||||
}
|
||||
|
||||
|
||||
private computeHours(start: Date, end: Date): number {
|
||||
const diffMs = end.getTime() - start.getTime();
|
||||
return +(diffMs / 1000 / 3600).toFixed(2);
|
||||
}
|
||||
|
||||
private computeWeekNumber(start: Date, date: Date): number {
|
||||
const dayMS = 86400000;
|
||||
const days = Math.floor((this.toUTC(date).getTime() - this.toUTC(start).getTime()) / dayMS);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user