mirror of
https://github.com/sergeyyarkov/asu_tools_service.git
synced 2026-10-11 10:29:22 +03:00
del reports before import
This commit is contained in:
parent
1f73377e33
commit
44fd57ef2c
@ -10,10 +10,10 @@ import { reportsSchema } from "#schemas/report.schema.js";
|
||||
* @type {import("#root/http-server/types/http-server.js").HttpRouteHandler}
|
||||
*/
|
||||
export default async ({ res, data }) => {
|
||||
const { reports } = await reportsSchema.validate(data).catch((err) => {
|
||||
const payload = await reportsSchema.validate(data).catch((err) => {
|
||||
throw new BadRequestError(err.message);
|
||||
});
|
||||
|
||||
const rows = await reportsService.syncReportsWithDatabase(reports);
|
||||
const rows = await reportsService.syncReportsWithDatabase(payload);
|
||||
res.sendJson({ data: { rows } });
|
||||
};
|
||||
|
||||
@ -1 +1,2 @@
|
||||
export * from "./uow.js";
|
||||
export * from "./report.repository.js";
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import sql from "mssql";
|
||||
import db from "#root/db.js";
|
||||
import { ReportModel } from "#models/index.js";
|
||||
import { ReportExecutorTable, ReportTable } from "#tables/index.js";
|
||||
import { UOW } from "./index.js";
|
||||
|
||||
/** @import { ReportColumns } from "#tables/report.table.js" */
|
||||
|
||||
export const reportRepository = {
|
||||
async getAll() {
|
||||
const request = new sql.Request(db);
|
||||
const request = UOW.request;
|
||||
const result = await request.query(`select * from dbo.${ReportTable.tableName};`);
|
||||
const reports = ReportModel.fromRecordset(result.recordset);
|
||||
|
||||
@ -15,18 +14,29 @@ export const reportRepository = {
|
||||
},
|
||||
|
||||
async getLast() {
|
||||
const request = new sql.Request(db);
|
||||
const request = UOW.request;
|
||||
const result = await request.query(`select top 1 * from ${ReportTable.tableName} order by id desc`);
|
||||
const report = ReportModel.fromRecordset(result.recordset);
|
||||
|
||||
return report.at(0);
|
||||
},
|
||||
|
||||
async delAll() {
|
||||
await UOW.run(async () => {
|
||||
const request = UOW.request;
|
||||
|
||||
await request.query(`delete from ${ReportExecutorTable.tableName};`);
|
||||
await request.query(`delete from ${ReportTable.tableName};`);
|
||||
await request.query(`DBCC CHECKIDENT ('${ReportExecutorTable.tableName}', RESEED, 0);`);
|
||||
await request.query(`DBCC CHECKIDENT ('${ReportTable.tableName}', RESEED, 0);`);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ReportColumns} entry
|
||||
*/
|
||||
async create(entry) {
|
||||
const request = new sql.Request(db);
|
||||
const request = UOW.request;
|
||||
const report = new ReportModel(entry);
|
||||
|
||||
request.input("date", ReportTable.getColumn("date"), report.date);
|
||||
@ -51,10 +61,9 @@ export const reportRepository = {
|
||||
|
||||
/**
|
||||
* @param {Record<string, Array<string | number>>[]} links
|
||||
* @param {sql.Transaction} [trx]
|
||||
*/
|
||||
async attachExecutors(links, trx) {
|
||||
const request = trx ? new sql.Request(trx) : new sql.Request(db);
|
||||
async attachExecutors(links) {
|
||||
const request = UOW.request;
|
||||
const table = ReportExecutorTable.createInstance();
|
||||
|
||||
for (const report of Object.values(links)) {
|
||||
@ -69,10 +78,9 @@ export const reportRepository = {
|
||||
|
||||
/**
|
||||
* @param {ReportColumns[]} entries
|
||||
* @param {sql.Transaction} [trx]
|
||||
*/
|
||||
async bulk(entries, trx) {
|
||||
const request = trx ? new sql.Request(trx) : new sql.Request(db);
|
||||
async bulk(entries) {
|
||||
const request = UOW.request;
|
||||
const table = ReportTable.createInstance();
|
||||
const lastReportId = (await this.getLast())?.id || 0;
|
||||
let nextAddId = typeof lastReportId === "string" ? Number.parseInt(lastReportId, 10) : lastReportId;
|
||||
|
||||
27
repositories/uow.js
Normal file
27
repositories/uow.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import sql from "mssql";
|
||||
import db from "#root/db.js";
|
||||
|
||||
export class UOW {
|
||||
/** @type {AsyncLocalStorage<sql.Transaction>} */
|
||||
static #als = new AsyncLocalStorage();
|
||||
|
||||
/** @param {() => Promise<unknown>} callback */
|
||||
static async run(callback) {
|
||||
const trx = new sql.Transaction(db);
|
||||
try {
|
||||
await trx.begin();
|
||||
const ret = await this.#als.run(trx, callback);
|
||||
await trx.commit();
|
||||
return ret;
|
||||
} catch (error) {
|
||||
await trx.rollback();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static get request() {
|
||||
const trx = this.#als.getStore();
|
||||
return trx ? new sql.Request(trx) : new sql.Request(db);
|
||||
}
|
||||
}
|
||||
@ -23,4 +23,6 @@ export const reportItemSchema = y.object({
|
||||
executors: y.array(y.object({ id: y.number().required(), fullname: y.string().required() })).required()
|
||||
});
|
||||
|
||||
export const reportsSchema = y.object({ reports: y.array(reportItemSchema).min(1).required() }).required();
|
||||
export const reportsSchema = y
|
||||
.object({ reports: y.array(reportItemSchema).min(1).required(), deleteAllBeforeImport: y.boolean().required() })
|
||||
.required();
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import xlsx from "xlsx";
|
||||
import pLimit from "p-limit";
|
||||
import db from "#root/db.js";
|
||||
import mssql from "mssql";
|
||||
import { reportRepository } from "#repositories/index.js";
|
||||
import { reportRepository, UOW } from "#repositories/index.js";
|
||||
import * as utilsDate from "#utils/date.js";
|
||||
|
||||
/** @import { reportsSchema } from "#schemas/report.schema.js" */
|
||||
@ -172,15 +171,20 @@ export const reportsService = {
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {InferType<typeof reportsSchema>['reports']} inReports
|
||||
* @param {InferType<typeof reportsSchema>} payload
|
||||
*/
|
||||
async syncReportsWithDatabase(inReports) {
|
||||
async syncReportsWithDatabase(payload) {
|
||||
const INVALID_DATE_FALLBACK = new Date("2016-10-24"); // дата для постановки вместо неверной. (колонка `date` в таблице имеет ограничение not null)
|
||||
const trx = new mssql.Transaction(db);
|
||||
const { reports: inReports, deleteAllBeforeImport } = payload;
|
||||
|
||||
/** @type {typeof payload['reports']} */
|
||||
let unImportedReports = [];
|
||||
|
||||
if (!deleteAllBeforeImport) {
|
||||
const reports = await reportRepository.getAll();
|
||||
|
||||
/** Отфильтровывание дубликатов по полям. */
|
||||
const filteredInReports = inReports.filter((inputR) => {
|
||||
unImportedReports = inReports.filter((inputR) => {
|
||||
const isDub = reports.some((dbR) => {
|
||||
return (
|
||||
inputR.reason_call === dbR.reason_call &&
|
||||
@ -193,13 +197,16 @@ export const reportsService = {
|
||||
return !isDub;
|
||||
});
|
||||
|
||||
if (filteredInReports.length === 0) return 0;
|
||||
if (unImportedReports.length === 0) return 0;
|
||||
} else {
|
||||
await reportRepository.delAll();
|
||||
unImportedReports = inReports;
|
||||
}
|
||||
|
||||
/** Добавление отчетов и связей с исполнителями к ним */
|
||||
try {
|
||||
await trx.begin();
|
||||
const ret = await UOW.run(async () => {
|
||||
const bulkResult = await reportRepository.bulk(
|
||||
filteredInReports.map((r) => {
|
||||
unImportedReports.map((r) => {
|
||||
const reportDate = new Date(r.date || "");
|
||||
return {
|
||||
applicant_id: r.applicant?.id || null,
|
||||
@ -209,22 +216,19 @@ export const reportsService = {
|
||||
reason_call: r.reason_call || "",
|
||||
root_cause: r.root_cause || ""
|
||||
};
|
||||
}),
|
||||
trx
|
||||
})
|
||||
);
|
||||
|
||||
const executorsLinks = filteredInReports.map((r, i) => {
|
||||
const executorsLinks = unImportedReports.map((r, i) => {
|
||||
return Object.fromEntries([[`${bulkResult.addedRowIds[i]}`, r.executors.map((e) => e.id)]]);
|
||||
});
|
||||
|
||||
await reportRepository.attachExecutors(executorsLinks, trx);
|
||||
await trx.commit();
|
||||
await reportRepository.attachExecutors(executorsLinks);
|
||||
|
||||
return bulkResult.rowsAffected;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
await trx.rollback();
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user