diff --git a/handlers/reports/syncParsed.handler.js b/handlers/reports/syncParsed.handler.js index c042ad4..1db4960 100644 --- a/handlers/reports/syncParsed.handler.js +++ b/handlers/reports/syncParsed.handler.js @@ -1,15 +1,6 @@ import { BadRequestError } from "#root/http-server/index.js"; -import yup from "yup"; - -var reportItemSchema = yup.object({ - date: yup.date().required(), - equipment: yup.string().nullable().required(), - reason_call: yup.string().required(), - job_description: yup.string().required(), - root_cause: yup.string().required(), - applicant: yup.number().required(), - executor_ids: yup.array(yup.number()).required() -}); +import { reportsService } from "#root/services/reports.service.js"; +import { reportsSchema } from "#schemas/report.schema.js"; /** * URL: /api/reports_sync @@ -19,13 +10,10 @@ var reportItemSchema = yup.object({ * @type {import("#root/http-server/types/http-server.js").HttpRouteHandler} */ export default async ({ res, data }) => { - const inputSchema = yup.object({ reports: yup.array(reportItemSchema).required() }).required(); - - await inputSchema.validate(data).catch((err) => { + const { reports } = await reportsSchema.validate(data).catch((err) => { throw new BadRequestError(err.message); }); - // TODO ... - - res.sendJson({ data }); + await reportsService.syncReportsWithDatabase(reports); + res.sendJson({ data: { message: "OK" } }); }; diff --git a/http-server/http-server.js b/http-server/http-server.js index e7f7520..10eb0ab 100644 --- a/http-server/http-server.js +++ b/http-server/http-server.js @@ -3,11 +3,7 @@ import { createRequest } from "./request.js"; import { createResponse } from "./response.js"; import { createRouter } from "./route.js"; -/** - * @typedef {import('./types/http-server.js').HttpServer} HttpServer - * @typedef {import('./types/http-server.js').HttpServerOptions} HttpServerOptions - * @typedef {import('./types/http-server.js').HttpContext} HttpContext - */ +/** @import { HttpServerOptions, HttpServer, HttpContext } from "./types/http-server.js" */ /** * @param {HttpServerOptions} options diff --git a/http-server/request.js b/http-server/request.js index d1feae4..c6f3f5e 100644 --- a/http-server/request.js +++ b/http-server/request.js @@ -1,6 +1,9 @@ +/** @import { IncomingMessage } from "node:http" */ +/** @import { HttpRequest } from "./types/http-server.js" */ + /** - * @param {import('node:http').IncomingMessage} req - * @returns {import('./types/http-server.js').HttpRequest} + * @param {IncomingMessage} req + * @returns {HttpRequest} */ export function createRequest(req) { return { diff --git a/jsconfig.json b/jsconfig.json index 82701e6..40793a2 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -10,7 +10,8 @@ "paths": { "#root/*": ["./*"], "#handlers/*": ["./handlers/*"], - "#services/*": ["./services/*"] + "#services/*": ["./services/*"], + "#schemas/*": ["./schemas/*"] } }, "exclude": ["./http-server/types/*.d.ts"] diff --git a/package.json b/package.json index 693cf65..d5348ff 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "imports": { "#root/*": "./*", "#handlers/*": "./handlers/*", - "#services/*": "./services/*" + "#services/*": "./services/*", + "#schemas/*": "./schemas/*" }, "devDependencies": { "@eslint/js": "^10.0.1", diff --git a/schemas/index.js b/schemas/index.js new file mode 100644 index 0000000..6113455 --- /dev/null +++ b/schemas/index.js @@ -0,0 +1 @@ +export * from "./report.schema.js"; diff --git a/schemas/report.schema.js b/schemas/report.schema.js new file mode 100644 index 0000000..9d58ca0 --- /dev/null +++ b/schemas/report.schema.js @@ -0,0 +1,26 @@ +import y from "yup"; + +export const reportItemSchema = y.object({ + date: y.string(), + equipment: y + .object({ + id: y.number(), + name: y.string(), + location: y + .object({ + id: y.string(), + name: y.string(), + base_location_name: y.string(), + base_location: y.string() + }) + .nullable() + }) + .nullable(), + reason_call: y.string(), + job_description: y.string(), + root_cause: y.string(), + applicant: y.object({ id: y.number(), name: y.string() }).nullable(), + executors: y.array(y.object({ id: y.number(), fullname: y.string() })).required() +}); + +export const reportsSchema = y.object({ reports: y.array(reportItemSchema).required() }).required(); diff --git a/services/reports.service.js b/services/reports.service.js index 1736d8f..7df9e7f 100644 --- a/services/reports.service.js +++ b/services/reports.service.js @@ -1,6 +1,10 @@ import xlsx from "xlsx"; import pLimit from "p-limit"; import db from "#root/db.js"; +import mssql from "mssql"; + +/** @import { reportsSchema } from "#schemas/report.schema.js" */ +/** @import { InferType } from "yup" */ const sheetName = "Отчеты"; @@ -163,6 +167,50 @@ export const reportsService = { }) ) }; + }, + + /** + * @param {InferType['reports']} reports + */ + async syncReportsWithDatabase(reports) { + const trx = new mssql.Transaction(db); + const table = new mssql.Table("dbo.gpp_report_api_report"); + + table.create = false; + + table.columns.add("date", mssql.Date, { nullable: false }); + table.columns.add("reason_call", mssql.NVarChar(mssql.MAX), { nullable: false }); + table.columns.add("job_description", mssql.NVarChar(mssql.MAX), { nullable: false }); + table.columns.add("root_cause", mssql.NVarChar(mssql.MAX), { nullable: true }); + table.columns.add("applicant_id", mssql.BigInt, { nullable: true }); + table.columns.add("equipment_id", mssql.BigInt, { nullable: true }); + + try { + const addReportsRequest = new mssql.Request(trx); + + for (const r of reports) { + let date = new Date(r.date || "2026"); + + if (!(date instanceof Date && !Number.isNaN(date.valueOf()))) date = new Date("2026"); + + table.rows.add( + date, + r.reason_call || " ", + r.job_description || " ", + r.root_cause || " ", + r.applicant?.id || null, + r.equipment?.id || null + ); + } + + await trx.begin(); + await addReportsRequest.bulk(table); + await trx.commit(); + } catch (error) { + console.error(error); + await trx.rollback(); + throw error; + } } };