@medicus.ai/medicus-report-pdf-generator 1.3.14 → 1.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/README.md +26 -26
  3. package/app/i18n.config.js +20 -20
  4. package/app/i18n_wellbeing.config.js +20 -20
  5. package/app/services/localeService.js +28 -28
  6. package/assets/Mediclinic/css/nasco_report.css +6297 -6297
  7. package/assets/Mediclinic/css/nasco_report_rtl.css +851 -851
  8. package/assets/Mediclinic/css/style.css +33 -33
  9. package/assets/Mediclinic/js/js.js +112 -112
  10. package/assets/Mediclinic/js/raphael.js +8437 -8437
  11. package/assets/arabic.css +275 -275
  12. package/assets/charts.min.js +7 -7
  13. package/assets/corporate_report/css/report.css +582 -582
  14. package/assets/corporate_report/css/report_rtl.css +144 -144
  15. package/assets/corporate_report/js/js.js +14 -14
  16. package/assets/data/data.json +124 -124
  17. package/assets/data/data2.json +675 -675
  18. package/assets/data/pdf_data_with_history.json +1255 -1255
  19. package/assets/doctor-note-insight-icon.svg +11 -11
  20. package/assets/imc/css/style.css +61 -61
  21. package/assets/jquery-1.4.min.js +151 -151
  22. package/assets/jquery-2.1.0.min.js +3 -3
  23. package/assets/js.js +201 -201
  24. package/assets/medicus_pdf/arabic.css +444 -444
  25. package/assets/medicus_pdf/styles.css +2427 -2427
  26. package/assets/print.css +4 -4
  27. package/assets/qr-code-style.css +68 -68
  28. package/assets/qrcode.min.js +3 -3
  29. package/assets/raphael-min.js +10 -10
  30. package/assets/sanusx/css/sanusx_report.css +707 -707
  31. package/assets/sizing.js +2 -2
  32. package/assets/styles.css +1545 -1545
  33. package/assets/styles.min.css +1358 -1358
  34. package/assets/translation.js +30 -30
  35. package/assets/wellbeing/css/nasco_report.css +3472 -3472
  36. package/assets/wellbeing/css/nasco_report_rtl.css +679 -679
  37. package/assets/wellbeing/js/js.js +111 -111
  38. package/assets/wellbeing/js/raphael.js +8437 -8437
  39. package/base64/cairo-font.js +2 -2
  40. package/config/Mediclinic.json +37 -37
  41. package/config/Najeeb.ai.json +35 -35
  42. package/config/Pha.json +64 -64
  43. package/config/bionext.json +37 -37
  44. package/config/default.json +35 -35
  45. package/config/diagnostikare.json +34 -34
  46. package/config/maisonsante.json +39 -39
  47. package/config/nasco.json +35 -35
  48. package/config/sanitas.json +35 -35
  49. package/config/sanusx.json +34 -34
  50. package/config/test.txt +4 -4
  51. package/data converter.js +53 -53
  52. package/downloadfile.js +6 -6
  53. package/example.txt +1188 -1188
  54. package/index.js +481 -481
  55. package/lib/big_integral_questionnaire.js +367 -298
  56. package/lib/corporate_report_generator.js +399 -399
  57. package/lib/pdf_generator.min.js +525 -525
  58. package/lib/sanusx_report_generator.js +533 -533
  59. package/lib/sendEmail.js +343 -343
  60. package/lib/template.js +2227 -2227
  61. package/lib/wellbeing_report_generator.js +2164 -2134
  62. package/locales/ar-AE.json +169 -169
  63. package/locales/ar-SA.json +169 -169
  64. package/locales/ar.json +397 -397
  65. package/locales/de.json +169 -169
  66. package/locales/en.json +229 -229
  67. package/locales/fr.json +168 -168
  68. package/locales/pt.json +165 -165
  69. package/locales/wellbeing/ar-AE.json +149 -149
  70. package/locales/wellbeing/ar-SA.json +257 -257
  71. package/locales/wellbeing/de.json +301 -301
  72. package/locales/wellbeing/en.json +423 -423
  73. package/locales/wellbeing/es.json +133 -133
  74. package/locales/wellbeing/fr.json +121 -121
  75. package/locales/wellbeing/it-IT.json +121 -121
  76. package/locales/wellbeing/pt.json +121 -121
  77. package/locales/wellbeing/tr.json +121 -121
  78. package/locales/wellbeing/zh-CN.json +121 -121
  79. package/locales/zh-CN.json +165 -165
  80. package/package.json +47 -47
  81. package/preview-big-integral.js +75 -75
  82. package/run.js +15 -15
  83. package/templates/Mediclinic/blocks/first-section.html +205 -205
  84. package/templates/Mediclinic/blocks/footer.html +7 -7
  85. package/templates/Mediclinic/blocks/header-template.html +5 -5
  86. package/templates/Mediclinic/blocks/header.html +20 -20
  87. package/templates/Mediclinic/blocks/patient-table.html +38 -38
  88. package/templates/Mediclinic/blocks/pdf-header.html +9 -9
  89. package/templates/Mediclinic/blocks/tips.html +8 -8
  90. package/templates/Mediclinic/ltr_no_pages.html +37 -37
  91. package/templates/Mediclinic/rtl_no_pages.html +42 -42
  92. package/templates/Mediclinic/wellbeing_template.html +41 -41
  93. package/templates/Pha/blocks/first-section.html +207 -207
  94. package/templates/Pha/blocks/footer.html +7 -7
  95. package/templates/Pha/blocks/header-template.html +5 -5
  96. package/templates/Pha/blocks/header.html +20 -20
  97. package/templates/Pha/blocks/patient-table.html +38 -38
  98. package/templates/Pha/blocks/pdf-header.html +8 -8
  99. package/templates/Pha/blocks/tips.html +8 -8
  100. package/templates/Pha/ltr_no_pages.html +37 -37
  101. package/templates/Pha/rtl_no_pages.html +42 -42
  102. package/templates/Pha/wellbeing_template.html +41 -41
  103. package/templates/base.html +23 -23
  104. package/templates/blocks/ar-first-page-header.html +68 -68
  105. package/templates/blocks/ar-footer.html +54 -54
  106. package/templates/blocks/ar-header.html +67 -67
  107. package/templates/blocks/biomarker-compact-ar.html +27 -27
  108. package/templates/blocks/biomarker-compact.html +27 -27
  109. package/templates/blocks/biomarker-details.html +41 -41
  110. package/templates/blocks/biomarker-insight.html +22 -22
  111. package/templates/blocks/biomarker-min.html +9 -9
  112. package/templates/blocks/doctor-note.html +11 -11
  113. package/templates/blocks/footer.html +35 -35
  114. package/templates/blocks/header-first-page.html +46 -46
  115. package/templates/blocks/header.html +49 -49
  116. package/templates/blocks/panel-compact.html +38 -38
  117. package/templates/blocks/panel-details.html +16 -16
  118. package/templates/blocks/report-summary.html +16 -16
  119. package/templates/blocks/section-title.html +4 -4
  120. package/templates/blocks/signature.html +16 -16
  121. package/templates/blocks/summary-insight.html +15 -15
  122. package/templates/blocks/summary.html +9 -9
  123. package/templates/corporate_report/cover_page.html +23 -23
  124. package/templates/corporate_report/footer.html +9 -9
  125. package/templates/corporate_report/ltr_no_pages.html +20 -20
  126. package/templates/corporate_report/page.html +24 -24
  127. package/templates/corporate_report/participant_analytics.html +5 -5
  128. package/templates/corporate_report/rtl_no_pages.html +20 -20
  129. package/templates/empty.html +10 -10
  130. package/templates/first_page_head.html +157 -157
  131. package/templates/imc/first-header-template.html +53 -53
  132. package/templates/ltr.html +1368 -1368
  133. package/templates/ltr_no_pages.html +89 -89
  134. package/templates/maisonsante/blocks/first-section.html +151 -207
  135. package/templates/maisonsante/blocks/footer.html +7 -7
  136. package/templates/maisonsante/blocks/header-template.html +5 -5
  137. package/templates/maisonsante/blocks/header.html +20 -20
  138. package/templates/maisonsante/blocks/patient-table.html +38 -38
  139. package/templates/maisonsante/blocks/pdf-header.html +8 -8
  140. package/templates/maisonsante/blocks/tips.html +8 -8
  141. package/templates/maisonsante/ltr_no_pages.html +38 -38
  142. package/templates/maisonsante/rtl_no_pages.html +43 -43
  143. package/templates/maisonsante/wellbeing_template.html +41 -41
  144. package/templates/no_pages.html +1224 -1224
  145. package/templates/popup/popup-template.html +129 -129
  146. package/templates/rtl_no_pages.html +92 -92
  147. package/templates/sanusx/blocks/footer.html +6 -6
  148. package/templates/sanusx/blocks/header.html +20 -20
  149. package/templates/sanusx/blocks/personal-details.html +123 -123
  150. package/templates/sanusx/blocks/predictions-section.html +57 -57
  151. package/templates/sanusx/blocks/recommendations-section.html +6 -6
  152. package/templates/sanusx/blocks/super-power-section.html +29 -29
  153. package/templates/sanusx/blocks/tips.html +8 -8
  154. package/templates/sanusx/ltr_no_pages.html +26 -26
  155. package/templates/sanusx/rtl_no_pages.html +36 -36
  156. package/templates/template.html +1377 -1377
  157. package/templates/wellbeing/blocks/first-section.html +106 -106
  158. package/templates/wellbeing/blocks/footer.html +7 -7
  159. package/templates/wellbeing/blocks/header.html +37 -37
  160. package/templates/wellbeing/blocks/tips.html +8 -8
  161. package/templates/wellbeing/ltr_no_pages.html +35 -35
  162. package/templates/wellbeing/rtl_no_pages.html +36 -36
  163. package/templates/wellbeing/wellbeing_template.html +43 -43
  164. package/test.js +74 -74
  165. package/.claude/settings.local.json +0 -16
  166. package/testing-reports/mediclinic/arabic-data.js +0 -439
  167. package/testing-reports/mediclinic/doctor-data.js +0 -523
  168. package/testing-reports/mediclinic/with-wellbeing.js +0 -415
  169. package/testing-reports/pha/notes-example.js +0 -397
