// Next.js API route support: https://nextjs.org/docs/api-routes/introduction import fs from 'fs'; import axios from 'axios'; import { Cookies } from 'react-cookie'; import cookie from 'cookie'; import moment from 'moment'; import jwt from 'jsonwebtoken'; import FormData from 'form-data'; import Redis from 'ioredis'; import md5 from 'md5'; import { inspect } from 'util'; import multer from 'multer'; import { get as _get, pick as _pick } from 'lodash'; import { eachSeries } from 'async'; import archiver from 'archiver'; import { fileTypeFromBuffer, fileTypeFromFile } from "file-type"; //import { MIMEType } from 'util'; import { cors } from '../../../lib/cors'; import RedisClient from '../../../lib/RedisClient'; const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); const uploads = `${ __dirname }/../../../../../uploads/`; function checkNullEmpty(value) { if(value === null) { return false; } if(value === "") { return false; } return true; } function createZipFile(zip_filename, files) { return new Promise((resolve) => { const output = fs.createWriteStream(`${ uploads }${ zip_filename }`); const archive = archiver('zip', { zlib: { level: 9 } // Sets the compression level. }); output.on('close', function() { console.log('archive on close'); resolve(); }); output.on('end', function() { console.log('archive on end'); }); archive.on('warning', function(err) { if (err.code === 'ENOENT') { // log warning } else { // throw error throw err; } }); archive.on('error', function(err) { throw err; }); archive.pipe(output); for(let i in files) { archive.append(fs.createReadStream(files[i].path), { name: files[i].name }); } archive.finalize(); }); } export default async function handler(req, res) { console.log("API", "questionnaire", "send"); await cors(req, res); return new Promise((resolve) => { if(req.headers.cookie !== undefined) { const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); if(cookies.jwt !== undefined && cookies.jwt !== null) { var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true }); console.log("JWT", cookies.jwt); console.log("CRM_JWT", crm_jwt); upload.single("file")(req, {}, async (err) => { const { file } = req; const id = parseInt(req.body.id, 10); const digital = req.body.digital == "true" ? true : false; console.log("id, digital", { id, digital }); const path = `${ process.env.CRM_API_HOST }/lk/Questionnaire/PreQuestionnaire/`; const filetype = await fileTypeFromBuffer(file.buffer); const timemark = moment().format("YYYY_MM_DD_HH_mm_ss"); const local_filename = digital ? `${ client_jwt_decoded.acc_number }_questionnaire_${ timemark }.sig` : `${ client_jwt_decoded.acc_number }_signed_questionnaire_${ timemark }.${ filetype.ext }`; const key = md5(`questionnaire_${ client_jwt_decoded.acc_number }`); const questionnaire = await RedisClient.get(key); try { fs.writeFileSync(`${ uploads }${ local_filename }`, file.buffer); console.log("multer.upload.single file"); console.log({ questionnaire }); const parsed = JSON.parse(questionnaire); console.log("parsed", ".".repeat(50)); console.log(parsed); const contacts = {}; for(let c in parsed.contacts) { if(parsed.contacts[c].name === null) { contacts[c] = null; } else { contacts[c] = parsed.contacts[c]; } } let payload = { ...parsed.main, ...contacts, ...{ head_person: parsed.head_person }, ...{ signatory_person: parsed.signatory_person }, }; payload.mail_delivery_address_type = parseInt(payload.mail_delivery_address_type, 10); payload.questionnaire_sign_type = digital ? "eds" : "paper"; payload.telephone = checkNullEmpty(payload.telephone) ? payload.telephone.replace(/[^0-9]/g, '') : null; payload.individual_executive_inn = checkNullEmpty(payload.individual_executive_inn) ? payload.individual_executive_inn.replace(/[^0-9]/g, '') : null; payload.individual_executive_kpp = checkNullEmpty(payload.individual_executive_kpp) ? payload.individual_executive_kpp.replace(/[^0-9]/g, '') : null; payload.individual_executive_docdate = checkNullEmpty(payload.individual_executive_docdate) ? moment(payload.individual_executive_docdate).format("YYYY-MM-DD") : null; if(payload.head_person.middlename !== "" && payload.head_person.middlename !== null) { payload.head_person.no_middle_name = false; } else { payload.head_person.no_middle_name = true; } payload.head_person.identity_document.citizenship_code = payload.head_person.identity_document.citizenship.code.toString(); payload.head_person.telephone = checkNullEmpty(payload.head_person.telephone) ? payload.head_person.telephone.replace(/[^0-9]/g, '') : null; payload.head_person.identity_document.issuedate = checkNullEmpty(payload.head_person.identity_document.issuedate) ? moment(payload.head_person.identity_document.issuedate).format("YYYY-MM-DD") : null; /* Запрос 2024-02-08 на удаление даты назначения и даты окончания полномочий payload.head_person.assignment_date = checkNullEmpty(payload.head_person.assignment_date) ? moment(payload.head_person.assignment_date).format("YYYY-MM-DD") : null; payload.head_person.credentials_dateend = checkNullEmpty(payload.head_person.credentials_dateend) ? moment(payload.head_person.credentials_dateend).format("YYYY-MM-DD") : null; */ payload.head_person.assignment_date = null; payload.head_person.credentials_dateend = null; if(payload.signatory_person.not_head_person) { if(payload.signatory_person.middlename !== "" && payload.signatory_person.middlename !== null) { payload.signatory_person.no_middle_name = false; } else { payload.signatory_person.no_middle_name = true; } } else { payload.signatory_person = { ...payload.signatory_person, ..._pick(payload.head_person, [ "lastname", "firstname", "middlename", "no_middle_name", "jobtitle", "telephone", "email", "identity_document", /* Запрос 2024-02-08 на удаление даты назначения и даты окончания полномочий "assignment_date", "credentials_dateend", "indefinite", */ ]) }; } payload.signatory_person.identity_document.citizenship_code = payload.signatory_person.identity_document.citizenship.code.toString(); payload.signatory_person.telephone = checkNullEmpty(payload.signatory_person.telephone) ? payload.signatory_person.telephone.replace(/[^0-9]/g, '') : null; payload.signatory_person.identity_document.issuedate = checkNullEmpty(payload.signatory_person.identity_document.issuedate) ? moment(payload.signatory_person.identity_document.issuedate).format("YYYY-MM-DD") : null; payload.signatory_person.docdate = checkNullEmpty(payload.signatory_person.docdate) ? moment(payload.signatory_person.docdate).format("YYYY-MM-DD") : null; /* Запрос 2024-02-08 на удаление даты назначения и даты окончания полномочий payload.signatory_person.assignment_date = checkNullEmpty(payload.signatory_person.assignment_date) ? moment(payload.signatory_person.assignment_date).format("YYYY-MM-DD") : null; payload.signatory_person.credentials_dateend = checkNullEmpty(payload.signatory_person.credentials_dateend) ? moment(payload.signatory_person.credentials_dateend).format("YYYY-MM-DD") : null; */ payload.signatory_person.birthdate = checkNullEmpty(payload.signatory_person.birthdate) ? moment(payload.signatory_person.birthdate).format("YYYY-MM-DD") : null; const founder_persons = parsed.founder_persons; for(let i in founder_persons) { founder_persons[i].founder_number = parseInt(i, 10) + 1; founder_persons[i].founder_part = parseFloat(founder_persons[i].founder_part); founder_persons[i].telephone = checkNullEmpty(founder_persons[i].telephone) ? founder_persons[i].telephone.replace(/[^0-9]/g, '') : null; founder_persons[i].identity_document.issuedate = checkNullEmpty(founder_persons[i].identity_document.issuedate) ? moment(founder_persons[i].identity_document.issuedate).format("YYYY-MM-DD") : null; founder_persons[i].identity_document.citizenship_code = founder_persons[i].identity_document.citizenship.code.toString(); founder_persons[i].birthdate = checkNullEmpty(founder_persons[i].birthdate) ? moment(founder_persons[i].birthdate).format("YYYY-MM-DD") : null; if(founder_persons[i].middlename !== "" && founder_persons[i].middlename !== null) { founder_persons[i].no_middle_name = false; } else { founder_persons[i].no_middle_name = true; } } payload = { ...payload, ...{ founder_persons }, ...{ revenue_source_main: parsed.non_profit.fin_source_business, revenue_source_donat: parsed.non_profit.fin_source_donate, revenue_source_entrance_fee: parsed.non_profit.fin_source_fees, revenue_source_other: parsed.non_profit.fin_source_another_description, foreign_countries_financing: parsed.non_profit.foreign_payers, purpose_use_la: parsed.non_profit.fin_goals_cars, purpose_use_lkt: parsed.non_profit.fin_goals_trucks, purpose_use_gt_sc: parsed.non_profit.fin_goals_special, is_nko: parsed.main.nko ? true : false, } }; payload.financial_loan = checkNullEmpty(payload.financial_loan) ? parseFloat(payload.financial_loan.toString().replace(/[^0-9.]/g, '')) : null; payload.licenses = parsed.licenses; console.log({ id, path }); console.log("payload", "*".repeat(100)); console.log(payload); console.log("files", "^".repeat(50)); console.log({ head_person_files: parsed.head_person_files }); console.log({ delegation_files: parsed.delegation_files }); console.log({ signatory_person_files: parsed.signatory_person_files }); console.log({ signatory_corporate_files: parsed.signatory_corporate_files }); const files_to_send = []; const files_groups = [ { name: "head_person", number: 1 }, { name: "delegation", number: 166, }, { name: "signatory_person", number: 23, }, { name: "signatory_corporate", number: 22, } ]; for(let g in files_groups) { if(parsed[`${ files_groups[g].name }_files`].length > 0) { let files_to_zip = []; for(let f in parsed[`${ files_groups[g].name }_files`]) { const ext_regex = new RegExp("\.([0-9a-z]+)$", "i"); const ext = parsed[`${ files_groups[g].name }_files`][f].name.match(ext_regex); files_to_zip.push({ name: `${ files_groups[g].name }_file_${ f+1 }.${ ext[1] }`, path: `${ uploads }${ parsed[`${ files_groups[g].name }_files`][f].filename }`, }); } let zip_filename = `${ client_jwt_decoded.acc_number }_${ files_groups[g].name }_files.zip`; await createZipFile(zip_filename, files_to_zip); files_to_send.push({ name: zip_filename, filename: zip_filename, number: files_groups[g].number, }); } } if(digital) { const zip_filename = `${ client_jwt_decoded.acc_number }_questionnaire.zip`; await createZipFile(zip_filename, [{ name: `${ client_jwt_decoded.acc_number }_questionnaire_${ timemark }.pdf`, path: `${ uploads }${ client_jwt_decoded.acc_number }_questionnaire.pdf`, }, { name: local_filename, path: `${ uploads }${ local_filename }`, }]); files_to_send.push({ name: zip_filename, filename: zip_filename, number: 162 }); } else { files_to_send.push({ name: local_filename, filename: local_filename, number: 161, }); } console.log("files_to_send", ".".repeat(100)); console.log(files_to_send); axios.put(path, payload, { params: { name: id }, headers: { "Authorization": `Bearer ${ crm_jwt }`, "Content-Type": "application/json" } } ) .then((crm_response) => { console.log("crm_response for", path); console.log(inspect(crm_response.data, true, null, true)); eachSeries(files_to_send, (file_entry, callback) => { if(fs.existsSync(`${ uploads }${ file_entry.filename }`)) { const file_to_send_data = fs.readFileSync(`${ uploads }${ file_entry.filename }`); const data = new FormData(); data.append("file", file_to_send_data, file_entry.name); console.log({ data }); const file_upload_url = `${ process.env.CRM_API_HOST }/lk/document/upload/?entity=evo_client_questionnaire&documentTypeNumber=${ file_entry.number }&name=${ id }`; console.log({ file_upload_url }); const headers = { "Content-Type": `multipart/form-data; boundary=${ data._boundary }`, "Authorization": `Bearer ${ crm_jwt }`, }; console.log("API", "questionnaire", "send", { headers, "filename": file_entry.filename }, ); axios.post(file_upload_url, data, { headers, withCredentials: true, }) .then(() => { console.log("FILE", file_entry.filename, "SENT"); callback(); }) .catch((crm_file_upload_error) => { if(crm_file_upload_error.response !== undefined) { console.error("crm_file_upload_error", { status: crm_file_upload_error.response.status, data: crm_file_upload_error.response }); } else { console.error({ crm_file_upload_error }); } callback(); }); } else { callback(); } }, async () => { const existed_files = fs.readdirSync(uploads); existed_files.forEach(file => { if(file.indexOf(client_jwt_decoded.acc_number) === 0) { fs.unlinkSync(`${ uploads }${ file }`); } }); await RedisClient.del(key); res.status(200).json({ payload, id, digital }); resolve(); }); }) .catch((crm_send_error) => { if(crm_send_error.response !== undefined) { console.error("crm_send_error", { status: crm_send_error.response.status, data: crm_send_error.response.data }); console.error({ payload: inspect(payload, true, null, true) }); } else { console.error({ crm_send_error }); } res.status(500).json({ payload, id, digital }); resolve(); }); //res.status(500).json({ payload, id, digital }); } catch(upload_single_error) { console.error("upload_single_error"); console.error(upload_single_error); res.status(500).json({ id, digital }); resolve(); } }); } else { res.status(403).send(); resolve(); } } }); } export const config = { api: { bodyParser: false } }