diff --git a/package.json b/package.json index 27706a8..71d6090 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,13 @@ "author": "", "license": "ISC", "dependencies": { + "@fast-csv/format": "^4.3.5", "@types/morgan": "^1.9.3", "@types/mysql": "^2.15.21", "cors": "^2.8.5", "express": "^4.18.1", "express-validator": "^6.14.2", + "fast-csv": "^4.3.6", "morgan": "^1.10.0", "mysql": "^2.18.1", "mysql2": "^2.3.3", diff --git a/src/models/member-service.model.ts b/src/models/member-service.model.ts new file mode 100644 index 0000000..8f79585 --- /dev/null +++ b/src/models/member-service.model.ts @@ -0,0 +1,6 @@ +interface LedgerOptions { + field: string; + header?: string; +} + +export { LedgerOptions }; diff --git a/src/routes/member.ts b/src/routes/member.ts index df4622e..5401caa 100644 --- a/src/routes/member.ts +++ b/src/routes/member.ts @@ -1,5 +1,6 @@ import { Router } from "express"; -import { query, validationResult } from "express-validator"; +import { body, query, validationResult } from "express-validator"; +import * as path from "path"; import MemberService from "../services/member-service"; @@ -35,4 +36,31 @@ router.get( } ); +/* POST /member/ledger */ + +router.post( + "/ledger", + body("options").isArray().notEmpty(), + body("options.*.field").isString().notEmpty(), + body("options.*.header").isString().optional(), + async (req, res) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(400).json({ errors: errors.array() }); + } + + const { options } = req.body; + + try { + await MemberService.writeLedgerFile(options); + return res.status(200).download(path.resolve(__dirname, "../services/member-ledger.csv")); + } catch (err) { + logger.error("MemberService.getLedgerFile failed. Error ="); + logger.error(err); + } + + return res.status(500).json({ message: "Unable to load resource" }); + } +); + export default router; diff --git a/src/services/member-service.ts b/src/services/member-service.ts index 3c6af2d..3591cd3 100644 --- a/src/services/member-service.ts +++ b/src/services/member-service.ts @@ -1,7 +1,9 @@ -// import { type } from "os"; +import { writeToPath } from "fast-csv"; import logger from "../utils/logger/logger"; +import * as path from "path"; import SQLService from "./sql-service"; +import { LedgerOptions as LedgerOption } from "src/models/member-service.model"; class MemberService { static async isMember(uh_id = "", email = "") { @@ -24,6 +26,20 @@ class MemberService { end_date: result[0].end_date, }; } + + static async writeLedgerFile(options: Array) { + logger.info("MemberService.getLedgerFile invoked! Options = " + options); + + const fields = options.map((option) => { return option.field; }); + const headers = options.map((option) => { return option.header ? option.header : option.field; }); + + const ledger_data = await SQLService.select("contact", { fields: fields }); + const rows = ledger_data.map(Object.values); + + writeToPath(path.resolve(__dirname, "member-ledger.csv"), rows, { headers: headers }) + .on("error", (err) => console.error(err)) + .on("finish", () => console.log("Done writing.")); + } } export default MemberService;