@medicus.ai/medicus-report-pdf-generator 1.3.13 → 1.3.15

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 (178) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/HANDOVER.md +146 -0
  3. package/README.md +26 -26
  4. package/app/i18n.config.js +20 -20
  5. package/app/i18n_wellbeing.config.js +20 -20
  6. package/app/services/localeService.js +28 -28
  7. package/assets/Mediclinic/css/nasco_report.css +6297 -6297
  8. package/assets/Mediclinic/css/nasco_report_rtl.css +851 -851
  9. package/assets/Mediclinic/css/style.css +33 -33
  10. package/assets/Mediclinic/js/js.js +112 -112
  11. package/assets/Mediclinic/js/raphael.js +8437 -8437
  12. package/assets/arabic.css +275 -275
  13. package/assets/charts.min.js +7 -7
  14. package/assets/corporate_report/css/report.css +582 -582
  15. package/assets/corporate_report/css/report_rtl.css +144 -144
  16. package/assets/corporate_report/js/js.js +14 -14
  17. package/assets/data/data.json +124 -124
  18. package/assets/data/data2.json +675 -675
  19. package/assets/data/pdf_data_with_history.json +1255 -1255
  20. package/assets/doctor-note-insight-icon.svg +11 -11
  21. package/assets/imc/css/style.css +61 -61
  22. package/assets/jquery-1.4.min.js +151 -151
  23. package/assets/jquery-2.1.0.min.js +3 -3
  24. package/assets/js.js +201 -201
  25. package/assets/medicus_pdf/arabic.css +444 -444
  26. package/assets/medicus_pdf/styles.css +2427 -2427
  27. package/assets/print.css +4 -4
  28. package/assets/qr-code-style.css +68 -68
  29. package/assets/qrcode.min.js +3 -3
  30. package/assets/raphael-min.js +10 -10
  31. package/assets/sanusx/css/sanusx_report.css +707 -707
  32. package/assets/sizing.js +2 -2
  33. package/assets/styles.css +1545 -1545
  34. package/assets/styles.min.css +1358 -1358
  35. package/assets/translation.js +30 -30
  36. package/assets/wellbeing/css/nasco_report.css +3472 -3472
  37. package/assets/wellbeing/css/nasco_report_rtl.css +679 -679
  38. package/assets/wellbeing/js/js.js +111 -111
  39. package/assets/wellbeing/js/raphael.js +8437 -8437
  40. package/base64/cairo-font.js +2 -2
  41. package/config/Mediclinic.json +37 -37
  42. package/config/Najeeb.ai.json +35 -35
  43. package/config/Pha.json +64 -64
  44. package/config/bionext.json +37 -37
  45. package/config/default.json +35 -35
  46. package/config/diagnostikare.json +34 -34
  47. package/config/maisonsante.json +39 -39
  48. package/config/nasco.json +35 -35
  49. package/config/sanitas.json +35 -35
  50. package/config/sanusx.json +34 -34
  51. package/config/test.txt +4 -4
  52. package/data converter.js +53 -53
  53. package/docs/01-architecture-overview.md +149 -0
  54. package/docs/02-configuration-and-whitelabelling.md +111 -0
  55. package/docs/03-templating-and-rendering.md +71 -0
  56. package/docs/04-report-pipelines.md +128 -0
  57. package/docs/05-questions-and-data-model.md +67 -0
  58. package/docs/06-internationalization.md +59 -0
  59. package/docs/07-email-notifications.md +59 -0
  60. package/docs/08-known-issues-and-technical-debt.md +41 -0
  61. package/docs/README.md +22 -0
  62. package/downloadfile.js +6 -6
  63. package/example.txt +1188 -1188
  64. package/index.js +481 -480
  65. package/lib/big_integral_questionnaire.js +370 -298
  66. package/lib/corporate_report_generator.js +399 -399
  67. package/lib/pdf_generator.min.js +525 -525
  68. package/lib/sanusx_report_generator.js +533 -533
  69. package/lib/sendEmail.js +343 -343
  70. package/lib/template.js +2227 -2227
  71. package/lib/wellbeing_report_generator.js +2164 -2134
  72. package/locales/ar-AE.json +169 -169
  73. package/locales/ar-SA.json +169 -169
  74. package/locales/ar.json +397 -397
  75. package/locales/de.json +169 -169
  76. package/locales/en.json +229 -229
  77. package/locales/fr.json +168 -168
  78. package/locales/pt.json +165 -165
  79. package/locales/wellbeing/ar-AE.json +149 -149
  80. package/locales/wellbeing/ar-SA.json +257 -257
  81. package/locales/wellbeing/de.json +301 -301
  82. package/locales/wellbeing/en.json +423 -423
  83. package/locales/wellbeing/es.json +133 -133
  84. package/locales/wellbeing/fr.json +121 -121
  85. package/locales/wellbeing/it-IT.json +121 -121
  86. package/locales/wellbeing/pt.json +121 -121
  87. package/locales/wellbeing/tr.json +121 -121
  88. package/locales/wellbeing/zh-CN.json +121 -121
  89. package/locales/zh-CN.json +165 -165
  90. package/package.json +47 -47
  91. package/preview-big-integral.js +75 -75
  92. package/run.js +15 -15
  93. package/templates/Mediclinic/blocks/first-section.html +205 -205
  94. package/templates/Mediclinic/blocks/footer.html +7 -7
  95. package/templates/Mediclinic/blocks/header-template.html +5 -5
  96. package/templates/Mediclinic/blocks/header.html +20 -20
  97. package/templates/Mediclinic/blocks/patient-table.html +38 -38
  98. package/templates/Mediclinic/blocks/pdf-header.html +9 -9
  99. package/templates/Mediclinic/blocks/tips.html +8 -8
  100. package/templates/Mediclinic/ltr_no_pages.html +37 -37
  101. package/templates/Mediclinic/rtl_no_pages.html +42 -42
  102. package/templates/Mediclinic/wellbeing_template.html +41 -41
  103. package/templates/Pha/blocks/first-section.html +207 -207
  104. package/templates/Pha/blocks/footer.html +7 -7
  105. package/templates/Pha/blocks/header-template.html +5 -5
  106. package/templates/Pha/blocks/header.html +20 -20
  107. package/templates/Pha/blocks/patient-table.html +38 -38
  108. package/templates/Pha/blocks/pdf-header.html +8 -8
  109. package/templates/Pha/blocks/tips.html +8 -8
  110. package/templates/Pha/ltr_no_pages.html +37 -37
  111. package/templates/Pha/rtl_no_pages.html +42 -42
  112. package/templates/Pha/wellbeing_template.html +41 -41
  113. package/templates/base.html +23 -23
  114. package/templates/blocks/ar-first-page-header.html +68 -68
  115. package/templates/blocks/ar-footer.html +54 -54
  116. package/templates/blocks/ar-header.html +67 -67
  117. package/templates/blocks/biomarker-compact-ar.html +27 -27
  118. package/templates/blocks/biomarker-compact.html +27 -27
  119. package/templates/blocks/biomarker-details.html +41 -41
  120. package/templates/blocks/biomarker-insight.html +22 -22
  121. package/templates/blocks/biomarker-min.html +9 -9
  122. package/templates/blocks/doctor-note.html +11 -11
  123. package/templates/blocks/footer.html +35 -35
  124. package/templates/blocks/header-first-page.html +46 -46
  125. package/templates/blocks/header.html +49 -49
  126. package/templates/blocks/panel-compact.html +38 -38
  127. package/templates/blocks/panel-details.html +16 -16
  128. package/templates/blocks/report-summary.html +16 -16
  129. package/templates/blocks/section-title.html +4 -4
  130. package/templates/blocks/signature.html +16 -16
  131. package/templates/blocks/summary-insight.html +15 -15
  132. package/templates/blocks/summary.html +9 -9
  133. package/templates/corporate_report/cover_page.html +23 -23
  134. package/templates/corporate_report/footer.html +9 -9
  135. package/templates/corporate_report/ltr_no_pages.html +20 -20
  136. package/templates/corporate_report/page.html +24 -24
  137. package/templates/corporate_report/participant_analytics.html +5 -5
  138. package/templates/corporate_report/rtl_no_pages.html +20 -20
  139. package/templates/empty.html +10 -10
  140. package/templates/first_page_head.html +157 -157
  141. package/templates/imc/first-header-template.html +53 -53
  142. package/templates/ltr.html +1368 -1368
  143. package/templates/ltr_no_pages.html +89 -89
  144. package/templates/maisonsante/blocks/first-section.html +151 -207
  145. package/templates/maisonsante/blocks/footer.html +7 -7
  146. package/templates/maisonsante/blocks/header-template.html +5 -5
  147. package/templates/maisonsante/blocks/header.html +20 -20
  148. package/templates/maisonsante/blocks/patient-table.html +38 -38
  149. package/templates/maisonsante/blocks/pdf-header.html +8 -8
  150. package/templates/maisonsante/blocks/tips.html +8 -8
  151. package/templates/maisonsante/ltr_no_pages.html +38 -38
  152. package/templates/maisonsante/rtl_no_pages.html +43 -43
  153. package/templates/maisonsante/wellbeing_template.html +41 -41
  154. package/templates/no_pages.html +1224 -1224
  155. package/templates/popup/popup-template.html +129 -129
  156. package/templates/rtl_no_pages.html +92 -92
  157. package/templates/sanusx/blocks/footer.html +6 -6
  158. package/templates/sanusx/blocks/header.html +20 -20
  159. package/templates/sanusx/blocks/personal-details.html +123 -123
  160. package/templates/sanusx/blocks/predictions-section.html +57 -57
  161. package/templates/sanusx/blocks/recommendations-section.html +6 -6
  162. package/templates/sanusx/blocks/super-power-section.html +29 -29
  163. package/templates/sanusx/blocks/tips.html +8 -8
  164. package/templates/sanusx/ltr_no_pages.html +26 -26
  165. package/templates/sanusx/rtl_no_pages.html +36 -36
  166. package/templates/template.html +1377 -1377
  167. package/templates/wellbeing/blocks/first-section.html +106 -106
  168. package/templates/wellbeing/blocks/footer.html +7 -7
  169. package/templates/wellbeing/blocks/header.html +37 -37
  170. package/templates/wellbeing/blocks/tips.html +8 -8
  171. package/templates/wellbeing/ltr_no_pages.html +35 -35
  172. package/templates/wellbeing/rtl_no_pages.html +36 -36
  173. package/templates/wellbeing/wellbeing_template.html +43 -43
  174. package/test.js +74 -74
  175. package/testing-reports/mediclinic/arabic-data.js +0 -439
  176. package/testing-reports/mediclinic/doctor-data.js +0 -523
  177. package/testing-reports/mediclinic/with-wellbeing.js +0 -415
  178. package/testing-reports/pha/notes-example.js +0 -397