@@ -1,400 +1,400 @@
1
- "use strict";
2
- const fs = require("fs");
3
- const {promisify} = require('util');
4
- const {JSDOM} = require("jsdom");
5
- const fetch = require("node-fetch");
6
- const path = require("path");
7
- const LocaleService = require('../app/services/localeService.js');
8
- const i18n = require('../app/i18n_wellbeing.config.js');
9
- const puppeteer = require("puppeteer");
10
- const hummus = require('hummus');
11
- const memoryStreams = require('memory-streams');
12
-
13
- var localeService = new LocaleService(i18n);
14
- let isRTL = false;
15
-
16
-
17
- let OUT_FILE = 'output/corporate-report-pdf.html';
18
- let Pdf_file = '';
19
- const appDir = path.dirname(require.main.filename);
20
-
21
-
22
- let debug = true;
23
-
24
- let debugLog = (val1, val2 = "") => {
25
- if (debug) {
26
- console.log(val1, val2);
27
- }
28
- }
29
-
30
-
31
- /***
32
- * HTML file generator to fill the html template
33
- * based on the json data from the POST request
34
- */
35
-
36
- let logo = ""
37
- let main_color = ""
38
- let body_font_color = ""
39
- let report_date_color = ""
40
- let section_title_color = ""
41
- let section_title_border_color = ""
42
- let chart_title = ""
43
- let summary_background = ""
44
- let relation_content_border_color = ""
45
- let relation_content_bg = ""
46
- let table_tr_even_bg = ""
47
- let recommends_bg = ""
48
- let show_second_footer_logo = ""
49
- let recommends_title = ""
50
- let show_medicus_logo = ""
51
- let generateHTMLCorporateReport = async (data, isDebugging) => {
52
-
53
- debug = isDebugging;
54
- let dateNow = Date.now()
55
- OUT_FILE = path.resolve(__dirname + '/../output/corporate-report-pdf' + dateNow + '.html');
56
- Pdf_file = '/output/corporate-report-pdf' + dateNow + '.html'
57
- let isRtl = false;
58
- // data.language = 'es'
59
-
60
-
61
- let client = data.clientName ? data.clientName.toLowerCase() : 'default'
62
- let pathFile = path.resolve(__dirname + '/../config/' + client + '.json');
63
- let defaultConfig = require('../config/default.json');
64
- if (fs.existsSync(pathFile)) {
65
- defaultConfig = require('../config/' + client + '.json');
66
- }
67
- logo = defaultConfig['corporate_report']['logo'];
68
- main_color = defaultConfig['corporate_report']['main_color'];
69
- report_date_color = defaultConfig['corporate_report']['report_date_color'];
70
- section_title_color = defaultConfig['corporate_report']['section_title_color'];
71
- section_title_border_color = defaultConfig['corporate_report']['section_title_border_color'];
72
- chart_title = defaultConfig['corporate_report']['chart_title'];
73
- summary_background = defaultConfig['corporate_report']['summary_background'];
74
- relation_content_border_color = defaultConfig['corporate_report']['relation_content_border_color'];
75
- relation_content_bg = defaultConfig['corporate_report']['relation_content_bg'];
76
- table_tr_even_bg = defaultConfig['corporate_report']['table_tr_even_bg'];
77
- recommends_bg = defaultConfig['corporate_report']['recommends_bg'];
78
- show_second_footer_logo = defaultConfig['corporate_report']['show_second_footer_logo'];
79
- body_font_color = defaultConfig['corporate_report']['body_font_color']
80
- recommends_title = defaultConfig['corporate_report']['recommends_title']
81
- show_medicus_logo = defaultConfig['corporate_report']['show_medicus_logo']
82
-
83
- /*
84
- if (data.language.indexOf('ar') !== -1) {
85
- data.language = 'ar-SA';
86
- isRtl = true;
87
- }*/
88
-
89
- /*check if the language is an RTL language*/
90
- if (!data.language) {
91
- localeService.setLocale("en")
92
- } else {
93
- if (data.language.indexOf('ar') !== -1) {
94
- data.language = 'ar-SA';
95
- isRTL = true;
96
- }
97
- localeService.setLocale(data.language);
98
- debugLog("pdf language:", data.language);
99
- }
100
- /*choose the right template*/
101
- let html = !isRTL ? fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/ltr_no_pages.html'), 'utf8') :
102
- fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/rtl_no_pages.html'), 'utf8')
103
-
104
- let coverPageTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/cover_page.html'), 'utf8');
105
- let participantAnalyticsTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/participant_analytics.html'), 'utf8');
106
- let pageAnalyticsTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/page.html'), 'utf8');
107
- let footerTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/footer.html'), 'utf8');
108
- footerTemplate = footerTemplate
109
- .replace("{{logo}}", logo)
110
- .replace("{{footer_Color}}", report_date_color)
111
- .replace("{{Page}}", localeService.t('Page'))
112
- /*create the dom element*/
113
- const dom = new JSDOM(html);
114
- let historyData = [];
115
- debugLog("templates loaded");
116
- let display_second_log = show_second_footer_logo ? "" : "display:none";
117
- let show_medicus = show_medicus_logo ? path.resolve(__dirname + "/../assets/corporate_report/images/medicus-logo-footer.png") : ""
118
- coverPageTemplate = coverPageTemplate
119
- .replace("{{logo}}", logo)
120
- .replace("{{reportHeader}}", data.reportHeader)
121
- .replace("{{reportTitle}}", data.reportTitle)
122
- .replace("{{reportDate}}", data.reportDate)
123
- .replace("{{Copyright}}", localeService.t('Copyright'))
124
- .replace("{{secondFooterLogoStyle}}", display_second_log)
125
- .replace("{{medicusLogo}}", show_medicus)
126
- .replace("{{companyLogo}}", data.reportLogo)
127
-
128
-
129
- /*get the window from the dom to be used as a jquery function*/
130
- const $ = (require('jquery'))(dom.window);
131
- $('#content').append(coverPageTemplate);
132
-
133
- let participantAnalyticsTemplateHTML = participantAnalyticsTemplate.replace("{{ParticipantAnalytics}}", localeService.t('Participant Analytics'));
134
- $('#content').append(participantAnalyticsTemplateHTML);
135
- $(".cover-overlay-container").addClass(client);
136
- $('#content').append('<style>' +
137
- '.report-header{color: ' + body_font_color + ' !important;}' +
138
- '.report-title,.single-relation,.relation-title,.recommends-title,.recommends-section ul,.sources-section a{color: ' + main_color + ' !important;}' +
139
- '.section-title{color: ' + section_title_color + ' !important;border-bottom: 3px solid ' + section_title_border_color + ';}' +
140
- '.chart_title{color: ' + chart_title + ' !important;}' +
141
- '.element-summary-text,.summary-bg{background: ' + summary_background + ' !important;}' +
142
- '.relation-content,table.data-by-gender th{border-color: ' + relation_content_border_color + ' !important;}' +
143
- '.relation-content{background: ' + relation_content_bg + ' !important;}' +
144
- 'table.data-by-gender tbody tr:nth-child(even){background-color: ' + table_tr_even_bg + ' !important;}' +
145
- '.report-date,table.data-by-gender th,table.data-by-gender tbody tr:first-child td,.sources-title{color: ' + report_date_color + ' !important;}' +
146
- '.recommends-section{background: ' + recommends_bg + ' !important;}' +
147
-
148
- '</style>');
149
-
150
- let participantAnalytics = data.participantAnalytics
151
-
152
- participantAnalytics.map((participantAnalytic) => {
153
- let barChart = renderBarChart(participantAnalytic)
154
- $('.participant-analytics-section .container').append(barChart);
155
- })
156
- let elementsHTML = ""
157
- if (!empty(data.elements)) {
158
- data.elements.map((element, index) => {
159
- let pageId = "page-" + index;
160
- elementsHTML = pageAnalyticsTemplate.replace("{{pageId}}", pageId)
161
- .replace("{{pageTitle}}", element.elementTitle);
162
- $('#content').append(elementsHTML);
163
- /*check summary*/
164
- if (!empty(element.summary)) {
165
- $("#" + pageId + " .element-summary-text").html(element.summary);
166
- } else {
167
- $("#" + pageId + " .element-summary-text").remove()
168
- }
169
- if (!empty(element.chartValues)) {
170
- $(renderBarChart(element.chartValues)).insertAfter("#" + pageId + " .element-summary-container");
171
- }
172
- if (!empty(element.secondChartValues)) {
173
- $(renderBarChart(element.secondChartValues)).insertAfter("#" + pageId + " .side-chart-container");
174
- }
175
- /*check relations*/
176
- if (!empty(element.relations)) {
177
- console.log("element.relations", element.relations.length)
178
- element.relations.map((relation) => {
179
- $("#" + pageId + " .relations-section-container .relations-section-titles").append("<div class='single-relation'>" +
180
- "<div class='relation-title'>" + relation.title + "</div>" +
181
- "<div class='relation-content'>" + relation.text + "</div>" +
182
- "<div class='relation-content-bottom-bg'></div>" +
183
- "</div>" +
184
- "</div>");
185
- $("#" + pageId + ".relation-content").html(relation.text)
186
- })
187
- } else {
188
- $("#" + pageId + " .relations-section-container").remove();
189
- }
190
- /*check data by gender*/
191
- if (!empty(element.dataByGender)) {
192
-
193
- let tabelHeader = element.dataByGender[0]
194
- let tabelHeaderHTML = '<thead>'
195
- tabelHeader.map((header) => {
196
- tabelHeaderHTML += "<th colspan='" + header.count + "'>" + header.value + "</th>"
197
- })
198
- tabelHeaderHTML += '</thead>'
199
- let tabelBody = element.dataByGender.slice(1)
200
- let dataByGenderHTML = '<tbody>'
201
- tabelBody.map((genderData) => {
202
- dataByGenderHTML += "<tr>"
203
- genderData.map((td) => {
204
- dataByGenderHTML += "<td>" + td.value + "</td>"
205
- })
206
- dataByGenderHTML += "</tr>"
207
- })
208
- dataByGenderHTML += "</tbody>"
209
- $("#" + pageId + " .data-by-gender").append(tabelHeaderHTML);
210
- $("#" + pageId + " .data-by-gender").append(dataByGenderHTML);
211
- } else {
212
- $("#" + pageId + " .data-by-gender").remove();
213
- }
214
-
215
- if (!empty(element.recommends)) {
216
- let recommendsHTML = '<div class=\'recommends-title\'>' + `${recommends_title} ${localeService.t('recommends...')}` + '</div><ul>';
217
- element.recommends.map((recommend) => {
218
- recommendsHTML += "<li>" +
219
- "<img src='" + __dirname + '/../assets/corporate_report/images/bulb.png' + "' />" +
220
- "<span>" + recommend.tip + "</span>" +
221
- "</li>"
222
- })
223
- recommendsHTML += '</ul>'
224
- $("#" + pageId + " .recommends-section-content").html(recommendsHTML);
225
- } else {
226
- $("#" + pageId + " .recommends-section").remove();
227
- }
228
-
229
-
230
- if (!empty(element.sources)) {
231
- let sourcesHTML = `<div class=\'sources-title\'>${localeService.t('Sources')}</div>`
232
- element.sources.map((source) => {
233
- sourcesHTML += "<span>"
234
- if (!empty(source.link)) {
235
- sourcesHTML += "<a class='hyperlink' href='" + source.link + "' target='_blank'>";
236
- }
237
- sourcesHTML += source.title
238
- if (!empty(source.link)) {
239
- sourcesHTML += "</a>";
240
- }
241
- sourcesHTML += "</span>"
242
- })
243
- $("#" + pageId + " .sources-section").html(sourcesHTML);
244
- $(".links").html(sourcesHTML);
245
- } else {
246
- $("#" + pageId + " .sources-section").remove();
247
- }
248
- })
249
- }
250
-
251
-
252
- let OUTPUT_DIRECTORY = path.resolve(`${__dirname}/../output`);
253
- if (!fs.existsSync(OUTPUT_DIRECTORY)) {
254
- fs.mkdirSync(OUTPUT_DIRECTORY)
255
- }
256
- await promisify(fs.writeFile)(OUT_FILE, dom.serialize());
257
-
258
-
259
- let REQUEST_OUTPUT_DIRECTORY = path.resolve(`${__dirname}/../output/request`);
260
- if (!fs.existsSync(REQUEST_OUTPUT_DIRECTORY)) {
261
- fs.mkdirSync(REQUEST_OUTPUT_DIRECTORY)
262
- }
263
-
264
- return {
265
- "html": dom.serialize(),
266
- "outputFile": OUT_FILE,
267
- "page1": coverPageTemplate,
268
- "header": '',
269
- "footer": footerTemplate,
270
- "historyData": historyData,
271
- };
272
- }
273
-
274
-
275
- let generatePDFCorporateReport = async (data) => {
276
- try {
277
- let contentHtml = data.html;
278
- OUT_FILE = data.outputFile;
279
- let footer = data.footer;
280
- let browser = await puppeteer.launch({
281
- args: ['--no-sandbox', '--disable-setuid-sandbox'],
282
- headless: true,
283
- ignoreHTTPSErrors: true,
284
- 'defaultViewport': {'width': 1024, 'height': 1600}
285
- });
286
- let page = await browser.newPage();
287
- debugLog("page launched!");
288
-
289
- await page.setContent(contentHtml, {waitUntil: 'networkidle2'});
290
-
291
- await page.evaluateHandle('document.fonts.ready');
292
- // await page.setViewport({width: 1440, height: 900, deviceScaleFactor: 2});
293
- await page.addScriptTag({url: 'https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js'});
294
- debugLog("fonts loaded!");
295
-
296
- await page.goto("file:///" + path.resolve(__dirname + `/../${Pdf_file}`), {
297
- timeout: 30000000,
298
- waitUntil: 'networkidle2'
299
- }).catch(e => {
300
- console.log("ERROR IS File path: " + e.message);
301
- });
302
-
303
- debugLog("page opened!");
304
- let buffer1 = await page.pdf({
305
- format: 'A4',
306
- landscape: false,
307
- fitWindow: true,
308
- printBackground: true,
309
- displayHeaderFooter: true,
310
- margin: {
311
- top: 0,
312
- bottom: 60,
313
- right: 0,
314
- left: 0
315
- },
316
- headerTemplate: '',
317
- "footerTemplate": footer
318
- });
319
-
320
- debugLog("Buffer1 loaded!");
321
- await browser.close();
322
- return buffer1;
323
-
324
- } catch (e) {
325
- debugLog("ERROR!: ", e);
326
- return "";
327
- }
328
- };
329
-
330
- const combinePDFBuffers = (firstBuffer, secondBuffer) => {
331
- var outStream = new memoryStreams.WritableStream();
332
-
333
- try {
334
- var firstPDFStream = new hummus.PDFRStreamForBuffer(firstBuffer);
335
- var secondPDFStream = new hummus.PDFRStreamForBuffer(secondBuffer);
336
-
337
- var pdfWriter = hummus.createWriterToModify(firstPDFStream, new hummus.PDFStreamForResponse(outStream));
338
- pdfWriter.appendPDFPagesFromPDF(secondPDFStream);
339
- pdfWriter.end();
340
- var newBuffer = outStream.toBuffer();
341
- outStream.end();
342
-
343
- return newBuffer;
344
- } catch (e) {
345
- outStream.end();
346
- throw new Error('Error during PDF combination: ' + e.message);
347
- }
348
- };
349
- const isEmpty = (obj) => {
350
- for (let key in obj) {
351
- if (obj.hasOwnProperty(key))
352
- return false;
353
- }
354
- return true;
355
- }
356
-
357
- const empty = (value) => {
358
- return (typeof value === "undefined" || typeof value === 'undefined' || typeof value === undefined || value === null || value === '' || value === "" || value.length === 0 || value === 'undefined');
359
- }
360
-
361
-
362
- let renderBarChart = (data) => {
363
- let total = 100;
364
- let barChart = ""
365
- if (!empty(data) && !empty(data.data)) {
366
- barChart = "<div class='side-chart-container'>"
367
- if (!empty(data.title)) {
368
- barChart += "<div class='chart_title'>" + data.title + "</div>"
369
- if (data.title === "Activity") {
370
- total = data.data[1].value
371
- }
372
- }
373
- if (!empty(data.data)) {
374
- barChart += "<div class='side-chart side-chart-with-border'><table>"
375
- let dataLength = data.data.length
376
- let barChartClass = ''
377
- if (dataLength > 5) {
378
- barChartClass = 'divide-bar'
379
- }
380
- data.data.map((chartData) => {
381
- barChart += "<tr>"
382
- barChart += "<td>" +
383
- "<div class='bar-chart " + barChartClass + "' style='background: " + chartData.color + "' data-value='" + chartData.value + "' data-total='" + total + "'>" + chartData.value + "</div>\n" +
384
- "</td>"
385
- barChart += "<td class='bar-title'><span>" + chartData.title + "</span></td>"
386
- barChart += "</tr>"
387
- })
388
-
389
- barChart += "</table></div>";
390
- }
391
-
392
- barChart += "</div>";
393
- }
394
- return barChart;
395
- }
396
-
397
- module.exports = {
398
- generatePDFCorporateReport,
399
- generateHTMLCorporateReport,
1
+ "use strict";
2
+ const fs = require("fs");
3
+ const {promisify} = require('util');
4
+ const {JSDOM} = require("jsdom");
5
+ const fetch = require("node-fetch");
6
+ const path = require("path");
7
+ const LocaleService = require('../app/services/localeService.js');
8
+ const i18n = require('../app/i18n_wellbeing.config.js');
9
+ const puppeteer = require("puppeteer");
10
+ const hummus = require('hummus');
11
+ const memoryStreams = require('memory-streams');
12
+
13
+ var localeService = new LocaleService(i18n);
14
+ let isRTL = false;
15
+
16
+
17
+ let OUT_FILE = 'output/corporate-report-pdf.html';
18
+ let Pdf_file = '';
19
+ const appDir = path.dirname(require.main.filename);
20
+
21
+
22
+ let debug = true;
23
+
24
+ let debugLog = (val1, val2 = "") => {
25
+ if (debug) {
26
+ console.log(val1, val2);
27
+ }
28
+ }
29
+
30
+
31
+ /***
32
+ * HTML file generator to fill the html template
33
+ * based on the json data from the POST request
34
+ */
35
+
36
+ let logo = ""
37
+ let main_color = ""
38
+ let body_font_color = ""
39
+ let report_date_color = ""
40
+ let section_title_color = ""
41
+ let section_title_border_color = ""
42
+ let chart_title = ""
43
+ let summary_background = ""
44
+ let relation_content_border_color = ""
45
+ let relation_content_bg = ""
46
+ let table_tr_even_bg = ""
47
+ let recommends_bg = ""
48
+ let show_second_footer_logo = ""
49
+ let recommends_title = ""
50
+ let show_medicus_logo = ""
51
+ let generateHTMLCorporateReport = async (data, isDebugging) => {
52
+
53
+ debug = isDebugging;
54
+ let dateNow = Date.now()
55
+ OUT_FILE = path.resolve(__dirname + '/../output/corporate-report-pdf' + dateNow + '.html');
56
+ Pdf_file = '/output/corporate-report-pdf' + dateNow + '.html'
57
+ let isRtl = false;
58
+ // data.language = 'es'
59
+
60
+
61
+ let client = data.clientName ? data.clientName.toLowerCase() : 'default'
62
+ let pathFile = path.resolve(__dirname + '/../config/' + client + '.json');
63
+ let defaultConfig = require('../config/default.json');
64
+ if (fs.existsSync(pathFile)) {
65
+ defaultConfig = require('../config/' + client + '.json');
66
+ }
67
+ logo = defaultConfig['corporate_report']['logo'];
68
+ main_color = defaultConfig['corporate_report']['main_color'];
69
+ report_date_color = defaultConfig['corporate_report']['report_date_color'];
70
+ section_title_color = defaultConfig['corporate_report']['section_title_color'];
71
+ section_title_border_color = defaultConfig['corporate_report']['section_title_border_color'];
72
+ chart_title = defaultConfig['corporate_report']['chart_title'];
73
+ summary_background = defaultConfig['corporate_report']['summary_background'];
74
+ relation_content_border_color = defaultConfig['corporate_report']['relation_content_border_color'];
75
+ relation_content_bg = defaultConfig['corporate_report']['relation_content_bg'];
76
+ table_tr_even_bg = defaultConfig['corporate_report']['table_tr_even_bg'];
77
+ recommends_bg = defaultConfig['corporate_report']['recommends_bg'];
78
+ show_second_footer_logo = defaultConfig['corporate_report']['show_second_footer_logo'];
79
+ body_font_color = defaultConfig['corporate_report']['body_font_color']
80
+ recommends_title = defaultConfig['corporate_report']['recommends_title']
81
+ show_medicus_logo = defaultConfig['corporate_report']['show_medicus_logo']
82
+
83
+ /*
84
+ if (data.language.indexOf('ar') !== -1) {
85
+ data.language = 'ar-SA';
86
+ isRtl = true;
87
+ }*/
88
+
89
+ /*check if the language is an RTL language*/
90
+ if (!data.language) {
91
+ localeService.setLocale("en")
92
+ } else {
93
+ if (data.language.indexOf('ar') !== -1) {
94
+ data.language = 'ar-SA';
95
+ isRTL = true;
96
+ }
97
+ localeService.setLocale(data.language);
98
+ debugLog("pdf language:", data.language);
99
+ }
100
+ /*choose the right template*/
101
+ let html = !isRTL ? fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/ltr_no_pages.html'), 'utf8') :
102
+ fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/rtl_no_pages.html'), 'utf8')
103
+
104
+ let coverPageTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/cover_page.html'), 'utf8');
105
+ let participantAnalyticsTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/participant_analytics.html'), 'utf8');
106
+ let pageAnalyticsTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/page.html'), 'utf8');
107
+ let footerTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/corporate_report/footer.html'), 'utf8');
108
+ footerTemplate = footerTemplate
109
+ .replace("{{logo}}", logo)
110
+ .replace("{{footer_Color}}", report_date_color)
111
+ .replace("{{Page}}", localeService.t('Page'))
112
+ /*create the dom element*/
113
+ const dom = new JSDOM(html);
114
+ let historyData = [];
115
+ debugLog("templates loaded");
116
+ let display_second_log = show_second_footer_logo ? "" : "display:none";
117
+ let show_medicus = show_medicus_logo ? path.resolve(__dirname + "/../assets/corporate_report/images/medicus-logo-footer.png") : ""
118
+ coverPageTemplate = coverPageTemplate
119
+ .replace("{{logo}}", logo)
120
+ .replace("{{reportHeader}}", data.reportHeader)
121
+ .replace("{{reportTitle}}", data.reportTitle)
122
+ .replace("{{reportDate}}", data.reportDate)
123
+ .replace("{{Copyright}}", localeService.t('Copyright'))
124
+ .replace("{{secondFooterLogoStyle}}", display_second_log)
125
+ .replace("{{medicusLogo}}", show_medicus)
126
+ .replace("{{companyLogo}}", data.reportLogo)
127
+
128
+
129
+ /*get the window from the dom to be used as a jquery function*/
130
+ const $ = (require('jquery'))(dom.window);
131
+ $('#content').append(coverPageTemplate);
132
+
133
+ let participantAnalyticsTemplateHTML = participantAnalyticsTemplate.replace("{{ParticipantAnalytics}}", localeService.t('Participant Analytics'));
134
+ $('#content').append(participantAnalyticsTemplateHTML);
135
+ $(".cover-overlay-container").addClass(client);
136
+ $('#content').append('<style>' +
137
+ '.report-header{color: ' + body_font_color + ' !important;}' +
138
+ '.report-title,.single-relation,.relation-title,.recommends-title,.recommends-section ul,.sources-section a{color: ' + main_color + ' !important;}' +
139
+ '.section-title{color: ' + section_title_color + ' !important;border-bottom: 3px solid ' + section_title_border_color + ';}' +
140
+ '.chart_title{color: ' + chart_title + ' !important;}' +
141
+ '.element-summary-text,.summary-bg{background: ' + summary_background + ' !important;}' +
142
+ '.relation-content,table.data-by-gender th{border-color: ' + relation_content_border_color + ' !important;}' +
143
+ '.relation-content{background: ' + relation_content_bg + ' !important;}' +
144
+ 'table.data-by-gender tbody tr:nth-child(even){background-color: ' + table_tr_even_bg + ' !important;}' +
145
+ '.report-date,table.data-by-gender th,table.data-by-gender tbody tr:first-child td,.sources-title{color: ' + report_date_color + ' !important;}' +
146
+ '.recommends-section{background: ' + recommends_bg + ' !important;}' +
147
+
148
+ '</style>');
149
+
150
+ let participantAnalytics = data.participantAnalytics
151
+
152
+ participantAnalytics.map((participantAnalytic) => {
153
+ let barChart = renderBarChart(participantAnalytic)
154
+ $('.participant-analytics-section .container').append(barChart);
155
+ })
156
+ let elementsHTML = ""
157
+ if (!empty(data.elements)) {
158
+ data.elements.map((element, index) => {
159
+ let pageId = "page-" + index;
160
+ elementsHTML = pageAnalyticsTemplate.replace("{{pageId}}", pageId)
161
+ .replace("{{pageTitle}}", element.elementTitle);
162
+ $('#content').append(elementsHTML);
163
+ /*check summary*/
164
+ if (!empty(element.summary)) {
165
+ $("#" + pageId + " .element-summary-text").html(element.summary);
166
+ } else {
167
+ $("#" + pageId + " .element-summary-text").remove()
168
+ }
169
+ if (!empty(element.chartValues)) {
170
+ $(renderBarChart(element.chartValues)).insertAfter("#" + pageId + " .element-summary-container");
171
+ }
172
+ if (!empty(element.secondChartValues)) {
173
+ $(renderBarChart(element.secondChartValues)).insertAfter("#" + pageId + " .side-chart-container");
174
+ }
175
+ /*check relations*/
176
+ if (!empty(element.relations)) {
177
+ console.log("element.relations", element.relations.length)
178
+ element.relations.map((relation) => {
179
+ $("#" + pageId + " .relations-section-container .relations-section-titles").append("<div class='single-relation'>" +
180
+ "<div class='relation-title'>" + relation.title + "</div>" +
181
+ "<div class='relation-content'>" + relation.text + "</div>" +
182
+ "<div class='relation-content-bottom-bg'></div>" +
183
+ "</div>" +
184
+ "</div>");
185
+ $("#" + pageId + ".relation-content").html(relation.text)
186
+ })
187
+ } else {
188
+ $("#" + pageId + " .relations-section-container").remove();
189
+ }
190
+ /*check data by gender*/
191
+ if (!empty(element.dataByGender)) {
192
+
193
+ let tabelHeader = element.dataByGender[0]
194
+ let tabelHeaderHTML = '<thead>'
195
+ tabelHeader.map((header) => {
196
+ tabelHeaderHTML += "<th colspan='" + header.count + "'>" + header.value + "</th>"
197
+ })
198
+ tabelHeaderHTML += '</thead>'
199
+ let tabelBody = element.dataByGender.slice(1)
200
+ let dataByGenderHTML = '<tbody>'
201
+ tabelBody.map((genderData) => {
202
+ dataByGenderHTML += "<tr>"
203
+ genderData.map((td) => {
204
+ dataByGenderHTML += "<td>" + td.value + "</td>"
205
+ })
206
+ dataByGenderHTML += "</tr>"
207
+ })
208
+ dataByGenderHTML += "</tbody>"
209
+ $("#" + pageId + " .data-by-gender").append(tabelHeaderHTML);
210
+ $("#" + pageId + " .data-by-gender").append(dataByGenderHTML);
211
+ } else {
212
+ $("#" + pageId + " .data-by-gender").remove();
213
+ }
214
+
215
+ if (!empty(element.recommends)) {
216
+ let recommendsHTML = '<div class=\'recommends-title\'>' + `${recommends_title} ${localeService.t('recommends...')}` + '</div><ul>';
217
+ element.recommends.map((recommend) => {
218
+ recommendsHTML += "<li>" +
219
+ "<img src='" + __dirname + '/../assets/corporate_report/images/bulb.png' + "' />" +
220
+ "<span>" + recommend.tip + "</span>" +
221
+ "</li>"
222
+ })
223
+ recommendsHTML += '</ul>'
224
+ $("#" + pageId + " .recommends-section-content").html(recommendsHTML);
225
+ } else {
226
+ $("#" + pageId + " .recommends-section").remove();
227
+ }
228
+
229
+
230
+ if (!empty(element.sources)) {
231
+ let sourcesHTML = `<div class=\'sources-title\'>${localeService.t('Sources')}</div>`
232
+ element.sources.map((source) => {
233
+ sourcesHTML += "<span>"
234
+ if (!empty(source.link)) {
235
+ sourcesHTML += "<a class='hyperlink' href='" + source.link + "' target='_blank'>";
236
+ }
237
+ sourcesHTML += source.title
238
+ if (!empty(source.link)) {
239
+ sourcesHTML += "</a>";
240
+ }
241
+ sourcesHTML += "</span>"
242
+ })
243
+ $("#" + pageId + " .sources-section").html(sourcesHTML);
244
+ $(".links").html(sourcesHTML);
245
+ } else {
246
+ $("#" + pageId + " .sources-section").remove();
247
+ }
248
+ })
249
+ }
250
+
251
+
252
+ let OUTPUT_DIRECTORY = path.resolve(`${__dirname}/../output`);
253
+ if (!fs.existsSync(OUTPUT_DIRECTORY)) {
254
+ fs.mkdirSync(OUTPUT_DIRECTORY)
255
+ }
256
+ await promisify(fs.writeFile)(OUT_FILE, dom.serialize());
257
+
258
+
259
+ let REQUEST_OUTPUT_DIRECTORY = path.resolve(`${__dirname}/../output/request`);
260
+ if (!fs.existsSync(REQUEST_OUTPUT_DIRECTORY)) {
261
+ fs.mkdirSync(REQUEST_OUTPUT_DIRECTORY)
262
+ }
263
+
264
+ return {
265
+ "html": dom.serialize(),
266
+ "outputFile": OUT_FILE,
267
+ "page1": coverPageTemplate,
268
+ "header": '',
269
+ "footer": footerTemplate,
270
+ "historyData": historyData,
271
+ };
272
+ }
273
+
274
+
275
+ let generatePDFCorporateReport = async (data) => {
276
+ try {
277
+ let contentHtml = data.html;
278
+ OUT_FILE = data.outputFile;
279
+ let footer = data.footer;
280
+ let browser = await puppeteer.launch({
281
+ args: ['--no-sandbox', '--disable-setuid-sandbox'],
282
+ headless: true,
283
+ ignoreHTTPSErrors: true,
284
+ 'defaultViewport': {'width': 1024, 'height': 1600}
285
+ });
286
+ let page = await browser.newPage();
287
+ debugLog("page launched!");
288
+
289
+ await page.setContent(contentHtml, {waitUntil: 'networkidle2'});
290
+
291
+ await page.evaluateHandle('document.fonts.ready');
292
+ // await page.setViewport({width: 1440, height: 900, deviceScaleFactor: 2});
293
+ await page.addScriptTag({url: 'https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js'});
294
+ debugLog("fonts loaded!");
295
+
296
+ await page.goto("file:///" + path.resolve(__dirname + `/../${Pdf_file}`), {
297
+ timeout: 30000000,
298
+ waitUntil: 'networkidle2'
299
+ }).catch(e => {
300
+ console.log("ERROR IS File path: " + e.message);
301
+ });
302
+
303
+ debugLog("page opened!");
304
+ let buffer1 = await page.pdf({
305
+ format: 'A4',
306
+ landscape: false,
307
+ fitWindow: true,
308
+ printBackground: true,
309
+ displayHeaderFooter: true,
310
+ margin: {
311
+ top: 0,
312
+ bottom: 60,
313
+ right: 0,
314
+ left: 0
315
+ },
316
+ headerTemplate: '',
317
+ "footerTemplate": footer
318
+ });
319
+
320
+ debugLog("Buffer1 loaded!");
321
+ await browser.close();
322
+ return buffer1;
323
+
324
+ } catch (e) {
325
+ debugLog("ERROR!: ", e);
326
+ return "";
327
+ }
328
+ };
329
+
330
+ const combinePDFBuffers = (firstBuffer, secondBuffer) => {
331
+ var outStream = new memoryStreams.WritableStream();
332
+
333
+ try {
334
+ var firstPDFStream = new hummus.PDFRStreamForBuffer(firstBuffer);
335
+ var secondPDFStream = new hummus.PDFRStreamForBuffer(secondBuffer);
336
+
337
+ var pdfWriter = hummus.createWriterToModify(firstPDFStream, new hummus.PDFStreamForResponse(outStream));
338
+ pdfWriter.appendPDFPagesFromPDF(secondPDFStream);
339
+ pdfWriter.end();
340
+ var newBuffer = outStream.toBuffer();
341
+ outStream.end();
342
+
343
+ return newBuffer;
344
+ } catch (e) {
345
+ outStream.end();
346
+ throw new Error('Error during PDF combination: ' + e.message);
347
+ }
348
+ };
349
+ const isEmpty = (obj) => {
350
+ for (let key in obj) {
351
+ if (obj.hasOwnProperty(key))
352
+ return false;
353
+ }
354
+ return true;
355
+ }
356
+
357
+ const empty = (value) => {
358
+ return (typeof value === "undefined" || typeof value === 'undefined' || typeof value === undefined || value === null || value === '' || value === "" || value.length === 0 || value === 'undefined');
359
+ }
360
+
361
+
362
+ let renderBarChart = (data) => {
363
+ let total = 100;
364
+ let barChart = ""
365
+ if (!empty(data) && !empty(data.data)) {
366
+ barChart = "<div class='side-chart-container'>"
367
+ if (!empty(data.title)) {
368
+ barChart += "<div class='chart_title'>" + data.title + "</div>"
369
+ if (data.title === "Activity") {
370
+ total = data.data[1].value
371
+ }
372
+ }
373
+ if (!empty(data.data)) {
374
+ barChart += "<div class='side-chart side-chart-with-border'><table>"
375
+ let dataLength = data.data.length
376
+ let barChartClass = ''
377
+ if (dataLength > 5) {
378
+ barChartClass = 'divide-bar'
379
+ }
380
+ data.data.map((chartData) => {
381
+ barChart += "<tr>"
382
+ barChart += "<td>" +
383
+ "<div class='bar-chart " + barChartClass + "' style='background: " + chartData.color + "' data-value='" + chartData.value + "' data-total='" + total + "'>" + chartData.value + "</div>\n" +
384
+ "</td>"
385
+ barChart += "<td class='bar-title'><span>" + chartData.title + "</span></td>"
386
+ barChart += "</tr>"
387
+ })
388
+
389
+ barChart += "</table></div>";
390
+ }
391
+
392
+ barChart += "</div>";
393
+ }
394
+ return barChart;
395
+ }
396
+
397
+ module.exports = {
398
+ generatePDFCorporateReport,
399
+ generateHTMLCorporateReport,
400
400
  };