New CCDA Templates (#4427)
[openemr.git] / ccdaservice / oe-blue-button-generate / lib / htmlHeaders.js
blob9f7652470d3fb519e0b38a2e865837a69c479f99
1 "use strict";
3 var bbu = require("../../oe-blue-button-util");
5 var fieldLevel = require("./fieldLevel");
6 var entryLevel = require("./entryLevel");
7 var leafLevel = require('./leafLevel');
8 var contentModifier = require("./contentModifier");
10 var required = contentModifier.required;
11 var bbud = bbu.datetime;
12 var bbuo = bbu.object;
14 var nda = "No Data Available";
16 var condition = require('./condition');
18 var getText = function (topArrayKey, headers, values) {
19     var result = {
20         key: "text",
21         existsWhen: condition.keyExists(topArrayKey),
23         content: [{
24             key: "table",
25             attributes: {
26                 border: "1",
27                 width: "100%"
28             },
29             content: [{
30                 key: "thead",
31                 content: [{
32                     key: "tr",
33                     content: []
34                 }]
35             }, {
36                 key: "tbody",
37                 content: [{
38                     key: "tr",
39                     content: [],
40                     dataKey: topArrayKey
41                 }]
42             }]
43         }]
44     };
45     var headerTarget = result.content[0].content[0].content[0].content;
46     headers.forEach(function (header) {
47         var element = {
48             key: "th",
49             text: header
50         };
51         headerTarget.push(element);
52     });
53     var valueTarget = result.content[0].content[1].content[0].content;
54     values.forEach(function (value) {
55         var data;
56         if (typeof value !== 'function') {
57             data = leafLevel.deepInputProperty(value, "");
58         } else {
59             data = value;
60         }
62         var element = {
63             key: "td",
64             text: data
65         };
66         valueTarget.push(element);
67     });
68     return result;
70 // Replace with static table
71 /*var alllergiesTextHeaders = ["Substance", "Overall Severity", "Reaction", "Reaction Severity", "Status"];
72 var allergiesTextRow = [
73     leafLevel.deepInputProperty("observation.allergen.name", ""),
74     leafLevel.deepInputProperty("observation.severity.code.name", ""),
75     leafLevel.deepInputProperty("observation.reactions.0.reaction.name", ""),
76     leafLevel.deepInputProperty("observation.reactions.0.severity.code.name", ""),
77     leafLevel.deepInputProperty("observation.status.name", "")
78 ];*/
80 //exports.allergiesSectionEntriesRequiredHtmlHeader = getText('allergies', alllergiesTextHeaders, allergiesTextRow);
82 exports.allergiesSectionEntriesRequiredHtmlHeader = {
83     key: "text",
84     existsWhen: condition.keyExists("allergies"),
86     content: [{
87         key: "table",
88         attributes: {
89             width: "100%",
90             border: "1"
91         },
92         content: [{
93             key: "thead",
94             content: [{
95                 key: "tr",
96                 content: [{
97                     key: "th",
98                     text: leafLevel.input,
99                     dataTransform: function () {
100                         return ["Substance", "Overall Severity", "Reaction", "Reaction Severity", "Status"];
101                     }
102                 }]
103             }]
104         }, {
105             key: "tbody",
106             content: [{
107                 key: "tr",
108                 content: [{
109                     key: "td",
110                     text: leafLevel.deepInputProperty("observation.allergen.name",  nda),
111                 }, {
112                     key: "td",
113                     attributes: {
114                         ID: leafLevel.nextTableReference("severity")
115                     },
116                     text: leafLevel.deepInputProperty("observation.severity.code.name",  nda)
117                 }, {
118                     key: "td",
119                     attributes: {
120                         ID: leafLevel.nextTableReference("reaction")
121                     },
122                     text: leafLevel.deepInputProperty("observation.reactions.0.reaction.name",  nda)
123                 }, {
124                     key: "td",
125                     attributes: {
126                         ID: leafLevel.nextTableReference("severity")
127                     },
128                     text: leafLevel.deepInputProperty("observation.reactions.0.severity.code.name",  nda)
129                 }, {
130                     key: "td",
131                     text: leafLevel.deepInputProperty("observation.status.name",  nda)
132                 }]
133             }],
134             dataKey: 'allergies'
135         }]
136     }]
139 exports.medicationsSectionEntriesRequiredHtmlHeader = {
140     key: "text",
141     existsWhen: condition.keyExists("medications"),
143     content: [{
144         key: "table",
145         attributes: {
146             width: "100%",
147             border: "1"
148         },
149         content: [{
150             key: "thead",
151             content: [{
152                 key: "tr",
153                 content: [{
154                     key: "th",
155                     text: leafLevel.input,
156                     dataTransform: function () {
157                         return ["Medication Class", "# fills", "Last fill date"];
158                     }
159                 }]
160             }]
161         }, {
162             key: "tbody",
163             content: [{
164                 key: "tr",
165                 content: [{
166                     key: "td",
167                     attributes: {
168                         ID: leafLevel.nextTableReference("medinfo")
169                     },
170                     text: function (input) {
171                         var value = bbuo.deepValue(input, 'product.product.name');
172                         if (!bbuo.exists(value)) {
173                             value = bbuo.deepValue(input, 'product.unencoded_name');
174                         }
175                         if (!bbuo.exists(value)) {
176                             return "";
177                         } else {
178                             return value;
179                         }
180                     },
181                 }, {
182                     key: "td",
183                     text: leafLevel.deepInputProperty("supply.repeatNumber", ""),
184                 }, {
185                     key: "td",
186                     text: leafLevel.deepInputDate("supply.date_time.low", nda)
187                 }]
188             }],
189             dataKey: 'medications'
190         }]
191     }]
194 exports.problemsSectionEntriesRequiredHtmlHeader = {
195     key: "text",
196     existsWhen: condition.keyExists("problems"),
198     content: [{
199         key: "table",
200         content: [{
201             key: "thead",
202             content: [{
203                 key: "tr",
204                 content: {
205                     key: "th",
206                     attributes: {
207                         colspan: "2"
208                     },
209                     text: "Problems"
210                 }
211             }, {
212                 key: "tr",
213                 content: [{
214                     key: "th",
215                     text: leafLevel.input,
216                     dataTransform: function () {
217                         return ['Condition', 'Status'];
218                     }
219                 }]
220             }]
221         }, {
222             key: "tbody",
223             content: [{
224                 key: "tr",
225                 content: [{
226                     key: "td",
227                     attributes: {
228                         ID: leafLevel.nextTableReference("problem")
229                     },
230                     text: leafLevel.deepInputProperty("problem.code.name", nda)
231                 }, {
232                     key: "td",
233                     attributes: {
234                         ID: leafLevel.nextTableReference("healthStatus")
235                     },
236                     text: leafLevel.deepInputProperty("problem.severity.code.name", nda)
237                 }]
238             }],
239             dataKey: 'problems'
240         }]
241     }]
244 exports.proceduresSectionEntriesRequiredHtmlHeader = {
246     key: "text",
247     existsWhen: condition.keyExists("procedures"),
249     content: [{
250         key: "table",
251         content: [{
252             key: "thead",
253             content: [{
254                 key: "tr",
255                 content: {
256                     key: "th",
257                     attributes: {
258                         colspan: "5"
259                     },
260                     text: "Procedures"
261                 }
262             }, {
263                 key: "tr",
264                 content: [{
265                     key: "th",
266                     text: leafLevel.input,
267                     dataTransform: function () {
268                         return ['Service', 'Procedure code', 'Service date', 'Servicing provider', 'Phone#'];
269                     }
270                 }]
271             }]
272         }, {
273             key: "tbody",
274             content: [{
275                 key: "tr",
276                 content: [{
277                     key: "td",
278                     attributes: {
279                         ID: leafLevel.nextTableReference("procedure")
280                     },
281                     text: leafLevel.deepInputProperty("procedure.name", nda)
282                 }, {
283                     key: "td",
284                     text: leafLevel.deepInputProperty("procedure.code", nda)
285                 }, {
286                     key: "td",
287                     text: leafLevel.deepInputDate("date_time.point", nda)
288                 }, {
289                     key: "td",
290                     text: leafLevel.deepInputProperty("performer.0.organization.0.name.0", nda)
291                 }, {
292                     key: "td",
293                     text: leafLevel.deepInputProperty("performer.0.organization.0.phone.0.value.number", nda)
294                 }]
295             }],
296             dataKey: 'procedures'
297         }]
298     }]
301 exports.resultsSectionEntriesRequiredHtmlHeader = {
302     key: "text",
303     existsWhen: condition.keyExists("results"),
305     content: [{
306         key: "table",
307         content: [{
308             key: "thead",
309             content: [{
310                 key: "tr",
311                 content: {
312                     key: "th",
313                     attributes: {
314                         colspan: "7"
315                     },
316                     text: "Laboratory Results"
317                 }
318             }, {
319                 key: "tr",
320                 content: [{
321                     key: "th",
322                     text: leafLevel.input,
323                     dataTransform: function () {
324                         return ['Test', 'Result', 'Units', 'Reference Range', 'Date', 'Source'];
325                     }
326                 }]
327             }]
328         }, {
329             key: "tbody",
330             content: [{
331                 key: "tr",
332                 content: [{
333                     key: "td",
334                     attributes: {
335                         colspan: "7"
336                     },
337                     text: leafLevel.deepInputProperty('result_set.name', nda),
338                 }]
339             }, {
340                 key: "tr",
341                 content: [{
342                     key: "td",
343                     text: leafLevel.deepInputProperty("result.name", nda)
344                 }, {
345                     key: "td",
346                     attributes: {
347                         ID: leafLevel.nextTableReference("result")
348                     },
349                     text: leafLevel.deepInputProperty("value", nda)
350                 }, {
351                     key: "td",
352                     text: leafLevel.deepInputProperty("unit", nda)
353                 }, {
354                     key: "td",
355                     text: leafLevel.deepInputProperty("reference_range.range", nda)
356                 }, {
357                     key: "td",
358                     text: leafLevel.deepInputDate("date_time.point", nda),
359                 }, {
360                     key: "td",
361                     text: nda
362                 }],
363                 dataKey: 'results'
364             }],
365             dataKey: 'results'
366         }]
367     }]
370 exports.encountersSectionEntriesOptionalHtmlHeader = {
371     key: "text",
372     existsWhen: condition.keyExists("encounters"),
374     content: [{
375         key: "table",
376         content: [{
377             key: "caption",
378             text: "Encounters"
379         }, {
380             key: "thead",
381             content: [{
382                 key: "tr",
383                 content: [{
384                     key: "th",
385                     text: leafLevel.input,
386                     dataTransform: function () {
387                         return ['Type', 'Facility', 'Date of Service', 'Diagnosis/Complaint'];
388                     }
389                 }]
390             }]
391         }, {
392             key: "tbody",
393             content: [{
394                 key: "tr",
395                 content: [{
396                     key: "td",
397                     attributes: {
398                         ID: leafLevel.nextTableReference("Encounter")
399                     },
400                     text: leafLevel.deepInputProperty("encounter.name", nda)
401                 }, {
402                     key: "td",
403                     text: leafLevel.deepInputProperty("locations.0.name", nda)
404                 }, {
405                     key: "td",
406                     text: function (input) {
407                         var value = bbuo.deepValue(input, "date_time.point");
408                         if (value) {
409                             value = bbud.modelToDate({
410                                 date: value.date,
411                                 precision: value.precision // workaround a bug in bbud.  Changes precision.
412                             });
413                             if (value) {
414                                 var vps = value.split('-');
415                                 if (vps.length === 3) {
416                                     return [vps[1], vps[2], vps[0]].join('/');
417                                 }
418                             }
419                         }
420                         return nda;
421                     }
422                 }, {
423                     key: "td",
424                     text: leafLevel.deepInputProperty("findings.0.value.name", nda)
425                 }],
426             }],
427             dataKey: 'encounters'
428         }]
429     }]
432 exports.immunizationsSectionEntriesOptionalHtmlHeader = {
433     key: "text",
434     existsWhen: condition.keyExists("immunizations"),
436     content: [{
437         key: "table",
438         content: [{
439             key: "thead",
440             content: [{
441                 key: "tr",
442                 content: {
443                     key: "th",
444                     attributes: {
445                         colspan: "3"
446                     },
447                     text: "Immunizations"
448                 }
449             }, {
450                 key: "tr",
451                 content: [{
452                     key: "th",
453                     text: leafLevel.input,
454                     dataTransform: function () {
455                         return ['Vaccine', 'Date', 'Status'];
456                     }
457                 }]
458             }]
459         }, {
460             key: "tbody",
461             content: [{
462                 key: "tr",
463                 content: [{
464                     key: "td",
465                     attributes: {
466                         ID: leafLevel.nextTableReference("immunization")
467                     },
468                     text: leafLevel.deepInputProperty("product.product.name", nda)
469                 }, {
470                     key: "td",
471                     text: leafLevel.deepInputDate("date_time.point", nda),
472                 }, {
473                     key: "td",
474                     text: leafLevel.deepInputProperty("status", nda)
475                 }]
476             }],
477             dataKey: 'immunizations'
478         }]
479     }]
482 exports.payersSectionHtmlHeader = {
483     key: "text",
484     existsWhen: condition.keyExists("payers"),
486     content: [{
487         key: "table",
488         content: [{
489             key: "thead",
490             content: [{
491                 key: "tr",
492                 content: {
493                     key: "th",
494                     attributes: {
495                         colspan: "5"
496                     },
497                     text: "Payers"
498                 }
499             }, {
500                 key: "tr",
501                 content: [{
502                     key: "th",
503                     text: leafLevel.input,
504                     dataTransform: function () {
505                         return ['Payer Name', 'Group ID', 'Member ID', 'Elegibility Start Date', 'Elegibility End Date'];
506                     }
507                 }]
508             }]
509         }, {
510             key: "tbody",
511             content: [{
512                 key: "tr",
513                 content: [{
514                     key: "td",
515                     text: leafLevel.deepInputProperty("policy.insurance.performer.organization.0.name.0", nda)
516                 }, {
517                     key: "td",
518                     text: leafLevel.deepInputProperty("policy.identifiers.0.extension", nda)
519                 }, {
520                     key: "td",
521                     text: leafLevel.deepInputProperty("participant.performer.identifiers.0.extension", nda)
522                 }, {
523                     key: "td",
524                     text: leafLevel.deepInputProperty("participant.date_time.low.date", nda)
525                 }, {
526                     key: "td",
527                     text: leafLevel.deepInputProperty("participant.date_time.high.date", nda)
528                 }]
529             }],
530             dataKey: 'payers'
531         }]
532     }]
535 exports.planOfCareSectionHtmlHeader = {
536     key: "text",
537     existsWhen: condition.keyExists("plan_of_care"),
538     content: [{
539         key: "table",
540         content: [{
541             key: "thead",
542             content: [{
543                 key: "tr",
544                 content: {
545                     key: "th",
546                     attributes: {
547                         colspan: "4"
548                     },
549                     text: "Plan of Care"
550                 }
551             }, {
552                 key: "tr",
553                 content: [{
554                     key: "th",
555                     text: leafLevel.input,
556                     dataTransform: function () {
557                         return ['Program', 'Start Date', 'Status', 'Goals'];
558                     }
559                 }]
560             }]
561         }, {
562             key: "tbody",
563             content: [{
564                 key: "tr",
565                 content: [{
566                     key: "td",
567                     attributes: {
568                         ID: leafLevel.nextTableReference("problem")
569                     },
570                     text: leafLevel.deepInputProperty("plan.name", nda)
571                 }, {
572                     key: "td",
573                     text: leafLevel.deepInputDate("date_time.center", nda)
574                 }, {
575                     key: "td",
576                     text: leafLevel.deepInputProperty("status.code", nda)
577                 },  {
578                     key: "td",
579                     text: leafLevel.deepInputProperty("goal.name", nda)
580                 }]
581             }],
582             dataKey: 'plan_of_care'
583         }]
584     }]
587 exports.goalSectionHtmlHeader = {
588     key: "text",
589     existsWhen: condition.keyExists("goals"),
590     content: [{
591         key: "table",
592         content: [{
593             key: "thead",
594             content: [{
595                 key: "tr",
596                 content: {
597                     key: "th",
598                     attributes: {
599                         colspan: "3"
600                     },
601                     text: "Goals"
602                 }
603             }, {
604                 key: "tr",
605                 content: [{
606                     key: "th",
607                     text: leafLevel.input,
608                     dataTransform: function () {
609                         return ['Start Date','Goal',  'Status'];
610                     }
611                 }]
612             }]
613         }, {
614             key: "tbody",
615             content: [{
616                 key: "tr",
617                 content: [{
618                     key: "td",
619                     text: leafLevel.deepInputDate("date_time.point", nda)
620                 }, {
621                     key: "td",
622                     attributes: {
623                         ID: leafLevel.nextTableReference("goal")
624                     },
625                     text: leafLevel.deepInputProperty("name", nda)
626                 },  {
627                     key: "td",
628                     text: leafLevel.deepInputProperty("status.code", nda)
629                 }]
630             }],
631             dataKey: 'goals'
632         }]
633     }]
636 exports.socialHistorySectionHtmlHeader = {key: "text",
637     existsWhen: condition.keyExists("social_history"),
639     content: [{
640         key: "table",
641         content: [{
642             key: "thead",
643             content: [{
644                 key: "tr",
645                 content: {
646                     key: "th",
647                     attributes: {
648                         colspan: "3"
649                     },
650                     text: "Social History"
651                 }
652             }, {
653                 key: "tr",
654                 content: [{
655                     key: "th",
656                     text: leafLevel.input,
657                     dataTransform: function () {
658                         return ['Social History Element', 'Description', 'Effective Dates'];
659                     }
660                 }]
661             }]
662         }, {
663             key: "tbody",
664             content: [{
665                 key: "tr",
666                 content: [{
667                     key: "td",
668                     attributes: {
669                         ID: leafLevel.nextTableReference("social")
670                     },
671                     text: leafLevel.deepInputProperty("code.name", nda)
672                 }, {
673                     key: "td",
674                     text: leafLevel.deepInputProperty("value", nda)
675                 }, {
676                     key: "td",
677                     text: leafLevel.deepInputDate("date_time.low", nda),
678                 }]
679             }],
680             dataKey: 'social_history'
681         }]
682     }]
685 exports.vitalSignsSectionEntriesOptionalHtmlHeader = {
686     key: "text",
687     existsWhen: condition.keyExists("vitals"),
689     content: [{
690         key: "table",
691         content: [{
692             key: "thead",
693             content: [{
694                 key: "tr",
695                 content: {
696                     key: "th",
697                     attributes: {
698                         colspan: "8"
699                     },
700                     text: "Vital Sign Observations"
701                 }
702             }, {
703                 key: "tr",
704                 content: [{
705                     key: "th",
706                     text: leafLevel.input,
707                     dataTransform: function () {
708                         return ['Date', 'Body Temperature', 'Systolic BP [90-140 mmHg]', 'Diastolic BP [60-90 mmHg]', 'Heart Rate', 'Height', 'Weight Measured', 'BMI (Body Mass Index)'];
709                     }
710                 }]
711             }]
712         }, {
713             key: "tbody",
714             content: [{
715                 key: "tr",
716                 content: [{
717                     key: "td",
718                     text: leafLevel.deepInputDate("date_time.point", nda)
719                 }, {
720                     key: "td",
721                     attributes: {
722                         ID: leafLevel.nextTableReference("vital")
723                     },
724                     text: leafLevel.deepInputProperty("vital_list.7.value", nda, "vital_list.7.unit")
725                 }, {
726                     key: "td",
727                     attributes: {
728                         ID: leafLevel.nextTableReference("vital")
729                     },
730                     text: leafLevel.deepInputProperty("vital_list.0.value", nda, "vital_list.0.unit")
731                 }, {
732                     key: "td",
733                     attributes: {
734                         ID: leafLevel.nextTableReference("vital")
735                     },
736                     text: leafLevel.deepInputProperty("vital_list.1.value", nda, "vital_list.1.unit")
737                 }, {
738                     key: "td",
739                     attributes: {
740                         ID: leafLevel.nextTableReference("vital")
741                     },
742                     text: leafLevel.deepInputProperty("vital_list.5.value", nda, "vital_list.5.unit")
743                 }, {
744                     key: "td",
745                     attributes: {
746                         ID: leafLevel.nextTableReference("vital")
747                     },
748                     text: leafLevel.deepInputProperty("vital_list.2.value", nda, "vital_list.2.unit")
749                 }, {
750                     key: "td",
751                     attributes: {
752                         ID: leafLevel.nextTableReference("vital")
753                     },
754                     text: leafLevel.deepInputProperty("vital_list.3.value", nda, "vital_list.3.unit")
755                 }, {
756                     key: "td",
757                     attributes: {
758                         ID: leafLevel.nextTableReference("vital")
759                     },
760                     text: leafLevel.deepInputProperty("vital_list.4.value", nda, "vital_list.4.unit")
761                 }]
762             }],
763             dataKey: 'vitals'
764         }]
765     }]
768 exports.medicalEquipmentSectionEntriesOptionalHtmlHeader = {
769     key: "text",
770     existsWhen: condition.keyExists("medical_devices"),
772     content: [{
773         key: "table",
774         attributes: {
775             width: "100%",
776             border: "1"
777         },
778         content: [{
779             key: "thead",
780             content: [{
781                 key: "tr",
782                 content: [{
783                     key: "th",
784                     text: leafLevel.input,
785                     dataTransform: function () {
786                         return ["Implant", "UDI"];
787                     }
788                 }]
789             }]
790         }, {
791             key: "tbody",
792             content: [{
793                 key: "tr",
794                 content: [{
795                     key: "td",
796                     attributes: {
797                         ID: leafLevel.nextTableReference("device")
798                     },
799                     text: leafLevel.deepInputProperty("device.name", nda),
800                 }, {
801                     key: "td",
802                     text: leafLevel.deepInputProperty("device.udi", "na"),
803                 }
804                 ]
805             }],
806             dataKey: 'medical_devices'
807         }]
808     }]
811 exports.functionalStatusSectionHtmlHeader = {
812     key: "text",
813     existsWhen: condition.keyExists("functional_status"),
815     content: [{
816         key: "table",
817         attributes: {
818             width: "100%",
819             border: "1"
820         },
821         content: [{
822             key: "thead",
823             content: [{
824                 key: "tr",
825                 content: [{
826                     key: "th",
827                     text: leafLevel.input,
828                     dataTransform: function () {
829                         return ["Functional Category", "Effective Date"];
830                     }
831                 }]
832             }]
833         }, {
834             key: "tbody",
835             content: [{
836                 key: "tr",
837                 content: [{
838                     key: "td",
839                     attributes: {
840                         ID: leafLevel.nextTableReference("functional_status")
841                     },
842                     text: leafLevel.deepInputProperty("observation.value.name", nda),
843                 }, {
844                     key: "td",
845                     text: leafLevel.deepInputDate("observation.date_time.point", nda),
846                 }
847                 ]
848             }],
849             dataKey: 'functional_status'
850         }]
851     }]
854 exports.functionalStatusSectionHtmlHeaderNA = "Not Available";
855 exports.allergiesSectionEntriesRequiredHtmlHeaderNA = "Not Available";
856 exports.medicationsSectionEntriesRequiredHtmlHeaderNA = "Not Available";
857 exports.problemsSectionEntriesRequiredHtmlHeaderNA = "Not Available";
858 exports.proceduresSectionEntriesRequiredHtmlHeaderNA = "Not Available";
859 exports.resultsSectionEntriesRequiredHtmlHeaderNA = "Not Available";
860 exports.encountersSectionEntriesOptionalHtmlHeaderNA = "Not Available";
861 exports.immunizationsSectionEntriesOptionalHtmlHeaderNA = "Not Available";
862 exports.payersSectionHtmlHeaderNA = "Not Available";
863 exports.planOfCareSectionHtmlHeaderNA = "Not Available";
864 exports.goalSectionHtmlHeaderNA = "Not Available";
865 exports.socialHistorySectionHtmlHeaderNA = "Not Available";
866 exports.vitalSignsSectionEntriesOptionalHtmlHeaderNA = "Not Available";
867 exports.medicalEquipmentSectionEntriesOptionalHtmlHeaderNA = "Not Available";