package/lib/sendEmail.js CHANGED
@@ -1,344 +1,344 @@
1
- "use strict";
2
- const LocaleService = require('../app/services/localeService.js');
3
- const i18n = require('../app/i18n.config.js');
4
- var localeService = new LocaleService(i18n);
5
- const nodemailer = require("nodemailer");
6
- const fs = require("fs");
7
- const path = require("path");
8
-
9
- function emailHeader(data) {
10
- let emailHeaderTemplate = '';
11
- let logo = data.logo
12
- let lang = !empty(data.lang) ? data.lang : "en";
13
- let floatAlignment = "left"
14
- if (lang === "ar") {
15
- floatAlignment = "right"
16
- }
17
- // Mail header
18
- emailHeaderTemplate += "<tr>" +
19
- "<td colspan='2'>" +
20
- "<div style='width: 100%;text-align: left;float: " + floatAlignment + ";background:#ffffff;padding:0;color:#7c7c7c'>" +
21
- "<a href='https://medicus.ai/' target='_blank' style='outline: 0'>" +
22
- "<img src='{logo}' width='100' style='max-width:120px;display: block;margin: 20px auto;float:" + floatAlignment + "' />" +
23
- "</a>" +
24
- "</div>" +
25
- "</td></tr>";
26
- emailHeaderTemplate = emailHeaderTemplate.replace("{logo}", logo);
27
- return emailHeaderTemplate;
28
- }
29
-
30
- function emailFooter(data) {
31
- let lang = !empty(data.lang) ? data.lang : "en";
32
- let floatAlignment = "left"
33
- let margin = "margin-right: 6px"
34
- let textAlign = "right"
35
- let direction = "ltr"
36
- if (lang === "ar") {
37
- floatAlignment = "right";
38
- margin = "margin-left: 6px";
39
- textAlign = "left";
40
- direction = "rtl"
41
- }
42
- let showSocialLinks = data.showSocialLinks
43
- let appStoreLink = !empty(data.appStoreLink) ? data.appStoreLink : "https://itunes.apple.com/us/app/medicus-ai/id1242441365?ls=1&mt=8"
44
- let googlePlayLink = !empty(data.appStoreLink) ? data.appStoreLink : "https://play.google.com/store/apps/details?id=ai.medicus.android"
45
- let facebookLink = !empty(data.facebookLink) ? data.facebookLink : "https://www.facebook.com/medicusai"
46
- let twitterLink = !empty(data.twitterLink) ? data.twitterLink : "https://twitter.com/medicusai"
47
- let linkedinLink = !empty(data.linkedinLink) ? data.linkedinLink : "https://www.linkedin.com/company/medicusai/"
48
-
49
- let emailFooterTemplate = '';
50
- //Mail footer
51
- // apps link and logo
52
- emailFooterTemplate += "<table style='width: 100%;margin: auto;direction:" + direction + ";max-width: 800px'>" +
53
- "<tr>" +
54
- "<td style='width: 35%;'>";
55
-
56
- emailFooterTemplate += "<p style='margin: 0;font-family: Helvetica,Arial,sans-serif;font-size: 0.75rem;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;text-align: " + floatAlignment + ";color: #7c7c7c;'>Powered by</p>";
57
-
58
- emailFooterTemplate += "<a href='https://medicus.ai/' target='_blank' style='outline: 0;margin: 0'>" +
59
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/logo-black-grey.png' width='154' style='max-width: 154px;width: 100%;'/></a>" +
60
- "</td>";
61
-
62
- emailFooterTemplate += "<td style='width: 5%;'>";
63
- if (showSocialLinks) {
64
- emailFooterTemplate += "<table style='width:100%;text-align:center;margin: 13px auto 0'>" +
65
- "<td><a href='{facebookLink}' style='display:inline-block;outline: 0' target='_blank'>" +
66
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-facebook-icon.png' width='24' style='max-width: 24px;" + margin + "'/>" +
67
- "</a></td>" +
68
- "<td><a href='{twitterLink} style='display:inline-block;outline: 0' target='_blank'>" +
69
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-twitter-icon.png' width='24' style='max-width: 24px;" + margin + "'/>" +
70
- "</a></td>" +
71
- "<td><a href='{linkedinLink}' style='display:inline-block;outline: 0' target='_blank'>" +
72
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-linked-in-icon.png' width='24' style='max-width: 24px;'/>" +
73
- "</a></td>" +
74
- "</table>";
75
- }
76
- let lastCellWidth = 30;
77
-
78
- if (!showSocialLinks) {
79
- lastCellWidth = 50;
80
- }
81
- emailFooterTemplate += "</td>" +
82
- "<td style='text-align: " + textAlign + ";width:" + lastCellWidth + "%;'>" +
83
- "<a href='{appStoreLink}' style='display: inline-block;width:100%;outline: 0'>" +
84
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/i-os-store-button.png' width='120' style='float: " + textAlign + ";width:auto;max-width: 120px;margin: 0px auto;display: block;padding: 0;box-sizing: border-box;' />" +
85
- "</a>" +
86
- "</td><td style='text-align: " + textAlign + ";width: 15%;'>" +
87
- "<a href='{googlePlayLink}' style='display: inline-block;width:100%;outline: 0'>" +
88
- "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/play-store-button.png' width='120' style='float: " + textAlign + ";width:auto;max-width: 120px;margin: 0px auto;display: block;padding:0;box-sizing: border-box;'/>" +
89
- "</a>" +
90
- "</td>" +
91
- "</tr>" +
92
- "</table>";
93
- emailFooterTemplate = emailFooterTemplate.replace("{appStoreLink}", appStoreLink);
94
- emailFooterTemplate = emailFooterTemplate.replace("{googlePlayLink}", googlePlayLink);
95
- emailFooterTemplate = emailFooterTemplate.replace("{facebookLink}", facebookLink);
96
- emailFooterTemplate = emailFooterTemplate.replace("{twitterLink}", twitterLink);
97
- emailFooterTemplate = emailFooterTemplate.replace("{linkedinLink}", linkedinLink);
98
-
99
- return emailFooterTemplate;
100
- }
101
-
102
-
103
- function emailTemplate(data) {
104
- let emailTemplate = '';
105
- let logo = data.logo
106
- let header_text = !empty(data.headerText) ? data.headerText : ""
107
- let welcoming_text = !empty(data.welcomingText) ? data.welcomingText : "";
108
- let qrImageLink = !empty(data.qrImageLink) ? data.qrImageLink : "";
109
- let sincerely = data.addSincerelySignature
110
- let signature = !empty(data.signature) ? data.signature : "";
111
- let email = !empty(data.patientEmail) ? data.patientEmail : "";
112
- let body = !empty(data.body) ? data.body : "";
113
- let imageLink = !empty(data.imageSrc) ? data.imageSrc : "";
114
- let url = "javascript:;";
115
- let button_text = !empty(data.buttonText) ? data.buttonText : "";
116
- let emailColor = !empty(data.emailColor) ? data.emailColor : "#02d9d1";
117
- let imgStyleViroOnly = "border: 1px solid #ccd6dd;";
118
- let customHeaderHTML = !empty(data.customHeaderHTML) ? data.customHeaderHTML : "";
119
- let customFooterHTML = !empty(data.customFooterHTML) ? data.customFooterHTML : "";
120
- let customBodyHTML = !empty(data.customBodyHTML) ? data.customBodyHTML : "";
121
- let lang = !empty(data.lang) ? data.lang : "en";
122
- let floatAlignment = "left"
123
- if (lang === "ar") {
124
- floatAlignment = "right"
125
- }
126
-
127
-
128
- /* Start main email container */
129
- emailTemplate += "<div style='width:100%;background:#ffffff;max-width: 800px;margin: auto;display: block;clear: both'>" +
130
- "<table role='presentation' border='0' cellpadding='0' cellspacing='0' width='100%' style='width:100%;background:#ffffff;max-width: 800px;margin: auto;display: block;clear: both'>" +
131
- "<tbody>"
132
- /* Email header */
133
- if (customHeaderHTML) {
134
- emailTemplate += customHeaderHTML
135
- } else {
136
- emailTemplate += emailHeader(data)
137
- }
138
- /* Email body */
139
- emailTemplate += "<tr><td colspan='2'>";
140
- if (customBodyHTML) {
141
- emailTemplate += customBodyHTML
142
- } else {
143
- emailTemplate += "<div style='float:left;width:100%;background:#ffffff;border: solid 1px #d3d3d3;margin: auto;display: block;clear: both;padding: 2em;box-sizing: border-box;margin-bottom: 0'>"
144
-
145
- if (header_text) {
146
- emailTemplate += "<div style='width:100%;text-align:" + floatAlignment + ";float:" + floatAlignment + ";background:#ffffff;padding:0;font-family: Helvetica,Arial,sans-serif;font-size: 20px;font-weight: bold;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;'>" +
147
- "<h2 style='margin: 0;'> " +
148
- "{header_text} " +
149
- "</h2>" +
150
- "</div>";
151
- emailTemplate = emailTemplate.replace("{header_text}", header_text);
152
- }
153
-
154
- emailTemplate += "<div id='welcoming' style='margin-bottom:0;font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;text-align:" + floatAlignment + "'>" +
155
- "<p style='margin-top: 20px;margin-bottom: 0;white-space:pre-line;width: 100%;float:" + floatAlignment + ";'>{welcoming_text}</p><br/>";
156
- emailTemplate = emailTemplate.replace("{welcoming_text}", welcoming_text);
157
-
158
- if (imageLink) {
159
- emailTemplate += "<img src='{imageLink}' width='100%' style='width:100%;height: auto;margin: 25px auto;{imgStyleViroOnly}'/>";
160
- emailTemplate = emailTemplate.replace("{imageLink}", imageLink);
161
- emailTemplate = emailTemplate.replace("{imgStyleViroOnly}", imgStyleViroOnly);
162
- }
163
-
164
- if (email) {
165
- emailTemplate += "<p style='font-size:15px;color:#7c7c7c;text-decoration: none;color:#3398c7;font-family: Helvetica,Arial,sans-serif;text-align:" + floatAlignment + ";'>" +
166
- "{email}" +
167
- "</p><br/>";
168
- emailTemplate = emailTemplate.replace("{email}", email);
169
- }
170
- if (body) {
171
- emailTemplate += "{body}<br/>";
172
- emailTemplate = emailTemplate.replace("{body}", body);
173
- }
174
-
175
- if (url && button_text) {
176
- emailTemplate += "<div style='width:100%;height:20px;'></div>";
177
-
178
- emailTemplate += "<table border='0' cellpadding='0' cellspacing='0' style='float: left;background:" + emailColor + " !important;width: fit-content;padding: 0;clear: both;margin:0;'>" +
179
- "<tr><td style='padding: 10px' align='center'>" +
180
- "<a href='{url}' bgcolor='" + emailColor + "' style='background:" + emailColor + ";text-decoration:none;display:inline-block;font-family: Helvetica,Arial,sans-serif;font-size: 18px;font-weight: bold;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;text-align: center;color: #fffffe;'>" +
181
- "{button_text}" +
182
- "</a>" +
183
- "</td></tr>" +
184
- "</table>"
185
- emailTemplate = emailTemplate.replace("{url}", url);
186
- emailTemplate = emailTemplate.replace("{button_text}", button_text);
187
- }
188
- emailTemplate += "<div style='width:100%;height:60px;'></div>";
189
-
190
- if (qrImageLink) {
191
- emailTemplate += "<p style='font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;margin-top: 0;margin-bottom: 15px'>" +
192
- "<span>" +
193
- "Or use the following QR code" +
194
- "</span>" +
195
- "</p>" +
196
- "<img src='{qrImageLink}' style='height: 150px;display: block; padding-top: 13px;margin-bottom: 60px;'>";
197
-
198
- emailTemplate = emailTemplate.replace("{qrImageLink}", qrImageLink);
199
- }
200
-
201
- //Mail signature
202
- emailTemplate += "<p style='font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: 1.29;letter-spacing: normal;color: #7c7c7c;margin-top: 0;margin-bottom: 0;{italicSignature}'>";
203
- if (sincerely) {
204
- emailTemplate += "{Sincerely}<br/>";
205
- }
206
- emailTemplate += "{signature}<br/>";
207
- emailTemplate += "</p></div></br></br>";
208
-
209
- emailTemplate = emailTemplate.replace("{signature}", signature);
210
- emailTemplate = emailTemplate.replace("{Sincerely}", localeService.t('sincerely'));
211
- if (data.isItalicSignature) {
212
- emailTemplate = emailTemplate.replace("{italicSignature}", "font-style: italic");
213
- } else {
214
- emailTemplate = emailTemplate.replace("{italicSignature}", "");
215
- }
216
- emailTemplate += "</div>";
217
- emailTemplate += "<table bgcolor='" + emailColor + "' border='0' cellpadding='0' cellspacing='0' width='100%' style='float:left;background:" + emailColor + ";width:100%;padding:0;margin:0'><tr><td style='padding:10px'></td></tr></table>";
218
- }
219
- emailTemplate += "</td></tr>";
220
- emailTemplate += "</tbody></table>";
221
- if (customFooterHTML) {
222
- emailTemplate += customFooterHTML
223
- } else {
224
- emailTemplate += emailFooter(data)
225
- }
226
-
227
- /*close main email container*/
228
- emailTemplate += "</div>";
229
- return emailTemplate;
230
- }
231
-
232
-
233
- async function sendNascoEmail(data, pdfAttach, mailConfig, clientName) {
234
- if (!empty(data.email)) {
235
- let client = clientName ? clientName : 'default'
236
- let pathFile = path.resolve(__dirname + '/../config/' + client + '.json');
237
- let defaultConfig = require('../config/default.json');
238
- if (fs.existsSync(pathFile)) {
239
- defaultConfig = require('../config/' + client + '.json');
240
- }
241
- let logo = defaultConfig['logo'];
242
- let signature = defaultConfig['signature']
243
- let fifth_level_color = defaultConfig['fifth-level-color']
244
-
245
- let emails = data.email.split(',')
246
- const emailSubject = localeService.t('wellbeingReport');
247
- let attachments = [{
248
- path: pdfAttach,
249
- filename: data.name + " WellbeingReport.pdf",
250
- contentType: "application/pdf"
251
- }]
252
- let emailProp = {
253
- logo: logo,
254
- headerText: localeService.t("Your Wellbeing Report"),
255
- body: localeService.t("Hi") + " " + data.name + ",<br/>" +
256
- "<br/>" +
257
- localeService.t("Your detailed Wellbeing Report is ready!") + "<br/>" +
258
- "<br/>" +
259
- localeService.t("Download the attached PDF to view your report.") + "<br/>" +
260
- "<br/>" +
261
- localeService.t("Learn more about what your physical and psychological scores mean and get recommendations on how you can start improving your health and wellbeing today.") + "<br/>" +
262
- "<br/>" +
263
- localeService.t("Congratulations, you’ve taken the first step towards better health. Keep going!"),
264
- emailColor: fifth_level_color,
265
- sincerely: false,
266
- signature: signature,
267
- isItalicSignature: true,
268
- showSocialLinks: false,
269
- }
270
-
271
- var mailOptions = {
272
- from: !empty(mailConfig.sendFromEmail) ? mailConfig.sendFromEmail : "noreply@medicus.ai",
273
- to: emails,
274
- subject: emailSubject,
275
- text: emailSubject,
276
- html: emailTemplate(emailProp),
277
- attachments: attachments,
278
- important: true
279
- };
280
-
281
- return await sendMail(mailOptions, mailConfig)
282
-
283
- } else {
284
- return null
285
- }
286
- }
287
-
288
- async function sendMail(mailOptions, mailConfig) {
289
- var transporter = nodemailer.createTransport({
290
- host: mailConfig.host,
291
- port: mailConfig.port,
292
- secure: false,
293
- pool: true,
294
- requireTLS: true,
295
- maxConnections: 20,
296
- maxMessages: 1,
297
- auth: {
298
- user: mailConfig.authUser,
299
- pass: mailConfig.authPass
300
- }
301
- });
302
-
303
- let info = await transporter.sendMail(mailOptions);
304
- console.log('Message sent: %s', info.messageId);
305
- return info;
306
- }
307
-
308
- async function sendEmailNotification(data) {
309
- if (!empty(data.toEmails)) {
310
- let emails = data.toEmails.split(',');
311
- data.showSocialLinks = true
312
- const emailSubject = data.emailSubject;
313
-
314
- var mailOptions = {
315
- from: !empty(data.sendFromEmail) ? data.sendFromEmail : "noreply@medicus.ai",
316
- to: emails,
317
- subject: emailSubject,
318
- text: emailSubject,
319
- html: emailTemplate(data)
320
- };
321
-
322
- let mailConfig = {
323
- host: data.host,
324
- port: data.port,
325
- authUser: data.authUser,
326
- authPass: data.authPass,
327
- sendFromEmail: data.sendFromEmail
328
- }
329
-
330
- return await sendMail(mailOptions, mailConfig)
331
- } else {
332
- return null
333
- }
334
-
335
- }
336
-
337
- const empty = (value) => {
338
- return (typeof value === "undefined" || typeof value === 'undefined' || typeof value === undefined || value === null || value === '' || value === "" || value.length === 0 || value === 'undefined');
339
- }
340
-
341
- module.exports = {
342
- sendNascoEmail,
343
- sendEmailNotification
1
+ "use strict";
2
+ const LocaleService = require('../app/services/localeService.js');
3
+ const i18n = require('../app/i18n.config.js');
4
+ var localeService = new LocaleService(i18n);
5
+ const nodemailer = require("nodemailer");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+
9
+ function emailHeader(data) {
10
+ let emailHeaderTemplate = '';
11
+ let logo = data.logo
12
+ let lang = !empty(data.lang) ? data.lang : "en";
13
+ let floatAlignment = "left"
14
+ if (lang === "ar") {
15
+ floatAlignment = "right"
16
+ }
17
+ // Mail header
18
+ emailHeaderTemplate += "<tr>" +
19
+ "<td colspan='2'>" +
20
+ "<div style='width: 100%;text-align: left;float: " + floatAlignment + ";background:#ffffff;padding:0;color:#7c7c7c'>" +
21
+ "<a href='https://medicus.ai/' target='_blank' style='outline: 0'>" +
22
+ "<img src='{logo}' width='100' style='max-width:120px;display: block;margin: 20px auto;float:" + floatAlignment + "' />" +
23
+ "</a>" +
24
+ "</div>" +
25
+ "</td></tr>";
26
+ emailHeaderTemplate = emailHeaderTemplate.replace("{logo}", logo);
27
+ return emailHeaderTemplate;
28
+ }
29
+
30
+ function emailFooter(data) {
31
+ let lang = !empty(data.lang) ? data.lang : "en";
32
+ let floatAlignment = "left"
33
+ let margin = "margin-right: 6px"
34
+ let textAlign = "right"
35
+ let direction = "ltr"
36
+ if (lang === "ar") {
37
+ floatAlignment = "right";
38
+ margin = "margin-left: 6px";
39
+ textAlign = "left";
40
+ direction = "rtl"
41
+ }
42
+ let showSocialLinks = data.showSocialLinks
43
+ let appStoreLink = !empty(data.appStoreLink) ? data.appStoreLink : "https://itunes.apple.com/us/app/medicus-ai/id1242441365?ls=1&mt=8"
44
+ let googlePlayLink = !empty(data.appStoreLink) ? data.appStoreLink : "https://play.google.com/store/apps/details?id=ai.medicus.android"
45
+ let facebookLink = !empty(data.facebookLink) ? data.facebookLink : "https://www.facebook.com/medicusai"
46
+ let twitterLink = !empty(data.twitterLink) ? data.twitterLink : "https://twitter.com/medicusai"
47
+ let linkedinLink = !empty(data.linkedinLink) ? data.linkedinLink : "https://www.linkedin.com/company/medicusai/"
48
+
49
+ let emailFooterTemplate = '';
50
+ //Mail footer
51
+ // apps link and logo
52
+ emailFooterTemplate += "<table style='width: 100%;margin: auto;direction:" + direction + ";max-width: 800px'>" +
53
+ "<tr>" +
54
+ "<td style='width: 35%;'>";
55
+
56
+ emailFooterTemplate += "<p style='margin: 0;font-family: Helvetica,Arial,sans-serif;font-size: 0.75rem;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;text-align: " + floatAlignment + ";color: #7c7c7c;'>Powered by</p>";
57
+
58
+ emailFooterTemplate += "<a href='https://medicus.ai/' target='_blank' style='outline: 0;margin: 0'>" +
59
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/logo-black-grey.png' width='154' style='max-width: 154px;width: 100%;'/></a>" +
60
+ "</td>";
61
+
62
+ emailFooterTemplate += "<td style='width: 5%;'>";
63
+ if (showSocialLinks) {
64
+ emailFooterTemplate += "<table style='width:100%;text-align:center;margin: 13px auto 0'>" +
65
+ "<td><a href='{facebookLink}' style='display:inline-block;outline: 0' target='_blank'>" +
66
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-facebook-icon.png' width='24' style='max-width: 24px;" + margin + "'/>" +
67
+ "</a></td>" +
68
+ "<td><a href='{twitterLink} style='display:inline-block;outline: 0' target='_blank'>" +
69
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-twitter-icon.png' width='24' style='max-width: 24px;" + margin + "'/>" +
70
+ "</a></td>" +
71
+ "<td><a href='{linkedinLink}' style='display:inline-block;outline: 0' target='_blank'>" +
72
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/grey-linked-in-icon.png' width='24' style='max-width: 24px;'/>" +
73
+ "</a></td>" +
74
+ "</table>";
75
+ }
76
+ let lastCellWidth = 30;
77
+
78
+ if (!showSocialLinks) {
79
+ lastCellWidth = 50;
80
+ }
81
+ emailFooterTemplate += "</td>" +
82
+ "<td style='text-align: " + textAlign + ";width:" + lastCellWidth + "%;'>" +
83
+ "<a href='{appStoreLink}' style='display: inline-block;width:100%;outline: 0'>" +
84
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/i-os-store-button.png' width='120' style='float: " + textAlign + ";width:auto;max-width: 120px;margin: 0px auto;display: block;padding: 0;box-sizing: border-box;' />" +
85
+ "</a>" +
86
+ "</td><td style='text-align: " + textAlign + ";width: 15%;'>" +
87
+ "<a href='{googlePlayLink}' style='display: inline-block;width:100%;outline: 0'>" +
88
+ "<img src='https://cerbo-media.dev.medicus.ai/cerbo/static/play-store-button.png' width='120' style='float: " + textAlign + ";width:auto;max-width: 120px;margin: 0px auto;display: block;padding:0;box-sizing: border-box;'/>" +
89
+ "</a>" +
90
+ "</td>" +
91
+ "</tr>" +
92
+ "</table>";
93
+ emailFooterTemplate = emailFooterTemplate.replace("{appStoreLink}", appStoreLink);
94
+ emailFooterTemplate = emailFooterTemplate.replace("{googlePlayLink}", googlePlayLink);
95
+ emailFooterTemplate = emailFooterTemplate.replace("{facebookLink}", facebookLink);
96
+ emailFooterTemplate = emailFooterTemplate.replace("{twitterLink}", twitterLink);
97
+ emailFooterTemplate = emailFooterTemplate.replace("{linkedinLink}", linkedinLink);
98
+
99
+ return emailFooterTemplate;
100
+ }
101
+
102
+
103
+ function emailTemplate(data) {
104
+ let emailTemplate = '';
105
+ let logo = data.logo
106
+ let header_text = !empty(data.headerText) ? data.headerText : ""
107
+ let welcoming_text = !empty(data.welcomingText) ? data.welcomingText : "";
108
+ let qrImageLink = !empty(data.qrImageLink) ? data.qrImageLink : "";
109
+ let sincerely = data.addSincerelySignature
110
+ let signature = !empty(data.signature) ? data.signature : "";
111
+ let email = !empty(data.patientEmail) ? data.patientEmail : "";
112
+ let body = !empty(data.body) ? data.body : "";
113
+ let imageLink = !empty(data.imageSrc) ? data.imageSrc : "";
114
+ let url = "javascript:;";
115
+ let button_text = !empty(data.buttonText) ? data.buttonText : "";
116
+ let emailColor = !empty(data.emailColor) ? data.emailColor : "#02d9d1";
117
+ let imgStyleViroOnly = "border: 1px solid #ccd6dd;";
118
+ let customHeaderHTML = !empty(data.customHeaderHTML) ? data.customHeaderHTML : "";
119
+ let customFooterHTML = !empty(data.customFooterHTML) ? data.customFooterHTML : "";
120
+ let customBodyHTML = !empty(data.customBodyHTML) ? data.customBodyHTML : "";
121
+ let lang = !empty(data.lang) ? data.lang : "en";
122
+ let floatAlignment = "left"
123
+ if (lang === "ar") {
124
+ floatAlignment = "right"
125
+ }
126
+
127
+
128
+ /* Start main email container */
129
+ emailTemplate += "<div style='width:100%;background:#ffffff;max-width: 800px;margin: auto;display: block;clear: both'>" +
130
+ "<table role='presentation' border='0' cellpadding='0' cellspacing='0' width='100%' style='width:100%;background:#ffffff;max-width: 800px;margin: auto;display: block;clear: both'>" +
131
+ "<tbody>"
132
+ /* Email header */
133
+ if (customHeaderHTML) {
134
+ emailTemplate += customHeaderHTML
135
+ } else {
136
+ emailTemplate += emailHeader(data)
137
+ }
138
+ /* Email body */
139
+ emailTemplate += "<tr><td colspan='2'>";
140
+ if (customBodyHTML) {
141
+ emailTemplate += customBodyHTML
142
+ } else {
143
+ emailTemplate += "<div style='float:left;width:100%;background:#ffffff;border: solid 1px #d3d3d3;margin: auto;display: block;clear: both;padding: 2em;box-sizing: border-box;margin-bottom: 0'>"
144
+
145
+ if (header_text) {
146
+ emailTemplate += "<div style='width:100%;text-align:" + floatAlignment + ";float:" + floatAlignment + ";background:#ffffff;padding:0;font-family: Helvetica,Arial,sans-serif;font-size: 20px;font-weight: bold;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;'>" +
147
+ "<h2 style='margin: 0;'> " +
148
+ "{header_text} " +
149
+ "</h2>" +
150
+ "</div>";
151
+ emailTemplate = emailTemplate.replace("{header_text}", header_text);
152
+ }
153
+
154
+ emailTemplate += "<div id='welcoming' style='margin-bottom:0;font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;text-align:" + floatAlignment + "'>" +
155
+ "<p style='margin-top: 20px;margin-bottom: 0;white-space:pre-line;width: 100%;float:" + floatAlignment + ";'>{welcoming_text}</p><br/>";
156
+ emailTemplate = emailTemplate.replace("{welcoming_text}", welcoming_text);
157
+
158
+ if (imageLink) {
159
+ emailTemplate += "<img src='{imageLink}' width='100%' style='width:100%;height: auto;margin: 25px auto;{imgStyleViroOnly}'/>";
160
+ emailTemplate = emailTemplate.replace("{imageLink}", imageLink);
161
+ emailTemplate = emailTemplate.replace("{imgStyleViroOnly}", imgStyleViroOnly);
162
+ }
163
+
164
+ if (email) {
165
+ emailTemplate += "<p style='font-size:15px;color:#7c7c7c;text-decoration: none;color:#3398c7;font-family: Helvetica,Arial,sans-serif;text-align:" + floatAlignment + ";'>" +
166
+ "{email}" +
167
+ "</p><br/>";
168
+ emailTemplate = emailTemplate.replace("{email}", email);
169
+ }
170
+ if (body) {
171
+ emailTemplate += "{body}<br/>";
172
+ emailTemplate = emailTemplate.replace("{body}", body);
173
+ }
174
+
175
+ if (url && button_text) {
176
+ emailTemplate += "<div style='width:100%;height:20px;'></div>";
177
+
178
+ emailTemplate += "<table border='0' cellpadding='0' cellspacing='0' style='float: left;background:" + emailColor + " !important;width: fit-content;padding: 0;clear: both;margin:0;'>" +
179
+ "<tr><td style='padding: 10px' align='center'>" +
180
+ "<a href='{url}' bgcolor='" + emailColor + "' style='background:" + emailColor + ";text-decoration:none;display:inline-block;font-family: Helvetica,Arial,sans-serif;font-size: 18px;font-weight: bold;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;text-align: center;color: #fffffe;'>" +
181
+ "{button_text}" +
182
+ "</a>" +
183
+ "</td></tr>" +
184
+ "</table>"
185
+ emailTemplate = emailTemplate.replace("{url}", url);
186
+ emailTemplate = emailTemplate.replace("{button_text}", button_text);
187
+ }
188
+ emailTemplate += "<div style='width:100%;height:60px;'></div>";
189
+
190
+ if (qrImageLink) {
191
+ emailTemplate += "<p style='font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: normal;letter-spacing: normal;color: #333333;margin-top: 0;margin-bottom: 15px'>" +
192
+ "<span>" +
193
+ "Or use the following QR code" +
194
+ "</span>" +
195
+ "</p>" +
196
+ "<img src='{qrImageLink}' style='height: 150px;display: block; padding-top: 13px;margin-bottom: 60px;'>";
197
+
198
+ emailTemplate = emailTemplate.replace("{qrImageLink}", qrImageLink);
199
+ }
200
+
201
+ //Mail signature
202
+ emailTemplate += "<p style='font-family: Helvetica,Arial,sans-serif;font-size: 17px;font-weight: normal;font-stretch: normal;font-style: normal;line-height: 1.29;letter-spacing: normal;color: #7c7c7c;margin-top: 0;margin-bottom: 0;{italicSignature}'>";
203
+ if (sincerely) {
204
+ emailTemplate += "{Sincerely}<br/>";
205
+ }
206
+ emailTemplate += "{signature}<br/>";
207
+ emailTemplate += "</p></div></br></br>";
208
+
209
+ emailTemplate = emailTemplate.replace("{signature}", signature);
210
+ emailTemplate = emailTemplate.replace("{Sincerely}", localeService.t('sincerely'));
211
+ if (data.isItalicSignature) {
212
+ emailTemplate = emailTemplate.replace("{italicSignature}", "font-style: italic");
213
+ } else {
214
+ emailTemplate = emailTemplate.replace("{italicSignature}", "");
215
+ }
216
+ emailTemplate += "</div>";
217
+ emailTemplate += "<table bgcolor='" + emailColor + "' border='0' cellpadding='0' cellspacing='0' width='100%' style='float:left;background:" + emailColor + ";width:100%;padding:0;margin:0'><tr><td style='padding:10px'></td></tr></table>";
218
+ }
219
+ emailTemplate += "</td></tr>";
220
+ emailTemplate += "</tbody></table>";
221
+ if (customFooterHTML) {
222
+ emailTemplate += customFooterHTML
223
+ } else {
224
+ emailTemplate += emailFooter(data)
225
+ }
226
+
227
+ /*close main email container*/
228
+ emailTemplate += "</div>";
229
+ return emailTemplate;
230
+ }
231
+
232
+
233
+ async function sendNascoEmail(data, pdfAttach, mailConfig, clientName) {
234
+ if (!empty(data.email)) {
235
+ let client = clientName ? clientName : 'default'
236
+ let pathFile = path.resolve(__dirname + '/../config/' + client + '.json');
237
+ let defaultConfig = require('../config/default.json');
238
+ if (fs.existsSync(pathFile)) {
239
+ defaultConfig = require('../config/' + client + '.json');
240
+ }
241
+ let logo = defaultConfig['logo'];
242
+ let signature = defaultConfig['signature']
243
+ let fifth_level_color = defaultConfig['fifth-level-color']
244
+
245
+ let emails = data.email.split(',')
246
+ const emailSubject = localeService.t('wellbeingReport');
247
+ let attachments = [{
248
+ path: pdfAttach,
249
+ filename: data.name + " WellbeingReport.pdf",
250
+ contentType: "application/pdf"
251
+ }]
252
+ let emailProp = {
253
+ logo: logo,
254
+ headerText: localeService.t("Your Wellbeing Report"),
255
+ body: localeService.t("Hi") + " " + data.name + ",<br/>" +
256
+ "<br/>" +
257
+ localeService.t("Your detailed Wellbeing Report is ready!") + "<br/>" +
258
+ "<br/>" +
259
+ localeService.t("Download the attached PDF to view your report.") + "<br/>" +
260
+ "<br/>" +
261
+ localeService.t("Learn more about what your physical and psychological scores mean and get recommendations on how you can start improving your health and wellbeing today.") + "<br/>" +
262
+ "<br/>" +
263
+ localeService.t("Congratulations, you’ve taken the first step towards better health. Keep going!"),
264
+ emailColor: fifth_level_color,
265
+ sincerely: false,
266
+ signature: signature,
267
+ isItalicSignature: true,
268
+ showSocialLinks: false,
269
+ }
270
+
271
+ var mailOptions = {
272
+ from: !empty(mailConfig.sendFromEmail) ? mailConfig.sendFromEmail : "noreply@medicus.ai",
273
+ to: emails,
274
+ subject: emailSubject,
275
+ text: emailSubject,
276
+ html: emailTemplate(emailProp),
277
+ attachments: attachments,
278
+ important: true
279
+ };
280
+
281
+ return await sendMail(mailOptions, mailConfig)
282
+
283
+ } else {
284
+ return null
285
+ }
286
+ }
287
+
288
+ async function sendMail(mailOptions, mailConfig) {
289
+ var transporter = nodemailer.createTransport({
290
+ host: mailConfig.host,
291
+ port: mailConfig.port,
292
+ secure: false,
293
+ pool: true,
294
+ requireTLS: true,
295
+ maxConnections: 20,
296
+ maxMessages: 1,
297
+ auth: {
298
+ user: mailConfig.authUser,
299
+ pass: mailConfig.authPass
300
+ }
301
+ });
302
+
303
+ let info = await transporter.sendMail(mailOptions);
304
+ console.log('Message sent: %s', info.messageId);
305
+ return info;
306
+ }
307
+
308
+ async function sendEmailNotification(data) {
309
+ if (!empty(data.toEmails)) {
310
+ let emails = data.toEmails.split(',');
311
+ data.showSocialLinks = true
312
+ const emailSubject = data.emailSubject;
313
+
314
+ var mailOptions = {
315
+ from: !empty(data.sendFromEmail) ? data.sendFromEmail : "noreply@medicus.ai",
316
+ to: emails,
317
+ subject: emailSubject,
318
+ text: emailSubject,
319
+ html: emailTemplate(data)
320
+ };
321
+
322
+ let mailConfig = {
323
+ host: data.host,
324
+ port: data.port,
325
+ authUser: data.authUser,
326
+ authPass: data.authPass,
327
+ sendFromEmail: data.sendFromEmail
328
+ }
329
+
330
+ return await sendMail(mailOptions, mailConfig)
331
+ } else {
332
+ return null
333
+ }
334
+
335
+ }
336
+
337
+ const empty = (value) => {
338
+ return (typeof value === "undefined" || typeof value === 'undefined' || typeof value === undefined || value === null || value === '' || value === "" || value.length === 0 || value === 'undefined');
339
+ }
340
+
341
+ module.exports = {
342
+ sendNascoEmail,
343
+ sendEmailNotification
344
344
  };