Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
| Entrambe le parti precedenti la revisioneRevisione precedenteProssima revisione | Revisione precedente | ||
| docuneo:programma_npt [2025/07/31 22:11] – neoadmin | docuneo:programma_npt [2025/08/11 15:34] (versione attuale) – neoadmin | ||
|---|---|---|---|
| Linea 3: | Linea 3: | ||
| <meta charset=" | <meta charset=" | ||
| <meta name=" | <meta name=" | ||
| - | < | + | < |
| + | <script src=" | ||
| + | <script src=" | ||
| + | |||
| + | < | ||
| + | // Simple Barcode Generator - CODE128 - Versione Embedded | ||
| + | window.SimpleBarcode = (function() { | ||
| + | |||
| + | // Patterns per CODE128 | ||
| + | const patterns = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | }; | ||
| + | |||
| + | function generateCode128(text) { | ||
| + | // START B (per caratteri ASCII normali) | ||
| + | let result = patterns[' | ||
| + | let checksum = 104; | ||
| + | |||
| + | // Aggiungi ogni carattere | ||
| + | for (let i = 0; i < text.length; | ||
| + | const charCode = text.charCodeAt(i) - 32; // ASCII offset | ||
| + | if (patterns[charCode.toString()]) { | ||
| + | result += patterns[charCode.toString()]; | ||
| + | checksum += charCode * (i + 1); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Calcola e aggiungi checksum | ||
| + | checksum = checksum % 103; | ||
| + | result += patterns[checksum.toString()]; | ||
| + | |||
| + | // Aggiungi STOP | ||
| + | result += patterns[' | ||
| + | |||
| + | return result; | ||
| + | } | ||
| + | |||
| + | function drawBarcode(canvas, | ||
| + | const ctx = canvas.getContext(' | ||
| + | const data = generateCode128(text); | ||
| + | |||
| + | // Opzioni default | ||
| + | const opts = { | ||
| + | width: options.width || 2, | ||
| + | height: options.height || 60, | ||
| + | margin: options.margin || 5, | ||
| + | background: options.background || '# | ||
| + | lineColor: options.lineColor || '# | ||
| + | }; | ||
| + | |||
| + | // Calcola dimensioni | ||
| + | const barWidth = opts.width; | ||
| + | const totalWidth = data.length * barWidth + (opts.margin * 2); | ||
| + | const totalHeight = opts.height + (opts.margin * 2); | ||
| + | |||
| + | // Imposta dimensioni canvas | ||
| + | canvas.width = totalWidth; | ||
| + | canvas.height = totalHeight; | ||
| + | |||
| + | // Pulisci canvas | ||
| + | ctx.clearRect(0, | ||
| + | |||
| + | // Background | ||
| + | ctx.fillStyle = opts.background; | ||
| + | ctx.fillRect(0, | ||
| + | |||
| + | // Disegna le barre | ||
| + | ctx.fillStyle = opts.lineColor; | ||
| + | let x = opts.margin; | ||
| + | |||
| + | for (let i = 0; i < data.length; | ||
| + | if (data[i] === ' | ||
| + | ctx.fillRect(x, | ||
| + | } | ||
| + | x += barWidth; | ||
| + | } | ||
| + | |||
| + | console.log(' | ||
| + | } | ||
| + | |||
| + | return { | ||
| + | generate: drawBarcode | ||
| + | }; | ||
| + | })(); | ||
| + | </ | ||
| + | | ||
| < | < | ||
| + | * { | ||
| + | font-family: | ||
| + | } | ||
| body { | body { | ||
| - | | + | |
| - | margin: 0; | + | margin: 0; |
| - | padding: 20px; | + | padding: 20px; |
| - | background-color: | + | background-color: |
| - | } | + | } |
| .container { | .container { | ||
| Linea 22: | Linea 131: | ||
| h1 { | h1 { | ||
| + | |||
| + | text-align: center; | ||
| + | color: white; | ||
| + | background: linear-gradient(135deg, | ||
| + | border: none; | ||
| + | padding: 20px; | ||
| + | border-radius: | ||
| + | margin-bottom: | ||
| + | text-shadow: | ||
| + | position: relative; | ||
| + | overflow: hidden; | ||
| + | } | ||
| + | |||
| + | h1::before { | ||
| + | content: " | ||
| + | font-size: 30px; | ||
| + | position: absolute; | ||
| + | left: 20px; | ||
| + | top: 50%; | ||
| + | transform: translateY(-50%); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | .version-info { | ||
| text-align: center; | text-align: center; | ||
| - | | + | |
| - | | + | |
| - | | + | |
| } | } | ||
| Linea 210: | Linea 343: | ||
| .hidden { | .hidden { | ||
| - | display: none !important; | + | display: none; |
| } | } | ||
| - | | + | /* CSS TAB ORIZZONTALI |
| - | display: block !important; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| .tabs { | .tabs { | ||
| display: flex; | display: flex; | ||
| Linea 226: | Linea 355: | ||
| .tab { | .tab { | ||
| - | padding: | + | padding: |
| background-color: | background-color: | ||
| border: 1px solid #ddd; | border: 1px solid #ddd; | ||
| Linea 234: | Linea 363: | ||
| transition: all 0.3s ease; | transition: all 0.3s ease; | ||
| text-align: center; | text-align: center; | ||
| - | min-width: | + | min-width: |
| flex: 1; | flex: 1; | ||
| - | max-width: | + | max-width: |
| + | font-size: 14px; | ||
| + | font-weight: | ||
| + | } | ||
| + | .config-tab { | ||
| + | min-width: 50px !important; | ||
| + | max-width: 50px !important; | ||
| + | width: 50px !important; | ||
| + | flex: 0 0 50px !important; | ||
| + | font-size: 24px !important; | ||
| + | padding: 12px 8px !important; | ||
| + | transform: none !important; | ||
| + | } | ||
| + | |||
| + | .config-tab: | ||
| + | background-color: | ||
| + | transform: none !important; | ||
| + | } | ||
| + | |||
| + | .config-tab.active { | ||
| + | background-color: | ||
| + | color: white; | ||
| + | transform: none !important; | ||
| } | } | ||
| Linea 311: | Linea 462: | ||
| } | } | ||
| - | | + | .config-table { |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| font-size: 12px; | font-size: 12px; | ||
| - | line-height: | ||
| - | max-width: 800px; | ||
| - | margin: 0 auto; | ||
| - | border: 1px solid #ddd; | ||
| } | } | ||
| - | .report-header | + | .config-table th, .config-table td { |
| - | display: flex; | + | border: |
| - | justify-content: | + | padding: |
| - | align-items: | + | |
| - | border-bottom: 2px solid #333; | + | |
| - | padding-bottom: 10px; | + | |
| - | | + | |
| } | } | ||
| - | .report-header-left | + | .config-table th { |
| - | | + | |
| + | color: white; | ||
| } | } | ||
| - | .report-header-right | + | .config-table input { |
| - | width: 100px; | + | width: 60px; |
| - | height: 60px; | + | |
| - | | + | border: 1px solid #ddd; |
| - | border: 1px solid #ccc; | + | |
| - | | + | |
| - | align-items: center; | + | |
| - | justify-content: | + | |
| - | font-size: 10px; | + | |
| - | color: #666; | + | |
| } | } | ||
| - | .report-title { | + | .component-name { |
| - | font-size: 14px; | + | |
| font-weight: | font-weight: | ||
| - | | + | |
| + | text-align: left !important; | ||
| } | } | ||
| - | .report-subtitle | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| + | | ||
| + | padding: 20px; | ||
| + | margin: 20px 0; | ||
| } | } | ||
| - | .report-section | + | .config-advanced h3 { |
| - | margin-bottom: | + | color: #0c5460; |
| + | margin-top: 0; | ||
| + | border-bottom: | ||
| + | padding-bottom: | ||
| } | } | ||
| - | .report-section-title { | + | .monitoring-table { |
| - | background-color: | + | |
| - | color: white; | + | |
| - | padding: 5px 10px; | + | |
| - | font-weight: | + | |
| - | font-size: 12px; | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | .report-table { | + | |
| width: 100%; | width: 100%; | ||
| border-collapse: | border-collapse: | ||
| - | font-size: | + | |
| + | | ||
| } | } | ||
| - | .report-table td { | + | .monitoring-table th, .monitoring-table td { |
| - | padding: 3px 8px; | + | border: 1px solid #17a2b8; |
| - | border-bottom: 1px solid #ddd; | + | padding: 8px; |
| - | | + | |
| } | } | ||
| - | .report-table | + | .monitoring-table |
| - | | + | |
| - | | + | |
| } | } | ||
| - | .report-table .value-col | + | .alert-critical |
| - | | + | |
| + | color: white; | ||
| + | padding: 15px; | ||
| + | border-radius: | ||
| + | margin: 15px 0; | ||
| font-weight: | font-weight: | ||
| } | } | ||
| - | .composition-table { | + | |
| - | | + | |
| - | border-collapse: collapse; | + | |
| - | | + | border-radius: 10px; |
| - | margin-top: | + | |
| + | margin-top: | ||
| + | background-color: | ||
| + | font-family: | ||
| + | line-height: | ||
| } | } | ||
| - | .composition-table th { | + | .medical-header |
| - | background-color: | + | |
| - | padding: 5px 8px; | + | |
| text-align: center; | text-align: center; | ||
| - | | + | |
| - | | + | |
| + | margin-bottom: | ||
| } | } | ||
| - | .composition-table td { | + | .medical-header h1 { |
| - | | + | |
| - | | + | |
| - | | + | |
| } | } | ||
| - | .composition-table .component-name-col | + | .medical-header h2 { |
| - | | + | |
| - | | + | color: #34495e; |
| + | | ||
| } | } | ||
| - | .composition-total { | + | .medical-header p { |
| - | | + | |
| - | | + | |
| + | | ||
| } | } | ||
| - | .elements-table { | + | .no-print { |
| - | | + | |
| - | border-collapse: | + | |
| - | font-size: 11px; | + | |
| - | margin-top: 0; | + | |
| } | } | ||
| - | .elements-table td { | + | |
| - | | + | |
| - | | + | display: none !important; |
| + | | ||
| + | body { | ||
| + | background: white; | ||
| + | | ||
| + | .container { | ||
| + | box-shadow: none; | ||
| + | } | ||
| + | |||
| + | | ||
| } | } | ||
| - | | + | /* NUOVA INTESTAZIONE MEDICA ASST LECCO */ |
| - | width: | + | |
| - | } | + | width: |
| + | border-collapse: | ||
| + | border: 2px solid #2c3e50; | ||
| + | margin-bottom: | ||
| + | } | ||
| - | | + | .medical-header-table |
| - | | + | |
| - | | + | |
| - | width: 80px; | + | |
| - | } | + | } |
| - | | + | .medical-header-left { |
| - | | + | width: |
| - | | + | |
| - | font-size: 10px; | + | } |
| - | } | + | |
| - | | + | .medical-header-center |
| - | margin-top: 30px; | + | |
| - | | + | text-align: center; |
| - | border-top: 1px solid #ddd; | + | background-color: |
| - | font-size: 10px; | + | } |
| - | color: #666; | + | |
| - | text-align: center; | + | .medical-header-right { |
| - | } | + | width: 25%; |
| + | text-align: center; | ||
| + | background-color: | ||
| + | } | ||
| + | |||
| + | .medical-header-left h2 { | ||
| + | font-size: 14px; | ||
| + | font-weight: | ||
| + | color: #2c3e50; | ||
| + | | ||
| + | } | ||
| + | |||
| + | .medical-header-left h3 { | ||
| + | font-size: 12px; | ||
| + | | ||
| + | margin: 0 0 5px 0; | ||
| + | } | ||
| + | |||
| + | .medical-header-left p { | ||
| + | font-size: 11px; | ||
| + | color: #7f8c8d; | ||
| + | margin: 0; | ||
| + | } | ||
| + | |||
| + | /* NUOVA INTESTAZIONE MEDICA ASST LECCO */ | ||
| + | .medical-header-table { | ||
| + | width: 100%; | ||
| + | border-collapse: collapse; | ||
| + | border: 2px solid #2c3e50; | ||
| + | margin-bottom: | ||
| + | } | ||
| + | |||
| + | .medical-header-table td { | ||
| + | border: 1px solid #2c3e50; | ||
| + | | ||
| + | vertical-align: | ||
| + | } | ||
| + | |||
| + | .medical-header-left { | ||
| + | width: 45%; | ||
| + | background-color: | ||
| + | } | ||
| + | |||
| + | .medical-header-center { | ||
| + | width: 30%; | ||
| + | text-align: center; | ||
| + | background-color: | ||
| + | } | ||
| + | |||
| + | .medical-header-right { | ||
| + | width: 25%; | ||
| + | text-align: center; | ||
| + | background-color: | ||
| + | } | ||
| + | |||
| + | .medical-header-left h2 { | ||
| + | | ||
| + | font-weight: | ||
| + | color: #2c3e50; | ||
| + | margin: 0 0 5px 0; | ||
| + | } | ||
| + | |||
| + | .medical-header-left h3 { | ||
| + | font-size: 12px; | ||
| + | color: #34495e; | ||
| + | margin: 0 0 5px 0; | ||
| + | } | ||
| + | |||
| + | .medical-header-left p { | ||
| + | font-size: 11px; | ||
| + | color: #7f8c8d; | ||
| + | margin: 0; | ||
| + | } | ||
| + | |||
| + | /* STILI KNOWLEDGE BASE */ | ||
| + | .knowledge-section { | ||
| + | display: none; | ||
| + | } | ||
| + | |||
| + | .knowledge-section.active { | ||
| + | display: block; | ||
| + | } | ||
| + | |||
| + | .knowledge-tooltip { | ||
| + | position: absolute; | ||
| + | background-color: | ||
| + | color: white; | ||
| + | padding: 10px; | ||
| + | | ||
| + | font-size: 12px; | ||
| + | max-width: 300px; | ||
| + | z-index: 1000; | ||
| + | box-shadow: 0 2px 10px rgba(0, | ||
| + | animation: fadeIn 0.3s ease-in-out; | ||
| + | } | ||
| + | |||
| + | @keyframes fadeIn { | ||
| + | from { opacity: 0; transform: translateY(-10px); | ||
| + | to { opacity: 1; transform: translateY(0); | ||
| + | } | ||
| + | |||
| + | .knowledge-section h3 { | ||
| + | | ||
| + | | ||
| + | padding-bottom: | ||
| + | margin-bottom: | ||
| + | } | ||
| + | |||
| + | .knowledge-section h4 { | ||
| + | color: #34495e; | ||
| + | margin-top: 20px; | ||
| + | margin-bottom: | ||
| + | } | ||
| + | |||
| + | /* STILI SPECIFICI PER ETICHETTA SACCA */ | ||
| + | .label-section { | ||
| + | border: 3px solid #2c3e50; | ||
| + | background-color: | ||
| + | padding: 15px; | ||
| + | margin: 15px 0; | ||
| + | border-radius: | ||
| + | } | ||
| + | |||
| + | .label-patient-id { | ||
| + | border: 4px solid #d32f2f; | ||
| + | background-color: | ||
| + | padding: 15px; | ||
| + | margin: 15px 0; | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | .label-content { | ||
| + | border: 3px solid #388e3c; | ||
| + | background-color: | ||
| + | padding: 15px; | ||
| + | margin: 15px 0; | ||
| + | border-radius: | ||
| + | } | ||
| + | |||
| + | .label-header { | ||
| + | text-align: center; | ||
| + | border-bottom: | ||
| + | padding-bottom: | ||
| + | margin-bottom: | ||
| + | } | ||
| + | |||
| + | .label-volume-total { | ||
| + | background-color: | ||
| + | color: white; | ||
| + | font-weight: | ||
| + | font-size: 16px; | ||
| + | } | ||
| - | @media print { | ||
| - | .npt-report { | ||
| - | box-shadow: none; | ||
| - | border: none; | ||
| - | margin: 0; | ||
| - | padding: 15px; | ||
| - | } | ||
| - | | ||
| - | .button { | ||
| - | display: none; | ||
| - | } | ||
| - | | ||
| - | .tabs, .tab-content: | ||
| - | display: none !important; | ||
| - | } | ||
| - | } | ||
| </ | </ | ||
| - | <script src=" | ||
| - | <script src=" | ||
| </ | </ | ||
| < | < | ||
| <div class=" | <div class=" | ||
| - | <h1>Programma NPT Neonatale v2.0</ | + | <h1>Gestione della Nutrizione del Neonato (GNN v3.0)</h1> |
| + | < | ||
| + | < | ||
| + | </div> | ||
| | | ||
| - | <!-- TAB ORIZZONTALI --> | + | <!-- TAB ORIZZONTALI |
| <div class=" | <div class=" | ||
| - | | + | |
| - | <span style=" | + | <span style=" |
| - | </ | + | </ |
| - | <div class=" | + | |
| - | <span style=" | + | <!-- SEZIONE CONFIGURAZIONE COMPONENTI (DA VERSIONE 17) --> |
| - | </ | + | |
| - | <div class=" | + | <span style=" |
| - | <span style=" | + | </ |
| - | </ | + | <div class=" |
| - | <div class=" | + | <span style=" |
| - | <span style=" | + | </ |
| - | </ | + | <div class=" |
| - | <div class=" | + | <span style=" |
| - | <span style=" | + | </ |
| - | </ | + | <div class=" |
| + | <span style=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | | ||
| + | </ | ||
| + | <div class=" | ||
| + | <span style=" | ||
| + | | ||
| </ | </ | ||
| - | <!-- TAB 1: DATI PAZIENTE --> | + | <!-- TAB 1: DATI PAZIENTE |
| <div id=" | <div id=" | ||
| - | | + | <div class=" |
| - | < | + | < |
| - | < | + | < |
| - | </ | + | |
| + | </ | ||
| <div class=" | <div class=" | ||
| < | < | ||
| Linea 524: | Linea 825: | ||
| <label for=" | <label for=" | ||
| <select id=" | <select id=" | ||
| - | <option value=""> | + | <!-- Popolato dinamicamente --> |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| </ | </ | ||
| </ | </ | ||
| Linea 559: | Linea 854: | ||
| <div class=" | <div class=" | ||
| <label for=" | <label for=" | ||
| - | <input type=" | + | <input type=" |
| </ | </ | ||
| <div class=" | <div class=" | ||
| Linea 565: | Linea 860: | ||
| <input type=" | <input type=" | ||
| </ | </ | ||
| + | |||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <div style=" | ||
| + | <input type=" | ||
| + | < | ||
| + | <input type=" | ||
| + | < | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <div style=" | ||
| + | <input type=" | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| </ | </ | ||
| <div class=" | <div class=" | ||
| Linea 612: | Linea 931: | ||
| </ | </ | ||
| - | <!-- TAB 2: NUTRIZIONE ENTERALE --> | + | <!-- TAB 2: NUTRIZIONE ENTERALE |
| <div id=" | <div id=" | ||
| <div class=" | <div class=" | ||
| Linea 711: | Linea 1030: | ||
| </ | </ | ||
| - | <!-- TAB 3: CALCOLO FABBISOGNI --> | + | <!-- TAB 3: CALCOLO FABBISOGNI |
| <div id=" | <div id=" | ||
| <div class=" | <div class=" | ||
| Linea 841: | Linea 1160: | ||
| </ | </ | ||
| - | <!-- TAB 4: NUTRIZIONE PARENTERALE --> | + | <!-- TAB 4: NUTRIZIONE PARENTERALE |
| <div id=" | <div id=" | ||
| <div class=" | <div class=" | ||
| Linea 883: | Linea 1202: | ||
| <div id=" | <div id=" | ||
| | | ||
| - | | + | |
| - | <h3 style=" | + | |
| - | <p style=" | + | <button class=" |
| - | <div style=" | + | <button class=" |
| - | <button id="generateWorkReportBtn" class=" | + | <button class=" |
| - | < | + | </ |
| - | <button id="printReportBtn" class=" | + | </ |
| - | <button id="savePdfBtn" class=" | + | </ |
| - | </ | + | |
| + | |||
| + | <!-- TAB 5: REPORT FINALE (SPOSTATO DA TAB 6) --> | ||
| + | <div id="report" class=" | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | | ||
| + | |||
| + | <!-- Banner stato prescrizione --> | ||
| + | | ||
| + | <!-- Popolato dinamicamente --> | ||
| + | </ | ||
| + | <div class="section no-print"> | ||
| + | < | ||
| + | < | ||
| + | <button class="button" | ||
| + | < | ||
| + | < | ||
| + | <!-- Report appare subito qui sotto i pulsanti --> | ||
| + | <div id=" | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 2A: VALIDAZIONE FARMACISTA --> | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Il farmacista deve validare la prescrizione medica prima dell' | ||
| + | | ||
| + | |||
| + | <div class="form-row"> | ||
| + | < | ||
| + | <div class="input-group"> | ||
| + | <label for=" | ||
| + | <select id=" | ||
| + | <option value=""> | ||
| + | <!-- Popolato dinamicamente da pharmacistsData --> | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | < | ||
| + | </div> | ||
| + | </ | ||
| + | |||
| + | <div class="form-col"> | ||
| + | < | ||
| + | 📝 VALIDA PRESCRIZIONE | ||
| + | </ | ||
| + | <div id=" | ||
| + | <!-- Status validazione --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 2B: ALLESTIMENTO TECNICI --> | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Due tecnici qualificati preparano la sacca NPT secondo protocolli GMP con controllo incrociato. | ||
| + | | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <select id=" | ||
| + | <option value=""> | ||
| + | <!-- Popolato dinamicamente da technicianData --> | ||
| + | </select> | ||
| </ | </ | ||
| | | ||
| - | <div id="nptWorkReport" class=" | + | < |
| - | <div id="nptFinalReport" class=" | + | <label for=" |
| + | < | ||
| + | <option value=""> | ||
| + | <!-- Popolato dinamicamente da technicianData --> | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | < | ||
| + | </div> | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <button class=" | ||
| + | 🧪 CONFERMA ALLESTIMENTO | ||
| + | </ | ||
| + | < | ||
| + | 💾 ARCHIVIA PREPARAZIONE (JSON) | ||
| + | </ | ||
| + | <button class=" | ||
| + | 🔒 BLOCCA PRESCRIZIONE | ||
| + | </ | ||
| + | <div id=" | ||
| + | <!-- Status preparazione --> | ||
| + | | ||
| </ | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE ARCHIVIAZIONE MENSILE --> | ||
| + | |||
| + | < | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Genera report Excel mensile con tutte le preparazioni NPT archiviate come JSON. | ||
| + | </ | ||
| + | | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | 📊 GENERA EXCEL MENSILE | ||
| + | </ | ||
| + | <button class=" | ||
| + | 👁️ ANTEPRIMA DATI | ||
| + | </ | ||
| + | | ||
| + | <div id=" | ||
| + | <!-- Statistiche mensili popolate dinamicamente --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | | ||
| + | </ | ||
| + | |||
| + | |||
| + | <!-- TAB 6: KNOWLEDGE BASE --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | <!-- NAVIGAZIONE INTERNA KNOWLEDGE BASE --> | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | 🧮 Regole Calcolo | ||
| + | </ | ||
| + | <div class=" | ||
| + | 👩⚕️ Linee Guida | ||
| + | </ | ||
| + | <div class=" | ||
| + | 🚨 Sistema Alert | ||
| + | </ | ||
| + | <div class=" | ||
| + | 📖 Evidenze | ||
| + | </ | ||
| + | <div class=" | ||
| + | 🎯 Decision Support | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 1: REGOLE DI CALCOLO --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | | ||
| + | <div class=" | ||
| + | < | ||
| + | | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | • < 600 mOsm/L: Accesso periferico possibile< | ||
| + | • 600-900 mOsm/L: CVC raccomandato< | ||
| + | • > 900 mOsm/L: Solo CVC (soluzione ipertonica) | ||
| + | </ | ||
| + | </ | ||
| + | | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | | ||
| + | <div class=" | ||
| + | < | ||
| + | <div style=" | ||
| + | <table class=" | ||
| + | < | ||
| + | <tr> | ||
| + | <th style=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | </ | ||
| + | < | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 2: LINEE GUIDA CLINICHE (placeholder per ora) --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Questa sezione conterrà protocolli per età, patologie e tempistiche. | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 3: SISTEMA ALERT (placeholder per ora) --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Questa sezione spiegherà soglie di allarme e azioni consigliate. | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 4: EVIDENZE (placeholder per ora) --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Questa sezione conterrà bibliografia e riferimenti scientifici. | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <!-- SEZIONE 5: DECISION SUPPORT (placeholder per ora) --> | ||
| + | <div id=" | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Questa sezione conterrà configurazione regole e simulatore. | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| </ | </ | ||
| - | <!-- TAB 5: CONFIGURAZIONE --> | + | <!-- TAB 6: CONFIGURAZIONE |
| <div id=" | <div id=" | ||
| <div class=" | <div class=" | ||
| - | < | + | < |
| - | < | + | < |
| </ | </ | ||
| - | | ||
| <div class=" | <div class=" | ||
| < | < | ||
| Linea 912: | Linea 1545: | ||
| <div class=" | <div class=" | ||
| <label for=" | <label for=" | ||
| - | <input type=" | + | <input type=" |
| </ | </ | ||
| <div class=" | <div class=" | ||
| Linea 926: | Linea 1559: | ||
| </ | </ | ||
| </ | </ | ||
| + | | ||
| <div class=" | <div class=" | ||
| < | < | ||
| <div style=" | <div style=" | ||
| - | <table class=" | + | <table class=" |
| < | < | ||
| <tr> | <tr> | ||
| Linea 943: | Linea 1576: | ||
| < | < | ||
| < | < | ||
| + | < | ||
| </tr> | </tr> | ||
| </ | </ | ||
| - | < | + | < |
| - | <tr> | + | <!-- Popolato dinamicamente --> |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </tr> | + | |
| </ | </ | ||
| </ | </ | ||
| </ | </ | ||
| - | <div class=" | + | <div class=" |
| - | <strong>ℹ️ Informazioni: | + | <div class="form-col"> |
| + | <button id=" | ||
| + | </div> | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | | ||
| </ | </ | ||
| </ | </ | ||
| <div class=" | <div class=" | ||
| - | <h2>Componenti Parenterali | + | <h2>Fortificanti in Polvere |
| <div style=" | <div style=" | ||
| - | <table class=" | + | <table class=" |
| < | < | ||
| <tr> | <tr> | ||
| - | <th style=" | + | <th style=" |
| - | <th>Calcio<br>(mg)</ | + | <th>Proteine<br>(g)</ |
| - | <th>Fosforo<br>(mg)</ | + | <th>Carboidrati<br>(g)</ |
| - | <th>Magnesio<br>(mEq)</ | + | <th>Lipidi<br>(g)</ |
| < | < | ||
| < | < | ||
| - | <th style=" | + | |
| + | < | ||
| + | < | ||
| + | < | ||
| + | | ||
| + | < | ||
| </tr> | </tr> | ||
| </ | </ | ||
| - | < | + | < |
| <tr> | <tr> | ||
| - | < | + | < |
| - | <td>840</ | + | |
| - | < | + | <td><input type=" |
| - | < | + | <td><input type=" |
| - | < | + | <td><input type=" |
| - | <td>0</ | + | <td><input type=" |
| - | <td>1g/10mL, 0.44 mEq/mL - Sale di calcio organico</td> | + | <td><input type=" |
| + | <td><input type=" | ||
| + | < | ||
| + | < | ||
| + | <td style=" | ||
| + | < | ||
| </tr> | </tr> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <button id=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div style=" | ||
| + | <table class=" | ||
| + | < | ||
| + | <tr> | ||
| + | <th style=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | <th style=" | ||
| + | < | ||
| + | </tr> | ||
| + | </ | ||
| + | <tbody id=" | ||
| + | <!-- Popolato dinamicamente --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <button id=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Gestisci la lista dei medici prescrittori. Le modifiche si applicano automaticamente alla dropdown del TAB 1. | ||
| + | </ | ||
| + | <div style=" | ||
| + | <table class=" | ||
| + | < | ||
| <tr> | <tr> | ||
| - | <td>< | + | <th style=" |
| - | <td>0</td> | + | <th style=" |
| - | <td>1600</td> | + | <th style=" |
| - | <td>0</td> | + | <th style=" |
| - | <td>130</ | + | <th>Azioni</th> |
| - | < | + | |
| - | < | + | |
| </tr> | </tr> | ||
| + | </ | ||
| + | <tbody id=" | ||
| + | <!-- Popolato dinamicamente --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <button id=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Gestisci la lista delle infermiere del reparto. Le modifiche si applicano automaticamente. | ||
| + | </ | ||
| + | <div style=" | ||
| + | <table class=" | ||
| + | < | ||
| <tr> | <tr> | ||
| - | <td>< | + | <th style=" |
| - | <td>0</td> | + | <th style=" |
| - | <td>0</td> | + | <th style=" |
| - | <td>800</td> | + | <th style=" |
| - | <td>0</ | + | <th>Azioni</th> |
| - | < | + | |
| - | < | + | |
| </tr> | </tr> | ||
| + | </ | ||
| + | <tbody id=" | ||
| + | <!-- Popolato dinamicamente --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <button id=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Gestisci la lista dei farmacisti ospedalieri. Le modifiche si applicano automaticamente. | ||
| + | </ | ||
| + | <div style=" | ||
| + | <table class=" | ||
| + | < | ||
| <tr> | <tr> | ||
| - | <td>< | + | <th style=" |
| - | < | + | <th style=" |
| - | < | + | <th style=" |
| - | < | + | <th style=" |
| - | < | + | <th>Azioni</th> |
| - | < | + | |
| - | < | + | |
| - | | + | |
| - | <tr> | + | |
| - | <td>< | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <td>2 mEq/ | + | |
| - | | + | |
| - | <tr> | + | |
| - | <td>< | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <td>2 mEq/ | + | |
| - | | + | |
| - | <tr> | + | |
| - | <td>< | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | | + | |
| - | <tr> | + | |
| - | <td>< | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| </tr> | </tr> | ||
| + | </ | ||
| + | <tbody id=" | ||
| + | <!-- Popolato dinamicamente --> | ||
| </ | </ | ||
| </ | </ | ||
| </ | </ | ||
| - | <div class=" | + | <div class=" |
| - | <strong>ℹ️ Informazioni: | + | <div class="form-col"> |
| + | <button id=" | ||
| + | </div> | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | | ||
| </ | </ | ||
| </ | </ | ||
| <div class=" | <div class=" | ||
| - | < | + | < |
| <div class=" | <div class=" | ||
| - | < | + | < |
| + | Gestisci la lista dei tecnici di farmacia. Le modifiche si applicano automaticamente. | ||
| </ | </ | ||
| <div style=" | <div style=" | ||
| - | <table class=" | + | <table class=" |
| < | < | ||
| <tr> | <tr> | ||
| - | < | + | < |
| - | < | + | < |
| - | < | + | < |
| - | < | + | < |
| + | < | ||
| </tr> | </tr> | ||
| </ | </ | ||
| - | < | + | < |
| - | <tr>< | + | <!-- Popolato dinamicamente --> |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| </ | </ | ||
| </ | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <button id=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <button class=" | ||
| + | </ | ||
| </ | </ | ||
| + | </ | ||
| </ | </ | ||
| - | <div class=" | + | |
| - | <h2>Informazioni Sistema</h2> | + | |
| - | <div class=" | + | <h3>🔬 CONFIGURAZIONE CLINICA AVANZATA</h3> |
| - | <strong>📊 NPT Calculator v2.0 - Stato Sistema</strong><br> | + | |
| - | <strong>• Database Formule:</strong> 9 formule enterali configurate<br> | + | <div class=" |
| - | <strong>• Database Componenti:</strong> 8 componenti parenterali configurati<br> | + | <h2>Parametri Elettroliti e Controlli</ |
| - | <strong>• Medici Prescrittori:</strong> 6 medici autorizzati<br> | + | <div class=" |
| - | <strong>• Algoritmi:</strong> Calcoli BUN, fasi nutrizionali, | + | <div class=" |
| - | <strong>• Report:</strong> Foglio di lavoro + Report parenterale completo<br> | + | <div class=" |
| - | <strong>• Ultimo Aggiornamento:</strong> Luglio 2025 | + | <label for=" |
| + | <input type=" | ||
| + | <span style=" | ||
| + | | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | | ||
| + | <span style=" | ||
| + | | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | | ||
| + | </div> | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | | ||
| + | <span style=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | | ||
| + | <span style=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | <span style=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <button class=" | ||
| </ | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <table class=" | ||
| + | < | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | </ | ||
| + | < | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | <td>2 volte/ | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | <tr> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </tr> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | • Glicemia > 250 mg/dL o < 40 mg/ | ||
| + | • Trigliceridi > 400 mg/ | ||
| + | • AST/ALT > 3x valore normale< | ||
| + | • Segni di sepsi cateter-correlata< | ||
| + | • Edema importante con bilancio positivo > 20 ml/kg/die | ||
| + | </ | ||
| + | | ||
| + | <div class=" | ||
| + | < | ||
| + | • GIR > 12 mg/kg/min → Ridurre glucosio< | ||
| + | • BUN > 20 mg/dL → Ridurre proteine< | ||
| + | • BUN < 5 mg/dL → Aumentare proteine< | ||
| + | • Trigliceridi 200-400 mg/dL → Ridurre/ | ||
| + | • Ipernatremia → Ridurre sodio, aumentare liquidi liberi | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <select id=" | ||
| + | <option value=" | ||
| + | <option value=" | ||
| + | </ | ||
| + | </ | ||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <select id=" | ||
| + | <option value=" | ||
| + | <option value=" | ||
| + | <option value=" | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | <button class=" | ||
| + | <button class=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div id=" | ||
| + | < | ||
| + | <div id=" | ||
| </ | </ | ||
| </ | </ | ||
| Linea 1201: | Linea 1966: | ||
| < | < | ||
| - | // DATI NUTRIZIONALI COMPLETI | + | // DATI NUTRIZIONALI COMPLETI |
| const formulaData = { | const formulaData = { | ||
| maternal: { name: "Latte Materno", | maternal: { name: "Latte Materno", | ||
| Linea 1214: | Linea 1979: | ||
| }; | }; | ||
| - | // CONFIGURAZIONI PARENTERALI COMPLETE | + | // CONFIGURAZIONI PARENTERALI COMPLETE |
| const parenteralConfig = { | const parenteralConfig = { | ||
| + | trophamine: { | ||
| + | name: " | ||
| + | protein: 6.0, carbs: 0, lipids: 0, sodium: 0, potassium: 0, | ||
| + | calcium: 0, phosphorus: 0, magnesium: 0, energy: 24, water: 94, | ||
| + | osmolarity: 360, // mOsm/L | ||
| + | description: | ||
| + | notes: " | ||
| + | }, | ||
| + | intralipid: { | ||
| + | name: " | ||
| + | protein: 0, carbs: 0, lipids: 20.0, sodium: 0, potassium: 0, | ||
| + | calcium: 0, phosphorus: 0, magnesium: 0, energy: 200, water: 80, | ||
| + | osmolarity: 280, // mOsm/L | ||
| + | description: | ||
| + | notes: " | ||
| + | }, | ||
| + | glucose50: { | ||
| + | name: " | ||
| + | protein: 0, carbs: 50.0, lipids: 0, sodium: 0, potassium: 0, | ||
| + | calcium: 0, phosphorus: 0, magnesium: 0, energy: 200, water: 50, | ||
| + | osmolarity: 2780, // mOsm/L | ||
| + | description: | ||
| + | notes: " | ||
| + | }, | ||
| ca_gluconato: | ca_gluconato: | ||
| - | name: " | + | name: " |
| - | | + | |
| - | | + | |
| + | osmolarity: 320, // mOsm/L | ||
| + | description: | ||
| + | notes: "8.4 mg Ca/ml. Non precipita con fosfati. Osmolarità: | ||
| }, | }, | ||
| esafosfina: { | esafosfina: { | ||
| - | name: " | + | name: " |
| - | | + | |
| - | | + | |
| + | osmolarity: 450, // mOsm/L | ||
| + | description: | ||
| + | notes: "16 mg P/ml + 1.3 mEq Na/ml. Fosforo organico. Osmolarità: | ||
| }, | }, | ||
| mg_sulfate: { | mg_sulfate: { | ||
| - | name: " | + | name: " |
| - | | + | |
| - | | + | |
| + | osmolarity: 1620, // mOsm/L | ||
| + | description: | ||
| + | notes: "8 mEq Mg/ml. Cofattore enzimatico. Osmolarità: | ||
| }, | }, | ||
| nacl: { | nacl: { | ||
| - | name: "Sodio Cloruro", | + | name: "Sodio Cloruro |
| - | | + | |
| - | | + | |
| + | osmolarity: 2050, // mOsm/L | ||
| + | description: | ||
| + | notes: "10 mEq Na/ml. Prima scelta per supplementazione sodio. Osmolarità: | ||
| }, | }, | ||
| sodium_acetate: | sodium_acetate: | ||
| - | name: "Sodio Acetato", | + | name: "Sodio Acetato |
| - | | + | |
| - | | + | |
| + | osmolarity: 1340, // mOsm/L | ||
| + | description: | ||
| + | notes: "6.67 mEq Na/ml. Per acidosi: pH < 7.25 o BE < -4. Osmolarità: | ||
| }, | }, | ||
| kcl: { | kcl: { | ||
| - | name: " | + | name: " |
| - | | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 99 | + | calcium: 0, phosphorus: 0, magnesium: 0, energy: 0, water: 99, |
| + | osmolarity: 2050, // mOsm/L | ||
| + | description: | ||
| + | notes: "10 mEq K/ml. Max velocità infusione: 0.5 mEq/kg/h. Osmolarità: | ||
| + | }, | ||
| + | carnitene: { | ||
| + | name: " | ||
| + | protein: 0, carbs: 0, lipids: 0, sodium: 0, potassium: 0, | ||
| + | calcium: 0, phosphorus: 0, magnesium: 0, energy: 0, water: 99, | ||
| + | osmolarity: 280, // mOsm/L | ||
| + | carnitine: 10000, // 100 mg/ml = 10000 mg/100ml | ||
| + | description: | ||
| + | notes: "100 mg/ml. Indicata per NPT > 1 mese. Dose: 5 mg/kg/die. Osmolarità: | ||
| } | } | ||
| }; | }; | ||
| - | // Database medici | + | // Database fortificanti dinamico |
| - | const doctorsData = { | + | let fortifierData = { |
| + | prenidina_fm85: | ||
| + | name: " | ||
| + | protein: 14, carbs: 4, lipids: 2.5, sodium: 2, potassium: 15, | ||
| + | calcium: 3500, phosphorus: 2000, magnesium: 150, energy: 400, | ||
| + | dose: " | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | // Database medici | ||
| + | let doctorsData = { | ||
| dr_bellu: { name: " | dr_bellu: { name: " | ||
| dr_condo: { name: " | dr_condo: { name: " | ||
| Linea 1255: | Linea 2081: | ||
| dr_meroni: { name: " | dr_meroni: { name: " | ||
| dr_calzatini: | dr_calzatini: | ||
| - | dr_ferrari: { name: " | + | dr_ferrari: { name: " |
| + | dr_ferendeles: | ||
| + | dr_fumagalli_l: | ||
| + | dr_fumagalli_m: | ||
| + | dr_corno: { name: " | ||
| + | dr_evasi: { name: " | ||
| + | dr_cereda: { name: " | ||
| + | dr_ceccon: { name: " | ||
| + | dr_nava: { name: " | ||
| + | dr_terenzi: { name: " | ||
| + | dr_raffa: { name: " | ||
| + | dr_aquisti: { name: " | ||
| }; | }; | ||
| + | |||
| + | // Database infermiere dinamico | ||
| + | let nursesData = { | ||
| + | inf_rossi: { name: " | ||
| + | inf_bianchi: | ||
| + | inf_verdi: { name: " | ||
| + | inf_ferrari: | ||
| + | inf_moretti: | ||
| + | inf_conti: { name: " | ||
| + | }; | ||
| + | |||
| + | // Database farmacisti dinamico | ||
| + | let pharmacistsData = { | ||
| + | farm_lombardi: | ||
| + | farm_ricci: { name: " | ||
| + | farm_marino: | ||
| + | farm_greco: { name: " | ||
| + | farm_bruno: { name: " | ||
| + | }; | ||
| + | |||
| + | // Database tecnici di farmacia dinamico | ||
| + | let technicianData = { | ||
| + | tec_russo: { name: " | ||
| + | tec_gallo: { name: " | ||
| + | tec_costa: { name: " | ||
| + | tec_rizzo: { name: " | ||
| + | tec_longo: { name: " | ||
| + | tec_giordano: | ||
| + | }; | ||
| + | |||
| + | |||
| // VARIABILI GLOBALI | // VARIABILI GLOBALI | ||
| let patientData = {}; | let patientData = {}; | ||
| let enteralData = null; | let enteralData = null; | ||
| - | window.currentActiveReport | + | let currentRequirements = null; |
| + | |||
| + | // CONFIGURAZIONE CLINICA AVANZATA (NUOVO) | ||
| + | let clinicalConfig = { | ||
| + | calciumReq: 160, | ||
| + | phosphorusReq: | ||
| + | magnesiumReq: | ||
| + | maxGIR: 12.0, | ||
| + | maxLipids: 3.0, | ||
| + | maxProtein: 4.5, | ||
| + | hospitalName: | ||
| + | departmentName: | ||
| + | directorName: | ||
| + | }; | ||
| + | |||
| + | // FUNZIONE RESET PULSANTE FABBISOGNI | ||
| + | function resetNutritionButton() { | ||
| + | const nutritionBtn = document.getElementById(' | ||
| + | if (nutritionBtn) { | ||
| + | nutritionBtn.className = ' | ||
| + | nutritionBtn.innerHTML = ' | ||
| + | |||
| + | // Nascondi i risultati precedenti | ||
| + | const nutritionResults = document.getElementById(' | ||
| + | if (nutritionResults) { | ||
| + | nutritionResults.classList.add(' | ||
| + | } | ||
| + | |||
| + | // Reset anche il pulsante NPT perché i fabbisogni sono cambiati | ||
| + | resetParenteralButton(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // FUNZIONE RESET PULSANTE PARENTERALE | ||
| + | function resetParenteralButton() { | ||
| + | const parenteralBtn = document.getElementById(' | ||
| + | if (parenteralBtn) { | ||
| + | parenteralBtn.className = ' | ||
| + | parenteralBtn.innerHTML = ' | ||
| + | |||
| + | // Reset anche i campi visualizzati | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Nascondi i risultati precedenti | ||
| + | const parenteralResults = document.getElementById(' | ||
| + | if (parenteralResults) { | ||
| + | parenteralResults.classList.add(' | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // SISTEMA PROTEZIONE CONFIGURAZIONE | ||
| + | function checkConfigAccess() { | ||
| + | // Password predefinita (modificabile) | ||
| + | const ADMIN_PASSWORD = " | ||
| + | |||
| + | // Controlla se l' | ||
| + | if (window.configAccessGranted === true) { | ||
| + | return true; | ||
| + | } | ||
| + | |||
| + | // Richiedi password | ||
| + | const userPassword = prompt( | ||
| + | "🔐 ACCESSO CONFIGURAZIONE RISERVATO\n\n" | ||
| + | " | ||
| + | ); | ||
| + | |||
| + | // Se utente cancella | ||
| + | if (userPassword === null) { | ||
| + | return false; | ||
| + | } | ||
| + | |||
| + | // Verifica password | ||
| + | if (userPassword === ADMIN_PASSWORD) { | ||
| + | window.configAccessGranted = true; | ||
| + | alert(" | ||
| + | return true; | ||
| + | } else { | ||
| + | alert(" | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Funzione per logout configurazione | ||
| + | function logoutConfig() { | ||
| + | window.configAccessGranted = false; | ||
| + | alert(" | ||
| + | // Torna al TAB 1 | ||
| + | showTab(' | ||
| + | } | ||
| - | // INIZIALIZZAZIONE | ||
| - | document.addEventListener(' | ||
| - | // Imposta data odierna | ||
| - | const today = new Date().toISOString().split(' | ||
| - | document.getElementById(' | ||
| - | }); | ||
| - | // FUNZIONE TAB | + | // FUNZIONE |
| function showTab(tabId) { | function showTab(tabId) { | ||
| - | // Rimuovi classe active da tutti i contenuti | + | // Nascondi |
| document.querySelectorAll(' | document.querySelectorAll(' | ||
| content.classList.remove(' | content.classList.remove(' | ||
| }); | }); | ||
| | | ||
| - | // Rimuovi classe active da tutte le tab | + | // Rimuovi classe active da tutti i tab |
| document.querySelectorAll(' | document.querySelectorAll(' | ||
| tab.classList.remove(' | tab.classList.remove(' | ||
| }); | }); | ||
| | | ||
| - | // Mostra il contenuto selezionato | + | // Mostra il contenuto |
| const targetContent = document.getElementById(tabId); | const targetContent = document.getElementById(tabId); | ||
| if (targetContent) { | if (targetContent) { | ||
| Linea 1288: | Linea 2243: | ||
| } | } | ||
| | | ||
| - | // Attiva la tab cliccata | + | // Trova e attiva il tab cliccato |
| - | event.target.closest(' | + | |
| + | if (clickedTab) { | ||
| + | clickedTab.classList.add(' | ||
| + | } | ||
| + | |||
| + | // Sistema di protezione per TAB configurazione | ||
| + | if (tabId === ' | ||
| + | if (!checkConfigAccess()) { | ||
| + | return; // Blocca l' | ||
| + | } | ||
| + | setTimeout(() => { | ||
| + | populateEnteralConfigTable(); | ||
| + | populateParenteralConfigTable(); | ||
| + | populateDoctorsConfigTable(); | ||
| + | populateNursesConfigTable(); | ||
| + | populatePharmacistsConfigTable(); | ||
| + | populateTechniciansConfigTable(); | ||
| + | }, 100); | ||
| + | } | ||
| + | |||
| + | // Popola le dropdown del personale quando si apre il TAB 5 (report) | ||
| + | if (tabId === ' | ||
| + | setTimeout(() => { | ||
| + | updatePreparationStaffDropdowns(); | ||
| + | }, 100); | ||
| } | } | ||
| - | // FUNZIONE CALCOLO FASE | + | } |
| + | |||
| + | // FUNZIONE GESTIONE CARTELLA CLINICA | ||
| + | function setupMedicalRecordField() { | ||
| + | const medicalRecordInput = document.getElementById(' | ||
| + | const currentYear = new Date().getFullYear().toString(); | ||
| + | |||
| + | // Imposta il valore iniziale con l'anno corrente | ||
| + | if (!medicalRecordInput.value) { | ||
| + | medicalRecordInput.value = currentYear; | ||
| + | } | ||
| + | |||
| + | // Gestisce l' | ||
| + | medicalRecordInput.addEventListener(' | ||
| + | let value = e.target.value.replace(/ | ||
| + | |||
| + | // Se l' | ||
| + | if (value.length < 4 || !value.startsWith(currentYear)) { | ||
| + | value = currentYear + value.slice(4); | ||
| + | } | ||
| + | |||
| + | // Limita a 10 cifre totali | ||
| + | if (value.length > 10) { | ||
| + | value = value.slice(0, | ||
| + | } | ||
| + | |||
| + | e.target.value = value; | ||
| + | }); | ||
| + | |||
| + | // Quando il campo ottiene il focus, posiziona il cursore dopo l' | ||
| + | medicalRecordInput.addEventListener(' | ||
| + | if (e.target.value === currentYear) { | ||
| + | // Posiziona il cursore alla fine | ||
| + | setTimeout(() => { | ||
| + | e.target.setSelectionRange(4, | ||
| + | }, 0); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | // Suggerimento visivo | ||
| + | medicalRecordInput.addEventListener(' | ||
| + | if (e.target.value === currentYear) { | ||
| + | e.target.placeholder = currentYear + ' | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | function updateDoctorsDropdown() { | ||
| + | console.log(' | ||
| + | const prescribingDoctorSelect = document.getElementById(' | ||
| + | console.log(' | ||
| + | |||
| + | if (!prescribingDoctorSelect) { | ||
| + | console.error(' | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | console.log(' | ||
| + | console.log(' | ||
| + | |||
| + | const currentValue = prescribingDoctorSelect.value; | ||
| + | prescribingDoctorSelect.innerHTML = '< | ||
| + | |||
| + | Object.keys(doctorsData).forEach(function(key) { | ||
| + | const doctor = doctorsData[key]; | ||
| + | console.log(' | ||
| + | const option = document.createElement(' | ||
| + | option.value = key; | ||
| + | option.textContent = doctor.fullName; | ||
| + | prescribingDoctorSelect.appendChild(option); | ||
| + | }); | ||
| + | |||
| + | // Ripristina il valore precedente se esiste ancora | ||
| + | if (currentValue && doctorsData[currentValue]) { | ||
| + | prescribingDoctorSelect.value = currentValue; | ||
| + | } | ||
| + | |||
| + | console.log(' | ||
| + | } | ||
| + | |||
| + | // FUNZIONE CALCOLO ETÀ POST-CONCEZIONALE | ||
| + | function calculatePostConceptionalAge() { | ||
| + | const gestWeeks = parseInt(document.getElementById(' | ||
| + | const gestDays = parseInt(document.getElementById(' | ||
| + | const daysOfLife = parseInt(document.getElementById(' | ||
| + | |||
| + | if (gestWeeks === 0 || daysOfLife === 0) { | ||
| + | document.getElementById(' | ||
| + | return null; | ||
| + | } | ||
| + | |||
| + | // Calcola età post-concezionale | ||
| + | const totalGestationalDays = (gestWeeks * 7) + gestDays; | ||
| + | const totalPostConceptionalDays = totalGestationalDays + daysOfLife; | ||
| + | |||
| + | // Converti in settimane+giorni | ||
| + | const pcWeeks = Math.floor(totalPostConceptionalDays / 7); | ||
| + | const pcDays = totalPostConceptionalDays % 7; | ||
| + | |||
| + | const pcAge = pcWeeks + ' | ||
| + | document.getElementById(' | ||
| + | |||
| + | return { weeks: pcWeeks, days: pcDays, format: pcAge }; | ||
| + | } | ||
| + | |||
| + | // FUNZIONE CALCOLO FASE NUTRIZIONALE (DA VERSIONE 17) | ||
| function calculatePhase() { | function calculatePhase() { | ||
| const medicalRecord = document.getElementById(' | const medicalRecord = document.getElementById(' | ||
| - | const birthWeight | + | const phaseBirthWeight |
| - | const currentWeight | + | const phaseCurrentWeight |
| const daysOfLife = parseInt(document.getElementById(' | const daysOfLife = parseInt(document.getElementById(' | ||
| const bun = document.getElementById(' | const bun = document.getElementById(' | ||
| Linea 1305: | Linea 2389: | ||
| const diuresis = document.getElementById(' | const diuresis = document.getElementById(' | ||
| const prescriptionDate = document.getElementById(' | const prescriptionDate = document.getElementById(' | ||
| - | const prescribingDoctor | + | const prescribingDoctorValue |
| | | ||
| - | patientData = { | + | |
| - | medicalRecord: | + | const doctorFullName = prescribingDoctorValue && doctorsData[prescribingDoctorValue] ? |
| - | birthWeight: | + | doctorsData[prescribingDoctorValue].fullName : ''; |
| - | currentWeight: | + | |
| - | daysOfLife: daysOfLife, | + | |
| - | bun: bun, | + | // Recupera età gestazionale per i report |
| - | glucose: glucose, | + | const gestationalWeeks = parseInt(document.getElementById(' |
| - | sodium: sodium, | + | const gestationalDays = parseInt(document.getElementById(' |
| - | ph: ph, | + | |
| - | baseExcess: baseExcess, | + | // Calcola età post-concezionale |
| - | diuresis: diuresis, | + | const postConceptionalAge = calculatePostConceptionalAge(); |
| - | prescriptionDate: | + | |
| - | prescribingDoctor: | + | patientData = { |
| - | }; | + | medicalRecord: |
| + | birthWeight: | ||
| + | currentWeight: | ||
| + | daysOfLife: daysOfLife, | ||
| + | | ||
| + | gestationalDays: | ||
| + | postConceptionalAge: | ||
| + | | ||
| + | glucose: glucose, | ||
| + | sodium: sodium, | ||
| + | ph: ph, | ||
| + | baseExcess: baseExcess, | ||
| + | diuresis: diuresis, | ||
| + | prescriptionDate: | ||
| + | prescribingDoctor: | ||
| + | | ||
| + | }; | ||
| | | ||
| document.getElementById(' | document.getElementById(' | ||
| Linea 1333: | Linea 2433: | ||
| if (bunValue < 9) { | if (bunValue < 9) { | ||
| bunStatus = 'Basso - Aumentare proteine'; | bunStatus = 'Basso - Aumentare proteine'; | ||
| - | bunWarning = 'BUN basso: considerare aumento | + | bunWarning = 'BUN basso: considerare aumento |
| } else if (bunValue > 14) { | } else if (bunValue > 14) { | ||
| bunStatus = ' | bunStatus = ' | ||
| - | bunWarning = 'BUN elevato: ridurre | + | bunWarning = 'BUN elevato: ridurre |
| } else { | } else { | ||
| bunStatus = ' | bunStatus = ' | ||
| Linea 1342: | Linea 2442: | ||
| } else { | } else { | ||
| bunStatus = 'Non inserito'; | bunStatus = 'Non inserito'; | ||
| + | } | ||
| + | | ||
| + | // Analisi altri parametri | ||
| + | let otherWarnings = []; | ||
| + | | ||
| + | if (glucose && glucose !== '' | ||
| + | const glucoseValue = parseFloat(glucose); | ||
| + | if (glucoseValue < 70) { | ||
| + | otherWarnings.push(' | ||
| + | } else if (glucoseValue > 150) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if (sodium && sodium !== '' | ||
| + | const sodiumValue = parseFloat(sodium); | ||
| + | if (sodiumValue < 135) { | ||
| + | otherWarnings.push(' | ||
| + | } else if (sodiumValue > 145) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if (ph && ph !== '' | ||
| + | const phValue = parseFloat(ph); | ||
| + | if (phValue < 7.35) { | ||
| + | otherWarnings.push(' | ||
| + | } else if (phValue > 7.45) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if (baseExcess && baseExcess !== '' | ||
| + | const beValue = parseFloat(baseExcess); | ||
| + | if (beValue < -4) { | ||
| + | otherWarnings.push(' | ||
| + | } else if (beValue > 2) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | // Raccomandazione combinata pH + BE per Sodio Acetato | ||
| + | if (ph && baseExcess) { | ||
| + | const phValue = parseFloat(ph); | ||
| + | const beValue = parseFloat(baseExcess); | ||
| + | if (phValue < 7.25 || beValue < -4) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | if (diuresis && diuresis !== '' | ||
| + | const diuresisValue = parseFloat(diuresis); | ||
| + | if (diuresisValue < 1) { | ||
| + | otherWarnings.push(' | ||
| + | } else if (diuresisValue > 3) { | ||
| + | otherWarnings.push(' | ||
| + | } | ||
| } | } | ||
| | | ||
| Linea 1351: | Linea 2508: | ||
| phaseInfoHtml += '< | phaseInfoHtml += '< | ||
| } | } | ||
| - | phaseInfoHtml += '< | + | phaseInfoHtml += '< |
| phaseInfoHtml += '< | phaseInfoHtml += '< | ||
| + | | ||
| + | if (gestationalWeeks && gestationalWeeks > 0) { | ||
| + | const gestDaysDisplay = gestationalDays || 0; | ||
| + | phaseInfoHtml += '< | ||
| + | if (postConceptionalAge && postConceptionalAge.format) { | ||
| + | phaseInfoHtml += '< | ||
| + | } | ||
| + | } | ||
| phaseInfoHtml += '< | phaseInfoHtml += '< | ||
| phaseInfoHtml += '</ | phaseInfoHtml += '</ | ||
| Linea 1359: | Linea 2524: | ||
| if (patientData.bun) { | if (patientData.bun) { | ||
| phaseInfoHtml += '< | phaseInfoHtml += '< | ||
| + | } | ||
| + | if (patientData.glucose) { | ||
| + | const gluStatus = parseFloat(patientData.glucose) >= 70 && parseFloat(patientData.glucose) <= 110 ? ' | ||
| + | phaseInfoHtml += '< | ||
| + | } | ||
| + | if (patientData.sodium) { | ||
| + | const naStatus = parseFloat(patientData.sodium) >= 135 && parseFloat(patientData.sodium) <= 145 ? ' | ||
| + | phaseInfoHtml += '< | ||
| + | } | ||
| + | if (patientData.ph) { | ||
| + | const phStatus = parseFloat(patientData.ph) >= 7.35 && parseFloat(patientData.ph) <= 7.45 ? ' | ||
| + | phaseInfoHtml += '< | ||
| + | } | ||
| + | if (patientData.baseExcess) { | ||
| + | const beStatus = parseFloat(patientData.baseExcess) >= -4 && parseFloat(patientData.baseExcess) <= 2 ? ' | ||
| + | phaseInfoHtml += '< | ||
| + | } | ||
| + | if (patientData.diuresis) { | ||
| + | const diuStatus = parseFloat(patientData.diuresis) >= 1 && parseFloat(patientData.diuresis) <= 3 ? ' | ||
| + | phaseInfoHtml += '< | ||
| } | } | ||
| phaseInfoHtml += '</ | phaseInfoHtml += '</ | ||
| Linea 1365: | Linea 2550: | ||
| if (bunWarning) { | if (bunWarning) { | ||
| phaseInfoHtml += '< | phaseInfoHtml += '< | ||
| + | } | ||
| + | | ||
| + | if (otherWarnings.length > 0) { | ||
| + | phaseInfoHtml += '< | ||
| } | } | ||
| | | ||
| Linea 1375: | Linea 2564: | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| + | // Aggiorna il suggerimento sodio se il TAB 3 è già stato visitato | ||
| updateSodiumRecommendation(); | updateSodiumRecommendation(); | ||
| + | | ||
| + | // RESET anche il pulsante NPT | ||
| + | resetParenteralButton(); | ||
| } | } | ||
| - | function updateSodiumRecommendation() { | + | // FUNZIONE |
| - | // Implementazione vuota per ora | + | |
| - | } | + | |
| - | + | ||
| - | // FUNZIONE FORTIFICANTE | + | |
| function updateFortifierOptions() { | function updateFortifierOptions() { | ||
| const formulaType = document.getElementById(' | const formulaType = document.getElementById(' | ||
| const fortifierSection = document.getElementById(' | const fortifierSection = document.getElementById(' | ||
| + | const fortifierSelect = document.getElementById(' | ||
| | | ||
| if (formulaType === ' | if (formulaType === ' | ||
| fortifierSection.classList.remove(' | fortifierSection.classList.remove(' | ||
| + | | ||
| + | fortifierSelect.innerHTML = '< | ||
| + | Object.keys(fortifierData).forEach(function(key) { | ||
| + | const option = document.createElement(' | ||
| + | option.value = key; | ||
| + | option.textContent = fortifierData[key].name; | ||
| + | fortifierSelect.appendChild(option); | ||
| + | }); | ||
| } else { | } else { | ||
| fortifierSection.classList.add(' | fortifierSection.classList.add(' | ||
| + | fortifierSelect.value = ' | ||
| } | } | ||
| } | } | ||
| + | // FUNZIONE AGGIORNAMENTO DISPLAY CONCENTRAZIONE | ||
| function updateConcentrationDisplay() { | function updateConcentrationDisplay() { | ||
| const concentration = document.getElementById(' | const concentration = document.getElementById(' | ||
| Linea 1399: | Linea 2599: | ||
| } | } | ||
| - | // FUNZIONE CALCOLO ENTERALE | + | // FUNZIONE CALCOLO |
| function calculateEnteral() { | function calculateEnteral() { | ||
| - | | + | |
| - | alert(' | + | const enteralCurrentWeight = parseInt(document.getElementById(' |
| + | const enteralBirthWeight = parseInt(document.getElementById(' | ||
| + | |||
| + | if (!enteralCurrentWeight || !enteralBirthWeight) { | ||
| + | alert(' | ||
| return; | return; | ||
| + | } | ||
| + | | ||
| + | // Aggiorna patientData se non è stato ancora fatto | ||
| + | if (!patientData.currentWeight) { | ||
| + | patientData.currentWeight = enteralCurrentWeight; | ||
| + | patientData.birthWeight = enteralBirthWeight; | ||
| } | } | ||
| | | ||
| Linea 1437: | Linea 2647: | ||
| const volumePerKg = (dailyVolume / currentWeight) * 1000; | const volumePerKg = (dailyVolume / currentWeight) * 1000; | ||
| | | ||
| + | // Calcoli finali per kg di peso | ||
| enteralData = { | enteralData = { | ||
| volume: dailyVolume, | volume: dailyVolume, | ||
| Linea 1456: | Linea 2667: | ||
| tableHtml += '< | tableHtml += '< | ||
| if (additionalFluids > 0) { | if (additionalFluids > 0) { | ||
| - | tableHtml += '< | + | tableHtml += '< |
| tableHtml += '< | tableHtml += '< | ||
| } else { | } else { | ||
| Linea 1476: | Linea 2687: | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| + | // Aggiorna il pulsante a verde | ||
| const enteralBtn = document.getElementById(' | const enteralBtn = document.getElementById(' | ||
| if (enteralBtn) { | if (enteralBtn) { | ||
| Linea 1481: | Linea 2693: | ||
| enteralBtn.innerHTML = ' | enteralBtn.innerHTML = ' | ||
| } | } | ||
| + | | ||
| + | // RESET del pulsante Fabbisogni quando si modificano gli apporti enterali | ||
| + | resetNutritionButton(); | ||
| } | } | ||
| - | // FUNZIONE CARICAMENTO VALORI | + | // FUNZIONE CARICAMENTO VALORI |
| function loadNutritionDefaults() { | function loadNutritionDefaults() { | ||
| - | | + | |
| - | alert(' | + | const defaultsCurrentWeight = parseInt(document.getElementById(' |
| + | const defaultsBirthWeight = parseInt(document.getElementById(' | ||
| + | const defaultsDaysOfLife = parseInt(document.getElementById(' | ||
| + | |||
| + | if (!defaultsCurrentWeight || !defaultsBirthWeight || !defaultsDaysOfLife) { | ||
| + | alert(' | ||
| return; | return; | ||
| + | } | ||
| + | | ||
| + | // Aggiorna patientData se non è stato ancora fatto | ||
| + | if (!patientData.currentWeight) { | ||
| + | patientData.currentWeight = defaultsCurrentWeight; | ||
| + | patientData.birthWeight = defaultsBirthWeight; | ||
| + | patientData.daysOfLife = defaultsDaysOfLife; | ||
| } | } | ||
| | | ||
| const targetDay = parseInt(document.getElementById(' | const targetDay = parseInt(document.getElementById(' | ||
| - | const birthWeight | + | const patientBirthWeightForCalculation |
| | | ||
| const weightCategorySelect = document.getElementById(' | const weightCategorySelect = document.getElementById(' | ||
| - | let selectedCategory = weightCategorySelect.value || (birthWeight | + | let selectedCategory = weightCategorySelect.value || (patientBirthWeightForCalculation |
| weightCategorySelect.value = selectedCategory; | weightCategorySelect.value = selectedCategory; | ||
| | | ||
| Linea 1520: | Linea 2747: | ||
| document.getElementById(' | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | // Usa configurazione clinica per elettroliti |
| - | document.getElementById(' | + | |
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| - | // Vitamine/ | + | // Gestione automatica tipo di sodio basata sui parametri clinici |
| - | const currentWeight | + | const sodiumSelect = document.getElementById(' |
| - | const enteralVolumePerKg = enteralData ? (enteralData.totalFluids / currentWeight | + | if (patientData.ph || patientData.baseExcess) { |
| + | const ph = patientData.ph ? parseFloat(patientData.ph) : null; | ||
| + | const be = patientData.baseExcess ? parseFloat(patientData.baseExcess) : null; | ||
| + | |||
| + | // Auto-seleziona Sodio Acetato se acidosi | ||
| + | if ((ph && ph < 7.30) || (be && be < -4)) { | ||
| + | sodiumSelect.value = ' | ||
| + | } else { | ||
| + | sodiumSelect.value = ' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Aggiorna il suggerimento sodio | ||
| + | updateSodiumRecommendation(); | ||
| + | |||
| + | // Gestione vitamine/ | ||
| + | const patientCurrentWeight | ||
| + | const enteralVolumePerKg = enteralData ? (enteralData.totalFluids / patientCurrentWeight | ||
| | | ||
| if (targetDay >= 3 && enteralVolumePerKg < 100) { | if (targetDay >= 3 && enteralVolumePerKg < 100) { | ||
| Linea 1535: | Linea 2781: | ||
| document.getElementById(' | document.getElementById(' | ||
| } else { | } else { | ||
| + | // Mantieni i valori a zero se prima del 3° giorno o se enterale ≥100 ml/kg/die | ||
| document.getElementById(' | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| Linea 1540: | Linea 2787: | ||
| } | } | ||
| | | ||
| - | document.getElementById(' | + | document.getElementById(' |
| | | ||
| - | | + | document.getElementById(' |
| - | if (loadBtn) { | + | |
| - | loadBtn.className = ' | + | |
| - | | + | // RESET del pulsante Fabbisogni quando si modificano i valori standard |
| - | | + | resetNutritionButton(); |
| } | } | ||
| + | // FUNZIONE AGGIORNAMENTO UNITÀ CARBOIDRATI | ||
| function updateCarbUnit() { | function updateCarbUnit() { | ||
| const unit = document.getElementById(' | const unit = document.getElementById(' | ||
| Linea 1563: | Linea 2811: | ||
| carbInput.setAttribute(' | carbInput.setAttribute(' | ||
| } | } | ||
| + | | ||
| + | // Reset fabbisogni quando si cambia unità | ||
| + | resetNutritionButton(); | ||
| } | } | ||
| + | // FUNZIONE AGGIORNAMENTO CATEGORIA PESO | ||
| function updateWeightCategory() { | function updateWeightCategory() { | ||
| - | // Placeholder | + | // Reset fabbisogni quando si cambia categoria peso |
| + | resetNutritionButton(); | ||
| } | } | ||
| + | // FUNZIONE AGGIORNAMENTO TIPO SODIO | ||
| function updateSodiumChoice() { | function updateSodiumChoice() { | ||
| - | // Placeholder | + | // Resetta i fabbisogni quando si cambia il tipo di sodio |
| + | resetNutritionButton(); | ||
| } | } | ||
| - | // FUNZIONE CALCOLO FABBISOGNI | + | // FUNZIONE AGGIORNAMENTO SUGGERIMENTO SODIO |
| + | function updateSodiumRecommendation() { | ||
| + | const sodiumSelect = document.getElementById(' | ||
| + | const recommendationDiv = document.getElementById(' | ||
| + | |||
| + | if (!patientData.ph && !patientData.baseExcess) { | ||
| + | // Nessun dato clinico disponibile | ||
| + | recommendationDiv.classList.add(' | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | const ph = patientData.ph ? parseFloat(patientData.ph) : null; | ||
| + | const be = patientData.baseExcess ? parseFloat(patientData.baseExcess) : null; | ||
| + | |||
| + | // Logica di raccomandazione | ||
| + | let needsAcetate = false; | ||
| + | let reason = ''; | ||
| + | |||
| + | if (ph && ph < 7.30) { | ||
| + | needsAcetate = true; | ||
| + | reason = 'pH < 7.30 (acidosi)'; | ||
| + | } else if (be && be < -4) { | ||
| + | needsAcetate = true; | ||
| + | reason = 'BE < -4 mEq/L (acidosi metabolica)'; | ||
| + | } else if (ph && be && (ph < 7.30 || be < -4)) { | ||
| + | needsAcetate = true; | ||
| + | reason = 'pH < 7.30 o BE < -4 (acidosi)'; | ||
| + | } | ||
| + | |||
| + | if (needsAcetate) { | ||
| + | // Suggerisci Sodio Acetato | ||
| + | if (sodiumSelect.value === ' | ||
| + | // L' | ||
| + | recommendationDiv.innerHTML = '< | ||
| + | '< | ||
| + | 'In base ai parametri clinici (' + reason + '), si raccomanda < | ||
| + | '</ | ||
| + | recommendationDiv.classList.remove(' | ||
| + | } else { | ||
| + | // L' | ||
| + | recommendationDiv.innerHTML = '< | ||
| + | '< | ||
| + | 'Sodio Acetato è indicato per i parametri clinici attuali (' + reason + ' | ||
| + | '</ | ||
| + | recommendationDiv.classList.remove(' | ||
| + | } | ||
| + | } else { | ||
| + | // Parametri normali | ||
| + | if (sodiumSelect.value === ' | ||
| + | // L' | ||
| + | recommendationDiv.innerHTML = '< | ||
| + | '< | ||
| + | 'I parametri clinici sono nella norma. Sodio Cloruro potrebbe essere sufficiente, | ||
| + | '</ | ||
| + | recommendationDiv.classList.remove(' | ||
| + | } else { | ||
| + | // Tutto normale | ||
| + | recommendationDiv.classList.add(' | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // FUNZIONE CALCOLO FABBISOGNI | ||
| function calculateNutrition() { | function calculateNutrition() { | ||
| - | | + | |
| - | alert(' | + | const nutritionCurrentWeight = parseInt(document.getElementById(' |
| + | const nutritionBirthWeight = parseInt(document.getElementById(' | ||
| + | |||
| + | if (!nutritionCurrentWeight || !nutritionBirthWeight) { | ||
| + | alert(' | ||
| return; | return; | ||
| + | } | ||
| + | | ||
| + | // Aggiorna patientData se non è stato ancora fatto | ||
| + | if (!patientData.currentWeight) { | ||
| + | patientData.currentWeight = nutritionCurrentWeight; | ||
| + | patientData.birthWeight = nutritionBirthWeight; | ||
| } | } | ||
| | | ||
| Linea 1601: | Linea 2928: | ||
| (requirements.carbs * 1440 / 1000) : requirements.carbs; | (requirements.carbs * 1440 / 1000) : requirements.carbs; | ||
| | | ||
| - | const currentWeight | + | const patientCurrentWeight |
| + | const enteralVolumePerKg = enteralData ? (enteralData.totalFluids / patientCurrentWeight * 1000) : 0; | ||
| | | ||
| const enteralProtein = enteralData ? enteralData.protein : 0; | const enteralProtein = enteralData ? enteralData.protein : 0; | ||
| Linea 1674: | Linea 3002: | ||
| document.getElementById(' | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| + | | ||
| + | // RESET del pulsante NPT quando si modificano i fabbisogni | ||
| + | resetParenteralButton(); | ||
| } | } | ||
| - | // FUNZIONE CALCOLO ELETTROLITI AGGIUNTIVI | + | // FUNZIONE CALCOLO ELETTROLITI AGGIUNTIVI |
| function calculateElectrolyteAdditions(calciumNeeded, | function calculateElectrolyteAdditions(calciumNeeded, | ||
| const additions = { | const additions = { | ||
| Linea 1686: | Linea 3017: | ||
| kcl: 0, | kcl: 0, | ||
| totalVolume: | totalVolume: | ||
| - | providedCalcium: | ||
| - | providedPhosphorus: | ||
| - | providedMagnesium: | ||
| - | providedSodium: | ||
| - | providedPotassium: | ||
| sodiumSource: | sodiumSource: | ||
| }; | }; | ||
| | | ||
| + | // Determina il tipo di sodio da utilizzare | ||
| const sodiumTypeSelect = document.getElementById(' | const sodiumTypeSelect = document.getElementById(' | ||
| const selectedSodiumType = sodiumTypeSelect ? sodiumTypeSelect.value : ' | const selectedSodiumType = sodiumTypeSelect ? sodiumTypeSelect.value : ' | ||
| additions.sodiumSource = selectedSodiumType; | additions.sodiumSource = selectedSodiumType; | ||
| | | ||
| - | const totalCalciumNeeded = calciumNeeded * currentWeightKg; | + | |
| - | const totalPhosphorusNeeded = phosphorusNeeded * currentWeightKg; | + | |
| - | const totalMagnesiumNeeded = magnesiumNeeded * currentWeightKg; | + | const totalPhosphorusNeeded = phosphorusNeeded * currentWeightKg; |
| - | const totalSodiumNeeded = sodiumNeeded * currentWeightKg; | + | const totalMagnesiumNeeded = magnesiumNeeded * currentWeightKg; |
| - | const totalPotassiumNeeded = potassiumNeeded * currentWeightKg; | + | const totalSodiumNeeded = sodiumNeeded * currentWeightKg; |
| + | const totalPotassiumNeeded = potassiumNeeded * currentWeightKg; | ||
| | | ||
| // Calcio Gluconato 10% (840 mg Ca/100ml) | // Calcio Gluconato 10% (840 mg Ca/100ml) | ||
| if (totalCalciumNeeded > 0) { | if (totalCalciumNeeded > 0) { | ||
| additions.ca_gluconato = totalCalciumNeeded / (parenteralConfig.ca_gluconato.calcium / 100); | additions.ca_gluconato = totalCalciumNeeded / (parenteralConfig.ca_gluconato.calcium / 100); | ||
| - | additions.providedCalcium = totalCalciumNeeded; | ||
| } | } | ||
| | | ||
| // Esafosfina (1600 mg P/100ml + 130 mEq Na/100ml) | // Esafosfina (1600 mg P/100ml + 130 mEq Na/100ml) | ||
| + | let sodiumFromEsafosfina = 0; | ||
| if (totalPhosphorusNeeded > 0) { | if (totalPhosphorusNeeded > 0) { | ||
| additions.esafosfina = totalPhosphorusNeeded / (parenteralConfig.esafosfina.phosphorus / 100); | additions.esafosfina = totalPhosphorusNeeded / (parenteralConfig.esafosfina.phosphorus / 100); | ||
| - | | + | |
| - | additions.providedSodium += (additions.esafosfina * parenteralConfig.esafosfina.sodium / 100); | + | |
| } | } | ||
| | | ||
| Linea 1720: | Linea 3047: | ||
| if (totalMagnesiumNeeded > 0) { | if (totalMagnesiumNeeded > 0) { | ||
| additions.mg_sulfate = totalMagnesiumNeeded / (parenteralConfig.mg_sulfate.magnesium / 100); | additions.mg_sulfate = totalMagnesiumNeeded / (parenteralConfig.mg_sulfate.magnesium / 100); | ||
| - | additions.providedMagnesium = totalMagnesiumNeeded; | ||
| } | } | ||
| | | ||
| - | // Sodio rimanente | + | // Sodio rimanente |
| - | const remainingSodium = Math.max(0, totalSodiumNeeded - additions.providedSodium); | + | const remainingSodium = Math.max(0, totalSodiumNeeded - sodiumFromEsafosfina); |
| | | ||
| if (remainingSodium > 0) { | if (remainingSodium > 0) { | ||
| Linea 1734: | Linea 3060: | ||
| additions.nacl = remainingSodium / concentrationNaCl; | additions.nacl = remainingSodium / concentrationNaCl; | ||
| } | } | ||
| - | additions.providedSodium += remainingSodium; | ||
| } | } | ||
| | | ||
| Linea 1740: | Linea 3065: | ||
| if (totalPotassiumNeeded > 0) { | if (totalPotassiumNeeded > 0) { | ||
| additions.kcl = totalPotassiumNeeded / (parenteralConfig.kcl.potassium / 100); | additions.kcl = totalPotassiumNeeded / (parenteralConfig.kcl.potassium / 100); | ||
| - | additions.providedPotassium = totalPotassiumNeeded; | ||
| } | } | ||
| | | ||
| + | // Volume totale degli elettroliti | ||
| additions.totalVolume = additions.ca_gluconato + additions.esafosfina + additions.mg_sulfate + additions.nacl + additions.sodium_acetate + additions.kcl; | additions.totalVolume = additions.ca_gluconato + additions.esafosfina + additions.mg_sulfate + additions.nacl + additions.sodium_acetate + additions.kcl; | ||
| | | ||
| Linea 1748: | Linea 3073: | ||
| } | } | ||
| - | // FUNZIONE CALCOLO NPT PARENTERALE | + | |
| + | // FUNZIONE CALCOLO OSMOLARITÀ NPT (MIGLIORATA) | ||
| + | function calculateNPTOsmolarity(calc, | ||
| + | let totalOsmolarity = 0; | ||
| + | let osmolarityBreakdown = {}; | ||
| + | let componentDetails = []; | ||
| + | |||
| + | // Glucosio 50% - osmolarità molto alta | ||
| + | if (calc.neededGlucose > 0) { | ||
| + | const glucoseOsmol = (calc.glucose50Volume * parenteralConfig.glucose50.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.glucose = glucoseOsmol; | ||
| + | totalOsmolarity += glucoseOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.glucose50Volume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | // Trophamine 6% | ||
| + | const proteinOsmol = (calc.proteinVolume * parenteralConfig.trophamine.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.protein = proteinOsmol; | ||
| + | totalOsmolarity += proteinOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.proteinVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | |||
| + | // Intralipid 20% | ||
| + | const lipidOsmol = (calc.lipidVolume * parenteralConfig.intralipid.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.lipid = lipidOsmol; | ||
| + | totalOsmolarity += lipidOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.lipidVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | |||
| + | // Elettroliti | ||
| + | if (calc.electrolyteAdditions.ca_gluconato > 0) { | ||
| + | const caOsmol = (calc.electrolyteAdditions.ca_gluconato * parenteralConfig.ca_gluconato.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.calcium = caOsmol; | ||
| + | totalOsmolarity += caOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.electrolyteAdditions.ca_gluconato, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (calc.electrolyteAdditions.esafosfina > 0) { | ||
| + | const pOsmol = (calc.electrolyteAdditions.esafosfina * parenteralConfig.esafosfina.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.phosphorus = pOsmol; | ||
| + | totalOsmolarity += pOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.electrolyteAdditions.esafosfina, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (calc.electrolyteAdditions.mg_sulfate > 0) { | ||
| + | const mgOsmol = (calc.electrolyteAdditions.mg_sulfate * parenteralConfig.mg_sulfate.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.magnesium = mgOsmol; | ||
| + | totalOsmolarity += mgOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.electrolyteAdditions.mg_sulfate, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (calc.electrolyteAdditions.nacl > 0) { | ||
| + | const naclOsmol = (calc.electrolyteAdditions.nacl * parenteralConfig.nacl.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.nacl = naclOsmol; | ||
| + | totalOsmolarity += naclOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: 'Sodio Cloruro', | ||
| + | volume: calc.electrolyteAdditions.nacl, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (calc.electrolyteAdditions.sodium_acetate > 0) { | ||
| + | const naAcetOsmol = (calc.electrolyteAdditions.sodium_acetate * parenteralConfig.sodium_acetate.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.sodium_acetate = naAcetOsmol; | ||
| + | totalOsmolarity += naAcetOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: 'Sodio Acetato', | ||
| + | volume: calc.electrolyteAdditions.sodium_acetate, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (calc.electrolyteAdditions.kcl > 0) { | ||
| + | const kclOsmol = (calc.electrolyteAdditions.kcl * parenteralConfig.kcl.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.kcl = kclOsmol; | ||
| + | totalOsmolarity += kclOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: calc.electrolyteAdditions.kcl, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | // Vitamine e Carnitina (osmolarità bassa) | ||
| + | let vitaminsOsmol = 0; | ||
| + | if (residualNeeds.vitalipid > 0) { | ||
| + | const vitalipidVolume = residualNeeds.vitalipid * currentWeightKg; | ||
| + | const vitOsmol = (vitalipidVolume * 280) / calc.totalVolume; | ||
| + | vitaminsOsmol += vitOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: vitalipidVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (residualNeeds.soluvit > 0) { | ||
| + | const soluvitVolume = residualNeeds.soluvit * currentWeightKg; | ||
| + | const solOsmol = (soluvitVolume * 300) / calc.totalVolume; | ||
| + | vitaminsOsmol += solOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: soluvitVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (residualNeeds.peditrace > 0) { | ||
| + | const peditraceVolume = residualNeeds.peditrace * currentWeightKg; | ||
| + | const pedOsmol = (peditraceVolume * 350) / calc.totalVolume; | ||
| + | vitaminsOsmol += pedOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: peditraceVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | if (vitaminsOsmol > 0) { | ||
| + | osmolarityBreakdown.vitamins = vitaminsOsmol; | ||
| + | totalOsmolarity += vitaminsOsmol; | ||
| + | } | ||
| + | |||
| + | if (residualNeeds.carnitine > 0) { | ||
| + | const carnitineVolume = (residualNeeds.carnitine * currentWeightKg) / 100; | ||
| + | const carOsmol = (carnitineVolume * parenteralConfig.carnitene.osmolarity) / calc.totalVolume; | ||
| + | osmolarityBreakdown.carnitine = carOsmol; | ||
| + | totalOsmolarity += carOsmol; | ||
| + | componentDetails.push({ | ||
| + | name: ' | ||
| + | volume: carnitineVolume, | ||
| + | concentration: | ||
| + | contribution: | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | return { | ||
| + | total: Math.round(totalOsmolarity), | ||
| + | breakdown: osmolarityBreakdown, | ||
| + | details: componentDetails, | ||
| + | isHypertonic: | ||
| + | requiresCVC: | ||
| + | }; | ||
| + | } | ||
| + | |||
| + | // FUNZIONE CALCOLO NPT PARENTERALE | ||
| function calculateParenteral() { | function calculateParenteral() { | ||
| if (!window.residualNeeds) { | if (!window.residualNeeds) { | ||
| Linea 1755: | Linea 3260: | ||
| } | } | ||
| | | ||
| - | const currentWeight | + | const parentCurrentWeight |
| - | const currentWeightKg = currentWeight | + | const currentWeightKg = parentCurrentWeight |
| const residualNeeds = window.residualNeeds; | const residualNeeds = window.residualNeeds; | ||
| | | ||
| + | // CONTROLLI DI SICUREZZA BASATI SU CONFIGURAZIONE CLINICA | ||
| + | const gir = (residualNeeds.carbs * 1000) / 1440; // mg/kg/min | ||
| + | let alerts = []; | ||
| + | | ||
| + | if (gir > clinicalConfig.maxGIR) { | ||
| + | alerts.push(' | ||
| + | } | ||
| + | if (residualNeeds.lipids > clinicalConfig.maxLipids) { | ||
| + | alerts.push(' | ||
| + | } | ||
| + | if (residualNeeds.protein > clinicalConfig.maxProtein) { | ||
| + | alerts.push(' | ||
| + | } | ||
| + | | ||
| + | // Volume totale residuo richiesto | ||
| const totalVolume = Math.round(residualNeeds.liquids * currentWeightKg); | const totalVolume = Math.round(residualNeeds.liquids * currentWeightKg); | ||
| | | ||
| + | // CALCOLA ELETTROLITI AGGIUNTIVI | ||
| const electrolyteAdditions = calculateElectrolyteAdditions( | const electrolyteAdditions = calculateElectrolyteAdditions( | ||
| residualNeeds.calcium, | residualNeeds.calcium, | ||
| Linea 1770: | Linea 3291: | ||
| ); | ); | ||
| | | ||
| + | // Volume proteine (Trophamine 6%) | ||
| const proteinVolume = Math.round((residualNeeds.protein * currentWeightKg * 100) / 6); | const proteinVolume = Math.round((residualNeeds.protein * currentWeightKg * 100) / 6); | ||
| + | | ||
| + | // Volume lipidi (Intralipid 20%) | ||
| const lipidVolume = Math.round((residualNeeds.lipids * currentWeightKg * 100) / 20); | const lipidVolume = Math.round((residualNeeds.lipids * currentWeightKg * 100) / 20); | ||
| | | ||
| + | // Volume vitamine/ | ||
| const vitaminsVolume = (residualNeeds.vitalipid * currentWeightKg) + (residualNeeds.soluvit * currentWeightKg) + (residualNeeds.peditrace * currentWeightKg); | const vitaminsVolume = (residualNeeds.vitalipid * currentWeightKg) + (residualNeeds.soluvit * currentWeightKg) + (residualNeeds.peditrace * currentWeightKg); | ||
| const carnitineVolume = residualNeeds.carnitine > 0 ? (residualNeeds.carnitine * currentWeightKg) / 100 : 0; | const carnitineVolume = residualNeeds.carnitine > 0 ? (residualNeeds.carnitine * currentWeightKg) / 100 : 0; | ||
| | | ||
| - | const neededGlucose = residualNeeds.carbs * currentWeightKg; | + | |
| - | const glucose50Volume = (neededGlucose * 100) / 50; | + | |
| + | const glucose50Volume = (neededGlucose * 100) / 50; // ml di glucosio 50% necessari | ||
| | | ||
| + | // Volume utilizzato | ||
| const usedVolume = proteinVolume + lipidVolume + vitaminsVolume + carnitineVolume + glucose50Volume + electrolyteAdditions.totalVolume; | const usedVolume = proteinVolume + lipidVolume + vitaminsVolume + carnitineVolume + glucose50Volume + electrolyteAdditions.totalVolume; | ||
| + | | ||
| + | // Volume rimanente = Acqua Bidistillata | ||
| const waterVolume = totalVolume - usedVolume; | const waterVolume = totalVolume - usedVolume; | ||
| - | | ||
| - | let glucoseMessage = ''; | ||
| - | | ||
| - | if (waterVolume < 0) { | ||
| - | glucoseMessage = '< | ||
| - | '• Volume totale richiesto: ' + totalVolume + ' ml< | ||
| - | '• Volume utilizzato: ' + usedVolume.toFixed(1) + ' ml< | ||
| - | '• Acqua rimanente: ' + waterVolume.toFixed(1) + ' ml (NEGATIVO!)< | ||
| - | '< | ||
| - | | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | return; | ||
| - | } | ||
| - | | ||
| - | if (neededGlucose <= 0) { | ||
| - | glucoseMessage = '< | ||
| - | '• Tutto il glucosio necessario proviene dall\' | ||
| - | '• Non necessario glucosio in NPT</ | ||
| - | | ||
| - | document.getElementById(' | ||
| - | } else { | ||
| - | glucoseMessage = '< | ||
| - | '• Glucosio necessario: ' + neededGlucose.toFixed(1) + ' | ||
| - | '• Glucosio 50%: ' + glucose50Volume.toFixed(1) + ' | ||
| - | '• Acqua bidistillata: | ||
| - | '• < | ||
| - | | ||
| - | document.getElementById(' | ||
| - | } | ||
| | | ||
| document.getElementById(' | document.getElementById(' | ||
| + | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| - | let resultHtml = glucoseMessage; | + | let resultHtml = '< |
| + | resultHtml += '< | ||
| + | resultHtml += '< | ||
| + | resultHtml += '< | ||
| + | resultHtml += '< | ||
| + | if (enteralData && enteralData.additionalFluids > 0) { | ||
| + | resultHtml += '< | ||
| + | } | ||
| + | resultHtml += '</ | ||
| | | ||
| - | resultHtml += '< | + | |
| - | resultHtml += '< | + | if (alerts.length > 0) { |
| - | resultHtml += '< | + | |
| - | resultHtml += '< | + | } |
| - | resultHtml | + | |
| | | ||
| resultHtml += '< | resultHtml += '< | ||
| Linea 1837: | Linea 3339: | ||
| | | ||
| resultHtml += '< | resultHtml += '< | ||
| - | resultHtml += '< | + | resultHtml += '< |
| | | ||
| + | // ELETTROLITI AGGIUNTIVI | ||
| if (electrolyteAdditions.ca_gluconato > 0) { | if (electrolyteAdditions.ca_gluconato > 0) { | ||
| resultHtml += '< | resultHtml += '< | ||
| Linea 1846: | Linea 3349: | ||
| } | } | ||
| if (electrolyteAdditions.mg_sulfate > 0) { | if (electrolyteAdditions.mg_sulfate > 0) { | ||
| - | resultHtml += '< | + | resultHtml += '< |
| } | } | ||
| if (electrolyteAdditions.nacl > 0) { | if (electrolyteAdditions.nacl > 0) { | ||
| Linea 1852: | Linea 3355: | ||
| } | } | ||
| if (electrolyteAdditions.sodium_acetate > 0) { | if (electrolyteAdditions.sodium_acetate > 0) { | ||
| - | resultHtml += '< | + | resultHtml += '< |
| } | } | ||
| if (electrolyteAdditions.kcl > 0) { | if (electrolyteAdditions.kcl > 0) { | ||
| resultHtml += '< | resultHtml += '< | ||
| } | } | ||
| - | | + | |
| + | // VITAMINE | ||
| if (residualNeeds.vitalipid > 0) { | if (residualNeeds.vitalipid > 0) { | ||
| const vitalipidVolume = residualNeeds.vitalipid * currentWeightKg; | const vitalipidVolume = residualNeeds.vitalipid * currentWeightKg; | ||
| Linea 1871: | Linea 3375: | ||
| } | } | ||
| | | ||
| + | | ||
| + | // CARNITINA | ||
| if (residualNeeds.carnitine > 0) { | if (residualNeeds.carnitine > 0) { | ||
| - | resultHtml += '< | + | resultHtml += '< |
| } | } | ||
| | | ||
| + | // ACQUA BIDISTILLATA | ||
| if (waterVolume > 0) { | if (waterVolume > 0) { | ||
| resultHtml += '< | resultHtml += '< | ||
| Linea 1884: | Linea 3391: | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| - | // PREPARAZIONE | + | // CALCOLO OSMOLARITÀ |
| + | const osmolarityData = calculateNPTOsmolarity({ | ||
| + | totalVolume: | ||
| + | waterVolume: | ||
| + | glucose50Volume: | ||
| + | proteinVolume: | ||
| + | lipidVolume: | ||
| + | electrolyteAdditions: | ||
| + | }, currentWeightKg, | ||
| + | |||
| + | // AGGIUNGI SEZIONE OSMOLARITÀ | ||
| + | let osmolarityHtml = '< | ||
| + | if (osmolarityData.isHypertonic) { | ||
| + | osmolarityHtml += '# | ||
| + | } else if (osmolarityData.requiresCVC) { | ||
| + | osmolarityHtml += '# | ||
| + | } else { | ||
| + | osmolarityHtml += '# | ||
| + | } | ||
| + | osmolarityHtml += '">'; | ||
| + | osmolarityHtml += '< | ||
| + | osmolarityHtml += '< | ||
| + | osmolarityHtml += '< | ||
| + | osmolarityHtml += '< | ||
| + | |||
| + | if (osmolarityData.isHypertonic) { | ||
| + | osmolarityHtml += '<p style=" | ||
| + | } else if (osmolarityData.requiresCVC) { | ||
| + | osmolarityHtml += '<p style=" | ||
| + | } else { | ||
| + | osmolarityHtml += '<p style=" | ||
| + | } | ||
| + | |||
| + | osmolarityHtml += '</ | ||
| + | osmolarityHtml += '< | ||
| + | osmolarityHtml += '< | ||
| + | osmolarityData.details.forEach(function(detail) { | ||
| + | if (detail.contribution > 30) { // Mostra contributi > 30 mOsm/L | ||
| + | osmolarityHtml += '<p style=" | ||
| + | } | ||
| + | }); | ||
| + | osmolarityHtml += '</ | ||
| + | osmolarityHtml += '</ | ||
| + | osmolarityHtml += '</ | ||
| + | |||
| + | document.getElementById(' | ||
| + | |||
| + | // CREAZIONE RICETTA PER PREPARAZIONE | ||
| const deflectorVolume = parseInt(document.getElementById(' | const deflectorVolume = parseInt(document.getElementById(' | ||
| const totalVolumeWithDeflector = totalVolume + deflectorVolume; | const totalVolumeWithDeflector = totalVolume + deflectorVolume; | ||
| + | const ratio = totalVolumeWithDeflector / totalVolume; | ||
| | | ||
| let preparationHtml = '< | let preparationHtml = '< | ||
| - | preparationHtml += '< | + | preparationHtml += '< |
| preparationHtml += '• < | preparationHtml += '• < | ||
| + | preparationHtml += '• < | ||
| preparationHtml += '• < | preparationHtml += '• < | ||
| preparationHtml += '</ | preparationHtml += '</ | ||
| | | ||
| preparationHtml += '< | preparationHtml += '< | ||
| - | preparationHtml += '< | + | preparationHtml += '< |
| - | + | ||
| - | const ratio = totalVolumeWithDeflector / totalVolume; | + | |
| | | ||
| if (neededGlucose > 0) { | if (neededGlucose > 0) { | ||
| Linea 1904: | Linea 3458: | ||
| | | ||
| preparationHtml += '< | preparationHtml += '< | ||
| - | preparationHtml += '< | + | preparationHtml += '< |
| | | ||
| if (electrolyteAdditions.ca_gluconato > 0) { | if (electrolyteAdditions.ca_gluconato > 0) { | ||
| Linea 1913: | Linea 3467: | ||
| } | } | ||
| if (electrolyteAdditions.mg_sulfate > 0) { | if (electrolyteAdditions.mg_sulfate > 0) { | ||
| - | preparationHtml += '< | + | preparationHtml += '< |
| } | } | ||
| if (electrolyteAdditions.nacl > 0) { | if (electrolyteAdditions.nacl > 0) { | ||
| Linea 1919: | Linea 3473: | ||
| } | } | ||
| if (electrolyteAdditions.sodium_acetate > 0) { | if (electrolyteAdditions.sodium_acetate > 0) { | ||
| - | preparationHtml += '< | + | preparationHtml += '< |
| } | } | ||
| if (electrolyteAdditions.kcl > 0) { | if (electrolyteAdditions.kcl > 0) { | ||
| Linea 1925: | Linea 3479: | ||
| } | } | ||
| | | ||
| + | // VITAMINE con denominazioni complete | ||
| if (residualNeeds.vitalipid > 0) { | if (residualNeeds.vitalipid > 0) { | ||
| const vitalipidVolume = residualNeeds.vitalipid * currentWeightKg; | const vitalipidVolume = residualNeeds.vitalipid * currentWeightKg; | ||
| Linea 1938: | Linea 3493: | ||
| } | } | ||
| | | ||
| + | // CARNITINA con denominazione completa | ||
| if (residualNeeds.carnitine > 0) { | if (residualNeeds.carnitine > 0) { | ||
| preparationHtml += '< | preparationHtml += '< | ||
| Linea 1947: | Linea 3503: | ||
| | | ||
| preparationHtml += '< | preparationHtml += '< | ||
| + | preparationHtml += '< | ||
| + | preparationHtml += '< | ||
| + | |||
| + | // Aggiungi avvertenze osmolarità nella tabella di preparazione | ||
| + | if (osmolarityData.isHypertonic) { | ||
| + | preparationHtml += '< | ||
| + | } else if (osmolarityData.requiresCVC) { | ||
| + | preparationHtml += '< | ||
| + | } else { | ||
| + | preparationHtml += '< | ||
| + | } | ||
| preparationHtml += '</ | preparationHtml += '</ | ||
| | | ||
| Linea 1952: | Linea 3519: | ||
| document.getElementById(' | document.getElementById(' | ||
| | | ||
| - | // Salva i dati per i report | + | |
| - | window.nptCalculationData | + | document.getElementById(' |
| - | | + | |
| - | proteinVolume, | + | |
| - | | + | window.nptCalculation |
| + | | ||
| + | waterVolume: | ||
| + | glucose50Volume: | ||
| + | | ||
| + | lipidVolume: | ||
| + | gir: gir, | ||
| + | neededGlucose: | ||
| + | | ||
| + | vitaminsVolume: | ||
| + | carnitineVolume: | ||
| + | deflectorVolume: | ||
| + | osmolarityData: | ||
| }; | }; | ||
| + | } | ||
| + | |||
| + | // FUNZIONI CONFIGURAZIONE (DA VERSIONE 17) | ||
| + | function populateEnteralConfigTable() { | ||
| + | const tbody = document.getElementById(' | ||
| + | if (!tbody) return; | ||
| | | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | const row = tbody.insertRow(); |
| - | } | + | row.innerHTML |
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | }); | ||
| } | } | ||
| - | // FUNZIONI REPORT | + | function |
| - | function | + | |
| - | | + | if (!tbody) |
| - | alert('Prima calcolare la NPT!'); | + | |
| - | return; | + | |
| - | } | + | |
| | | ||
| - | const reportHtml | + | |
| - | | + | Object.keys(parenteralConfig).forEach(function(key) { |
| - | | + | |
| - | | + | const row = tbody.insertRow(); |
| - | | + | row.innerHTML = '< |
| - | | + | '< |
| - | | + | '< |
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | | ||
| + | } | ||
| + | |||
| + | function populateDoctorsConfigTable() { | ||
| + | const tbody = document.getElementById('doctorsConfigTable'); | ||
| + | if (!tbody) return; | ||
| | | ||
| - | const generateBtn | + | |
| - | | + | Object.keys(doctorsData).forEach(key => { |
| - | | + | const doctor = doctorsData[key]; |
| + | | ||
| + | row.innerHTML = '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '</ | ||
| + | '< | ||
| + | | ||
| + | }); | ||
| } | } | ||
| - | function | + | function |
| - | | + | |
| - | alert('Prima calcolare la NPT!'); | + | if (!tbody) |
| - | return; | + | |
| - | } | + | |
| | | ||
| - | | + | |
| - | | + | |
| - | | + | const nurse = nursesData[key]; |
| - | | + | const row = tbody.insertRow(); |
| - | | + | row.innerHTML = '< |
| - | | + | '< |
| - | | + | '< |
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '</ | ||
| + | '< | ||
| + | '< | ||
| + | | ||
| + | } | ||
| + | |||
| + | function populatePharmacistsConfigTable() { | ||
| + | const tbody = document.getElementById('pharmacistsConfigTable'); | ||
| + | if (!tbody) return; | ||
| | | ||
| - | const generateBtn | + | |
| - | | + | Object.keys(pharmacistsData).forEach(key => { |
| - | | + | const pharmacist = pharmacistsData[key]; |
| + | | ||
| + | row.innerHTML = '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '</ | ||
| + | '< | ||
| + | | ||
| + | }); | ||
| } | } | ||
| - | function | + | function |
| - | const data = window.nptCalculationData; | + | const tbody = document.getElementById(' |
| - | const deflectorVolume = parseInt(document.getElementById(' | + | |
| - | | + | |
| - | const ratio = totalVolumeWithDeflector / data.totalVolume; | + | |
| | | ||
| - | | + | |
| - | const dateStr | + | Object.keys(technicianData).forEach(key => { |
| + | const technician = technicianData[key]; | ||
| + | const row = tbody.insertRow(); | ||
| + | row.innerHTML = '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '</ | ||
| + | '< | ||
| + | '< | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | function markConfigChanged(configType) { | ||
| + | let buttonId = ''; | ||
| + | let buttonText = '' | ||
| | | ||
| - | | + | |
| - | | + | case ' |
| + | buttonId | ||
| + | buttonText = 'SALVA MODIFICHE ENTERALI'; | ||
| + | break; | ||
| + | | ||
| + | buttonId = 'updateParenteralBtn'; | ||
| + | buttonText = 'SALVA MODIFICHE PARENTERALI'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA MODIFICHE FORTIFICANTI'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA MODIFICHE MEDICI'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA MODIFICHE INFERMIERE'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA MODIFICHE FARMACISTI'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA MODIFICHE TECNICI'; | ||
| + | break; | ||
| + | case ' | ||
| + | buttonId = ' | ||
| + | buttonText = 'SALVA PARAMETRI SISTEMA'; | ||
| + | break; | ||
| + | } | ||
| | | ||
| - | const infusionRate | + | const button |
| - | | + | |
| - | const estimatedOsmolarity | + | button.className = ' |
| + | | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | function updateEnteralConfig() { | ||
| + | let changesCount = 0; | ||
| | | ||
| - | | + | |
| + | const oldValues = Object.assign({}, | ||
| + | |||
| + | const proteinEl = document.getElementById('config_' | ||
| + | if (proteinEl) { | ||
| + | formulaData[key].protein | ||
| + | formulaData[key].carbs = parseFloat(document.getElementById('config_' | ||
| + | formulaData[key].lipids = parseFloat(document.getElementById(' | ||
| + | formulaData[key].sodium = parseFloat(document.getElementById(' | ||
| + | formulaData[key].potassium = parseFloat(document.getElementById(' | ||
| + | formulaData[key].calcium = parseFloat(document.getElementById(' | ||
| + | formulaData[key].phosphorus = parseFloat(document.getElementById(' | ||
| + | formulaData[key].magnesium = parseFloat(document.getElementById(' | ||
| + | formulaData[key].energy = parseFloat(document.getElementById(' | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(formulaData[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | html += '<div class=" | + | |
| - | | + | button.className |
| - | html += '<div style=" | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| - | html += '<div class=" | + | |
| - | | + | }, 3000); |
| + | | ||
| + | } | ||
| + | |||
| + | function updateParenteralConfig() { | ||
| + | let changesCount | ||
| | | ||
| - | | + | |
| - | html += '< | + | const oldValues |
| - | html += '<div class=" | + | |
| - | html += '< | + | const proteinEl |
| - | html += '< | + | if (proteinEl) { |
| - | html += '< | + | parenteralConfig[key].protein |
| - | html += '< | + | parenteralConfig[key].carbs |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| - | html += '</ | + | parenteralConfig[key].calcium = parseFloat(document.getElementById('config_' |
| + | | ||
| + | | ||
| + | parenteralConfig[key].energy = parseFloat(document.getElementById(' | ||
| + | | ||
| + | | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(parenteralConfig[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | html += '<div class=" | + | |
| - | | + | button.className |
| - | html += '<table class=" | + | |
| - | html += '< | + | |
| - | + | | |
| - | if (data.waterVolume | + | button.innerHTML = 'Aggiorna Componenti Parenterali'; |
| - | html += '< | + | }, 3000); |
| } | } | ||
| - | if (data.glucose50Volume > 0) { | + | } |
| - | | + | |
| + | function updateFortifierConfig() { | ||
| + | // Aggiorna Prenidina FM85 predefinita | ||
| + | const proteinEl = document.getElementById(' | ||
| + | if (proteinEl) { | ||
| + | | ||
| + | fortifierData.prenidina_fm85.carbs = parseFloat(document.getElementById('fortifier_prenidina_fm85_carbs' | ||
| + | fortifierData.prenidina_fm85.lipids | ||
| + | fortifierData.prenidina_fm85.sodium = parseFloat(document.getElementById('fortifier_prenidina_fm85_sodium' | ||
| + | fortifierData.prenidina_fm85.potassium = parseFloat(document.getElementById(' | ||
| + | fortifierData.prenidina_fm85.calcium = parseFloat(document.getElementById('fortifier_prenidina_fm85_calcium').value); | ||
| + | fortifierData.prenidina_fm85.phosphorus = parseFloat(document.getElementById(' | ||
| + | fortifierData.prenidina_fm85.magnesium = parseFloat(document.getElementById(' | ||
| + | fortifierData.prenidina_fm85.energy = parseFloat(document.getElementById('fortifier_prenidina_fm85_energy').value); | ||
| } | } | ||
| - | if (data.electrolyteAdditions.ca_gluconato > 0) { | + | |
| - | | + | const button = document.getElementById(' |
| + | | ||
| + | | ||
| + | button.innerHTML = 'FORTIFICANTI SALVATE ✓'; | ||
| + | setTimeout(() => { | ||
| + | button.className = 'button'; | ||
| + | button.innerHTML = ' | ||
| + | }, 3000); | ||
| } | } | ||
| - | if (data.electrolyteAdditions.nacl > 0) { | + | } |
| - | | + | |
| + | function updateDoctorsConfig() { | ||
| + | let changesCount = 0; | ||
| + | |||
| + | Object.keys(doctorsData).forEach(key => { | ||
| + | | ||
| + | |||
| + | const nameEl = document.getElementById('doctor_' | ||
| + | if (nameEl) { | ||
| + | const newName | ||
| + | const newSurname = document.getElementById(' | ||
| + | const newTitle = document.getElementById(' | ||
| + | |||
| + | doctorsData[key].name = newName; | ||
| + | doctorsData[key].surname = newSurname; | ||
| + | doctorsData[key].title = newTitle; | ||
| + | doctorsData[key].fullName = newTitle | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(doctorsData[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | updateDoctorsDropdown(); | ||
| + | populateDoctorsConfigTable(); | ||
| + | |||
| + | const button = document.getElementById(' | ||
| + | if (button) { | ||
| + | button.className = ' | ||
| + | button.innerHTML = ' | ||
| + | setTimeout(() => { | ||
| + | button.className = 'button'; | ||
| + | button.innerHTML = ' | ||
| + | }, 3000); | ||
| } | } | ||
| - | if (data.electrolyteAdditions.sodium_acetate | + | } |
| - | | + | |
| + | function updateNursesConfig() { | ||
| + | let changesCount = 0; | ||
| + | |||
| + | Object.keys(nursesData).forEach(key => { | ||
| + | | ||
| + | |||
| + | const nameEl = document.getElementById('nurse_' | ||
| + | if (nameEl) { | ||
| + | const newName | ||
| + | const newSurname = document.getElementById(' | ||
| + | const newTitle = document.getElementById(' | ||
| + | |||
| + | nursesData[key].name = newName; | ||
| + | nursesData[key].surname = newSurname; | ||
| + | nursesData[key].title = newTitle; | ||
| + | nursesData[key].fullName = newTitle | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(nursesData[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | populateNursesConfigTable(); | ||
| + | |||
| + | const button = document.getElementById(' | ||
| + | if (button) { | ||
| + | button.className = ' | ||
| + | button.innerHTML = ' | ||
| + | setTimeout(() => { | ||
| + | button.className = 'button'; | ||
| + | button.innerHTML = ' | ||
| + | }, 3000); | ||
| } | } | ||
| - | if (data.electrolyteAdditions.kcl > 0) { | + | } |
| - | | + | |
| - | } | + | function updatePharmacistsConfig() { |
| - | if (data.electrolyteAdditions.mg_sulfate > 0) { | + | let changesCount = 0; |
| - | html += '< | + | |
| - | } | + | Object.keys(pharmacistsData).forEach(key => { |
| - | | + | |
| - | | + | |
| + | const nameEl = document.getElementById(' | ||
| + | if (nameEl) { | ||
| + | const newName = nameEl.value.trim(); | ||
| + | const newSurname = document.getElementById('pharmacist_' + key + ' | ||
| + | const newTitle = document.getElementById(' | ||
| + | |||
| + | | ||
| + | pharmacistsData[key].surname = newSurname; | ||
| + | | ||
| + | pharmacistsData[key].fullName = newTitle + ' | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(pharmacistsData[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | | ||
| + | populatePharmacistsConfigTable(); | ||
| + | |||
| + | const button = document.getElementById(' | ||
| + | if (button) { | ||
| + | | ||
| + | button.innerHTML = ' | ||
| + | setTimeout(() => { | ||
| + | button.className = 'button'; | ||
| + | button.innerHTML = ' | ||
| + | }, 3000); | ||
| } | } | ||
| + | } | ||
| + | |||
| + | function updateTechniciansConfig() { | ||
| + | let changesCount = 0; | ||
| | | ||
| - | | + | |
| + | const oldValues | ||
| + | |||
| + | const nameEl = document.getElementById(' | ||
| + | if (nameEl) { | ||
| + | const newName = nameEl.value.trim(); | ||
| + | const newSurname = document.getElementById('technician_' + key + ' | ||
| + | const newTitle = document.getElementById(' | ||
| + | |||
| + | technicianData[key].name = newName; | ||
| + | technicianData[key].surname = newSurname; | ||
| + | technicianData[key].title = newTitle; | ||
| + | technicianData[key].fullName = newTitle | ||
| + | |||
| + | if (JSON.stringify(oldValues) !== JSON.stringify(technicianData[key])) { | ||
| + | changesCount++; | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | | + | |
| + | const button = document.getElementById(' | ||
| + | if (button) { | ||
| + | | ||
| + | button.innerHTML = ' | ||
| + | setTimeout(() => { | ||
| + | button.className = 'button'; | ||
| + | button.innerHTML = ' | ||
| + | }, 3000); | ||
| } | } | ||
| - | if (data.residualNeeds.peditrace > 0) { | + | } |
| - | const peditraceVolume | + | |
| - | html += '< | + | function updateSystemConfig() { |
| - | } | + | const button |
| - | if (data.residualNeeds.soluvit > 0) { | + | if (button) { |
| - | | + | |
| - | html += '< | + | button.innerHTML = 'PARAMETRI SALVATI ✓'; |
| - | } | + | setTimeout(() => { |
| - | if (data.residualNeeds.vitalipid > 0) { | + | |
| - | const vitalipidVolume = data.residualNeeds.vitalipid * data.currentWeightKg; | + | button.innerHTML = 'Aggiorna Parametri Sistema'; |
| - | html += '< | + | }, 3000); |
| } | } | ||
| | | ||
| - | | + | |
| + | } | ||
| + | |||
| + | // FUNZIONI CONFIGURAZIONE CLINICA AVANZATA (NUOVE) | ||
| + | function updateClinicalConfig() { | ||
| + | clinicalConfig.calciumReq | ||
| + | clinicalConfig.phosphorusReq = parseFloat(document.getElementById(' | ||
| + | clinicalConfig.magnesiumReq = parseFloat(document.getElementById('magnesiumReq').value); | ||
| + | clinicalConfig.maxGIR = parseFloat(document.getElementById(' | ||
| + | clinicalConfig.maxLipids = parseFloat(document.getElementById(' | ||
| + | clinicalConfig.maxProtein = parseFloat(document.getElementById('maxProtein').value); | ||
| | | ||
| - | | + | |
| - | html += '<tr class=" | + | '• Calcio standard: |
| - | html += '< | + | '• Fosforo standard: ' + clinicalConfig.phosphorusReq |
| - | html += '< | + | '• GIR massimo: |
| - | | + | |
| - | | + | } |
| - | | + | |
| + | function resetConfiguration() { | ||
| + | // Reset configurazione clinica | ||
| + | document.getElementById('calciumReq').value = 160; | ||
| + | document.getElementById('phosphorusReq' | ||
| + | | ||
| + | document.getElementById('maxGIR').value = 12.0; | ||
| + | | ||
| + | document.getElementById('maxProtein').value = 4.5; | ||
| | | ||
| - | | + | |
| - | | + | document.getElementById(' |
| - | | + | document.getElementById('hospitalName' |
| + | | ||
| + | | ||
| | | ||
| - | | + | // Reset configurazione clinica globale |
| + | clinicalConfig = { | ||
| + | calciumReq: 160, | ||
| + | phosphorusReq: | ||
| + | magnesiumReq: | ||
| + | maxGIR: 12.0, | ||
| + | maxLipids: 3.0, | ||
| + | maxProtein: 4.5, | ||
| + | hospitalName: | ||
| + | departmentName: | ||
| + | directorName: | ||
| + | }; | ||
| | | ||
| - | | + | |
| } | } | ||
| - | function | + | function |
| - | const data = window.nptCalculationData; | + | const config |
| - | | + | deflectorVolume: document.getElementById(' |
| - | const totalVolumeWithDeflector = data.totalVolume + deflectorVolume; | + | hospitalName: |
| - | const ratio = totalVolumeWithDeflector / data.totalVolume; | + | |
| + | | ||
| + | autoSave: document.getElementById(' | ||
| + | decimalPlaces: | ||
| + | clinicalConfig: | ||
| + | doctorsData: | ||
| + | nursesData: nursesData, | ||
| + | pharmacistsData: | ||
| + | technicianData: | ||
| + | }; | ||
| | | ||
| - | | + | |
| - | | + | clinicalConfig.hospitalName |
| + | | ||
| + | clinicalConfig.directorName | ||
| | | ||
| - | | + | // Simula salvataggio configurazione |
| - | | + | |
| - | new Date(new Date(patientData.prescriptionDate).getTime() - (patientData.daysOfLife * 24 * 60 * 60 * 1000)).toLocaleDateString('it-IT') : | + | alert(' |
| - | 'N/A'; | + | ' |
| - | | + | '• ' + Object.keys(doctorsData).length + ' medici\n' |
| - | | + | '• ' + Object.keys(nursesData).length + ' infermiere\n' |
| + | '• ' + Object.keys(pharmacistsData).length + ' | ||
| + | '• ' | ||
| + | } | ||
| + | |||
| + | function generatePrescription() { | ||
| + | | ||
| + | | ||
| + | return; | ||
| + | } | ||
| | | ||
| - | const infusionRate | + | const currentDate |
| - | const finalConcentration | + | const currentTime |
| - | const estimatedOsmolarity | + | const prescriptionPatientWeightKg = patientData.currentWeight |
| + | const calc = window.nptCalculation; | ||
| | | ||
| - | let html = '< | + | |
| + | alert(' | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | const birthDate = new Date(); | ||
| + | birthDate.setDate(birthDate.getDate() - patientData.daysOfLife); | ||
| + | |||
| + | // Genera ID prescrizione univoco (una sola volta per sessione) | ||
| + | if (!window.currentPrescriptionID) { | ||
| + | window.currentPrescriptionID = generatePreparationID(); | ||
| + | } | ||
| + | const prescriptionID = window.currentPrescriptionID; | ||
| + | |||
| + | // Recupera il medico attualmente selezionato | ||
| + | const currentPrescribingDoctor = document.getElementById(' | ||
| + | const doctorName = currentPrescribingDoctor && doctorsData[currentPrescribingDoctor] ? | ||
| + | doctorsData[currentPrescribingDoctor].fullName : | ||
| + | (patientData.prescribingDoctorName || 'Non specificato' | ||
| + | |||
| + | | ||
| + | |||
| + | // INTESTAZIONE MEDICA (già OK secondo le tue indicazioni) | ||
| + | html += '< | ||
| | | ||
| - | // INTESTAZIONE | + | // PARTE SINISTRA |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '<h2 style=" |
| - | html += '<div style=" | + | html += '<h3 style=" |
| - | html += '<div style=" | + | html += '<p style=" |
| html += '</ | html += '</ | ||
| - | html += '< | + | |
| + | // PARTE DESTRA - LOGO ASST | ||
| + | | ||
| + | html += '< | ||
| html += '</ | html += '</ | ||
| | | ||
| - | html += '< | + | html += '</ |
| - | html += '< | + | |
| | | ||
| - | // INFO PAZIENTE | + | // TITOLO DOCUMENTO |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '<h2 style="font-size: 18px; font-weight: bold; color: #2c3e50; margin: 10px 0;">CALCOLO NUTRIZIONALE PARENTERALE |
| - | html += '< | + | html += '<h3 style="font-size: 16px; color: #2c3e50; margin: 10px 0;">REPORT PARENTERALE</h3>'; |
| - | html += '<tr>< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '<tr>< | + | |
| - | html += '< | + | |
| - | html += '</table>'; | + | |
| html += '</ | html += '</ | ||
| | | ||
| - | // LISTA APPORTI ENTERALI | + | // INFO PAZIENTE (con cartella clinica e ID prescrizione) |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | | + | html += '< |
| - | const formulaName = document.getElementById(' | + | html += '< |
| - | const formulaDisplayName = formulaData[formulaName]? | + | html += '< |
| - | | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | if (prescriptionID) { |
| - | html += '</table>'; | + | html += '< |
| - | } else { | + | |
| - | html += '<table class=" | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| } | } | ||
| + | | ||
| + | | ||
| + | html += '< | ||
| + | html += '< | ||
| + | | ||
| + | if (patientData.gestationalWeeks && patientData.gestationalWeeks > 0) { | ||
| + | const gestDays = patientData.gestationalDays || 0; | ||
| + | html += '< | ||
| + | if (patientData.postConceptionalAge && patientData.postConceptionalAge.format) { | ||
| + | html += '< | ||
| + | } | ||
| + | } | ||
| + | html += '< | ||
| + | html += '</ | ||
| html += '</ | html += '</ | ||
| | | ||
| - | // COMPOSIZIONE PARENTERALE | + | // LISTA DEGLI APPORTI PER LA GIORNATA CORRENTE |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| | | ||
| - | // Componenti con ordine identico al foglio di lavoro | + | // Apporti enterali |
| - | if (data.waterVolume | + | if (enteralData && enteralData.volume |
| - | html += '< | + | const formulaType = document.getElementById(' |
| + | const formulaName = formulaData[formulaType] ? formulaData[formulaType].name : ' | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.glucose50Volume | + | |
| - | html += '< | + | // Altri liquidi |
| + | | ||
| + | const fluidType = document.getElementById(' | ||
| + | let fluidName = 'Altri liquidi'; | ||
| + | switch(fluidType) { | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | } | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.electrolyteAdditions.ca_gluconato > 0) { | + | |
| - | html += '< | + | // Se nessun apporto enterale |
| + | | ||
| + | html += '< | ||
| } | } | ||
| - | | + | |
| - | html += '< | + | html += '</ |
| + | html += '</ | ||
| + | |||
| + | // COMPOSIZIONE PARENTERALE | ||
| + | const deflectorVolume = parseInt(document.getElementById(' | ||
| + | const totalVolumeWithDeflector = calc.totalVolume + deflectorVolume; | ||
| + | const ratio = totalVolumeWithDeflector / calc.totalVolume; | ||
| + | |||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | | ||
| + | |||
| + | // Componenti nell' | ||
| + | html += '< | ||
| + | |||
| + | if (calc.neededGlucose > 0) { | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.electrolyteAdditions.kcl > 0) { | + | |
| - | html += '< | + | |
| + | html += '< | ||
| } | } | ||
| - | if (data.electrolyteAdditions.mg_sulfate | + | |
| - | html += '<tr>< | + | html += '< |
| + | | ||
| + | html += '<td style=" | ||
| + | } else if (calc.electrolyteAdditions.sodium_acetate > 0) { | ||
| + | html += '< | ||
| + | } else { | ||
| + | html += '</ | ||
| } | } | ||
| - | if (data.carnitineVolume | + | |
| - | html += '< | + | |
| + | html += '< | ||
| } | } | ||
| - | if (data.proteinVolume | + | |
| - | html += '< | + | |
| + | html += '< | ||
| } | } | ||
| - | if (data.electrolyteAdditions.esafosfina | + | |
| - | html += '<tr>< | + | html += '< |
| + | | ||
| + | const carnitineVolume = (window.residualNeeds.carnitine * prescriptionPatientWeightKg) / 100; | ||
| + | html += '< | ||
| + | } else { | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.residualNeeds.peditrace | + | |
| - | const peditraceVolume = data.residualNeeds.peditrace * data.currentWeightKg; | + | html += '< |
| - | html += '< | + | |
| + | | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.residualNeeds.soluvit | + | |
| - | const soluvitVolume | + | |
| - | html += '< | + | const peditraceVolume |
| + | html += '< | ||
| + | } else { | ||
| + | html += '< | ||
| } | } | ||
| - | if (data.residualNeeds.vitalipid | + | |
| - | const vitalipidVolume | + | |
| - | html += '< | + | const soluvitVolume |
| + | html += '< | ||
| + | } else { | ||
| + | html += '< | ||
| } | } | ||
| - | // Gestione valore negativo per Intralipid | ||
| - | const displayLipidVolume = data.lipidVolume < 0 ? 0 : data.lipidVolume; | ||
| - | html += '< | ||
| | | ||
| - | | + | |
| - | html += '< | + | const vitalipidVolume = window.residualNeeds.vitalipid * prescriptionPatientWeightKg; |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| + | } | ||
| + | |||
| + | html += '<tr>< | ||
| + | |||
| + | // TOTALI | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '<tr>< | ||
| html += '</ | html += '</ | ||
| html += '</ | html += '</ | ||
| | | ||
| // TOTALE ELEMENTI PRO KILO | // TOTALE ELEMENTI PRO KILO | ||
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| | | ||
| - | // Calcoli degli elementi | + | // Calcola valori |
| - | const totalLiquids | + | const totalLiquidsPerKg = window.residualNeeds.liquids; |
| - | const totalLiquidsPerKg | + | const totalProteinPerKg |
| + | const totalLipidsPerKg | ||
| + | const totalCarbsPerKg = (enteralData ? enteralData.carbs : 0) + window.residualNeeds.carbs; | ||
| + | const totalCalciumPerKg = (enteralData ? enteralData.calcium : 0) + window.residualNeeds.calcium; | ||
| + | const totalPhosphorusPerKg = (enteralData ? enteralData.phosphorus : 0) + window.residualNeeds.phosphorus; | ||
| + | const totalSodiumPerKg = (enteralData ? enteralData.sodium : 0) + window.residualNeeds.sodium; | ||
| + | const totalPotassiumPerKg = (enteralData ? enteralData.potassium : 0) + window.residualNeeds.potassium; | ||
| + | const totalMagnesiumPerKg = (enteralData ? enteralData.magnesium : 0) + window.residualNeeds.magnesium; | ||
| + | const totalCarnitinePerKg = window.residualNeeds.carnitine; | ||
| + | const totalOligoelementsPerKg = window.residualNeeds.peditrace; | ||
| + | const totalVitLiposolubiliPerKg = window.residualNeeds.vitalipid; | ||
| + | const totalVitIdrosolubiliPerKg = window.residualNeeds.soluvit; | ||
| | | ||
| - | | + | // Energia totale e non proteiche |
| - | const totalLipids | + | const totalEnergyPerKg |
| - | const totalCarbs | + | const nonProteinEnergyPerKg |
| - | const totalCalcium = (enteralData ? enteralData.calcium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.calcium * data.currentWeightKg / 1000); | + | |
| - | const totalPhosphorus = (enteralData ? enteralData.phosphorus * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.phosphorus * data.currentWeightKg / 1000); | + | |
| - | const totalSodium = (enteralData ? enteralData.sodium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.sodium * data.currentWeightKg / 1000); | + | |
| - | const totalPotassium = (enteralData ? enteralData.potassium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.potassium * data.currentWeightKg / 1000); | + | |
| - | const totalMagnesium = (enteralData ? enteralData.magnesium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.magnesium * data.currentWeightKg / 1000); | + | |
| - | const totalCarnitine = data.residualNeeds.carnitine * data.currentWeightKg / 1000; | + | |
| | | ||
| - | | + | html += '< |
| - | const totalNonProteinEnergy = totalEnergy - (totalProtein * 4); | + | html += '< |
| - | const glucoseMgKgMin = ((totalCarbs * 1000) / 1440).toFixed(3); | + | html += '< |
| - | + | html += '< | |
| - | | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | html += '< |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| html += '</ | html += '</ | ||
| html += '</ | html += '</ | ||
| | | ||
| - | html += '< | ||
| - | html += 'NPT Calculator v2.0 - Report Parenterale generato il ' + new Date().toLocaleString(' | ||
| html += '</ | html += '</ | ||
| | | ||
| - | | + | |
| - | + | ||
| - | return | + | |
| } | } | ||
| - | function | + | function |
| - | | + | |
| - | document.getElementById(' | + | |
| - | | + | return; |
| + | } | ||
| | | ||
| - | const reportTitle | + | const currentDate |
| - | ' | + | const calc = window.nptCalculation; |
| | | ||
| - | | + | |
| + | alert('Prima calcolare la NPT nel TAB 4'); | ||
| + | return; | ||
| + | } | ||
| | | ||
| - | | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | body { margin: 0; padding: 15px; font-family: | + | |
| - | | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | ${reportContent} | + | |
| - | </ | + | |
| - | </ | + | |
| - | `); | + | |
| | | ||
| - | printWindow.document.close(); | + | // Recupera il medico attualmente selezionato |
| - | printWindow.print(); | + | const currentPrescribingDoctor |
| - | } | + | const doctorName |
| - | + | | |
| - | function updateSystemConfig() { | + | (patientData.prescribingDoctorName || 'Medico non specificato'); |
| - | | + | |
| - | | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | | + | // Usa lo stesso ID prescrizione della sessione |
| - | | + | if (!window.currentPrescriptionID) { |
| - | }, 3000); | + | window.currentPrescriptionID = generatePreparationID(); |
| + | } | ||
| + | const worksheetPreparationID | ||
| + | |||
| + | let html = '< | ||
| + | |||
| + | // INTESTAZIONE ASST LECCO | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | // TITOLO E DATA | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | html += '< | ||
| + | |||
| + | // INFO PAZIENTE | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | if (worksheetPreparationID) | ||
| + | html += '< | ||
| + | } | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | | ||
| + | if (patientData.gestationalWeeks && patientData.gestationalWeeks > 0) { | ||
| + | const gestDays = patientData.gestationalDays || 0; | ||
| + | html += '< | ||
| + | if (patientData.postConceptionalAge && patientData.postConceptionalAge.format) { | ||
| + | html += '< | ||
| + | } | ||
| + | } | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | // COMPOSIZIONE PARENTERALE - FORMATO FOGLIO DI LAVORO | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | // Ordine esatto come nel PDF del foglio di lavoro | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | html += '</ | ||
| + | |||
| + | document.getElementById(' | ||
| } | } | ||
| - | // FUNZIONE SALVATAGGIO PDF | + | function |
| - | async function | + | if (!window.residualNeeds |
| - | if (!window.currentActiveReport | + | alert(' |
| - | alert(' | + | |
| return; | return; | ||
| } | } | ||
| | | ||
| - | | + | const currentDate |
| - | // Mostra messaggio di caricamento | + | const currentTime |
| - | | + | const calc = window.nptCalculation; |
| - | const originalText = savePdfBtn.innerHTML; | + | |
| - | savePdfBtn.innerHTML = '⏳ Generando PDF...'; | + | |
| - | savePdfBtn.disabled = true; | + | alert(' |
| - | + | | |
| - | // Seleziona il report attivo | + | |
| - | const reportElement = window.currentActiveReport === ' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | + | ||
| - | const reportTitle = window.currentActiveReport === ' | + | |
| - | ' | + | |
| - | + | ||
| - | // Genera il nome file con data e cartella | + | |
| - | const today = new Date(); | + | |
| - | const dateStr = today.toISOString().split('T' | + | |
| - | const medicalRecord = patientData.medicalRecord || ' | + | |
| - | const fileName = `NPT_${reportTitle}_${medicalRecord}_${dateStr}.pdf`; | + | |
| - | + | ||
| - | // Configurazione html2canvas per qualità migliore | + | |
| - | const canvas = await html2canvas(reportElement, | + | |
| - | scale: 2, // Migliore qualità | + | |
| - | useCORS: true, | + | |
| - | backgroundColor: | + | |
| - | width: reportElement.offsetWidth, | + | |
| - | height: reportElement.offsetHeight, | + | |
| - | scrollX: 0, | + | |
| - | scrollY: 0 | + | |
| - | }); | + | |
| - | + | ||
| - | // Crea PDF con dimensioni A4 | + | |
| - | const { jsPDF } = window.jspdf; | + | |
| - | | + | |
| - | orientation: | + | |
| - | unit: ' | + | |
| - | format: ' | + | |
| - | }); | + | |
| - | + | ||
| - | // Calcola dimensioni per adattare alla pagina A4 | + | |
| - | const imgWidth = 210; // A4 width in mm | + | |
| - | const pageHeight = 297; // A4 height in mm | + | |
| - | const imgHeight = (canvas.height * imgWidth) / canvas.width; | + | |
| - | + | ||
| - | let heightLeft = imgHeight; | + | |
| - | let position = 0; | + | |
| - | + | ||
| - | // Aggiungi l' | + | |
| - | pdf.addImage(canvas.toDataURL('image/ | + | |
| - | heightLeft | + | |
| - | + | ||
| - | // Se il contenuto è più lungo di una pagina, aggiungi pagine | + | |
| - | while (heightLeft >= 0) { | + | |
| - | position = heightLeft - imgHeight; | + | |
| - | pdf.addPage(); | + | |
| - | pdf.addImage(canvas.toDataURL('image/ | + | |
| - | heightLeft -= pageHeight; | + | |
| - | } | + | |
| - | + | ||
| - | // Aggiungi metadati al PDF | + | |
| - | pdf.setProperties({ | + | |
| - | title: `NPT Calculator | + | |
| - | subject: ' | + | |
| - | author: 'NPT Calculator v2.0', | + | |
| - | keywords: 'NPT, Nutrizione Parenterale, | + | |
| - | creator: 'NPT Calculator v2.0' | + | |
| - | | + | |
| - | + | ||
| - | // Salva il PDF | + | |
| - | pdf.save(fileName); | + | |
| - | + | ||
| - | // Ripristina il pulsante | + | |
| - | savePdfBtn.innerHTML = '✅ PDF Salvato!'; | + | |
| - | savePdfBtn.style.backgroundColor = '# | + | |
| - | + | ||
| - | setTimeout(() => { | + | |
| - | savePdfBtn.innerHTML = originalText; | + | |
| - | savePdfBtn.style.backgroundColor = '# | + | |
| - | savePdfBtn.disabled = false; | + | |
| - | }, 3000); | + | |
| - | + | ||
| - | // Mostra messaggio di conferma | + | |
| - | | + | |
| - | | + | |
| - | < | + | |
| - | padding: 15px 20px; border-radius: | + | |
| - | < | + | |
| - | File: ${fileName}< | + | |
| - | < | + | |
| - | </ | + | |
| - | `; | + | |
| - | document.body.appendChild(confirmationMsg); | + | |
| - | + | ||
| - | setTimeout(() => { | + | |
| - | document.body.removeChild(confirmationMsg); | + | |
| - | }, 5000); | + | |
| - | + | ||
| - | } catch (error) { | + | |
| - | console.error(' | + | |
| - | alert(' | + | |
| - | | + | |
| - | // Ripristina il pulsante in caso di errore | + | |
| - | const savePdfBtn = document.getElementById(' | + | |
| - | savePdfBtn.innerHTML = '💾 Salva PDF'; | + | |
| - | savePdfBtn.disabled = false; | + | |
| } | } | ||
| - | } | + | |
| + | const birthDate = new Date(); | ||
| + | birthDate.setDate(birthDate.getDate() - patientData.daysOfLife); | ||
| + | |||
| + | // Recupera il medico attualmente selezionato | ||
| + | const currentPrescribingDoctor = document.getElementById(' | ||
| + | const doctorName = currentPrescribingDoctor && doctorsData[currentPrescribingDoctor] ? | ||
| + | doctorsData[currentPrescribingDoctor].fullName : | ||
| + | (patientData.prescribingDoctorName || ' | ||
| + | |||
| + | // Usa lo stesso ID prescrizione della sessione | ||
| + | if (!window.currentPrescriptionID) { | ||
| + | window.currentPrescriptionID = generatePreparationID(); | ||
| + | | ||
| + | const labelPreparationID = window.currentPrescriptionID; | ||
| + | |||
| + | let html = '< | ||
| + | |||
| + | // INTESTAZIONE COMPATTA PER ETICHETTA | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | |||
| + | |||
| + | // SEZIONE IDENTIFICAZIONE PAZIENTE - GRANDE E VISIBILE | ||
| + | html += '< | ||
| + | html += '< | ||
| - | </script> | + | |
| - | </body> | + | if (patientData.medicalRecord && patientData.medicalRecord.trim() |
| - | </ | + | html += '<div style="margin: 15px 0; padding: 10px; background-color: white; border: 2px solid #d32f2f; border-radius: |
| - | <html lang=" | + | html += '<canvas id="barcodeCanvas" |
| - | <head> | + | html += '<div style="font-size: 12px; color: #666; margin-top: 5px;"> |
| - | <meta charset="UTF-8"> | + | |
| - | <meta name="viewport" | + | |
| - | < | + | |
| - | <style> | + | |
| - | body { | + | |
| - | | + | |
| - | margin: 0; | + | |
| - | padding: 20px; | + | |
| - | background-color: #f5f5f5; | + | |
| - | } | + | |
| - | .container { | + | html += '< |
| - | max-width: | + | html += '< |
| - | margin: 0 auto; | + | |
| - | background: white; | + | |
| - | padding: | + | |
| - | border-radius: 10px; | + | |
| - | box-shadow: 0 2px 10px rgba(0,0,0,0.1); | + | |
| - | } | + | |
| - | h1 { | + | if (labelPreparationID) |
| - | text-align: | + | html += '< |
| - | color: #2c3e50; | + | } |
| - | border-bottom: 3px solid #3498db; | + | |
| - | | + | |
| - | } | + | |
| - | .section { | + | html += '< |
| - | margin: 20px 0; | + | html += '< |
| - | | + | |
| - | border: 1px solid #ddd; | + | |
| - | | + | |
| - | background-color: #f9f9f9; | + | |
| - | } | + | |
| - | | + | if (patientData.gestationalWeeks && patientData.gestationalWeeks > 0) { |
| - | | + | const gestDays = patientData.gestationalDays || 0; |
| - | | + | html += '< |
| - | border-bottom: 2px solid #3498db; | + | if (patientData.postConceptionalAge && patientData.postConceptionalAge.format) { |
| - | padding-bottom: 5px; | + | |
| } | } | ||
| + | } | ||
| - | | + | html += '< |
| - | margin: 10px 0; | + | html += '</ |
| - | | + | html += '</ |
| - | align-items: center; | + | |
| + | // SEZIONE PRESCRIZIONE | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | // SEZIONE CONTENUTO SACCA - COMPATTA | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | // Solo componenti principali per l' | ||
| + | if (calc.neededGlucose > 0) { | ||
| + | html += '< | ||
| + | } | ||
| + | html += '< | ||
| + | html += '< | ||
| + | html += '< | ||
| + | |||
| + | // Elettroliti principali | ||
| + | if (calc.electrolyteAdditions.ca_gluconato > 0) { | ||
| + | html += '< | ||
| + | } | ||
| + | if (calc.electrolyteAdditions.esafosfina > 0) { | ||
| + | html += '< | ||
| + | } | ||
| + | |||
| + | html += '< | ||
| + | html += '</ | ||
| + | html += '</ | ||
| + | |||
| + | html += '</ | ||
| + | |||
| + | document.getElementById(' | ||
| + | // Genera il codice a barre se presente la cartella clinica | ||
| + | if (patientData.medicalRecord && patientData.medicalRecord.trim() !== '' | ||
| + | setTimeout(() => { | ||
| + | const canvas = document.getElementById(' | ||
| + | if (canvas && window.SimpleBarcode) { | ||
| + | try { | ||
| + | window.SimpleBarcode.generate(canvas, | ||
| + | width: 2, | ||
| + | height: 60, | ||
| + | margin: 5, | ||
| + | background: "# | ||
| + | lineColor: "# | ||
| + | }); | ||
| + | console.log(' | ||
| + | } catch (error) { | ||
| + | console.error(' | ||
| + | // Fallback: mostra solo il testo | ||
| + | const ctx = canvas.getContext(' | ||
| + | ctx.fillStyle = '# | ||
| + | ctx.font = '14px monospace'; | ||
| + | ctx.textAlign = ' | ||
| + | ctx.fillText(patientData.medicalRecord, | ||
| + | } | ||
| + | } else { | ||
| + | console.error(' | ||
| } | } | ||
| + | }, 100); | ||
| + | } | ||
| - | .input-group label { | ||
| - | display: inline-block; | ||
| - | width: 220px; | ||
| - | font-weight: | ||
| - | color: #2c3e50; | ||
| - | } | ||
| - | | + | // Genera il codice a barre se presente la cartella clinica |
| - | padding: 8px; | + | if (patientData.medicalRecord && patientData.medicalRecord.trim() !== '' |
| - | border: 1px solid #ddd; | + | |
| - | border-radius: | + | |
| - | width: 150px; | + | |
| - | font-size: 14px; | + | |
| - | } | + | |
| - | + | | |
| - | | + | |
| - | | + | width: |
| - | border-color: | + | height: |
| - | box-shadow: 0 0 5px rgba(52, 152, 219, 0.3); | + | margin: |
| - | } | + | background: |
| - | + | | |
| - | .button | + | }); |
| - | background-color: | + | |
| - | color: white; | + | } catch (error) |
| - | padding: 12px 24px; | + | |
| - | border: none; | + | |
| - | border-radius: | + | |
| - | cursor: pointer; | + | |
| - | font-size: 16px; | + | |
| - | margin: 10px 5px; | + | |
| - | transition: background-color 0.3s; | + | |
| - | } | + | |
| - | + | ||
| - | .button: | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .button.secondary { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .button.secondary: | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .results { | + | |
| - | margin-top: 20px; | + | |
| - | padding: 15px; | + | |
| - | background-color: | + | |
| - | border-left: | + | |
| - | border-radius: | + | |
| - | } | + | |
| - | + | ||
| - | .results h3 { | + | |
| - | color: #27ae60; | + | |
| - | margin-top: 0; | + | |
| - | } | + | |
| - | + | ||
| - | .results-table { | + | |
| - | width: 100%; | + | |
| - | border-collapse: | + | |
| - | margin: 10px 0; | + | |
| - | } | + | |
| - | + | ||
| - | .results-table th, .results-table td { | + | |
| - | border: 1px solid #ddd; | + | |
| - | padding: 8px; | + | |
| - | text-align: left; | + | |
| - | } | + | |
| - | + | ||
| - | .results-table th { | + | |
| - | background-color: | + | |
| - | color: white; | + | |
| - | } | + | |
| - | + | ||
| - | .results-table tr: | + | |
| - | background-color: | + | |
| - | | + | |
| - | + | ||
| - | | + | |
| - | | + | |
| - | color: #856404; | + | |
| - | padding: 15px; | + | |
| - | border-radius: | + | |
| - | border-left: | + | |
| - | margin: 10px 0; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .error | + | |
| - | | + | |
| - | color: #721c24; | + | |
| - | padding: 10px; | + | |
| - | border-radius: | + | |
| - | border-left: | + | |
| - | margin: 10px 0; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | background-color: | + | |
| - | color: #0c5460; | + | |
| - | padding: 10px; | + | |
| - | border-radius: | + | |
| - | border-left: | + | |
| - | margin: 10px 0; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | border-radius: | + | |
| - | font-size: 12px; | + | |
| - | font-weight: | + | |
| - | margin-left: | + | |
| - | } | + | |
| - | + | ||
| - | .phase-transizione { | + | |
| - | background-color: | + | |
| - | color: #856404; | + | |
| - | } | + | |
| - | + | ||
| - | .phase-stabilizzazione { | + | |
| - | background-color: | + | |
| - | color: #0c5460; | + | |
| - | } | + | |
| - | + | ||
| - | .phase-crescita { | + | |
| - | background-color: | + | |
| - | color: #155724; | + | |
| - | } | + | |
| - | + | ||
| - | .nutrition-table { | + | |
| - | width: 100%; | + | |
| - | border-collapse: | + | |
| - | margin: 15px 0; | + | |
| - | font-size: 13px; | + | |
| - | } | + | |
| - | + | ||
| - | .nutrition-table th, .nutrition-table td { | + | |
| - | | + | |
| - | padding: 8px; | + | |
| - | text-align: center; | + | |
| - | } | + | |
| - | + | ||
| - | .nutrition-table th { | + | |
| - | background-color: | + | |
| - | color: white; | + | |
| - | } | + | |
| - | + | ||
| - | .day-column { | + | |
| - | background-color: | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .day-column.energy-highlight { | + | |
| - | background-color: | + | |
| - | color: white !important; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .hidden { | + | |
| - | display: none !important; | + | |
| - | } | + | |
| - | + | ||
| - | .visible { | + | |
| - | display: block !important; | + | |
| - | } | + | |
| - | + | ||
| - | /* CSS TAB ORIZZONTALI */ | + | |
| - | .tabs { | + | |
| - | display: flex; | + | |
| - | margin-bottom: | + | |
| - | border-bottom: | + | |
| - | gap: 5px; | + | |
| - | } | + | |
| - | + | ||
| - | .tab { | + | |
| - | padding: 10px 20px; | + | |
| - | background-color: | + | |
| - | border: 1px solid #ddd; | + | |
| - | border-bottom: | + | |
| - | cursor: pointer; | + | |
| - | border-radius: | + | |
| - | transition: all 0.3s ease; | + | |
| - | text-align: center; | + | |
| - | min-width: | + | |
| - | flex: 1; | + | |
| - | max-width: 200px; | + | |
| - | } | + | |
| - | + | ||
| - | .tab:hover { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .tab.active { | + | |
| - | background-color: | + | |
| - | color: white; | + | |
| - | border-color: | + | |
| - | border-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | .tab-content { | + | |
| - | display: none; | + | |
| - | } | + | |
| - | + | ||
| - | .tab-content.active { | + | |
| - | display: block; | + | |
| - | } | + | |
| - | + | ||
| - | .form-row { | + | |
| - | display: flex; | + | |
| - | flex-wrap: wrap; | + | |
| - | gap: 20px; | + | |
| - | margin: 15px 0; | + | |
| - | } | + | |
| - | + | ||
| - | .form-col { | + | |
| - | flex: 1; | + | |
| - | min-width: 300px; | + | |
| - | } | + | |
| - | + | ||
| - | .highlight { | + | |
| - | background-color: | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .energy-highlight { | + | |
| - | background-color: | + | |
| - | color: white !important; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .load-defaults-pending { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .load-defaults-completed { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .calculate-nutrition-pending { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .calculate-nutrition-completed { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .calculate-phase-pending { | + | |
| - | background-color: | + | |
| - | } | + | |
| - | + | ||
| - | .config-update-pending { | + | |
| - | background-color: | + | |
| - | color: white !important; | + | |
| - | } | + | |
| - | + | ||
| - | .config-update-completed { | + | |
| - | background-color: | + | |
| - | color: white !important; | + | |
| - | } | + | |
| - | + | ||
| - | /* STILI PER IL REPORT NPT */ | + | |
| - | .npt-report { | + | |
| - | background: white; | + | |
| - | padding: 20px; | + | |
| - | font-family: | + | |
| - | | + | |
| - | line-height: | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | } | + | |
| - | + | ||
| - | .report-header { | + | |
| - | display: flex; | + | |
| - | justify-content: | + | |
| - | align-items: | + | |
| - | border-bottom: | + | |
| - | padding-bottom: | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | .report-header-left { | + | |
| - | flex: 1; | + | |
| - | } | + | |
| - | + | ||
| - | .report-header-right { | + | |
| - | width: 100px; | + | |
| - | height: 60px; | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | align-items: | + | |
| - | justify-content: | + | |
| - | font-size: 10px; | + | |
| - | color: #666; | + | |
| - | | + | |
| - | + | ||
| - | .report-title { | + | |
| - | font-size: 14px; | + | |
| - | | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | font-size: 11px; | + | |
| - | color: #666; | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | .report-section-title { | + | |
| - | | + | |
| - | color: white; | + | |
| - | padding: 5px 10px; | + | |
| - | font-weight: | + | |
| - | font-size: 12px; | + | |
| - | margin-bottom: | + | |
| - | | + | |
| - | + | ||
| - | .report-table | + | |
| - | | + | |
| - | border-collapse: | + | |
| - | font-size: 11px; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | padding: 3px 8px; | + | |
| - | border-bottom: | + | |
| - | vertical-align: | + | |
| - | } | + | |
| - | + | ||
| - | .report-table .label-col { | + | |
| - | width: 200px; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .report-table .value-col { | + | |
| - | text-align: right; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .composition-table { | + | |
| - | width: 100%; | + | |
| - | border-collapse: | + | |
| - | font-size: 11px; | + | |
| - | margin-top: 0; | + | |
| - | } | + | |
| - | + | ||
| - | .composition-table th { | + | |
| - | background-color: | + | |
| - | padding: 5px 8px; | + | |
| - | text-align: center; | + | |
| - | font-weight: | + | |
| - | border: 1px solid #ddd; | + | |
| - | } | + | |
| - | + | ||
| - | .composition-table td { | + | |
| - | padding: 3px 8px; | + | |
| - | border: 1px solid #ddd; | + | |
| - | text-align: right; | + | |
| - | } | + | |
| - | + | ||
| - | .composition-table .component-name-col { | + | |
| - | text-align: left !important; | + | |
| - | width: 60%; | + | |
| - | } | + | |
| - | + | ||
| - | .composition-total { | + | |
| - | background-color: | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | + | ||
| - | .elements-table { | + | |
| - | width: 100%; | + | |
| - | border-collapse: | + | |
| - | font-size: 11px; | + | |
| - | margin-top: 0; | + | |
| - | } | + | |
| - | + | ||
| - | .elements-table td { | + | |
| - | padding: 3px 8px; | + | |
| - | border-bottom: | + | |
| - | } | + | |
| - | + | ||
| - | .elements-table .element-name { | + | |
| - | width: 200px; | + | |
| - | } | + | |
| - | + | ||
| - | .elements-table .element-value { | + | |
| - | text-align: right; | + | |
| - | font-weight: | + | |
| - | width: 80px; | + | |
| - | } | + | |
| - | + | ||
| - | .elements-table .element-unit { | + | |
| - | text-align: left; | + | |
| - | width: 40px; | + | |
| - | font-size: 10px; | + | |
| - | } | + | |
| - | + | ||
| - | .report-footer { | + | |
| - | margin-top: 30px; | + | |
| - | padding-top: | + | |
| - | border-top: 1px solid #ddd; | + | |
| - | font-size: 10px; | + | |
| - | color: #666; | + | |
| - | text-align: center; | + | |
| - | } | + | |
| - | + | ||
| - | @media print { | + | |
| - | .npt-report { | + | |
| - | | + | |
| - | border: none; | + | |
| - | margin: 0; | + | |
| - | padding: 15px; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | display: none; | + | |
| - | } | + | |
| - | + | ||
| - | | + | |
| - | | + | |
| } | } | ||
| } | } | ||
| - | | + | |
| - | < | + | } |
| - | <script src=" | + | |
| - | </ | + | |
| - | < | + | |
| - | <div class=" | + | } |
| - | < | + | |
| - | + | ||
| - | <!-- TAB ORIZZONTALI --> | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <span style=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <span style=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <span style=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <span style=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <span style=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <!-- TAB 1: DATI PAZIENTE --> | + | // FUNZIONE GENERAZIONE PDF COMPLETA |
| - | <div id=" | + | function generatePDF(type) |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=""> | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | • La data viene impostata automaticamente ad oggi< | + | |
| - | • Selezionare il medico responsabile della prescrizione< | + | |
| - | • Questi dati appariranno nel riepilogo finale | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <button id=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div id=" | + | |
| - | < | + | |
| - | <div id=" | + | |
| - | </ | + | |
| - | | + | |
| - | + | ||
| - | <!-- TAB 2: NUTRIZIONE ENTERALE --> | + | |
| - | <div id=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | • Antibiotici in soluzione< | + | |
| - | • Flebo di mantenimento< | + | |
| - | • Soluzioni elettrolitiche | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div id=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | <span id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <button id=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div id=" | + | |
| - | < | + | |
| - | <div id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- TAB 3: CALCOLO FABBISOGNI --> | + | |
| - | <div id=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <button id=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=""> | + | |
| - | <option value=" | + | |
| - | <option value="> | + | |
| - | </ | + | |
| - | </ | + | |
| - | <button id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <select id=" | + | |
| - | <option value=" | + | |
| - | <option value=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div id=" | + | |
| - | <!-- Popolato dinamicamente --> | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | | + | |
| - | + | ||
| - | <div id=" | + | |
| - | < | + | |
| - | <div id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- TAB 4: NUTRIZIONE PARENTERALE --> | + | |
| - | <div id=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <button id=" | + | |
| - | | + | |
| - | + | ||
| - | <div id=" | + | |
| - | < | + | |
| - | <div id=" | + | |
| - | + | ||
| - | <h3 style=" | + | |
| - | <div id=" | + | |
| - | + | ||
| - | <div style=" | + | |
| - | <h3 style=" | + | |
| - | <p style=" | + | |
| - | <div style=" | + | |
| - | <button id=" | + | |
| - | <button id=" | + | |
| - | <button id=" | + | |
| - | <button id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div id=" | + | |
| - | <div id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- TAB 5: CONFIGURAZIONE --> | + | |
| - | <div id=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <label for=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | • Volume perso nel deflussore durante la preparazione< | + | |
| - | • Viene aggiunto automaticamente alla ricetta di preparazione< | + | |
| - | • Valore standard: 30 ml (modificabile) | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <button id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div style=" | + | |
| - | <table class=" | + | |
| - | < | + | |
| - | < | + | |
| - | <th style=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div style=" | + | |
| - | <table class=" | + | |
| - | < | + | |
| - | < | + | |
| - | <th style=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <th style=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <td>2 mEq/mL - Alcalinizzante per acidosi</ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <td>2 mEq/mL - Max vel. 0.5 mEq/ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div style=" | + | |
| - | <table class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | // DATI NUTRIZIONALI COMPLETI | + | |
| - | const formulaData = { | + | |
| - | maternal: { name: "Latte Materno", | + | |
| - | maternal_fortified: | + | |
| - | nan_supreme: | + | |
| - | humana1: { name: " | + | |
| - | bbmilk_zero: | + | |
| - | bbmilk_pdf: { name: " | + | |
| - | prenan: { name: " | + | |
| - | alfare: { name: " | + | |
| - | infatrini: { name: " | + | |
| - | }; | + | |
| - | + | ||
| - | // CONFIGURAZIONI PARENTERALI COMPLETE | + | |
| - | const parenteralConfig = { | + | |
| - | ca_gluconato: | + | |
| - | name: " | + | |
| - | calcium: 840, phosphorus: 0, magnesium: 0, sodium: 0, potassium: 0, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 90 | + | |
| - | }, | + | |
| - | esafosfina: { | + | |
| - | name: " | + | |
| - | calcium: 0, phosphorus: 1600, magnesium: 0, sodium: 130, potassium: 0, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 98 | + | |
| - | }, | + | |
| - | mg_sulfate: { | + | |
| - | name: " | + | |
| - | calcium: 0, phosphorus: 0, magnesium: 800, sodium: 0, potassium: 0, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 99 | + | |
| - | }, | + | |
| - | nacl: { | + | |
| - | name: "Sodio Cloruro", | + | |
| - | calcium: 0, phosphorus: 0, magnesium: 0, sodium: 1000, potassium: 0, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 99 | + | |
| - | }, | + | |
| - | sodium_acetate: | + | |
| - | name: "Sodio Acetato", | + | |
| - | calcium: 0, phosphorus: 0, magnesium: 0, sodium: 667, potassium: 0, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 99 | + | |
| - | }, | + | |
| - | kcl: { | + | |
| - | name: " | + | |
| - | calcium: 0, phosphorus: 0, magnesium: 0, sodium: 0, potassium: 1000, | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, water: 99 | + | |
| } | } | ||
| - | }; | ||
| - | // Database medici | + | |
| - | const doctorsData = { | + | const doc = new jsPDF(); |
| - | dr_bellu: { name: " | + | |
| - | dr_condo: { name: " | + | |
| - | dr_maccioni: | + | |
| - | dr_meroni: { name: " | + | |
| - | dr_calzatini: | + | |
| - | dr_ferrari: { name: " | + | |
| - | }; | + | |
| - | + | ||
| - | // VARIABILI GLOBALI | + | |
| - | let patientData | + | |
| - | let enteralData = null; | + | |
| - | window.currentActiveReport = null; | + | |
| - | + | ||
| - | // INIZIALIZZAZIONE | + | |
| - | document.addEventListener(' | + | |
| - | // Imposta data odierna | + | |
| - | const today = new Date().toISOString().split(' | + | |
| - | document.getElementById(' | + | |
| - | }); | + | |
| - | + | ||
| - | // FUNZIONE TAB | + | |
| - | function showTab(tabId) { | + | |
| - | // Rimuovi classe active da tutti i contenuti | + | |
| - | document.querySelectorAll(' | + | |
| - | content.classList.remove(' | + | |
| - | }); | + | |
| | | ||
| - | // Rimuovi classe active da tutte le tab | + | // INTESTAZIONE COMUNE |
| - | | + | |
| - | tab.classList.remove(' | + | doc.text(clinicalConfig.departmentName, |
| - | | + | |
| | | ||
| - | // Mostra il contenuto selezionato | + | // Logo ASST (posizionamento approssimativo) |
| - | const targetContent | + | doc.text(clinicalConfig.hospitalName, |
| - | if (targetContent) { | + | |
| - | | + | const currentDate |
| + | doc.text(' | ||
| + | | ||
| + | if (type === ' | ||
| + | | ||
| + | } else if (type === ' | ||
| + | generatePrescriptionPDFContent(doc); | ||
| + | } else if (type === ' | ||
| + | generateLabelPDFContent(doc); | ||
| + | } | ||
| + | |||
| + | // Salva il PDF | ||
| + | let fileName = ''; | ||
| + | switch(type) { | ||
| + | case ' | ||
| + | fileName = ' | ||
| + | break; | ||
| + | case ' | ||
| + | fileName = ' | ||
| + | break; | ||
| + | case ' | ||
| + | fileName = ' | ||
| + | break; | ||
| + | default: | ||
| + | fileName = ' | ||
| } | } | ||
| | | ||
| - | | + | |
| - | event.target.closest(' | + | |
| } | } | ||
| - | + | // CONTENUTO PDF PRESCRIZIONE MEDICA | |
| - | // FUNZIONE CALCOLO FASE | + | function |
| - | function | + | const currentDate |
| - | const medicalRecord | + | const calc = window.nptCalculation; |
| - | const birthWeight = parseInt(document.getElementById('birthWeight').value); | + | const prescriptionPatientWeightKg |
| - | const currentWeight | + | |
| - | const daysOfLife | + | |
| - | const bun = document.getElementById(' | + | |
| - | const glucose = document.getElementById(' | + | |
| - | const sodium = document.getElementById(' | + | |
| - | const ph = document.getElementById(' | + | |
| - | const baseExcess = document.getElementById(' | + | |
| - | const diuresis = document.getElementById(' | + | |
| - | const prescriptionDate = document.getElementById(' | + | |
| - | const prescribingDoctor = document.getElementById(' | + | |
| | | ||
| - | | + | |
| - | | + | const currentPrescribingDoctor |
| - | | + | const doctorName = currentPrescribingDoctor && doctorsData[currentPrescribingDoctor] ? |
| - | | + | |
| - | daysOfLife: daysOfLife, | + | |
| - | bun: bun, | + | |
| - | glucose: glucose, | + | |
| - | sodium: sodium, | + | |
| - | ph: ph, | + | |
| - | baseExcess: baseExcess, | + | |
| - | diuresis: diuresis, | + | |
| - | prescriptionDate: | + | |
| - | prescribingDoctor: | + | |
| - | }; | + | |
| | | ||
| - | | + | |
| + | birthDate.setDate(birthDate.getDate() - patientData.daysOfLife); | ||
| | | ||
| - | | + | |
| - | | + | window.currentPrescriptionID |
| - | | + | |
| + | | ||
| | | ||
| - | | + | |
| - | | + | |
| - | const bunValue | + | doc.setFontSize(12); |
| - | | + | doc.text('REPORT PARENTERALE', 20, yPos); |
| - | | + | yPos += 20; |
| - | | + | |
| - | } else if (bunValue > 14) { | + | doc.setFontSize(10); |
| - | bunStatus | + | |
| - | | + | yPos += 10; |
| - | } else { | + | doc.text('Peso: ' |
| - | bunStatus | + | yPos += 10; |
| - | } | + | doc.text('Giorni di vita: ' |
| - | | + | yPos += 10; |
| - | | + | doc.text('Medico: ' |
| + | yPos += 20; | ||
| + | |||
| + | | ||
| + | | ||
| + | yPos += 10; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | | + | doc.text('COMPOSIZIONE NPT:', 20, yPos); |
| - | | + | yPos += 15; |
| - | | + | |
| - | if (medicalRecord) { | + | doc.text('Volume totale NPT: ' + calc.totalVolume |
| - | | + | |
| + | doc.text('GIR: ' | ||
| + | | ||
| + | | ||
| + | yPos += 10; | ||
| + | | ||
| + | if (calc.osmolarityData) { | ||
| + | | ||
| + | yPos += 10; | ||
| } | } | ||
| - | phaseInfoHtml += '< | ||
| - | phaseInfoHtml += '< | ||
| - | phaseInfoHtml += '< | ||
| - | phaseInfoHtml += '</ | ||
| - | phaseInfoHtml += '< | ||
| - | phaseInfoHtml += '< | ||
| - | if (patientData.bun) { | ||
| - | phaseInfoHtml += '< | ||
| - | } | ||
| - | phaseInfoHtml += '</ | ||
| - | phaseInfoHtml += '</ | ||
| | | ||
| - | if (bunWarning) { | + | |
| - | | + | yPos += 10; |
| + | doc.text(' | ||
| + | yPos += 15; | ||
| + | |||
| + | | ||
| + | | ||
| + | yPos += 8; | ||
| } | } | ||
| | | ||
| - | | + | |
| + | yPos += 8; | ||
| + | doc.text('Intralipid 20%: ' + calc.lipidVolume.toFixed(1) + ' ml', 20, yPos); | ||
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 15; | ||
| | | ||
| - | | + | |
| - | | + | const totalProteinPerKg = (enteralData ? enteralData.protein : 0) + window.residualNeeds.protein; |
| + | | ||
| + | const totalCarbsPerKg = (enteralData ? enteralData.carbs : 0) + window.residualNeeds.carbs; | ||
| + | const totalEnergyPerKg = window.residualNeeds.totalEnergyRequirement; | ||
| | | ||
| - | | + | |
| - | | + | yPos += 15; |
| - | + | doc.text('Proteine: | |
| - | | + | |
| + | doc.text('Lipidi: | ||
| + | yPos += 8; | ||
| + | doc.text('Glucidi: | ||
| + | | ||
| + | | ||
| } | } | ||
| - | function updateSodiumRecommendation() { | + | // CONTENUTO PDF FOGLIO DI LAVORO |
| - | | + | function |
| - | } | + | const calc = window.nptCalculation; |
| - | + | | |
| - | // FUNZIONE FORTIFICANTE | + | let yPos = 50; |
| - | function | + | |
| - | const formulaType | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | | + | doc.text('FOGLIO DI LAVORO NPT', 20, yPos); |
| - | | + | yPos += 20; |
| - | | + | |
| - | | + | doc.setFontSize(10); |
| - | } | + | doc.text('Paziente: ' + (patientData.medicalRecord || 'N/A'), 20, yPos); |
| - | + | | |
| - | function updateConcentrationDisplay() { | + | doc.text('Peso: ' |
| - | const concentration | + | |
| - | | + | |
| - | } | + | yPos += 20; |
| - | + | ||
| - | // FUNZIONE CALCOLO ENTERALE | + | doc.text(' |
| - | function calculateEnteral() { | + | yPos += 15; |
| - | if (!patientData.birthWeight) { | + | |
| - | | + | const deflectorVolume |
| - | | + | |
| + | |||
| + | doc.text('Volume prescrizione: | ||
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 8; | ||
| + | | ||
| + | yPos += 15; | ||
| + | |||
| + | doc.text(' | ||
| + | yPos += 15; | ||
| + | | ||
| + | if (calc.neededGlucose > 0) { | ||
| + | | ||
| + | | ||
| } | } | ||
| | | ||
| - | | + | |
| - | | + | |
| - | | + | doc.text('Intralipid 20%: ' |
| + | | ||
| + | doc.text('Acqua Bidistillata: | ||
| + | yPos += 15; | ||
| | | ||
| - | | + | |
| - | const totalFluids = dailyVolume | + | |
| - | const totalFluidsPerKg | + | yPos += 8; |
| + | } | ||
| | | ||
| - | if (formulaType === ' | + | if (calc.electrolyteAdditions.esafosfina |
| - | enteralData = { | + | |
| - | volume: dailyVolume, | + | |
| - | additionalFluids: | + | |
| - | totalFluids: | + | |
| - | protein: 0, carbs: 0, lipids: 0, energy: 0, | + | |
| - | sodium: 0, potassium: 0, calcium: 0, phosphorus: 0, magnesium: 0 | + | |
| - | }; | + | |
| - | + | ||
| - | let tableHtml = '< | + | |
| - | if (additionalFluids | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | } else { | + | |
| - | tableHtml += ' | + | |
| - | } | + | |
| - | tableHtml += '</ | + | |
| - | | + | |
| - | | + | |
| - | } else { | + | |
| - | const formula = formulaData[formulaType]; | + | |
| - | const volumePerKg = (dailyVolume / currentWeight) * 1000; | + | |
| - | + | ||
| - | enteralData = { | + | |
| - | volume: dailyVolume, | + | |
| - | additionalFluids: | + | |
| - | totalFluids: | + | |
| - | protein: (dailyVolume * formula.protein / 100) / (currentWeight / 1000), | + | |
| - | carbs: (dailyVolume * formula.carbs / 100) / (currentWeight / 1000), | + | |
| - | lipids: (dailyVolume * formula.lipids / 100) / (currentWeight / 1000), | + | |
| - | energy: (dailyVolume * formula.energy / 100) / (currentWeight / 1000), | + | |
| - | sodium: (dailyVolume * formula.sodium / 100) / (currentWeight / 1000), | + | |
| - | potassium: (dailyVolume * formula.potassium / 100) / (currentWeight / 1000), | + | |
| - | calcium: (dailyVolume * formula.calcium / 100) / (currentWeight / 1000), | + | |
| - | phosphorus: (dailyVolume * formula.phosphorus / 100) / (currentWeight / 1000), | + | |
| - | magnesium: (dailyVolume * formula.magnesium / 100) / (currentWeight / 1000) | + | |
| - | }; | + | |
| - | + | ||
| - | let tableHtml = '<div class=" | + | |
| - | tableHtml | + | |
| - | tableHtml += '< | + | |
| - | if (additionalFluids > 0) { | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | } else { | + | |
| - | tableHtml += '< | + | |
| - | } | + | |
| - | tableHtml += '</ | + | |
| - | + | ||
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '</ | + | |
| - | + | ||
| - | document.getElementById(' | + | |
| } | } | ||
| | | ||
| - | | + | |
| + | yPos += 8; | ||
| | | ||
| - | | + | |
| - | if (enteralBtn) { | + | doc.text('Osmolarità: |
| - | | + | if (calc.osmolarityData.isHypertonic) { |
| - | | + | yPos += 8; |
| + | doc.text('ATTENZIONE: SOLO ACCESSO VENOSO CENTRALE', 20, yPos); | ||
| + | } | ||
| } | } | ||
| } | } | ||
| - | // FUNZIONE CARICAMENTO VALORI DEFAULT | + | // CONTENUTO PDF ETICHETTA SACCA |
| - | function | + | function |
| - | | + | |
| - | alert('Prima inserire i dati del paziente nel TAB 1'); | + | const currentTime = new Date().toLocaleTimeString(' |
| - | | + | const calc = window.nptCalculation; |
| + | |||
| + | const birthDate = new Date(); | ||
| + | birthDate.setDate(birthDate.getDate() - patientData.daysOfLife); | ||
| + | |||
| + | // Recupera il medico attualmente selezionato | ||
| + | const currentPrescribingDoctor = document.getElementById('prescribingDoctor').value; | ||
| + | const doctorName = currentPrescribingDoctor && doctorsData[currentPrescribingDoctor] ? | ||
| + | doctorsData[currentPrescribingDoctor].fullName : | ||
| + | (patientData.prescribingDoctorName || ' | ||
| + | |||
| + | if (!window.currentPrescriptionID) { | ||
| + | | ||
| } | } | ||
| + | const labelPreparationID = window.currentPrescriptionID; | ||
| | | ||
| - | | + | |
| - | const birthWeight = patientData.birthWeight; | + | |
| | | ||
| - | | + | |
| - | | + | doc.setFont(undefined, |
| - | | + | |
| + | | ||
| | | ||
| - | | + | |
| - | | + | doc.setFontSize(12); |
| - | plan = targetDay <= 3 ? {liquids: 100, protein: 3.5, carbs: 8.0, lipids: 1.0} : | + | |
| - | {liquids: 140, protein: 4.0, carbs: | + | doc.text(' |
| - | | + | yPos += 15; |
| - | plan = targetDay <= 3 ? {liquids: 120, protein: 3.0, carbs: 8.0, lipids: 2.0} : | + | |
| - | | + | doc.setFontSize(10); |
| + | doc.setFont(undefined, ' | ||
| + | | ||
| + | yPos += 10; | ||
| + | |||
| + | if (labelPreparationID) | ||
| + | doc.text(' | ||
| + | yPos += 10; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | if (patientData.bun && patientData.bun !== '' | + | yPos += 10; |
| - | const bunValue | + | doc.text(' |
| - | | + | yPos += 10; |
| - | plan.protein = Math.min(6.0, plan.protein | + | |
| - | | + | if (patientData.gestationalWeeks |
| - | | + | const gestDays |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | yPos += 10; | ||
| } | } | ||
| } | } | ||
| | | ||
| - | | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById('reqPhosphorus' | + | |
| - | document.getElementById('reqMagnesium').value = targetDay > 3 ? 0.6 : 0; | + | |
| - | document.getElementById(' | + | |
| - | | + | |
| | | ||
| - | // Vitamine/ | + | // DATI PRESCRIZIONE |
| - | | + | |
| - | | + | doc.setFont(undefined, |
| + | doc.text(' | ||
| + | yPos += 15; | ||
| + | |||
| + | doc.setFontSize(10); | ||
| + | | ||
| + | doc.text(' | ||
| + | yPos += 8; | ||
| + | doc.text('Data Prescrizione: | ||
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 20; | ||
| | | ||
| - | | + | |
| - | | + | doc.setFontSize(12); |
| - | | + | doc.setFont(undefined, |
| - | | + | doc.text('CONTENUTO SACCA NPT', 20, yPos); |
| - | | + | yPos += 15; |
| - | | + | |
| - | document.getElementById('reqSoluvit').value = 0; | + | doc.setFontSize(10); |
| - | | + | doc.setFont(undefined, |
| + | | ||
| + | if (calc.neededGlucose > 0) { | ||
| + | | ||
| + | | ||
| } | } | ||
| | | ||
| - | | + | |
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 8; | ||
| + | doc.text(' | ||
| + | yPos += 15; | ||
| + | |||
| + | doc.setFont(undefined, | ||
| + | doc.text(' | ||
| + | yPos += 10; | ||
| + | doc.text(' | ||
| | | ||
| - | | + | |
| - | if (loadBtn) { | + | if (calc.osmolarityData) { |
| - | | + | yPos += 15; |
| - | | + | doc.setFontSize(11); |
| + | doc.text('Osmolarità: | ||
| + | |||
| + | | ||
| + | yPos += 10; | ||
| + | doc.setTextColor(255, | ||
| + | doc.text('ATTENZIONE: SOLO ACCESSO VENOSO CENTRALE', 20, yPos); | ||
| + | doc.setTextColor(0, | ||
| + | } | ||
| } | } | ||
| } | } | ||
| - | function updateCarbUnit() { | + | |
| - | const unit = document.getElementById(' | + | |
| - | const carbLabel = document.getElementById(' | + | // FUNZIONI PLACEHOLDER |
| - | const carbInput = document.getElementById(' | + | function showAddEnteralForm() { |
| - | + | | |
| - | if (unit === ' | + | |
| - | carbLabel.textContent = ' | + | |
| - | | + | |
| - | carbInput.setAttribute(' | + | |
| - | | + | |
| - | carbLabel.textContent = ' | + | |
| - | carbInput.setAttribute(' | + | |
| - | carbInput.setAttribute(' | + | |
| - | } | + | |
| } | } | ||
| - | function | + | function |
| - | | + | |
| } | } | ||
| - | function | + | function |
| - | | + | |
| } | } | ||
| - | // FUNZIONE CALCOLO FABBISOGNI | + | |
| - | function | + | function |
| - | if (!patientData.birthWeight) { | + | const name = prompt(' |
| - | alert('Prima inserire i dati del paziente nel TAB 1'); | + | if (!name || name.trim() === '' |
| - | | + | |
| - | } | + | |
| | | ||
| - | const requirements | + | const surname |
| - | liquids: parseFloat(document.getElementById('reqLiquids' | + | |
| - | protein: parseFloat(document.getElementById(' | + | |
| - | | + | |
| - | carbUnit: document.getElementById(' | + | |
| - | lipids: parseFloat(document.getElementById(' | + | |
| - | calcium: parseFloat(document.getElementById(' | + | |
| - | phosphorus: parseFloat(document.getElementById(' | + | |
| - | magnesium: parseFloat(document.getElementById(' | + | |
| - | sodium: parseFloat(document.getElementById(' | + | |
| - | potassium: parseFloat(document.getElementById(' | + | |
| - | vitalipid: parseFloat(document.getElementById(' | + | |
| - | soluvit: parseFloat(document.getElementById(' | + | |
| - | peditrace: parseFloat(document.getElementById('reqPeditrace').value) || 0, | + | |
| - | carnitine: parseFloat(document.getElementById(' | + | |
| - | }; | + | |
| | | ||
| - | | + | const title = prompt(' |
| - | | + | if (!title || title.trim() |
| - | (requirements.carbs * 1440 / 1000) : requirements.carbs; | + | |
| | | ||
| - | const currentWeight | + | const key = ' |
| + | const fullName = title.trim() + ' ' + name.trim() + ' ' + surname.trim(); | ||
| | | ||
| - | | + | |
| - | const enteralCarbs = enteralData ? enteralData.carbs : 0; | + | name: name.trim(), |
| - | const enteralLipids = enteralData ? enteralData.lipids | + | surname: surname.trim(), |
| - | | + | |
| + | | ||
| + | | ||
| | | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | const totalEnergyRequirement | + | } |
| - | | + | |
| + | function showAddNurseForm() { | ||
| + | const name = prompt(' | ||
| + | | ||
| | | ||
| - | | + | const surname |
| - | | + | |
| - | | + | |
| - | const enteralMagnesium | + | |
| - | const enteralSodium | + | |
| - | const enteralPotassium | + | |
| | | ||
| - | | + | const title = prompt(' |
| - | | + | |
| - | const residualPhosphorus = Math.max(0, requirements.phosphorus - enteralPhosphorus); | + | |
| - | | + | const key = ' |
| - | const residualSodium | + | const fullName |
| - | const residualPotassium | + | |
| | | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | carbs: residualCarbs, | + | |
| - | lipids: residualLipids, | + | |
| - | calcium: residualCalcium, | + | |
| - | phosphorus: residualPhosphorus, | + | |
| - | magnesium: residualMagnesium, | + | |
| - | sodium: residualSodium, | + | |
| - | potassium: residualPotassium, | + | |
| - | vitalipid: requirements.vitalipid, | + | |
| - | | + | |
| - | peditrace: requirements.peditrace, | + | |
| - | carnitine: requirements.carnitine, | + | |
| - | energy: residualEnergy, | + | |
| - | | + | |
| }; | }; | ||
| | | ||
| - | | + | |
| - | | + | |
| - | const enteralCarbsMgPerKgMin | + | } |
| - | | + | |
| + | function showAddPharmacistForm() { | ||
| + | const name = prompt(' | ||
| + | | ||
| | | ||
| - | | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '< | + | |
| - | tableHtml += '</ | + | |
| | | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | const key = ' |
| + | | ||
| + | | ||
| + | pharmacistsData[key] = { | ||
| + | name: name.trim(), | ||
| + | surname: surname.trim(), | ||
| + | title: title.trim(), | ||
| + | fullName: fullName | ||
| + | }; | ||
| + | |||
| + | populatePharmacistsConfigTable(); | ||
| + | alert('Farmacista aggiunto con successo!\n' | ||
| } | } | ||
| - | // FUNZIONE CALCOLO ELETTROLITI AGGIUNTIVI | + | function |
| - | function | + | const name = prompt(' |
| - | const additions | + | if (!name || name.trim() === '' |
| - | ca_gluconato: 0, | + | |
| - | | + | |
| - | mg_sulfate: 0, | + | |
| - | nacl: 0, | + | |
| - | sodium_acetate: | + | |
| - | kcl: 0, | + | |
| - | totalVolume: | + | |
| - | providedCalcium: | + | |
| - | providedPhosphorus: | + | |
| - | providedMagnesium: | + | |
| - | providedSodium: | + | |
| - | providedPotassium: | + | |
| - | sodiumSource: | + | |
| - | }; | + | |
| | | ||
| - | const sodiumTypeSelect | + | const surname |
| - | | + | |
| - | additions.sodiumSource = selectedSodiumType; | + | |
| | | ||
| - | const totalCalciumNeeded | + | const title = prompt(' |
| - | | + | |
| - | const totalMagnesiumNeeded | + | |
| - | const totalSodiumNeeded = sodiumNeeded * currentWeightKg; | + | |
| - | const totalPotassiumNeeded | + | |
| | | ||
| - | // Calcio Gluconato 10% (840 mg Ca/100ml) | + | |
| - | | + | |
| - | | + | |
| - | | + | technicianData[key] = { |
| - | } | + | |
| + | surname: surname.trim(), | ||
| + | | ||
| + | fullName: fullName | ||
| + | }; | ||
| | | ||
| - | | + | |
| - | | + | |
| - | | + | } |
| - | | + | |
| - | additions.providedSodium += (additions.esafosfina * parenteralConfig.esafosfina.sodium / 100); | + | |
| + | function removeEnteralFormula(key) { | ||
| + | if (confirm('Sei sicuro di voler rimuovere questa formula?' | ||
| + | | ||
| } | } | ||
| + | } | ||
| + | |||
| + | function removeParenteralComponent(key) { | ||
| + | if (confirm(' | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function removeFortifier(key) { | ||
| + | if (confirm(' | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function removeDoctor(key) { | ||
| + | if (confirm(' | ||
| + | delete doctorsData[key]; | ||
| + | populateDoctorsConfigTable(); | ||
| + | updateDoctorsDropdown(); | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function removeNurse(key) { | ||
| + | if (confirm(' | ||
| + | delete nursesData[key]; | ||
| + | populateNursesConfigTable(); | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function removePharmacist(key) { | ||
| + | if (confirm(' | ||
| + | delete pharmacistsData[key]; | ||
| + | populatePharmacistsConfigTable(); | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function removeTechnician(key) { | ||
| + | if (confirm(' | ||
| + | delete technicianData[key]; | ||
| + | populateTechniciansConfigTable(); | ||
| + | alert(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // FUNZIONI VALIDAZIONE E ARCHIVIAZIONE PREPARAZIONE | ||
| + | function updatePreparationStaffDropdowns() { | ||
| + | console.log(' | ||
| | | ||
| - | // Magnesio Solfato | + | // Farmacisti |
| - | if (totalMagnesiumNeeded > 0) { | + | const pharmacistSelect = document.getElementById(' |
| - | | + | if (pharmacistSelect) { |
| - | | + | |
| + | Object.keys(pharmacistsData).forEach(key => { | ||
| + | const option = document.createElement(' | ||
| + | | ||
| + | option.textContent = pharmacistsData[key].fullName; | ||
| + | pharmacistSelect.appendChild(option); | ||
| + | }); | ||
| + | console.log(' | ||
| } | } | ||
| | | ||
| - | // Sodio rimanente | + | // Tecnici (per entrambe le dropdown) |
| - | const remainingSodium | + | |
| + | | ||
| + | if (select) { | ||
| + | select.innerHTML = '< | ||
| + | Object.keys(technicianData).forEach(key => { | ||
| + | const option = document.createElement(' | ||
| + | option.value = key; | ||
| + | option.textContent = technicianData[key].fullName; | ||
| + | select.appendChild(option); | ||
| + | }); | ||
| + | } | ||
| + | }); | ||
| + | console.log(' | ||
| + | } | ||
| + | |||
| + | // ===================================================== | ||
| + | // SISTEMA VALIDAZIONE E PREPARAZIONE IN DUE FASI | ||
| + | // ===================================================== | ||
| + | |||
| + | // FASE 1: Validazione Farmacista | ||
| + | function validatePrescription() { | ||
| + | const pharmacist = document.getElementById(' | ||
| | | ||
| - | if (remainingSodium > 0) { | + | if (!pharmacist) { |
| - | | + | |
| - | const concentrationSodiumAcetate = parenteralConfig.sodium_acetate.sodium / 100; | + | |
| - | additions.sodium_acetate = remainingSodium / concentrationSodiumAcetate; | + | |
| - | } else { | + | |
| - | const concentrationNaCl = parenteralConfig.nacl.sodium / 100; | + | |
| - | additions.nacl = remainingSodium / concentrationNaCl; | + | |
| - | } | + | |
| - | | + | |
| } | } | ||
| | | ||
| - | | + | if (!window.residualNeeds || !window.nptCalculation || !patientData.currentWeight) { |
| - | | + | |
| - | | + | |
| - | | + | |
| } | } | ||
| | | ||
| - | | + | |
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| | | ||
| - | | + | |
| + | const pharmacistName = pharmacistsData[pharmacist].fullName; | ||
| + | const validationHtml = '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '</ | ||
| + | |||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Abilita fase 2 - Allestimento | ||
| + | enablePreparationPhase(); | ||
| + | |||
| + | alert(' | ||
| } | } | ||
| - | // FUNZIONE CALCOLO NPT PARENTERALE | + | // Abilita la fase di allestimento tecnici |
| - | function | + | function |
| - | if (!window.residualNeeds) { | + | const tech1Select = document.getElementById(' |
| - | alert(' | + | const tech2Select = document.getElementById(' |
| + | |||
| + | // Abilita le dropdown tecnici | ||
| + | tech1Select.disabled = false; | ||
| + | tech2Select.disabled = false; | ||
| + | |||
| + | // Popola le dropdown tecnici | ||
| + | [tech1Select, | ||
| + | select.innerHTML = '< | ||
| + | Object.keys(technicianData).forEach(key => { | ||
| + | const option = document.createElement(' | ||
| + | option.value = key; | ||
| + | option.textContent = technicianData[key].fullName; | ||
| + | select.appendChild(option); | ||
| + | }); | ||
| + | }); | ||
| + | |||
| + | // Abilita il pulsante conferma (ma ancora non attivo finché non si selezionano i tecnici) | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Event listeners per controllare quando entrambi i tecnici sono selezionati | ||
| + | [tech1Select, | ||
| + | select.addEventListener(' | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | // Controlla se entrambi i tecnici sono selezionati | ||
| + | function checkTechniciansSelection() { | ||
| + | const tech1 = document.getElementById(' | ||
| + | const tech2 = document.getElementById(' | ||
| + | const confirmBtn = document.getElementById(' | ||
| + | | ||
| + | if (tech1 && tech2 && tech1 !== tech2) { | ||
| + | confirmBtn.className = ' | ||
| + | confirmBtn.innerHTML = '🧪 CONFERMA ALLESTIMENTO'; | ||
| + | } else if (tech1 === tech2 && tech1 !== '' | ||
| + | confirmBtn.className = ' | ||
| + | confirmBtn.innerHTML = ' | ||
| + | } else { | ||
| + | confirmBtn.className = ' | ||
| + | confirmBtn.innerHTML = '🧪 CONFERMA ALLESTIMENTO (seleziona tecnici)'; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // FASE 2: Conferma Allestimento | ||
| + | function confirmPreparation() { | ||
| + | const tech1 = document.getElementById(' | ||
| + | const tech2 = document.getElementById(' | ||
| + | |||
| + | if (!tech1 || !tech2) { | ||
| + | alert(' | ||
| return; | return; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | const currentWeightKg = currentWeight / 1000; | + | alert(' |
| - | | + | |
| + | | ||
| | | ||
| - | | + | |
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| | | ||
| - | const electrolyteAdditions | + | |
| - | | + | |
| - | | + | const tech2Name = technicianData[tech2].fullName; |
| - | | + | const preparationHtml = '< |
| - | | + | |
| - | | + | '< |
| - | | + | '< |
| + | '< | ||
| + | | ||
| + | '</ | ||
| + | |||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Abilita download JSON | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Abilita pulsante blocco prescrizione | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Genera e salva l'ID preparazione per il sistema di blocco | ||
| + | if (!window.currentPrescriptionID) { | ||
| + | | ||
| + | } | ||
| + | window.lastPreparationID = window.currentPrescriptionID; | ||
| + | |||
| + | console.log(' | ||
| + | |||
| + | |||
| + | |||
| + | alert(' | ||
| + | } | ||
| + | |||
| + | // ===================================================== | ||
| + | // SISTEMA BLOCCO PRESCRIZIONE | ||
| + | // ===================================================== | ||
| + | |||
| + | // Variabile globale per stato blocco | ||
| + | window.prescriptionLocked = false; | ||
| + | |||
| + | // Funzione per bloccare la prescrizione | ||
| + | function lockPrescription() { | ||
| + | const confirmed = confirm( | ||
| + | | ||
| + | ' | ||
| + | '• Non sarà più possibile modificare i dati\n' | ||
| + | '• La preparazione sarà considerata FINALIZZATA\n' | ||
| + | '• Per modifiche servirà una NUOVA prescrizione\n\n' | ||
| + | | ||
| ); | ); | ||
| | | ||
| - | | + | |
| - | | + | return; |
| + | | ||
| | | ||
| - | | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | | + | document.getElementById(' |
| + | document.getElementById(' | ||
| + | | ||
| + | |||
| + | // Assicurati che l'ID preparazione sia disponibile per il banner | ||
| + | if (!window.lastPreparationID && window.currentPrescriptionID) { | ||
| + | window.lastPreparationID = window.currentPrescriptionID; | ||
| + | } | ||
| + | | ||
| + | showPrescriptionLockedBanner(); | ||
| | | ||
| - | | + | |
| - | | + | |
| | | ||
| - | | + | |
| + | 'La prescrizione NPT è ora finalizzata e non può essere modificata.\n' | ||
| + | 'Per eventuali modifiche sarà necessaria una nuova prescrizione.' | ||
| + | } | ||
| + | |||
| + | // Mostra banner di prescrizione bloccata | ||
| + | function showPrescriptionLockedBanner() { | ||
| + | const currentDateTime | ||
| + | const preparationID = window.lastPreparationID || window.currentPrescriptionID || ' | ||
| + | const bannerHtml = '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | '< | ||
| + | | ||
| | | ||
| - | | + | |
| - | glucoseMessage = '< | + | document.getElementById(' |
| - | '• Volume totale richiesto: ' + totalVolume + ' ml< | + | } |
| - | '• Volume utilizzato: ' + usedVolume.toFixed(1) + ' | + | |
| - | '• Acqua rimanente: ' + waterVolume.toFixed(1) + ' ml (NEGATIVO!)< | + | // Disabilita tutti gli input quando prescrizione è bloccata |
| - | '< | + | function disableAllInputs() { |
| - | + | // Disabilita TAB 2-4, mantieni TAB 1 accessibile per consultazione | |
| - | | + | const tabButtons = document.querySelectorAll('.tab'); |
| - | document.getElementById('suggestedGlucose').value = ' | + | |
| - | | + | |
| - | | + | tab.style.opacity |
| - | | + | |
| - | document.getElementById('parenteralTable').innerHTML = glucoseMessage; | + | |
| - | | + | |
| - | return; | + | |
| } | } | ||
| + | }); | ||
| | | ||
| - | if (neededGlucose <= 0) { | + | // Disabilita input solo nei TAB 2-4, mantieni TAB 1 consultabile |
| - | | + | const inputElements |
| - | '• Tutto il glucosio necessario proviene dall\' | + | |
| - | '• Non necessario glucosio in NPT</ | + | |
| - | + | ||
| - | document.getElementById('suggestedGlucose').value = 'Non necessario (enterale sufficiente)'; | + | inputElements.forEach(element => { |
| - | } else { | + | |
| - | | + | |
| - | ' | + | }); |
| - | '• Glucosio 50%: ' | + | |
| - | '• Acqua bidistillata: | + | // TAB 1: disabilita solo i pulsanti di modifica, mantieni visibili i dati |
| - | '• < | + | const tab1Buttons = document.querySelectorAll('# |
| - | + | tab1Buttons.forEach(button => { | |
| - | | + | button.disabled = true; |
| + | button.style.opacity | ||
| + | }); | ||
| + | | ||
| + | // Mostra overlay sui TAB bloccati | ||
| + | addLockedOverlay(); | ||
| + | } | ||
| + | |||
| + | // Aggiunge overlay visivo sui TAB bloccati | ||
| + | function addLockedOverlay() | ||
| + | const lockedTabs | ||
| + | | ||
| + | const tabElement = document.getElementById(tabId); | ||
| + | if (tabElement && !tabElement.querySelector('.locked-overlay')) { | ||
| + | const overlay = document.createElement('div'); | ||
| + | | ||
| + | overlay.style.cssText = ` | ||
| + | position: absolute; | ||
| + | top: 0; | ||
| + | left: 0; | ||
| + | width: 100%; | ||
| + | height: 100%; | ||
| + | background-color: | ||
| + | z-index: 1000; | ||
| + | display: flex; | ||
| + | align-items: | ||
| + | justify-content: | ||
| + | font-size: 24px; | ||
| + | font-weight: | ||
| + | color: #e74c3c; | ||
| + | pointer-events: | ||
| + | `; | ||
| + | overlay.innerHTML = '🔒 PRESCRIZIONE BLOCCATA'; | ||
| + | |||
| + | tabElement.style.position = 'relative'; | ||
| + | tabElement.appendChild(overlay); | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | // Funzione per iniziare nuova prescrizione | ||
| + | function startNewPrescription() { | ||
| + | const confirmed = confirm( | ||
| + | '📋 NUOVA PRESCRIZIONE NPT\n\n' | ||
| + | | ||
| + | | ||
| + | '• Permetterà di iniziare una nuova prescrizione\n' | ||
| + | '• La prescrizione precedente rimarrà archiviata\n\n' + | ||
| + | | ||
| + | ); | ||
| + | |||
| + | if (!confirmed) { | ||
| + | return; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | | + | resetToNewPrescription(); |
| - | | + | } |
| + | |||
| + | // Reset per nuova prescrizione | ||
| + | function resetToNewPrescription() { | ||
| + | // Reset variabili globali | ||
| + | window.prescriptionLocked | ||
| + | | ||
| + | window.nptCalculation | ||
| + | | ||
| + | window.currentPrescriptionID | ||
| + | patientData = {}; | ||
| + | enteralData = null; | ||
| + | currentRequirements = null; | ||
| | | ||
| - | | + | |
| + | enableAllInputs(); | ||
| | | ||
| - | | + | // Reset tutti i form |
| - | resultHtml += '< | + | |
| - | resultHtml += '< | + | |
| - | | + | |
| - | resultHtml += '</ | + | |
| | | ||
| - | | + | |
| - | resultHtml += '< | + | document.getElementById('prescriptionStatusBanner').style.display |
| | | ||
| - | | + | // Vai al TAB 1 |
| - | resultHtml += '< | + | showTab('patient-data'); |
| - | } | + | |
| | | ||
| - | | + | // Imposta nuova data |
| - | | + | const today = new Date().toISOString().split('T')[0]; |
| + | | ||
| | | ||
| - | | + | |
| - | | + | } |
| + | |||
| + | // Funzioni di supporto per reset completo | ||
| + | function enableAllInputs() { | ||
| + | // Riabilita tutti i TAB | ||
| + | const tabButtons | ||
| + | tabButtons.forEach(tab => { | ||
| + | tab.style.opacity = ' | ||
| + | tab.style.pointerEvents = ' | ||
| + | tab.style.cursor = ' | ||
| + | }); | ||
| + | |||
| + | | ||
| + | const inputElements = document.querySelectorAll('# | ||
| + | '# | ||
| + | '# | ||
| + | '# | ||
| + | |||
| + | inputElements.forEach(element => { | ||
| + | element.disabled = false; | ||
| + | element.style.opacity = ' | ||
| + | }); | ||
| + | |||
| + | | ||
| + | removeLockedOverlays(); | ||
| + | } | ||
| + | |||
| + | function removeLockedOverlays() { | ||
| + | const overlays = document.querySelectorAll('.locked-overlay' | ||
| + | overlays.forEach(overlay => { | ||
| + | overlay.remove(); | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | function resetAllForms() { | ||
| + | // Reset TAB 1 - Dati Paziente | ||
| + | document.getElementById(' | ||
| + | document.getElementById('birthWeight' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | | ||
| + | const phaseBtn = document.getElementById('calculatePhaseBtn' | ||
| + | if (phaseBtn) { | ||
| + | phaseBtn.className = ' | ||
| + | phaseBtn.innerHTML = ' | ||
| + | phaseBtn.disabled = false; | ||
| } | } | ||
| - | if (electrolyteAdditions.esafosfina > 0) { | + | |
| - | | + | // Nascondi risultati fase |
| + | const phaseResults = document.getElementById(' | ||
| + | | ||
| + | | ||
| } | } | ||
| - | | + | |
| - | resultHtml += '< | + | // Reset TAB 2 - Nutrizione Enterale |
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | | ||
| + | const enteralBtn = document.getElementById(' | ||
| + | if (enteralBtn) { | ||
| + | enteralBtn.className = ' | ||
| + | enteralBtn.innerHTML = ' | ||
| } | } | ||
| - | | + | |
| - | | + | // Nascondi risultati enterali |
| - | | + | |
| - | if (electrolyteAdditions.sodium_acetate > 0) { | + | if (enteralResults) { |
| - | resultHtml += '< | + | |
| - | } | + | |
| - | if (electrolyteAdditions.kcl > 0) { | + | |
| - | | + | |
| } | } | ||
| | | ||
| - | | + | |
| - | const vitalipidVolume | + | document.getElementById(' |
| - | | + | document.getElementById(' |
| + | | ||
| + | |||
| + | // Reset pulsanti TAB 3 | ||
| + | | ||
| + | const nutritionBtn | ||
| + | if (loadBtn) { | ||
| + | loadBtn.className = 'button load-defaults-pending'; | ||
| + | loadBtn.innerHTML = ' | ||
| } | } | ||
| - | if (residualNeeds.soluvit > 0) { | + | if (nutritionBtn) { |
| - | | + | |
| - | resultHtml += '< | + | |
| - | } | + | |
| - | if (residualNeeds.peditrace > 0) { | + | |
| - | | + | |
| - | resultHtml += '< | + | |
| } | } | ||
| | | ||
| - | if (residualNeeds.carnitine > 0) { | + | |
| - | | + | const nutritionResults = document.getElementById(' |
| + | | ||
| + | | ||
| } | } | ||
| | | ||
| - | | + | // Reset TAB 4 - Parenterale |
| - | resultHtml += '< | + | resetParenteralFields(); |
| - | } | + | |
| | | ||
| - | | + | // Reset TAB 5 - Report |
| - | resultHtml += '</ | + | resetReportFields(); |
| | | ||
| - | | + | |
| + | } | ||
| + | |||
| + | function resetNutritionFields() { | ||
| + | const nutritionFields | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ]; | ||
| | | ||
| - | | + | |
| - | const deflectorVolume | + | const field = document.getElementById(fieldId); |
| - | | + | if (field) { |
| + | field.value | ||
| + | } | ||
| + | | ||
| | | ||
| - | | + | |
| - | | + | |
| - | preparationHtml += '• < | + | |
| - | | + | |
| - | preparationHtml += '</div>'; | + | |
| | | ||
| - | | + | |
| - | preparationHtml += '< | + | document.getElementById('sodiumType').value |
| | | ||
| - | const ratio = totalVolumeWithDeflector / totalVolume; | + | |
| + | | ||
| + | if (sodiumRec) { | ||
| + | sodiumRec.classList.add(' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function resetParenteralFields() { | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| | | ||
| - | if (neededGlucose > 0) { | + | |
| - | | + | |
| + | | ||
| + | parenteralBtn.innerHTML = 'CALCOLA NPT AUTOMATICA'; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | | + | if (parenteralResults) { |
| + | parenteralResults.classList.add('hidden'); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function resetReportFields() { | ||
| + | // Reset dropdown personale | ||
| + | document.getElementById(' | ||
| + | | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Reset pulsanti validazione/ | ||
| + | const validateBtn = document.getElementById(' | ||
| + | const confirmBtn = document.getElementById(' | ||
| + | const downloadBtn = document.getElementById(' | ||
| + | const lockBtn = document.getElementById('lockPrescriptionBtn'); | ||
| | | ||
| - | if (electrolyteAdditions.ca_gluconato > 0) { | + | if (validateBtn) { |
| - | | + | |
| + | validateBtn.innerHTML = '✅ VALIDA PRESCRIZIONE'; | ||
| + | validateBtn.disabled = false; | ||
| } | } | ||
| - | if (electrolyteAdditions.esafosfina > 0) { | + | |
| - | | + | |
| + | | ||
| + | confirmBtn.innerHTML = '🧪 CONFERMA ALLESTIMENTO'; | ||
| + | confirmBtn.disabled = true; | ||
| } | } | ||
| - | if (electrolyteAdditions.mg_sulfate > 0) { | + | |
| - | | + | |
| + | | ||
| + | downloadBtn.innerHTML = '💾 ARCHIVIA PREPARAZIONE | ||
| + | downloadBtn.disabled = true; | ||
| } | } | ||
| - | if (electrolyteAdditions.nacl > 0) { | + | |
| - | | + | |
| + | | ||
| + | lockBtn.innerHTML = '🔒 BLOCCA PRESCRIZIONE'; | ||
| + | lockBtn.disabled = true; | ||
| + | lockBtn.style.backgroundColor = '#e74c3c'; | ||
| } | } | ||
| - | | + | |
| - | | + | // Nascondi status |
| + | const validationStatus = document.getElementById(' | ||
| + | const preparationStatus = document.getElementById(' | ||
| + | if (validationStatus) validationStatus.style.display | ||
| + | if (preparationStatus) preparationStatus.style.display = ' | ||
| + | |||
| + | | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | |||
| + | // SISTEMA DI ARCHIVIAZIONE JSON | ||
| + | function generatePreparationID() { | ||
| + | const medicalRecord = patientData.medicalRecord; | ||
| + | let prescriptionDate = patientData.prescriptionDate; | ||
| + | |||
| + | if (!medicalRecord || medicalRecord.trim() === '' | ||
| + | return null; | ||
| } | } | ||
| - | if (electrolyteAdditions.kcl > 0) { | + | |
| - | | + | |
| + | | ||
| + | const today = new Date().toISOString().split('T')[0]; | ||
| + | prescriptionDate = today; // ✅ Ora funziona correttamente | ||
| } | } | ||
| | | ||
| - | | + | |
| - | const vitalipidVolume | + | const dateObj = new Date(prescriptionDate); |
| - | | + | const day = dateObj.getDate().toString().padStart(2, |
| + | const month = (dateObj.getMonth() + 1).toString().padStart(2, | ||
| + | const year = dateObj.getFullYear().toString(); | ||
| + | const formattedDate = day + month + year; | ||
| + | |||
| + | | ||
| + | const counterKey = medicalRecord + '_' + formattedDate; | ||
| + | |||
| + | // Inizializza il contatore se non esiste | ||
| + | if (!window.preparationCounter) { | ||
| + | window.preparationCounter = {}; | ||
| } | } | ||
| - | | + | |
| - | const soluvitVolume = residualNeeds.soluvit * currentWeightKg; | + | if (!window.preparationCounter[counterKey]) { |
| - | preparationHtml += '< | + | |
| - | } | + | |
| - | if (residualNeeds.peditrace > 0) { | + | |
| - | | + | |
| - | preparationHtml += '< | + | |
| } | } | ||
| | | ||
| - | | + | |
| - | | + | window.preparationCounter[counterKey]++; |
| + | |||
| + | // Genera l'ID con formato: CARTELLA_DDMMYYYY_NN | ||
| + | const counter = window.preparationCounter[counterKey].toString().padStart(2, '0'); | ||
| + | const preparationID | ||
| + | |||
| + | return preparationID; | ||
| + | } | ||
| + | function createPreparationJSON() { | ||
| + | if (!window.residualNeeds || !window.nptCalculation || !patientData.currentWeight) { | ||
| + | alert('❌ Errore: Prima completare tutti i calcoli NPT (TAB 1-4)'); | ||
| + | return null; | ||
| } | } | ||
| | | ||
| - | if (waterVolume > 0) { | + | |
| - | | + | const preparationID = generatePreparationID(); |
| + | | ||
| + | | ||
| + | return null; | ||
| } | } | ||
| | | ||
| - | | + | // Recupera dati personale |
| - | | + | const pharmacistKey = document.getElementById('validatingPharmacist').value; |
| + | const tech1Key = document.getElementById('preparingTechnician1').value; | ||
| + | | ||
| | | ||
| - | | + | |
| - | | + | |
| + | const tech2Name = tech2Key ? technicianData[tech2Key].fullName : 'NON SPECIFICATO'; | ||
| | | ||
| - | // Salva i dati per i report | + | // Crea oggetto JSON completo |
| - | | + | |
| - | currentWeight, | + | |
| - | proteinVolume, | + | preparationID: |
| - | | + | cartellaClinica: |
| + | dataPrescrizione: | ||
| + | dataCreazione: | ||
| + | |||
| + | // DATI PAZIENTE | ||
| + | paziente: { | ||
| + | pesoAttuale: | ||
| + | pesoNascita: | ||
| + | giorniVita: patientData.daysOfLife || 0, | ||
| + | etaGestazionale: | ||
| + | settimane: patientData.gestationalWeeks || null, | ||
| + | giorni: patientData.gestationalDays || null, | ||
| + | formato: patientData.gestationalWeeks && patientData.gestationalWeeks > 0 ? | ||
| + | patientData.gestationalWeeks + ' | ||
| + | } | ||
| + | }, | ||
| + | |||
| + | // DATI CLINICI | ||
| + | parametriClinici: | ||
| + | bun: patientData.bun || null, | ||
| + | glicemia: patientData.glucose || null, | ||
| + | natremia: patientData.sodium || null, | ||
| + | ph: patientData.ph || null, | ||
| + | baseExcess: patientData.baseExcess || null, | ||
| + | diuresi: patientData.diuresis || null | ||
| + | }, | ||
| + | |||
| + | // COMPOSIZIONE NPT | ||
| + | npt: { | ||
| + | volumeTotale: | ||
| + | energia: window.residualNeeds.energy.toFixed(1), | ||
| + | proteine: window.residualNeeds.protein.toFixed(2), | ||
| + | lipidi: window.residualNeeds.lipids.toFixed(2), | ||
| + | glucidi: window.residualNeeds.carbs.toFixed(2), | ||
| + | gir: window.nptCalculation.gir.toFixed(1), | ||
| + | osmolarita: window.nptCalculation.osmolarityData ? window.nptCalculation.osmolarityData.total : 0, | ||
| + | velocitaInfusione: | ||
| + | | ||
| + | |||
| + | // COMPONENTI DETTAGLIATI | ||
| + | componenti: { | ||
| + | glucosio50: window.nptCalculation.glucose50Volume.toFixed(1), | ||
| + | trophamine: window.nptCalculation.proteinVolume.toFixed(1), | ||
| + | intralipid: window.nptCalculation.lipidVolume.toFixed(1), | ||
| + | acquaBidistillata: | ||
| + | elettroliti: | ||
| + | }, | ||
| + | | ||
| + | // PERSONALE | ||
| + | personale: { | ||
| + | medicoPrescrittore: | ||
| + | farmacistValidatore: | ||
| + | tecnico1: tech1Name, | ||
| + | tecnico2: tech2Name | ||
| + | }, | ||
| + | |||
| + | // METADATA | ||
| + | sistema: { | ||
| + | versione: "NPT Calculator v3.0 UNIFIED", | ||
| + | dataCalcolo: | ||
| + | } | ||
| }; | }; | ||
| | | ||
| - | | + | |
| - | if (parenteralBtn) { | + | |
| - | parenteralBtn.className = ' | + | |
| - | parenteralBtn.innerHTML = 'NPT CALCOLATA ✓'; | + | |
| - | } | + | |
| } | } | ||
| - | // FUNZIONI REPORT | + | function |
| - | function | + | |
| - | | + | |
| - | alert('Prima calcolare la NPT!'); | + | const preparationData = createPreparationJSON(); |
| - | return; | + | if (!preparationData) { |
| + | return; | ||
| } | } | ||
| | | ||
| - | const reportHtml | + | |
| - | | + | // Crea il file JSON |
| - | document.getElementById('nptWorkReport').classList.remove(' | + | |
| - | | + | const blob = new Blob([jsonString], |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | // Nome file: NPT_[ID].json |
| - | window.currentActiveReport | + | const filename |
| - | + | ||
| - | const generateBtn = document.getElementById('generateWorkReportBtn'); | + | // Download automatico |
| - | | + | const url = URL.createObjectURL(blob); |
| - | | + | const a = document.createElement('a'); |
| + | a.href = url; | ||
| + | a.download = filename; | ||
| + | document.body.appendChild(a); | ||
| + | a.click(); | ||
| + | document.body.removeChild(a); | ||
| + | | ||
| + | |||
| + | // Feedback successo | ||
| + | | ||
| + | document.getElementById(' | ||
| + | |||
| + | alert(`✅ Preparazione archiviata con successo!\n\n` + | ||
| + | `📋 ID: ${preparationData.preparationID}\n` + | ||
| + | `📁 File: ${filename}\n` + | ||
| + | `📊 Dati: ${Object.keys(preparationData).length} sezioni salvate`); | ||
| + | // Salva ID per il sistema di blocco | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | console.error('Errore nella generazione JSON:', error); | ||
| + | | ||
| + | } | ||
| } | } | ||
| - | function | + | |
| - | if (!window.nptCalculationData) { | + | // ===================================================== |
| - | alert(' | + | // SISTEMA ARCHIVIAZIONE MENSILE EXCEL |
| + | // ===================================================== | ||
| + | |||
| + | // Variabile globale per i dati mensili | ||
| + | window.monthlyPreparations = []; | ||
| + | |||
| + | // Funzione per inizializzare il mese corrente | ||
| + | function | ||
| + | const now = new Date(); | ||
| + | const currentMonth = now.getFullYear() + ' | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | // Funzione anteprima dati mensili | ||
| + | function previewMonthlyData() { | ||
| + | const fileInput = document.getElementById(' | ||
| + | const files = fileInput.files; | ||
| + | | ||
| + | if (!files || files.length === 0) { | ||
| + | alert(' | ||
| return; | return; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | document.getElementById(' | + | window.monthlyPreparations |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | window.currentActiveReport | + | |
| | | ||
| - | const generateBtn | + | |
| - | | + | |
| - | | + | |
| + | // Processa tutti i file JSON | ||
| + | Array.from(files).forEach((file, | ||
| + | const reader = new FileReader(); | ||
| + | |||
| + | reader.onload | ||
| + | try { | ||
| + | const jsonData = JSON.parse(e.target.result); | ||
| + | |||
| + | // Valida che sia un file NPT valido | ||
| + | if (validateNPTJson(jsonData)) { | ||
| + | window.monthlyPreparations.push(jsonData); | ||
| + | } else { | ||
| + | console.warn('File non valido ignorato:', file.name); | ||
| + | } | ||
| + | |||
| + | processedFiles++; | ||
| + | |||
| + | // Quando tutti i file sono processati, mostra l' | ||
| + | if (processedFiles | ||
| + | showMonthlyPreview(); | ||
| + | } | ||
| + | |||
| + | } catch (error) { | ||
| + | console.error('Errore parsing JSON:', file.name, error); | ||
| + | processedFiles++; | ||
| + | |||
| + | if (processedFiles === totalFiles) { | ||
| + | showMonthlyPreview(); | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | reader.readAsText(file); | ||
| + | }); | ||
| } | } | ||
| - | function | + | // Funzione di validazione JSON NPT |
| - | | + | function |
| - | const deflectorVolume | + | |
| - | const totalVolumeWithDeflector | + | |
| - | const ratio = totalVolumeWithDeflector / data.totalVolume; | + | |
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | // Funzione per mostrare l' | ||
| + | function showMonthlyPreview() { | ||
| + | const statsDiv | ||
| + | const selectedMonth | ||
| + | const monthName | ||
| + | year: ' | ||
| + | month: ' | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | const dateStr | + | |
| - | + | | |
| - | const doctorName = patientData.prescribingDoctor ? | + | return; |
| - | | + | } |
| | | ||
| - | | + | // Calcola statistiche |
| - | const finalConcentration = data.neededGlucose > 0 ? (data.neededGlucose * 100) / data.totalVolume : 0; | + | const stats = calculateMonthlyStats(window.monthlyPreparations); |
| - | const estimatedOsmolarity | + | |
| | | ||
| - | let html = '< | + | let html = '< |
| - | + | html += '<h4 style="margin-top: 0;">📊 ANTEPRIMA - ' + monthName + '</ | |
| - | // Header | + | html += '<p>< |
| - | html += '<div class="report-header">'; | + | html += '<p>< |
| - | html += '<div class=" | + | html += '<p>< |
| - | html += '<div style=" | + | html += '< |
| - | html += '<div style=" | + | html += '<p>< |
| - | html += '</div>'; | + | |
| - | html += '<div class=" | + | |
| html += '</ | html += '</ | ||
| | | ||
| - | | + | html += '< |
| - | | + | html += '<strong>📋 File da processare:</strong><br>'; |
| - | html += '< | + | |
| - | html += '< | + | html += '• ' + prep.preparationID |
| - | html += '< | + | |
| - | html += '<tr><td class=" | + | |
| - | | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | | + | |
| html += '</ | html += '</ | ||
| | | ||
| - | | + | |
| - | html += '< | + | |
| - | | + | |
| - | | + | |
| - | html += '< | + | |
| | | ||
| - | | + | |
| - | html += '< | + | document.getElementById('generateExcelBtn').disabled = false; |
| - | | + | document.getElementById('generateExcelBtn').className = 'button'; |
| - | if (data.glucose50Volume > 0) { | + | |
| - | html += '< | + | } |
| - | } | + | |
| - | | + | // Funzione per calcolare statistiche mensili |
| - | html += '< | + | function calculateMonthlyStats(preparations) { |
| - | | + | const uniquePatients |
| - | if (data.electrolyteAdditions.nacl > 0) { | + | |
| - | html += '< | + | |
| - | | + | |
| - | if (data.electrolyteAdditions.sodium_acetate > 0) { | + | |
| - | html += '< | + | |
| - | | + | |
| - | if (data.electrolyteAdditions.kcl > 0) { | + | averageWeight: |
| - | html += '< | + | averageGIR: totalGIR |
| - | | + | averageVolume: |
| - | | + | }; |
| - | | + | } |
| - | } | + | |
| - | if (data.carnitineVolume > 0) { | + | // Funzione principale per generare Excel mensile |
| - | | + | function generateMonthlyExcel() { |
| + | if (!window.monthlyPreparations || window.monthlyPreparations.length === 0) { | ||
| + | | ||
| + | return; | ||
| } | } | ||
| | | ||
| - | | + | |
| - | + | | |
| - | | + | const wb = XLSX.utils.book_new(); |
| - | | + | |
| - | } | + | |
| - | | + | const summaryData = createSummarySheet(window.monthlyPreparations); |
| - | const peditraceVolume | + | const ws_summary = XLSX.utils.aoa_to_sheet(summaryData); |
| - | | + | |
| - | } | + | |
| - | if (data.residualNeeds.soluvit > 0) { | + | // FOGLIO 2: Dettaglio Preparazioni |
| - | | + | const detailData = createDetailSheet(window.monthlyPreparations); |
| - | | + | |
| - | } | + | XLSX.utils.book_append_sheet(wb, ws_detail, " |
| - | | + | |
| - | | + | |
| - | | + | const statsData = createStatsSheet(window.monthlyPreparations); |
| + | const ws_stats = XLSX.utils.aoa_to_sheet(statsData); | ||
| + | XLSX.utils.book_append_sheet(wb, ws_stats, " | ||
| + | |||
| + | // FOGLIO 4: Componenti NPT | ||
| + | const componentsData = createComponentsSheet(window.monthlyPreparations); | ||
| + | const ws_components | ||
| + | | ||
| + | |||
| + | | ||
| + | const selectedMonth = document.getElementById('selectedMonth').value; | ||
| + | const monthYear = selectedMonth.replace('-', ' | ||
| + | const fileName = `NPT_Consolidato_${monthYear}.xlsx`; | ||
| + | | ||
| + | // Salva il file | ||
| + | XLSX.writeFile(wb, | ||
| + | | ||
| + | // Feedback successo | ||
| + | document.getElementById('generateExcelBtn' | ||
| + | document.getElementById('generateExcelBtn').innerHTML = '📊 EXCEL GENERATO ✓'; | ||
| + | |||
| + | alert(`✅ Excel generato con successo!\n\n` + | ||
| + | `📁 File: ${fileName}\n` + | ||
| + | `📊 Preparazioni: | ||
| + | `📋 Fogli: 4 (Riepilogo, Dettaglio, Statistiche, | ||
| + | |||
| + | } catch (error) { | ||
| + | | ||
| + | | ||
| } | } | ||
| + | } | ||
| + | |||
| + | // Crea foglio riepilogo mensile | ||
| + | function createSummarySheet(preparations) { | ||
| + | const selectedMonth = document.getElementById(' | ||
| + | const monthName = new Date(selectedMonth + ' | ||
| + | year: ' | ||
| + | month: ' | ||
| + | }); | ||
| | | ||
| - | | + | |
| | | ||
| - | | + | |
| - | html += '<tr class=" | + | [`REPORT MENSILE NPT - ${monthName.toUpperCase()}`, |
| - | html += '<tr><td class=" | + | [`Generato il: ${new Date().toLocaleDateString(' |
| - | html += '<tr><td class=" | + | [`Sistema: NPT Calculator v3.0 UNIFIED`, '', |
| - | html += '<tr><td class=" | + | ['', |
| - | html += '</ | + | [' |
| - | | + | ['Totale |
| + | [' | ||
| + | ['Peso medio pazienti:', | ||
| + | ['GIR medio:', | ||
| + | [' | ||
| + | ['', '', | ||
| + | [' | ||
| + | ['ELBW (≤1000g):', | ||
| + | ['VLBW (1001-1500g):', | ||
| + | ['LBW (1501-2500g):', | ||
| + | ['NBW (>2500g):', | ||
| + | ['', '', | ||
| + | [' | ||
| + | ['0-7 giorni:', | ||
| + | ['8-14 giorni:', | ||
| + | ['15-30 giorni:', | ||
| + | ['>30 giorni:', | ||
| + | | ||
| | | ||
| - | | + | return |
| - | html += 'NPT Calculator v2.0 - Foglio di Lavoro generato il ' + new Date().toLocaleString(' | + | |
| - | html += '</ | + | |
| - | + | ||
| - | html += '</ | + | |
| - | + | ||
| - | | + | |
| } | } | ||
| - | function | + | // Crea foglio dettaglio preparazioni |
| - | const data = window.nptCalculationData; | + | function |
| - | const deflectorVolume = parseInt(document.getElementById('deflectorVolume').value) || 30; | + | const header |
| - | const totalVolumeWithDeflector = data.totalVolume + deflectorVolume; | + | ' |
| - | | + | ' |
| + | ' | ||
| + | ' | ||
| + | | ||
| | | ||
| - | const today = new Date(); | + | const data = [header]; |
| - | const dateStr = today.toLocaleDateString(' | + | |
| | | ||
| - | const medicalRecord | + | |
| - | const birthDate = patientData.prescriptionDate ? | + | |
| - | new Date(new Date(patientData.prescriptionDate).getTime() - (patientData.daysOfLife * 24 * 60 * 60 * 1000)).toLocaleDateString('it-IT') : | + | prep.preparationID |
| - | 'N/A'; | + | prep.cartellaClinica || '', |
| - | const doctorName = patientData.prescribingDoctor | + | prep.dataPrescrizione || '' |
| - | | + | |
| + | prep.paziente?.pesoAttuale || 0, | ||
| + | prep.paziente?.giorniVita || 0, | ||
| + | prep.npt? | ||
| + | prep.npt? | ||
| + | prep.npt? | ||
| + | prep.npt? | ||
| + | prep.npt? | ||
| + | prep.npt? | ||
| + | prep.personale? | ||
| + | prep.personale? | ||
| + | prep.personale? | ||
| + | ]; | ||
| + | data.push(row); | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | const finalConcentration | + | } |
| - | | + | |
| + | // Crea foglio statistiche cliniche | ||
| + | function createStatsSheet(preparations) { | ||
| + | const header | ||
| + | ' | ||
| + | | ||
| | | ||
| - | | + | |
| + | [' | ||
| + | ['', | ||
| + | header | ||
| + | ]; | ||
| | | ||
| - | // INTESTAZIONE | + | // Calcola statistiche per ogni parametro clinico |
| - | | + | |
| - | html += '<div class=" | + | { name: 'Peso (g)', values: preparations.map(p |
| - | html += '<div style=" | + | { name: 'Giorni di vita', values: preparations.map(p |
| - | html += '<div style=" | + | { name: 'Volume NPT (ml)', values: preparations.map(p |
| - | html += '</div>'; | + | { name: 'GIR (mg/ |
| - | html += '< | + | { name: 'Proteine (g/ |
| - | html += '</div>'; | + | { name: ' |
| + | { name: 'Energia (kcal/kg/die)', values: preparations.map(p | ||
| + | { name: 'Osmolarità (mOsm/L)', values: preparations.map(p => p.npt.osmolarita).filter(v => v > 0) } | ||
| + | ]; | ||
| | | ||
| - | | + | |
| - | html += '< | + | if (param.values.length > 0) { |
| + | const avg = param.values.reduce((a, | ||
| + | const min = Math.min(...param.values); | ||
| + | const max = Math.max(...param.values); | ||
| + | const variance = param.values.reduce((acc, | ||
| + | const stdDev = Math.sqrt(variance); | ||
| + | |||
| + | data.push([ | ||
| + | param.name, | ||
| + | avg.toFixed(2), | ||
| + | min.toFixed(2), | ||
| + | max.toFixed(2), | ||
| + | stdDev.toFixed(2), | ||
| + | param.values.length | ||
| + | ]); | ||
| + | } | ||
| + | }); | ||
| | | ||
| - | // INFO PAZIENTE | + | // Aggiungi sezione parametri ematochimici se disponibili |
| - | | + | |
| - | html += '<div class=" | + | |
| - | html += '<table class=" | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| - | html += '</ | + | |
| | | ||
| - | | + | |
| - | html += '< | + | { name: 'BUN (mg/dL)', values: preparations.map(p => parseFloat(p.parametriClinici?.bun)).filter(v |
| - | html += '<div class=" | + | |
| - | if (enteralData && enteralData.volume | + | |
| - | const formulaName = document.getElementById(' | + | |
| - | const formulaDisplayName = formulaData[formulaName]?.name || ' | + | |
| - | html += '< | + | |
| - | | + | |
| - | | + | |
| - | html += '</ | + | |
| - | | + | |
| - | | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| - | | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | html += '< | + | if (param.values.length > 0) { |
| - | html += '< | + | const avg = param.values.reduce((a, |
| - | html += '< | + | const min = Math.min(...param.values); |
| - | html += '< | + | const max = Math.max(...param.values); |
| + | const variance | ||
| + | const stdDev | ||
| + | |||
| + | data.push([ | ||
| + | param.name, | ||
| + | avg.toFixed(2), | ||
| + | min.toFixed(2), | ||
| + | max.toFixed(2), | ||
| + | stdDev.toFixed(2), | ||
| + | param.values.length | ||
| + | ]); | ||
| + | } | ||
| + | }); | ||
| | | ||
| - | | + | |
| - | if (data.waterVolume > 0) { | + | } |
| - | html += '< | + | |
| - | } | + | // Crea foglio componenti NPT |
| - | if (data.glucose50Volume > 0) { | + | function createComponentsSheet(preparations) { |
| - | html += '< | + | |
| - | | + | 'ID Preparazione' |
| - | if (data.electrolyteAdditions.ca_gluconato > 0) { | + | 'Intralipid |
| - | | + | 'Mg Solfato |
| - | } | + | 'Vitalipid |
| - | if (data.electrolyteAdditions.nacl > 0) { | + | |
| - | html += '< | + | |
| - | } | + | |
| - | if (data.electrolyteAdditions.kcl > 0) { | + | |
| - | | + | |
| - | } | + | |
| - | if (data.electrolyteAdditions.mg_sulfate > 0) { | + | |
| - | html += '< | + | |
| - | } | + | |
| - | if (data.carnitineVolume > 0) { | + | |
| - | | + | |
| - | } | + | |
| - | if (data.proteinVolume > 0) { | + | |
| - | html += '< | + | |
| - | } | + | |
| - | if (data.electrolyteAdditions.esafosfina > 0) { | + | |
| - | | + | |
| - | } | + | |
| - | if (data.residualNeeds.peditrace > 0) { | + | |
| - | const peditraceVolume = data.residualNeeds.peditrace * data.currentWeightKg; | + | |
| - | html += '< | + | |
| - | } | + | |
| - | if (data.residualNeeds.soluvit > 0) { | + | |
| - | const soluvitVolume = data.residualNeeds.soluvit * data.currentWeightKg; | + | |
| - | html += '< | + | |
| - | } | + | |
| - | if (data.residualNeeds.vitalipid > 0) { | + | |
| - | const vitalipidVolume = data.residualNeeds.vitalipid * data.currentWeightKg; | + | |
| - | html += '< | + | |
| - | | + | |
| - | // Gestione valore negativo per Intralipid | + | |
| - | const displayLipidVolume = data.lipidVolume < 0 ? 0 : data.lipidVolume; | + | |
| - | html += '< | + | |
| | | ||
| - | | + | |
| - | html += '<tr class=" | + | ['DETTAGLIO COMPONENTI NPT', '' |
| - | html += '< | + | ['' |
| - | html += '< | + | header |
| - | html += '< | + | ]; |
| - | html += '</ | + | |
| - | html += '</ | + | |
| | | ||
| - | | + | |
| - | html += '< | + | const comp = prep.componenti || {}; |
| - | html += '<div class=" | + | const row = [ |
| - | | + | prep.preparationID || '', |
| + | prep.cartellaClinica || '', | ||
| + | comp.glucosio50 || ' | ||
| + | comp.trophamine || ' | ||
| + | comp.intralipid || ' | ||
| + | comp.acquaBidistillata || ' | ||
| + | comp.elettroliti? | ||
| + | comp.elettroliti? | ||
| + | comp.elettroliti? | ||
| + | comp.elettroliti? | ||
| + | comp.elettroliti? | ||
| + | comp.elettroliti? | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | | ||
| + | ]; | ||
| + | data.push(row); | ||
| + | | ||
| | | ||
| - | // Calcoli degli elementi totali (enterale + parenterale) | + | // Aggiungi statistiche componenti |
| - | | + | data.push(['', |
| - | | + | data.push([' |
| + | data.push(['', | ||
| | | ||
| - | | + | // Calcola medie componenti |
| - | const totalLipids | + | const avgGlucose |
| - | const totalCarbs | + | const avgProtein |
| - | const totalCalcium = (enteralData ? enteralData.calcium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.calcium * data.currentWeightKg / 1000); | + | const avgLipid |
| - | const totalPhosphorus | + | const avgWater |
| - | const totalSodium = (enteralData ? enteralData.sodium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.sodium * data.currentWeightKg / 1000); | + | |
| - | const totalPotassium | + | |
| - | const totalMagnesium = (enteralData ? enteralData.magnesium * data.currentWeightKg / 1000 : 0) + (data.residualNeeds.magnesium * data.currentWeightKg | + | |
| - | const totalCarnitine = data.residualNeeds.carnitine * data.currentWeightKg / 1000; | + | |
| | | ||
| - | | + | data.push([' |
| - | | + | |
| - | | + | |
| + | | ||
| + | data.push([' | ||
| | | ||
| - | | + | |
| - | html += '< | + | } |
| - | html += '< | + | |
| - | html += '< | + | // ===================================================== |
| - | html += '< | + | // SISTEMA KNOWLEDGE BASE |
| - | html += '< | + | // ===================================================== |
| - | html += '< | + | |
| - | html += '< | + | // Funzione per mostrare sezioni Knowledge Base |
| - | html += '< | + | function showKnowledgeSection(sectionId) { |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | html += '< | + | |
| - | | + | |
| - | html += '< | + | |
| - | html += '</ | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | | + | const knowledgeTabs |
| - | | + | |
| + | tab.classList.remove('active'); | ||
| + | | ||
| | | ||
| - | | + | |
| + | const targetSection | ||
| + | if (targetSection) { | ||
| + | targetSection.classList.remove('hidden' | ||
| + | targetSection.classList.add(' | ||
| + | } | ||
| | | ||
| - | | + | |
| + | const clickedTab = event.target.closest(' | ||
| + | if (clickedTab) { | ||
| + | clickedTab.classList.add(' | ||
| + | } | ||
| + | |||
| + | console.log(' | ||
| } | } | ||
| - | function printCurrentReport() { | + | // Database delle regole di calcolo |
| - | const reportContent | + | const knowledgeBase |
| - | | + | calculationRules: |
| - | | + | |
| + | name: " | ||
| + | formula: " | ||
| + | unit: " | ||
| + | normalRange: | ||
| + | alerts: [ | ||
| + | { condition: "> 12", action: " | ||
| + | { condition: "> 15", action: " | ||
| + | ], | ||
| + | rationale: "Il GIR elevato può causare iperglicemia e richiede monitoraggio glicemico frequente" | ||
| + | | ||
| + | osmolarity: { | ||
| + | name: " | ||
| + | formula: "Σ(Volume componente × Osmolarità componente) ÷ Volume totale", | ||
| + | unit: " | ||
| + | thresholds: [ | ||
| + | { range: "< 600", access: " | ||
| + | { range: " | ||
| + | { range: "> 900", access: "Solo CVC (ipertonica)", | ||
| + | ], | ||
| + | rationale: "L'osmolarità determina la via di accesso vascolare per evitare flebiti" | ||
| + | }, | ||
| + | proteinAdjustment: | ||
| + | name: " | ||
| + | rules: [ | ||
| + | { bun: "< 9 mg/ | ||
| + | { bun: "9-14 mg/ | ||
| + | { bun: "> 14 mg/ | ||
| + | ], | ||
| + | monitoring: " | ||
| + | } | ||
| + | }, | ||
| | | ||
| - | | + | |
| - | | + | |
| + | elbw: { name: "ELBW ≤1000g", | ||
| + | vlbw: { name: "VLBW 1001-1500g", | ||
| + | lbw: { name: "LBW 1501-2500g", | ||
| + | term: { name: "Term > | ||
| + | } | ||
| + | }, | ||
| | | ||
| - | | + | |
| + | critical: [], | ||
| + | warning: [], | ||
| + | info: [] | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | // Funzione per ottenere spiegazione di una regola | ||
| + | function getCalculationExplanation(parameter, value) { | ||
| + | const rules = knowledgeBase.calculationRules; | ||
| + | let explanation = "" | ||
| | | ||
| - | | + | |
| - | | + | |
| - | < | + | if (value |
| - | < | + | |
| - | | + | } else if (value |
| - | < | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | < | + | |
| - | | + | |
| - | </ | + | if (value |
| - | | + | |
| - | `); | + | } else if (value |
| + | explanation = "🟠 Osmolarità elevata: Raccomandato accesso venoso centrale."; | ||
| + | | ||
| + | explanation = "🟢 Osmolarità normale: Compatibile con accesso periferico."; | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| | | ||
| - | | + | |
| - | printWindow.print(); | + | |
| } | } | ||
| - | function | + | // Funzione per mostrare tooltip informativi |
| - | const updateBtn | + | function |
| - | | + | // Crea tooltip dinamico |
| - | | + | const tooltip |
| + | | ||
| + | | ||
| + | tooltip.style.cssText = ` | ||
| + | position: absolute; | ||
| + | background-color: | ||
| + | color: white; | ||
| + | padding: 10px; | ||
| + | border-radius: | ||
| + | font-size: 12px; | ||
| + | max-width: 300px; | ||
| + | z-index: 1000; | ||
| + | box-shadow: 0 2px 10px rgba(0, | ||
| + | `; | ||
| | | ||
| + | document.body.appendChild(tooltip); | ||
| + | | ||
| + | // Posiziona tooltip | ||
| + | const rect = element.getBoundingClientRect(); | ||
| + | tooltip.style.left = rect.left + ' | ||
| + | tooltip.style.top = (rect.bottom + 5) + ' | ||
| + | | ||
| + | // Rimuovi dopo 3 secondi | ||
| setTimeout(() => { | setTimeout(() => { | ||
| - | | + | |
| - | | + | |
| + | } | ||
| }, 3000); | }, 3000); | ||
| } | } | ||
| - | // FUNZIONE SALVATAGGIO PDF | + | // Aggiorna la funzione showTab esistente per gestire il knowledge base |
| - | async function | + | function |
| - | if (!window.currentActiveReport || !window.nptCalculationData) { | + | |
| - | | + | // Questa è solo per referenza |
| - | | + | } |
| + | |||
| + | // INIZIALIZZAZIONE | ||
| + | document.addEventListener(' | ||
| + | console.log(' | ||
| + | |||
| + | // Imposta la data odierna come default | ||
| + | const today = new Date().toISOString().split(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | // Configura il campo cartella clinica | ||
| + | setupMedicalRecordField(); | ||
| + | |||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | }); | ||
| + | |||
| + | // Event listeners per resettare Fabbisogni e NPT quando si modificano i valori manualmente | ||
| + | const requirementFields = [ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ]; | ||
| + | |||
| + | requirementFields.forEach(fieldId => { | ||
| + | const field = document.getElementById(fieldId); | ||
| + | | ||
| + | field.addEventListener(' | ||
| + | resetNutritionButton(); | ||
| + | }); | ||
| + | field.addEventListener(' | ||
| + | resetNutritionButton(); | ||
| + | }); | ||
| + | | ||
| + | }); | ||
| + | |||
| + | // Event listener per il tipo di sodio | ||
| + | const sodiumTypeSelect = document.getElementById('sodiumType'); | ||
| + | if (sodiumTypeSelect) { | ||
| + | | ||
| + | updateSodiumChoice(); | ||
| + | updateSodiumRecommendation(); | ||
| + | }); | ||
| } | } | ||
| | | ||
| - | | + | // Event listener per il volume del deflussore |
| - | | + | const deflectorVolumeInput |
| - | const savePdfBtn = document.getElementById(' | + | |
| - | const originalText = savePdfBtn.innerHTML; | + | |
| - | savePdfBtn.innerHTML = '⏳ Generando PDF...'; | + | |
| - | savePdfBtn.disabled = true; | + | |
| - | + | ||
| - | // Seleziona | + | |
| - | const reportElement | + | |
| - | | + | |
| - | document.getElementById(' | + | |
| - | + | ||
| - | const reportTitle = window.currentActiveReport === ' | + | |
| - | ' | + | |
| - | + | ||
| - | // Genera il nome file con data e cartella | + | |
| - | const today = new Date(); | + | |
| - | | + | |
| - | const medicalRecord = patientData.medicalRecord || ' | + | |
| - | const fileName = `NPT_${reportTitle}_${medicalRecord}_${dateStr}.pdf`; | + | |
| - | + | ||
| - | // Configurazione html2canvas per qualità migliore | + | |
| - | const canvas = await html2canvas(reportElement, | + | |
| - | scale: 2, // Migliore qualità | + | |
| - | useCORS: true, | + | |
| - | backgroundColor: | + | |
| - | width: reportElement.offsetWidth, | + | |
| - | height: reportElement.offsetHeight, | + | |
| - | scrollX: 0, | + | |
| - | scrollY: 0 | + | |
| }); | }); | ||
| - | | + | } |
| - | // Crea PDF con dimensioni A4 | + | |
| - | const { jsPDF } = window.jspdf; | + | // Inizializza configurazione clinica avanzata |
| - | const pdf = new jsPDF({ | + | |
| - | orientation: | + | |
| - | | + | |
| - | | + | |
| - | }); | + | |
| - | + | | |
| - | // Calcola dimensioni per adattare alla pagina A4 | + | |
| - | const imgWidth | + | |
| - | const pageHeight | + | |
| - | const imgHeight = (canvas.height * imgWidth) / canvas.width; | + | |
| - | + | | |
| - | let heightLeft | + | // Inizializza tutte le dropdown e tabelle |
| - | let position | + | |
| - | + | console.log('Dropdown medici inizializzata con', Object.keys(doctorsData).length, 'medici'); | |
| - | // Aggiungi l' | + | // Test per verificare che la dropdown sia stata popolata |
| - | | + | |
| - | | + | const prescribingDoctorSelect |
| - | + | if (prescribingDoctorSelect) { | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | pdf.addPage(); | + | |
| - | | + | |
| - | heightLeft -= pageHeight; | + | |
| } | } | ||
| - | + | | |
| - | // Aggiungi metadati al PDF | + | |
| - | pdf.setProperties({ | + | |
| - | title: `NPT Calculator - ${reportTitle}`, | + | |
| - | subject: ' | + | |
| - | author: 'NPT Calculator v2.0', | + | |
| - | keywords: 'NPT, Nutrizione Parenterale, | + | |
| - | creator: 'NPT Calculator v2.0' | + | |
| - | }); | + | |
| - | + | ||
| - | // Salva il PDF | + | |
| - | pdf.save(fileName); | + | |
| - | + | ||
| - | // Ripristina il pulsante | + | |
| - | savePdfBtn.innerHTML = '✅ PDF Salvato!'; | + | |
| - | savePdfBtn.style.backgroundColor = '# | + | |
| - | + | ||
| - | setTimeout(() => { | + | |
| - | savePdfBtn.innerHTML = originalText; | + | |
| - | savePdfBtn.style.backgroundColor = '# | + | |
| - | savePdfBtn.disabled = false; | + | |
| - | }, 3000); | + | |
| - | + | ||
| - | // Mostra messaggio di conferma | + | |
| - | const confirmationMsg = document.createElement(' | + | |
| - | confirmationMsg.innerHTML = ` | + | |
| - | <div style=" | + | |
| - | padding: 15px 20px; border-radius: | + | |
| - | < | + | |
| - | File: ${fileName}< | + | |
| - | < | + | |
| - | </ | + | |
| - | `; | + | |
| - | document.body.appendChild(confirmationMsg); | + | |
| - | + | ||
| - | setTimeout(() => { | + | |
| - | document.body.removeChild(confirmationMsg); | + | |
| - | }, 5000); | + | |
| - | + | ||
| - | } catch (error) { | + | |
| - | console.error(' | + | |
| - | alert(' | + | |
| - | + | ||
| - | // Ripristina il pulsante in caso di errore | + | |
| - | const savePdfBtn = document.getElementById(' | + | |
| - | savePdfBtn.innerHTML = '💾 Salva PDF'; | + | |
| - | savePdfBtn.disabled = false; | + | |
| - | } | + | |
| - | } | + | |
| + | // Inizializza sezione mensile | ||
| + | initializeMonthlySection(); | ||
| + | console.log(' | ||
| + | }); | ||
| </ | </ | ||
| + | |||
| </ | </ | ||
| </ | </ | ||