Merge branch 'refs/heads/master' into dev_sikander
# Conflicts: # lib/presentation/habib_wallet/habib_wallet_page.dart # lib/presentation/hmg_services/services_page.dart # lib/presentation/home/landing_page.dart # lib/presentation/home/widgets/habib_wallet_card.dart # lib/presentation/insurance/insurance_home_page.dart # lib/presentation/lab/lab_orders_page.dart # lib/presentation/medical_file/medical_file_page.dart # lib/presentation/profile_settings/profile_settings.dart # lib/presentation/radiology/radiology_orders_page.dart # lib/widgets/appbar/collapsing_list_view.dartdev_sikander
|
After Width: | Height: | Size: 37 KiB |
@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.98978 14.0362H21.2589C22.0592 14.0362 22.7076 13.3877 22.7076 12.5874C22.7076 11.7871 22.0592 11.1387 21.2589 11.1387H1.98978C1.18949 11.1387 0.541029 11.7871 0.541029 12.5874C0.541029 13.3877 1.18949 14.0362 1.98978 14.0362Z" fill="#2E3039"/>
|
||||
<path d="M14.6241 20.8879C14.9764 20.8879 15.3299 20.7598 15.6087 20.5013L22.9973 13.6488C23.2952 13.3723 23.4638 12.9835 23.4609 12.5767C23.458 12.1704 23.2847 11.7833 22.9828 11.511L15.3914 4.65838C14.7974 4.12234 13.8812 4.16928 13.3451 4.76327C12.8091 5.35726 12.856 6.27345 13.45 6.80949L19.8663 12.601L13.6384 18.3769C13.0519 18.921 13.0171 19.8378 13.5613 20.4243C13.847 20.732 14.2347 20.8879 14.6241 20.8879Z" fill="#2E3039"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 803 B |
@ -0,0 +1,4 @@
|
||||
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10C18 10.5523 18.4477 11 19 11C19.5523 11 20 10.5523 20 10C20 4.47715 15.5228 0 10 0C4.47715 0 0 4.47715 0 10C0 10.5523 0.447715 11 1 11C1.55228 11 2 10.5523 2 10Z" fill="white"/>
|
||||
<path d="M10 6C10.5523 6 11 6.44772 11 7L11 12.1707C12.1652 12.5825 13 13.6938 13 15C13 16.6569 11.6569 18 10 18C8.34315 18 7 16.6569 7 15C7 13.6938 7.83481 12.5825 9 12.1707L9 7C9 6.44772 9.44772 6 10 6Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 568 B |
@ -0,0 +1,3 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 6.75C4 3.02208 7.02208 0 10.75 0C14.4779 0 17.5 3.02208 17.5 6.75C17.5 6.81385 17.5 6.84578 17.4946 6.87394C17.4654 7.02516 17.324 7.13066 17.1708 7.11566C17.1422 7.11287 17.1041 7.10157 17.028 7.07899C16.306 6.86492 15.5414 6.75 14.75 6.75C11.4211 6.75 8.56706 8.78325 7.36206 11.6756C7.21403 12.031 7.14001 12.2086 6.99327 12.2449C6.84654 12.2812 6.71484 12.1723 6.45145 11.9546L6.45144 11.9546C4.95411 10.7165 4 8.84466 4 6.75ZM8 14.75C8 11.0221 11.0221 8 14.75 8C18.4779 8 21.5 11.0221 21.5 14.75C21.5 18.4779 18.4779 21.5 14.75 21.5C11.0221 21.5 8 18.4779 8 14.75ZM6.77538 14.11C6.75857 14.3217 6.75 14.5358 6.75 14.7519C6.75 16.87 7.57313 18.7958 8.91695 20.227L8.91696 20.227C9.22203 20.5519 9.37457 20.7143 9.33165 20.8754C9.28873 21.0365 9.09982 21.0941 8.72199 21.2093C8.09819 21.3996 7.43605 21.5019 6.75 21.5019C3.02208 21.5019 0 18.4798 0 14.7519C0 12.6572 0.954182 10.7853 2.45161 9.54723C2.715 9.32946 2.8467 9.22057 2.99343 9.25688C3.14016 9.29319 3.21416 9.4708 3.36215 9.82601C3.9893 11.3312 5.0627 12.6033 6.41512 13.4766L6.4968 13.5294C6.64871 13.6275 6.72467 13.6765 6.76134 13.7507C6.79802 13.8249 6.79047 13.9199 6.77538 14.11Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,4 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="40" height="40" rx="10" fill="#EFEFF0"/>
|
||||
<path d="M11.9998 21.25C11.5858 21.2503 11.2498 21.5859 11.2498 22C11.2498 22.4141 11.5858 22.7497 11.9998 22.75H14.3953C14.577 22.75 14.7553 22.7915 14.9158 22.8691L16.9578 23.8564C17.3233 24.0333 17.7251 24.125 18.1316 24.125H19.1746C19.601 24.1251 19.9516 24.3534 20.1277 24.6719L18.1931 25.207C17.9121 25.2847 17.6116 25.2563 17.3523 25.1309L15.1687 24.0752C14.7959 23.895 14.3471 24.051 14.1667 24.4238C13.9866 24.7966 14.1427 25.2454 14.5154 25.4258L16.699 26.4814C17.2874 26.7661 17.9622 26.8265 18.5925 26.6523L21.1335 25.9502C21.4836 25.8534 21.7498 25.5327 21.7498 25.1416C21.7498 25.1125 21.7468 25.0836 21.7458 25.0547L25.8132 23.8057L25.8162 23.8047C26.3135 23.6499 26.8624 23.8288 27.1892 24.2812C27.3052 24.4419 27.2446 24.6626 27.1033 24.7441L19.5876 29.0811C19.2867 29.2546 18.9351 29.2953 18.6082 29.1982L12.2136 27.3008C11.8165 27.1829 11.3988 27.4095 11.281 27.8066C11.1632 28.2037 11.3898 28.6214 11.7869 28.7393L18.1814 30.6367C18.9059 30.8517 19.6827 30.7578 20.3376 30.3799L27.8533 26.0439C28.7864 25.5055 29.0265 24.2639 28.405 23.4033C27.7121 22.4438 26.5013 22.0206 25.3708 22.3721L25.3699 22.373L21.241 23.6416C20.7675 23.0215 20.0117 22.6251 19.1746 22.625H18.1316C17.95 22.625 17.7716 22.5844 17.6111 22.5068L15.5691 21.5186C15.2035 21.3417 14.8017 21.25 14.3953 21.25H11.9998ZM22.6511 9.91992C21.7188 9.02657 20.2817 9.02657 19.3494 9.91992C18.7347 10.5091 17.9734 11.3294 17.3611 12.2773C16.7542 13.2169 16.2498 14.3489 16.2498 15.5469C16.2498 17.8542 18.0478 20.25 21.0007 20.25C23.9534 20.2497 25.7507 17.854 25.7507 15.5469C25.7507 14.3489 25.2463 13.2169 24.6394 12.2773C24.0271 11.3294 23.2657 10.5091 22.6511 9.91992ZM20.3875 11.0029C20.7396 10.6657 21.2609 10.6657 21.613 11.0029C22.181 11.5474 22.8538 12.2767 23.3796 13.0908C23.9109 13.9134 24.2507 14.7575 24.2507 15.5469C24.2507 17.1367 23.0181 18.7497 21.0007 18.75C18.9831 18.75 17.7498 17.1369 17.7498 15.5469C17.7498 14.7575 18.0895 13.9134 18.6208 13.0908C19.1467 12.2767 19.8195 11.5474 20.3875 11.0029Z" fill="#8F9AA3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.0102 14.0362H2.74111C1.94082 14.0362 1.29236 13.3877 1.29236 12.5874C1.29236 11.7871 1.94082 11.1387 2.74111 11.1387H22.0102C22.8105 11.1387 23.459 11.7871 23.459 12.5874C23.459 13.3877 22.8105 14.0362 22.0102 14.0362Z" fill="#2E3039"/>
|
||||
<path d="M9.3759 20.8879C9.02357 20.8879 8.67007 20.7598 8.39133 20.5013L1.0027 13.6488C0.704836 13.3723 0.536202 12.9835 0.539099 12.5767C0.541997 12.1704 0.715267 11.7833 1.01719 11.511L8.60864 4.65838C9.20263 4.12234 10.1188 4.16928 10.6549 4.76327C11.1909 5.35726 11.144 6.27345 10.55 6.80949L4.13374 12.601L10.3616 18.3769C10.9481 18.921 10.9829 19.8378 10.4387 20.4243C10.153 20.732 9.76533 20.8879 9.3759 20.8879Z" fill="#2E3039"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 800 B |
@ -0,0 +1,5 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="40" height="40" rx="10" fill="#EFEFF0"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.9999 9.25C17.9288 9.25 16.2499 10.9289 16.2499 13C16.2499 14.0736 16.805 15.1188 17.4741 15.8701C17.8161 16.2541 18.2118 16.5896 18.6284 16.8334C19.038 17.0732 19.5126 17.25 19.9999 17.25C20.4872 17.25 20.9617 17.0732 21.3714 16.8334C21.7879 16.5896 22.1837 16.2541 22.5257 15.8701C23.1947 15.1188 23.7499 14.0736 23.7499 13C23.7499 10.9289 22.0709 9.25 19.9999 9.25ZM17.7499 13C17.7499 11.7574 18.7572 10.75 19.9999 10.75C21.2425 10.75 22.2499 11.7574 22.2499 13C22.2499 13.5832 21.9259 14.2881 21.4054 14.8725C21.1526 15.1564 20.876 15.3853 20.6137 15.5388C20.3444 15.6964 20.1334 15.75 19.9999 15.75C19.8663 15.75 19.6554 15.6964 19.3861 15.5388C19.1238 15.3853 18.8471 15.1564 18.5943 14.8725C18.0738 14.2881 17.7499 13.5832 17.7499 13Z" fill="#8F9AA3"/>
|
||||
<path d="M24.536 16.4361C24.2245 16.163 23.7507 16.1941 23.4776 16.5056C23.2045 16.817 23.2356 17.2909 23.5471 17.5639C24.916 18.7642 25.6946 20.6997 24.9738 22.4145C24.8973 22.5965 24.7277 22.7039 24.5514 22.7039C24.4876 22.7039 24.4316 22.7013 24.3593 22.6978C24.3058 22.6953 24.2432 22.6923 24.1618 22.6897C24.0028 22.6845 23.7976 22.6828 23.5892 22.7127C23.3824 22.7424 23.1208 22.8099 22.8813 22.9807C22.6237 23.1644 22.4437 23.4309 22.3633 23.7588L21.266 28.2337C21.1173 28.8402 20.5889 29.25 20.0001 29.25C19.4112 29.25 18.8828 28.8402 18.7341 28.2337L17.6368 23.7588C17.5564 23.4309 17.3764 23.1644 17.1188 22.9807C16.8793 22.8099 16.6177 22.7424 16.4109 22.7127C16.2025 22.6828 15.9973 22.6845 15.8383 22.6897C15.7569 22.6923 15.6944 22.6953 15.6408 22.6978C15.5685 22.7013 15.5125 22.7039 15.4487 22.7039C15.2724 22.7039 15.1028 22.5965 15.0263 22.4145C14.3055 20.6997 15.0841 18.7642 16.4531 17.5639C16.7645 17.2909 16.7956 16.817 16.5226 16.5056C16.2495 16.1941 15.7756 16.163 15.4642 16.4361C13.7871 17.9065 12.5919 20.4941 13.6435 22.9958C13.9489 23.7223 14.6555 24.2039 15.4487 24.2039C15.5413 24.2039 15.6638 24.1985 15.7652 24.1939C15.8118 24.1918 15.8541 24.1899 15.8869 24.1889C16.0232 24.1845 16.1226 24.1867 16.1979 24.1975L16.2 24.1978L17.2772 28.591C17.5861 29.8506 18.7022 30.75 20.0001 30.75C21.2979 30.75 22.414 29.8506 22.7229 28.591L23.8001 24.1978L23.8022 24.1975C23.8775 24.1867 23.9769 24.1845 24.1132 24.1889C24.146 24.1899 24.1881 24.1918 24.2346 24.1939C24.336 24.1984 24.4588 24.2039 24.5514 24.2039C25.3446 24.2039 26.0512 23.7223 26.3566 22.9958C27.4082 20.4941 26.213 17.9065 24.536 16.4361Z" fill="#8F9AA3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.0625 16.125C3.6097 16.125 0 12.5153 0 8.0625C0 3.6097 3.6097 0 8.0625 0C12.5153 0 16.125 3.6097 16.125 8.0625C16.125 12.5153 12.5153 16.125 8.0625 16.125ZM8.0625 4.3125C8.47671 4.3125 8.8125 4.64829 8.8125 5.0625V8.43749H8.93401C9.15181 8.43742 9.38226 8.43734 9.56413 8.45912C9.69673 8.47499 10.1846 8.53481 10.4097 8.99153C10.635 9.4486 10.3763 9.85561 10.3061 9.96553C10.2094 10.1169 10.0646 10.2914 9.92764 10.4564L9.90413 10.4848C9.68853 10.7449 9.43178 11.0409 9.1743 11.2764C9.04572 11.394 8.89699 11.5151 8.73553 11.6109C8.58584 11.6996 8.34945 11.8125 8.0625 11.8125C7.77556 11.8125 7.53916 11.6996 7.38947 11.6109C7.22801 11.5151 7.07929 11.394 6.95071 11.2764C6.69322 11.0409 6.43647 10.7449 6.22087 10.4848L6.19736 10.4564C6.06041 10.2914 5.91565 10.1169 5.81894 9.96552C5.74871 9.85561 5.49001 9.4486 5.71529 8.99153C5.94038 8.53481 6.42827 8.47499 6.56087 8.45912C6.74274 8.43734 6.9732 8.43742 7.191 8.43749H7.3125L7.3125 5.0625C7.3125 4.64829 7.64829 4.3125 8.0625 4.3125Z" fill="#FF9E15"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,7 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="20" height="3" rx="1.5" fill="#18C273"/>
|
||||
<rect y="4" width="20" height="3" rx="1.5" fill="#18C273" fill-opacity="0.7"/>
|
||||
<rect y="8" width="20" height="3" rx="1.5" fill="#18C273" fill-opacity="0.5"/>
|
||||
<rect y="12" width="20" height="3" rx="1.5" fill="#18C273" fill-opacity="0.35"/>
|
||||
<rect y="16" width="20" height="3" rx="1.5" fill="#18C273" fill-opacity="0.2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 476 B |
@ -0,0 +1,3 @@
|
||||
<svg width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.52965 0.0727261C9.98692 -0.024143 11.5101 -0.024341 12.9704 0.0727261C17.537 0.376286 21.1603 4.06258 21.4582 8.67235C21.5139 9.53477 21.5139 10.4268 21.4582 11.2892C21.1603 15.899 17.537 19.5853 12.9704 19.8889C11.5101 19.9859 9.98692 19.9857 8.52965 19.8889C7.96472 19.8513 7.34978 19.7177 6.80839 19.4948C6.5703 19.3967 6.40868 19.3304 6.29041 19.287C6.20909 19.3429 6.10108 19.4223 5.9438 19.5383C5.15136 20.1226 4.15092 20.5325 2.73117 20.498L2.68544 20.4969C2.41155 20.4903 2.11961 20.4834 1.88152 20.4373C1.59475 20.3818 1.23996 20.2431 1.01791 19.8645C0.776229 19.4525 0.873128 19.0358 0.966883 18.7734C1.05536 18.5257 1.20874 18.2352 1.36542 17.9385L1.3869 17.8978C1.85323 17.0141 1.98314 16.2919 1.73381 15.8104C0.901479 14.554 0.152725 13.0056 0.0418013 11.2892C-0.0139338 10.4268 -0.0139338 9.53477 0.0418013 8.67235C0.339716 4.06258 3.963 0.376286 8.52965 0.0727261ZM6.5 7.75C6.5 8.16421 6.83579 8.5 7.25 8.5H10.75C11.1642 8.5 11.5 8.16421 11.5 7.75C11.5 7.33579 11.1642 7 10.75 7L7.25 7C6.83579 7 6.5 7.33579 6.5 7.75ZM6.5 12.75C6.5 13.1642 6.83579 13.5 7.25 13.5L14.25 13.5C14.6642 13.5 15 13.1642 15 12.75C15 12.3358 14.6642 12 14.25 12L7.25 12C6.83579 12 6.5 12.3358 6.5 12.75Z" fill="#ED1C2B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.39392 1.28104e-06L11.1061 1.28104e-06C12.009 -2.95155e-05 12.7711 -5.55068e-05 13.3749 0.0704231C14.005 0.143956 14.6207 0.308473 15.1206 0.759151C15.3458 0.962221 15.5373 1.19899 15.6876 1.46113C15.9826 1.97573 16.0312 2.52334 15.9847 3.06609C16.9603 3.1787 17.7696 3.43604 18.4021 4.06966C19.0038 4.67238 19.2625 5.43113 19.3835 6.33241C19.5 7.2007 19.5 8.30477 19.5 9.67486V14.793C19.5 16.1631 19.5 17.2672 19.3835 18.1355C19.2625 19.0367 19.0038 19.7955 18.4021 20.3982C17.8002 21.0011 17.0423 21.2605 16.1419 21.3818C15.2749 21.4986 14.1725 21.4986 12.805 21.4985L6.69504 21.4985C5.32752 21.4986 4.22513 21.4986 3.35808 21.3818C2.45774 21.2605 1.69976 21.0011 1.0979 20.3982C0.496209 19.7955 0.237469 19.0367 0.116503 18.1355C-3.37213e-05 17.2672 -1.84605e-05 16.1631 4.81163e-07 14.7931L4.81163e-07 9.67484C-1.84605e-05 8.30478 -3.37213e-05 7.20069 0.116503 6.33241C0.237469 5.43113 0.496209 4.67238 1.0979 4.06966C1.73043 3.43604 2.53975 3.1787 3.51534 3.06608C3.46879 2.52334 3.51736 1.97573 3.81239 1.46113C3.96268 1.19899 4.15422 0.962221 4.37944 0.759151C4.8793 0.308473 5.49503 0.143956 6.12506 0.0704231C6.72893 -5.54994e-05 7.49097 -2.95155e-05 8.39392 1.28104e-06ZM6.35067 1.9573C5.88641 2.01149 5.74252 2.10241 5.67575 2.1626C5.5993 2.23154 5.53534 2.31095 5.48568 2.39756C5.44637 2.46613 5.39027 2.6108 5.44746 3.05137C5.50673 3.50797 5.66092 4.11081 5.89823 5.02796C6.08725 5.75848 6.21246 6.23783 6.34555 6.59684C6.47171 6.93716 6.57647 7.08584 6.6787 7.18308C6.75978 7.26021 6.85016 7.32847 6.9482 7.38631C7.07461 7.46091 7.2556 7.52465 7.63389 7.56094C7.88784 7.58531 8.19058 7.59448 8.58009 7.59793L9.30138 5.43404C9.47603 4.9101 10.0424 4.62694 10.5663 4.80159C11.0902 4.97624 11.3734 5.54256 11.1988 6.0665L10.6878 7.59935C11.1924 7.59743 11.5638 7.58994 11.8661 7.56094C12.2444 7.52465 12.4254 7.46091 12.5518 7.38631C12.6498 7.32847 12.7402 7.26021 12.8213 7.18308C12.9235 7.08584 13.0283 6.93716 13.1545 6.59684C13.2875 6.23783 13.4128 5.75848 13.6018 5.02796C13.8391 4.11081 13.9933 3.50797 14.0525 3.05137C14.1097 2.6108 14.0536 2.46613 14.0143 2.39756C13.9647 2.31095 13.9007 2.23153 13.8242 2.1626C13.7575 2.10241 13.6136 2.01149 13.1493 1.9573C12.6718 1.90157 12.0247 1.9 11.0479 1.9L8.45213 1.9C7.47532 1.9 6.82816 1.90157 6.35067 1.9573ZM7.75 15.75C7.19772 15.75 6.75 16.1977 6.75 16.75C6.75 17.3023 7.19772 17.75 7.75 17.75H11.75C12.3023 17.75 12.75 17.3023 12.75 16.75C12.75 16.1977 12.3023 15.75 11.75 15.75L7.75 15.75Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,316 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:device_calendar/device_calendar.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_reminder_view.dart';
|
||||
import 'package:hmg_patient_app_new/services/dialog_service.dart';
|
||||
import 'package:hmg_patient_app_new/services/permission_service.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:manage_calendar_events/manage_calendar_events.dart' as ios;
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:timezone/data/latest.dart' as tzl;
|
||||
|
||||
final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin();
|
||||
final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin();
|
||||
|
||||
class CalendarUtils {
|
||||
static Completer<CalendarUtils>? _completer;
|
||||
|
||||
dynamic get writableCalendars => calendars.firstWhere((c) => !c.isReadOnly!);
|
||||
dynamic calendars;
|
||||
|
||||
CalendarUtils._(this.calendars);
|
||||
|
||||
// static Future<CalendarUtils> getInstance() async {
|
||||
// if (_completer == null) {
|
||||
// _completer = Completer<CalendarUtils>();
|
||||
// print(_completer!.isCompleted);
|
||||
// try {
|
||||
// final dynamic calendarsResult;
|
||||
// if (Platform.isIOS) {
|
||||
// calendarsResult = await _myPlugin.getCalendars();
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer?.complete(CalendarUtils._(await calendarsResult!));
|
||||
// }
|
||||
// } else {
|
||||
// calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer?.complete(CalendarUtils._(await calendarsResult.data!));
|
||||
// }
|
||||
// }
|
||||
// } on Exception catch (e) {
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer!.completeError(e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return _completer!.future;
|
||||
// }
|
||||
|
||||
static Future<CalendarUtils> getInstance() async {
|
||||
tzl.initializeTimeZones();
|
||||
if (_completer != null) {
|
||||
return _completer!.future;
|
||||
}
|
||||
_completer = Completer<CalendarUtils>();
|
||||
try {
|
||||
final dynamic calendarsResult;
|
||||
if (Platform.isIOS) {
|
||||
calendarsResult = await _myPlugin.getCalendars();
|
||||
_completer!.complete(CalendarUtils._(calendarsResult));
|
||||
} else {
|
||||
calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
|
||||
_completer!.complete(CalendarUtils._(calendarsResult.data));
|
||||
}
|
||||
} catch (e) {
|
||||
_completer!.completeError(e);
|
||||
}
|
||||
|
||||
return _completer!.future;
|
||||
}
|
||||
|
||||
Future createOrUpdateEvents({List<DateTime>? scheduleList, String? title, String? description, List<DateTime>? scheduleDateTime, List<DayOfWeek>? daysOfWeek}) async {
|
||||
tzl.initializeTimeZones();
|
||||
List<Event> events = [];
|
||||
Location _currentLocation;
|
||||
if (DateTime.now().timeZoneName == "+04")
|
||||
_currentLocation = getLocation('Asia/Dubai');
|
||||
else
|
||||
_currentLocation = getLocation('Asia/Riyadh');
|
||||
|
||||
scheduleDateTime!.forEach((element) {
|
||||
RecurrenceRule recurrenceRule = RecurrenceRule(
|
||||
// RecurrenceFrequency.Daily,
|
||||
// daysOfWeek: daysOfWeek,
|
||||
// endDate: element,
|
||||
until: element, frequency: Frequency.daily,
|
||||
);
|
||||
//added byAamir Tz Time
|
||||
Event event = Event(writableCalendars!.id,
|
||||
recurrenceRule: recurrenceRule,
|
||||
start: TZDateTime.from(element, _currentLocation),
|
||||
end: TZDateTime.from(element.add(Duration(minutes: 30)), _currentLocation),
|
||||
title: title,
|
||||
description: description);
|
||||
events.add(event);
|
||||
});
|
||||
|
||||
events.forEach((element) {
|
||||
deviceCalendarPlugin.createOrUpdateEvent(element);
|
||||
});
|
||||
}
|
||||
|
||||
Future createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId}) async {
|
||||
RecurrenceRule recurrenceRule = RecurrenceRule(
|
||||
// RecurrenceFrequency.Daily,
|
||||
// daysOfWeek: daysOfWeek,
|
||||
// endDate: scheduleDateTime,
|
||||
until: scheduleDateTime, frequency: Frequency.daily,
|
||||
);
|
||||
|
||||
Location _currentLocation;
|
||||
// if (DateTime.now().timeZoneName == "+04")
|
||||
// _currentLocation = getLocation('Asia/Dubai');
|
||||
// else
|
||||
_currentLocation = getLocation('Asia/Riyadh');
|
||||
|
||||
TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation);
|
||||
|
||||
print("writableCalendars-name: " + writableCalendars.name);
|
||||
print("writableCalendars-Id: " + writableCalendars.id);
|
||||
print("writableCalendarsToString: " + writableCalendars.toString());
|
||||
print("writableCalendarsToString: " + writableCalendars!.id!);
|
||||
Event event = Event(
|
||||
writableCalendars!.id,
|
||||
start: scheduleDateTimeUTZ,
|
||||
end: scheduleDateTimeUTZ.add(Duration(minutes: 30)),
|
||||
title: title,
|
||||
description: description,
|
||||
);
|
||||
|
||||
ios.CalendarEvent iosCalEvent =
|
||||
ios.CalendarEvent(location: location, startDate: scheduleDateTimeUTZ, endDate: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description, isAllDay: false);
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
Result<bool> result = await deviceCalendarPlugin.hasPermissions();
|
||||
print(result);
|
||||
await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) {
|
||||
print("catchError " + e.toString());
|
||||
}).whenComplete(() {
|
||||
print("whenComplete Calender ID " + eventId!);
|
||||
});
|
||||
} else {
|
||||
await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) {
|
||||
print("catchError " + e.toString());
|
||||
}).whenComplete(() {
|
||||
print("whenComplete Calender ID iOS " + eventId!);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteEvent(String _calendarId, String _eventId) async {
|
||||
if (Platform.isIOS) {
|
||||
await _myPlugin.deleteEvent(calendarId: _calendarId, eventId: _eventId);
|
||||
} else {
|
||||
await deviceCalendarPlugin.deleteEvent(_calendarId, _eventId);
|
||||
}
|
||||
}
|
||||
|
||||
Future retrieveEvents(
|
||||
String calendarId,
|
||||
RetrieveEventsParams retrieveEventsParams,
|
||||
) async {
|
||||
if (Platform.isIOS) {
|
||||
return await _myPlugin.getEvents(calendarId: calendarId);
|
||||
} else {
|
||||
return await deviceCalendarPlugin.retrieveEvents(calendarId, retrieveEventsParams);
|
||||
}
|
||||
}
|
||||
|
||||
Future createCalendar(
|
||||
String calendarName, {
|
||||
Color? calendarColor,
|
||||
String? localAccountName,
|
||||
}) async {
|
||||
return await deviceCalendarPlugin.createCalendar(calendarName, calendarColor: calendarColor, localAccountName: localAccountName);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<Permission, PermissionStatus>> requestPermissions() async {
|
||||
var permissionResults = [Permission.calendarFullAccess].request();
|
||||
return permissionResults;
|
||||
}
|
||||
|
||||
showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
|
||||
{required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async {
|
||||
if (Platform.isAndroid) {
|
||||
if (await PermissionService.isCalendarPermissionEnabled()) {
|
||||
_showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
} else {
|
||||
// Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async {
|
||||
// if (await Permission.calendarFullAccess.request().isGranted) {
|
||||
// _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
// onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
} else {
|
||||
if (await Permission.calendarWriteOnly.request().isGranted) {
|
||||
if (await Permission.calendarFullAccess.request().isGranted) {
|
||||
_showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
|
||||
{required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async {
|
||||
showCommonBottomSheetWithoutHeight(providedContext, title: "Set the timer of reminder", child: PrescriptionReminderView(
|
||||
setReminder: (int value) async {
|
||||
if (!isMultiAllowed!) {
|
||||
if (onMultiDateSuccess == null) {
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
await calendarUtils.createOrUpdateEvent(
|
||||
title: title ?? "You have appointment with Dr. $doctorName",
|
||||
description: description ?? "At $appoDateFormatted $appoTimeFormatted",
|
||||
scheduleDateTime: dateTime,
|
||||
eventId: eventId,
|
||||
location: '');
|
||||
onSuccess();
|
||||
}
|
||||
} else {
|
||||
onMultiDateSuccess!(value);
|
||||
}
|
||||
},
|
||||
), callBackFunc: () {}, isFullScreen: false);
|
||||
}
|
||||
|
||||
setCalender(BuildContext context,
|
||||
{required String eventId, required int selectedMinutes, int? frequencyNumber, required int days, required String orderDate, required String itemDescriptionN, required String route}) async {
|
||||
DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0);
|
||||
frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2
|
||||
|
||||
int remainingDays = days - (Jiffy.parseFromDateTime(DateTime.now()).diff(Jiffy.parseFromDateTime(DateUtil.convertStringToDate(orderDate)), unit: Unit.day) as int);
|
||||
if (remainingDays.isNegative) {
|
||||
getIt.get<DialogService>().showErrorBottomSheet(message: "Prescription date has been already passed you can not add a reminder for this prescription.");
|
||||
return;
|
||||
}
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < remainingDays; i++) {
|
||||
//event for number of days.
|
||||
for (int j = 0; j < frequencyNumber; j++) {
|
||||
// event for number of times per day.
|
||||
if (j != 0) {
|
||||
actualDate.add(new Duration(hours: 8)); // 8 hours addition for daily dose.
|
||||
}
|
||||
//Time subtraction from actual reminder time. like before 30, or 1 hour.
|
||||
|
||||
actualDate = Jiffy.parseFromDateTime(actualDate).subtract(minutes: selectedMinutes).dateTime;
|
||||
|
||||
calendarUtils.createOrUpdateEvent(
|
||||
title: "$itemDescriptionN} Prescription Reminder",
|
||||
description: "$itemDescriptionN $frequencyNumber $route ",
|
||||
scheduleDateTime: actualDate,
|
||||
eventId: eventId + (i.toString() + j.toString()),
|
||||
location: '', //event id with varitions
|
||||
);
|
||||
print("Creating event #$j for day $i → $actualDate");
|
||||
actualDate = DateTime(actualDate.year, actualDate.month, actualDate.day, 8, 0);
|
||||
}
|
||||
actualDate = Jiffy.parseFromDateTime(actualDate).add(days: 1).dateTime;
|
||||
}
|
||||
} catch (ex) {
|
||||
getIt.get<DialogService>().showErrorBottomSheet(message: "catch:$ex");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkAndRemove(hasReminder, {bool delete = false, String itemDescriptionN = ""}) async {
|
||||
final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin();
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime;
|
||||
DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime;
|
||||
RetrieveEventsParams params = RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate);
|
||||
|
||||
if (calendarUtils.calendars != null) {
|
||||
if (Platform.isAndroid) {
|
||||
await processEvents(calendarUtils.calendars, calendarUtils, params, delete, itemDescriptionN, hasReminder);
|
||||
} else {
|
||||
List<ios.Calendar>? iosCalendars = await _myPlugin.getCalendars();
|
||||
if (iosCalendars != null) {
|
||||
await processEvents(iosCalendars.map((cal) => Calendar(id: cal.id, name: cal.name, accountName: cal.accountName)).toList(), calendarUtils, params, delete, itemDescriptionN, hasReminder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> processEvents(List<Calendar> calendars, calendarUtils, params, delete, String itemDescriptionN, hasReminder) async {
|
||||
for (var calendar in calendars) {
|
||||
Result<UnmodifiableListView<Event>> events = await calendarUtils.retrieveEvents(calendar.id!, params);
|
||||
for (var event in events.data!) {
|
||||
if (event.title!.contains(itemDescriptionN)) {
|
||||
if (delete) {
|
||||
await calendarUtils.deleteEvent(calendar, event);
|
||||
// AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess);
|
||||
hasReminder = false;
|
||||
} else {
|
||||
hasReminder = false;
|
||||
// setState(() {
|
||||
// hasReminder = true;
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:hmg_patient_app_new/features/active_prescriptions/models/active_prescriptions_response_model.dart';
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/api_consts.dart';
|
||||
import '../../core/common_models/generic_api_model.dart';
|
||||
import '../../core/exceptions/api_failure.dart';
|
||||
import '../../services/logger_service.dart';
|
||||
|
||||
abstract class ActivePrescriptionsRepo {
|
||||
|
||||
Future<Either<Failure, GenericApiModel<List<ActivePrescriptionsResponseModel>>>> getActivePrescriptionsDetails();
|
||||
|
||||
}
|
||||
|
||||
class ActivePrescriptionsRepoImp implements ActivePrescriptionsRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
ActivePrescriptionsRepoImp({required this.loggerService, required this.apiClient});
|
||||
|
||||
@override
|
||||
|
||||
Future<Either<Failure, GenericApiModel<List<ActivePrescriptionsResponseModel>>>> getActivePrescriptionsDetails() async
|
||||
{
|
||||
try {
|
||||
GenericApiModel<List<ActivePrescriptionsResponseModel>>? apiResponse;
|
||||
Failure? failure;
|
||||
await apiClient.post(
|
||||
ApiConsts.getActivePrescriptionsDetails,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
var list = response['List_ActiveGetPrescriptionReportByPatientID'];
|
||||
var res = list
|
||||
.map<ActivePrescriptionsResponseModel>(
|
||||
(item) => ActivePrescriptionsResponseModel.fromJson(item))
|
||||
.toList();
|
||||
|
||||
apiResponse = GenericApiModel<List<ActivePrescriptionsResponseModel>>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: null,
|
||||
// data: response,
|
||||
data: res
|
||||
);
|
||||
return apiResponse;
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/features/active_prescriptions/models/active_prescriptions_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_repo.dart';
|
||||
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
||||
|
||||
class ActivePrescriptionsViewModel extends ChangeNotifier {
|
||||
late ActivePrescriptionsRepo activePrescriptionsRepo;
|
||||
late ErrorHandlerService errorHandlerService;
|
||||
List<ActivePrescriptionsResponseModel> activePrescriptionsDetailsList = [];
|
||||
|
||||
ActivePrescriptionsViewModel({
|
||||
required this.activePrescriptionsRepo,
|
||||
required this.errorHandlerService,
|
||||
});
|
||||
|
||||
Future<void> getActiveMedications({
|
||||
Function(dynamic)? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
final result =
|
||||
await activePrescriptionsRepo.getActivePrescriptionsDetails();
|
||||
result.fold(
|
||||
(failure) async =>
|
||||
await errorHandlerService.handleError(failure: failure),
|
||||
(apiResponse) {
|
||||
if (apiResponse.messageStatus == 1) {
|
||||
activePrescriptionsDetailsList = apiResponse.data ?? [];
|
||||
notifyListeners();
|
||||
if (onSuccess != null) onSuccess(apiResponse.data);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
DateTime parseDate(String? date) {
|
||||
if (date == null) return DateTime.now();
|
||||
final regex = RegExp(r"\/Date\((\d+)([+-]\d+)?\)\/");
|
||||
final match = regex.firstMatch(date);
|
||||
if (match != null) {
|
||||
final millis = int.parse(match.group(1)!);
|
||||
return DateTime.fromMillisecondsSinceEpoch(millis);
|
||||
}
|
||||
return DateTime.tryParse(date) ?? DateTime.now();
|
||||
}
|
||||
|
||||
List<DateTime> generateMedicationDays(ActivePrescriptionsResponseModel med) {
|
||||
final start = parseDate(med.startDate);
|
||||
final duration = med.days ?? 0;
|
||||
if (duration <= 0) return [];
|
||||
final f = (med.frequency ?? "").toLowerCase().trim();
|
||||
int intervalDays = 1;
|
||||
|
||||
if (f.contains("every six hours") ||
|
||||
f.contains("every 6 hours") ||
|
||||
f.contains("every four hours") ||
|
||||
f.contains("every 4 hours") ||
|
||||
f.contains("every eight hours") ||
|
||||
f.contains("every 8 hours") ||
|
||||
f.contains("every 12 hours") ||
|
||||
f.contains("every twelve hours") ||
|
||||
f.contains("every 24 hours") ||
|
||||
f.contains("3 times a day") ||
|
||||
f.contains("once a day")) {
|
||||
intervalDays = 1;
|
||||
}
|
||||
else if (f.contains("once a week")) {
|
||||
intervalDays = 7;
|
||||
}
|
||||
else if (f.contains("every 3 days")) {
|
||||
intervalDays = 3;
|
||||
}
|
||||
else if (f.contains("every other day")) {
|
||||
intervalDays = 2;
|
||||
}
|
||||
|
||||
List<DateTime> result = [];
|
||||
for (int offset = 0; offset < duration; offset += intervalDays) {
|
||||
result.add(start.add(Duration(days: offset)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool sameYMD(DateTime a, DateTime b) =>
|
||||
a.year == b.year && a.month == b.month && a.day == b.day;
|
||||
|
||||
List<ActivePrescriptionsResponseModel> getMedsForSelectedDay(
|
||||
DateTime selectedDate) {
|
||||
final clean = DateTime(selectedDate.year, selectedDate.month, selectedDate.day);
|
||||
|
||||
return activePrescriptionsDetailsList.where((med) {
|
||||
final days = generateMedicationDays(med);
|
||||
return days.any((d) => sameYMD(d, clean));
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
|
||||
class ActivePrescriptionsResponseModel {
|
||||
String? itemId;
|
||||
String? itemDescription;
|
||||
String? route;
|
||||
String? frequency;
|
||||
int? frequencyNumber;
|
||||
int? doseDailyQuantity;
|
||||
int? days;
|
||||
String? startDate;
|
||||
String? endDate;
|
||||
String? orderDate;
|
||||
String? productImageString;
|
||||
bool isReminderOn;
|
||||
List<String?> selectedDoseTimes = [];
|
||||
|
||||
ActivePrescriptionsResponseModel({
|
||||
this.itemId,
|
||||
this.itemDescription,
|
||||
this.route,
|
||||
this.frequency,
|
||||
this.frequencyNumber,
|
||||
this.doseDailyQuantity,
|
||||
this.days,
|
||||
this.startDate,
|
||||
this.endDate,
|
||||
this.orderDate,
|
||||
this.productImageString,
|
||||
this.isReminderOn = false,
|
||||
List<String?>? selectedDoseTimes,
|
||||
}) {
|
||||
this.selectedDoseTimes = selectedDoseTimes ?? [];
|
||||
}
|
||||
|
||||
/// ========== JSON FROM ==========
|
||||
factory ActivePrescriptionsResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
return ActivePrescriptionsResponseModel(
|
||||
itemId: json["ItemID"]?.toString() ?? "",
|
||||
itemDescription: json["ItemDescription"] ?? "",
|
||||
route: json["Route"] ?? "",
|
||||
frequency: json["Frequency"] ?? "",
|
||||
frequencyNumber: json["FrequencyNumber"],
|
||||
doseDailyQuantity: json["DoseDailyQuantity"] ?? 1,
|
||||
days: json["Days"] ?? 0,
|
||||
startDate: json["StartDate"] ?? "",
|
||||
endDate: json["EndDate"] ?? "",
|
||||
orderDate: json["OrderDate"] ?? "",
|
||||
productImageString: json["ProductImageString"] ?? "",
|
||||
isReminderOn: json["IsReminderOn"] == true,
|
||||
selectedDoseTimes:
|
||||
(json["SelectedDoseTimes"] as List<dynamic>?)
|
||||
?.map((e) => e?.toString())
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// ========== JSON TO ==========
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"ItemID": itemId,
|
||||
"ItemDescription": itemDescription,
|
||||
"Route": route,
|
||||
"Frequency": frequency,
|
||||
"FrequencyNumber": frequencyNumber,
|
||||
"DoseDailyQuantity": doseDailyQuantity,
|
||||
"Days": days,
|
||||
"StartDate": startDate,
|
||||
"EndDate": endDate,
|
||||
"OrderDate": orderDate,
|
||||
"ProductImageString": productImageString,
|
||||
"IsReminderOn": isReminderOn,
|
||||
"SelectedDoseTimes": selectedDoseTimes,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class BdProjectsHaveBdClinicsModel {
|
||||
List<BdGetProjectsHaveBdClinic>? bdGetProjectsHaveBdClinics;
|
||||
|
||||
BdProjectsHaveBdClinicsModel({
|
||||
this.bdGetProjectsHaveBdClinics,
|
||||
});
|
||||
|
||||
factory BdProjectsHaveBdClinicsModel.fromRawJson(String str) => BdProjectsHaveBdClinicsModel.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory BdProjectsHaveBdClinicsModel.fromJson(Map<String, dynamic> json) => BdProjectsHaveBdClinicsModel(
|
||||
bdGetProjectsHaveBdClinics: json["BD_getProjectsHaveBDClinics"] == null ? [] : List<BdGetProjectsHaveBdClinic>.from(json["BD_getProjectsHaveBDClinics"]!.map((x) => BdGetProjectsHaveBdClinic.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"BD_getProjectsHaveBDClinics": bdGetProjectsHaveBdClinics == null ? [] : List<dynamic>.from(bdGetProjectsHaveBdClinics!.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
|
||||
class BdGetProjectsHaveBdClinic {
|
||||
int? rowId;
|
||||
int? id;
|
||||
int? projectId;
|
||||
int? numberOfRooms;
|
||||
bool? isActive;
|
||||
int? createdBy;
|
||||
String? createdOn;
|
||||
dynamic editedBy;
|
||||
dynamic editedOn;
|
||||
String? projectName;
|
||||
dynamic projectNameN;
|
||||
|
||||
BdGetProjectsHaveBdClinic({
|
||||
this.rowId,
|
||||
this.id,
|
||||
this.projectId,
|
||||
this.numberOfRooms,
|
||||
this.isActive,
|
||||
this.createdBy,
|
||||
this.createdOn,
|
||||
this.editedBy,
|
||||
this.editedOn,
|
||||
this.projectName,
|
||||
this.projectNameN,
|
||||
});
|
||||
|
||||
factory BdGetProjectsHaveBdClinic.fromRawJson(String str) => BdGetProjectsHaveBdClinic.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory BdGetProjectsHaveBdClinic.fromJson(Map<String, dynamic> json) => BdGetProjectsHaveBdClinic(
|
||||
rowId: json["RowID"],
|
||||
id: json["ID"],
|
||||
projectId: json["ProjectID"],
|
||||
numberOfRooms: json["NumberOfRooms"],
|
||||
isActive: json["IsActive"],
|
||||
createdBy: json["CreatedBy"],
|
||||
createdOn: json["CreatedOn"],
|
||||
editedBy: json["EditedBy"],
|
||||
editedOn: json["EditedON"],
|
||||
projectName: json["ProjectName"],
|
||||
projectNameN: json["ProjectNameN"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"RowID": rowId,
|
||||
"ID": id,
|
||||
"ProjectID": projectId,
|
||||
"NumberOfRooms": numberOfRooms,
|
||||
"IsActive": isActive,
|
||||
"CreatedBy": createdBy,
|
||||
"CreatedOn": createdOn,
|
||||
"EditedBy": editedBy,
|
||||
"EditedON": editedOn,
|
||||
"ProjectName": projectName,
|
||||
"ProjectNameN": projectNameN,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors;
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HospitalBottomSheetBodySelection extends StatelessWidget {
|
||||
final Function(BdGetProjectsHaveBdClinic userSelection) onUserHospitalSelection;
|
||||
|
||||
const HospitalBottomSheetBodySelection({super.key, required this.onUserHospitalSelection(BdGetProjectsHaveBdClinic userSelection)});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bloodDonationVm = Provider.of<BloodDonationViewModel>(context, listen: false);
|
||||
AppState appState = getIt.get<AppState>();
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.selectHospital.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.greyTextColor),
|
||||
SizedBox(height: 16.h),
|
||||
SizedBox(
|
||||
height: MediaQuery.sizeOf(context).height * .4,
|
||||
child: ListView.separated(
|
||||
itemBuilder: (_, index) {
|
||||
return DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 20.h,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 8.h,
|
||||
children: [
|
||||
hospitalName(bloodDonationVm.hospitalList[index]).onPress(() {
|
||||
onUserHospitalSelection(bloodDonationVm.hospitalList[index]);
|
||||
Navigator.of(context).pop();
|
||||
})
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.flip(
|
||||
flipX: appState.isArabic(),
|
||||
child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, iconColor: AppColors.blackColor, width: 40.h, height: 40.h, fit: BoxFit.contain),
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(16.h, 16.h),
|
||||
).onPress(() {
|
||||
bloodDonationVm.setSelectedHospital(bloodDonationVm.hospitalList[index]);
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
},
|
||||
separatorBuilder: (_, __) => SizedBox(height: 16.h),
|
||||
itemCount: bloodDonationVm.hospitalList.length),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget hospitalName(dynamic hospital) => Row(
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.hmg).paddingOnly(right: 10),
|
||||
Expanded(
|
||||
child: Text(hospital.projectName ?? "", style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16, color: AppColors.blackColor)),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,873 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:hmg_patient_app_new/core/api/api_client.dart';
|
||||
import 'package:hmg_patient_app_new/core/api_consts.dart';
|
||||
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
|
||||
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
|
||||
import 'package:hmg_patient_app_new/services/logger_service.dart';
|
||||
|
||||
/// Progress types to request different ranges from the progress API.
|
||||
enum ProgressType { today, week, month }
|
||||
|
||||
abstract class HealthTrackersRepo {
|
||||
// ==================== BLOOD SUGAR (DIABETIC) ====================
|
||||
/// Get blood sugar result averages (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResultAverage();
|
||||
|
||||
/// Get blood sugar results (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResults();
|
||||
|
||||
/// Add new blood sugar result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({
|
||||
required String bloodSugarDateChart,
|
||||
required String bloodSugarResult,
|
||||
required String diabeticUnit,
|
||||
required int measuredTime,
|
||||
});
|
||||
|
||||
/// Update existing blood sugar result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateDiabeticResult({
|
||||
required DateTime month,
|
||||
required DateTime hour,
|
||||
required String bloodSugarResult,
|
||||
required String diabeticUnit,
|
||||
required int measuredTime,
|
||||
required int lineItemNo,
|
||||
});
|
||||
|
||||
/// Deactivate blood sugar record.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateDiabeticStatus({
|
||||
required int lineItemNo,
|
||||
});
|
||||
|
||||
/// Send blood sugar report by email.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendBloodSugarReportByEmail({
|
||||
required String email,
|
||||
});
|
||||
|
||||
// ==================== BLOOD PRESSURE ====================
|
||||
/// Get blood pressure result averages (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getBloodPressureResultAverage();
|
||||
|
||||
/// Get blood pressure results (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getBloodPressureResults();
|
||||
|
||||
/// Add new blood pressure result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addBloodPressureResult({
|
||||
required String bloodPressureDate,
|
||||
required String diastolicPressure,
|
||||
required String systolicePressure,
|
||||
required int measuredArm,
|
||||
});
|
||||
|
||||
/// Update existing blood pressure result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateBloodPressureResult({
|
||||
required String bloodPressureDate,
|
||||
required String diastolicPressure,
|
||||
required String systolicePressure,
|
||||
required int measuredArm,
|
||||
required int lineItemNo,
|
||||
});
|
||||
|
||||
/// Deactivate blood pressure record.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateBloodPressureStatus({
|
||||
required int lineItemNo,
|
||||
});
|
||||
|
||||
/// Send blood pressure report by email.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendBloodPressureReportByEmail({
|
||||
required String email,
|
||||
});
|
||||
|
||||
// ==================== WEIGHT MEASUREMENT ====================
|
||||
/// Get weight measurement result averages (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getWeightMeasurementResultAverage();
|
||||
|
||||
/// Get weight measurement results (week, month, year).
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getWeightMeasurementResults();
|
||||
|
||||
/// Add new weight measurement result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addWeightMeasurementResult({
|
||||
required String weightDate,
|
||||
required String weightMeasured,
|
||||
required int weightUnit,
|
||||
});
|
||||
|
||||
/// Update existing weight measurement result.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateWeightMeasurementResult({
|
||||
required int lineItemNo,
|
||||
required int weightUnit,
|
||||
required String weightMeasured,
|
||||
required String weightDate,
|
||||
});
|
||||
|
||||
/// Deactivate weight measurement record.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateWeightMeasurementStatus({
|
||||
required int lineItemNo,
|
||||
});
|
||||
|
||||
/// Send weight report by email.
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendWeightReportByEmail({
|
||||
required String email,
|
||||
});
|
||||
}
|
||||
|
||||
class HealthTrackersRepoImp implements HealthTrackersRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
HealthTrackersRepoImp({required this.loggerService, required this.apiClient});
|
||||
|
||||
// ==================== BLOOD SUGAR (DIABETIC) METHODS ====================
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResultAverage() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getDiabeticResultAverage,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract average lists
|
||||
extracted = {
|
||||
'monthAverageList': response['List_MonthDiabtectResultAverage'] ?? [],
|
||||
'weekAverageList': response['List_WeekDiabtectResultAverage'] ?? [],
|
||||
'yearAverageList': response['List_YearDiabtecResultAverage'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getDiabeticResults() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getDiabeticResult,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract patient result lists
|
||||
extracted = {
|
||||
'monthResultList': response['List_MonthDiabtecPatientResult'] ?? [],
|
||||
'weekResultList': response['List_WeekDiabtecPatientResult'] ?? [],
|
||||
'yearResultList': response['List_YearDiabtecPatientResult'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addDiabeticResult({
|
||||
required String bloodSugarDateChart,
|
||||
required String bloodSugarResult,
|
||||
required String diabeticUnit,
|
||||
required int measuredTime,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'BloodSugerDateChart': bloodSugarDateChart,
|
||||
'BloodSugerResult': bloodSugarResult,
|
||||
'DiabtecUnit': diabeticUnit,
|
||||
'MeasuredTime': measuredTime + 1, // Add 1 as per old service
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.addDiabeticResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateDiabeticResult({
|
||||
required DateTime month,
|
||||
required DateTime hour,
|
||||
required String bloodSugarResult,
|
||||
required String diabeticUnit,
|
||||
required int measuredTime,
|
||||
required int lineItemNo,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
// Format: 'YYYY-MM-DD HH:MM:SS' as per old service
|
||||
String formattedDate = '${month.year}-${month.month}-${month.day} ${hour.hour}:${hour.minute}:00';
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'BloodSugerDateChart': formattedDate,
|
||||
'BloodSugerResult': bloodSugarResult,
|
||||
'DiabtecUnit': diabeticUnit,
|
||||
'MeasuredTime': measuredTime + 1, // Add 1 as per old service
|
||||
'LineItemNo': lineItemNo,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.updateDiabeticResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateDiabeticStatus({
|
||||
required int lineItemNo,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'LineItemNo': lineItemNo,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.deactivateDiabeticStatus,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendBloodSugarReportByEmail({
|
||||
required String email,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'To': email,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.sendAverageBloodSugarReport,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== BLOOD PRESSURE METHODS ====================
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getBloodPressureResultAverage() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getBloodPressureResultAverage,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract all three list types
|
||||
extracted = {
|
||||
'monthList': response['List_MonthBloodPressureResultAverage'] ?? [],
|
||||
'weekList': response['List_WeekBloodPressureResultAverage'] ?? [],
|
||||
'yearList': response['List_YearBloodPressureResultAverage'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getBloodPressureResults() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getBloodPressureResult,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract all three list types
|
||||
extracted = {
|
||||
'weekList': response['List_WeekBloodPressureResult'] ?? [],
|
||||
'monthList': response['List_MonthBloodPressureResult'] ?? [],
|
||||
'yearList': response['List_YearBloodPressureResult'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addBloodPressureResult({
|
||||
required String bloodPressureDate,
|
||||
required String diastolicPressure,
|
||||
required String systolicePressure,
|
||||
required int measuredArm,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'BloodPressureDate': bloodPressureDate,
|
||||
'DiastolicPressure': diastolicPressure,
|
||||
'SystolicePressure': systolicePressure,
|
||||
'MeasuredArm': measuredArm,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.addBloodPressureResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateBloodPressureResult({
|
||||
required String bloodPressureDate,
|
||||
required String diastolicPressure,
|
||||
required String systolicePressure,
|
||||
required int measuredArm,
|
||||
required int lineItemNo,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'BloodPressureDate': bloodPressureDate,
|
||||
'DiastolicPressure': diastolicPressure,
|
||||
'SystolicePressure': systolicePressure,
|
||||
'MeasuredArm': measuredArm,
|
||||
'LineItemNo': lineItemNo,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.updateBloodPressureResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateBloodPressureStatus({
|
||||
required int lineItemNo,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'LineItemNo': lineItemNo,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.deactivateBloodPressureStatus,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendBloodPressureReportByEmail({
|
||||
required String email,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'To': email,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.sendAverageBloodPressureReport,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== WEIGHT MEASUREMENT METHODS ====================
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getWeightMeasurementResultAverage() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getWeightMeasurementResultAverage,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract average lists
|
||||
extracted = {
|
||||
'monthAverageList': response['List_MonthWeightMeasurementResultAverage'] ?? [],
|
||||
'weekAverageList': response['List_WeekWeightMeasurementResultAverage'] ?? [],
|
||||
'yearAverageList': response['List_YearWeightMeasurementResultAverage'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> getWeightMeasurementResults() async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getWeightMeasurementResult,
|
||||
body: {},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
dynamic extracted;
|
||||
if (response is Map) {
|
||||
// Extract result lists
|
||||
extracted = {
|
||||
'weekResultList': response['List_WeekWeightMeasurementResult'] ?? [],
|
||||
'monthResultList': response['List_MonthWeightMeasurementResult'] ?? [],
|
||||
'yearResultList': response['List_YearWeightMeasurementResult'] ?? [],
|
||||
};
|
||||
} else {
|
||||
extracted = response;
|
||||
}
|
||||
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: extracted,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> addWeightMeasurementResult({
|
||||
required String weightDate,
|
||||
required String weightMeasured,
|
||||
required int weightUnit,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'WeightDate': weightDate,
|
||||
'WeightMeasured': weightMeasured,
|
||||
'weightUnit': weightUnit,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.addWeightMeasurementResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> updateWeightMeasurementResult({
|
||||
required int lineItemNo,
|
||||
required int weightUnit,
|
||||
required String weightMeasured,
|
||||
required String weightDate,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'LineItemNo': lineItemNo,
|
||||
'weightUnit': '$weightUnit', // Convert to string as per old service
|
||||
'WeightMeasured': weightMeasured,
|
||||
'WeightDate': weightDate,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.updateWeightMeasurementResult,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateWeightMeasurementStatus({required int lineItemNo}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'LineItemNo': lineItemNo,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.deactivateWeightMeasurementStatus,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> sendWeightReportByEmail({
|
||||
required String email,
|
||||
}) async {
|
||||
try {
|
||||
GenericApiModel<dynamic>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
Map<String, dynamic> body = {
|
||||
'To': email,
|
||||
};
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.sendAverageBodyWeightReport,
|
||||
body: body,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
apiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class BloodPressureResult {
|
||||
int? patientID;
|
||||
int? lineItemNo;
|
||||
DateTime? bloodPressureDate;
|
||||
int? measuredArm;
|
||||
int? systolicePressure;
|
||||
int? diastolicPressure;
|
||||
dynamic remark;
|
||||
bool? isActive;
|
||||
int? chartYear;
|
||||
String? chartMonth;
|
||||
dynamic yearSystolicePressureAverageResult;
|
||||
dynamic monthSystolicePressureResult;
|
||||
dynamic weekSystolicePressureResult;
|
||||
int? yearDiastolicPressureAverageResult;
|
||||
dynamic monthDiastolicPressureResult;
|
||||
dynamic weekDiastolicPressureResult;
|
||||
String? measuredArmDesc;
|
||||
dynamic weekDesc;
|
||||
|
||||
BloodPressureResult(
|
||||
{this.patientID,
|
||||
this.lineItemNo,
|
||||
this.bloodPressureDate,
|
||||
this.measuredArm,
|
||||
this.systolicePressure,
|
||||
this.diastolicPressure,
|
||||
this.remark,
|
||||
this.isActive,
|
||||
this.chartYear,
|
||||
this.chartMonth,
|
||||
this.yearSystolicePressureAverageResult,
|
||||
this.monthSystolicePressureResult,
|
||||
this.weekSystolicePressureResult,
|
||||
this.yearDiastolicPressureAverageResult,
|
||||
this.monthDiastolicPressureResult,
|
||||
this.weekDiastolicPressureResult,
|
||||
this.measuredArmDesc,
|
||||
this.weekDesc});
|
||||
|
||||
BloodPressureResult.fromJson(Map<String, dynamic> json) {
|
||||
patientID = json['PatientID'];
|
||||
lineItemNo = json['LineItemNo'];
|
||||
bloodPressureDate = DateUtil.convertStringToDate(json['BloodPressureDate']);
|
||||
measuredArm = json['MeasuredArm'];
|
||||
systolicePressure = json['SystolicePressure'];
|
||||
diastolicPressure = json['DiastolicPressure'];
|
||||
remark = json['Remark'];
|
||||
isActive = json['IsActive'];
|
||||
chartYear = json['ChartYear'];
|
||||
chartMonth = json['ChartMonth'];
|
||||
yearSystolicePressureAverageResult = json['YearSystolicePressureAverageResult'];
|
||||
monthSystolicePressureResult = json['MonthSystolicePressureResult'];
|
||||
weekSystolicePressureResult = json['WeekSystolicePressureResult'];
|
||||
yearDiastolicPressureAverageResult = json['YearDiastolicPressureAverageResult'];
|
||||
monthDiastolicPressureResult = json['MonthDiastolicPressureResult'];
|
||||
weekDiastolicPressureResult = json['WeekDiastolicPressureResult'];
|
||||
measuredArmDesc = json['MeasuredArmDesc'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['PatientID'] = patientID;
|
||||
data['LineItemNo'] = lineItemNo;
|
||||
data['BloodPressureDate'] = bloodPressureDate;
|
||||
data['MeasuredArm'] = measuredArm;
|
||||
data['SystolicePressure'] = systolicePressure;
|
||||
data['DiastolicPressure'] = diastolicPressure;
|
||||
data['Remark'] = remark;
|
||||
data['IsActive'] = isActive;
|
||||
data['ChartYear'] = chartYear;
|
||||
data['ChartMonth'] = chartMonth;
|
||||
data['YearSystolicePressureAverageResult'] = yearSystolicePressureAverageResult;
|
||||
data['MonthSystolicePressureResult'] = monthSystolicePressureResult;
|
||||
data['WeekSystolicePressureResult'] = weekSystolicePressureResult;
|
||||
data['YearDiastolicPressureAverageResult'] = yearDiastolicPressureAverageResult;
|
||||
data['MonthDiastolicPressureResult'] = monthDiastolicPressureResult;
|
||||
data['WeekDiastolicPressureResult'] = weekDiastolicPressureResult;
|
||||
data['MeasuredArmDesc'] = measuredArmDesc;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
class MonthBloodPressureResultAverage {
|
||||
dynamic weekfourSystolicePressureAverageResult;
|
||||
dynamic weekfourDiastolicPressureAverageResult;
|
||||
dynamic weekthreeSystolicePressureAverageResult;
|
||||
dynamic weekthreeDiastolicPressureAverageResult;
|
||||
dynamic weektwoSystolicePressureAverageResult;
|
||||
dynamic weektwoDiastolicPressureAverageResult;
|
||||
dynamic weekoneSystolicePressureAverageResult;
|
||||
dynamic weekoneDiastolicPressureAverageResult;
|
||||
String? weekDesc;
|
||||
int? weekDiastolicPressureAverageResult;
|
||||
int? weekSystolicePressureAverageResult;
|
||||
|
||||
MonthBloodPressureResultAverage({
|
||||
this.weekfourSystolicePressureAverageResult,
|
||||
this.weekfourDiastolicPressureAverageResult,
|
||||
this.weekthreeSystolicePressureAverageResult,
|
||||
this.weekthreeDiastolicPressureAverageResult,
|
||||
this.weektwoSystolicePressureAverageResult,
|
||||
this.weektwoDiastolicPressureAverageResult,
|
||||
this.weekoneSystolicePressureAverageResult,
|
||||
this.weekoneDiastolicPressureAverageResult,
|
||||
this.weekDesc,
|
||||
this.weekDiastolicPressureAverageResult,
|
||||
this.weekSystolicePressureAverageResult,
|
||||
});
|
||||
|
||||
MonthBloodPressureResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
weekfourSystolicePressureAverageResult = json['weekfourSystolicePressureAverageResult'];
|
||||
weekfourDiastolicPressureAverageResult = json['weekfourDiastolicPressureAverageResult'];
|
||||
weekthreeSystolicePressureAverageResult = json['weekthreeSystolicePressureAverageResult'];
|
||||
weekthreeDiastolicPressureAverageResult = json['weekthreeDiastolicPressureAverageResult'];
|
||||
weektwoSystolicePressureAverageResult = json['weektwoSystolicePressureAverageResult'];
|
||||
weektwoDiastolicPressureAverageResult = json['weektwoDiastolicPressureAverageResult'];
|
||||
weekoneSystolicePressureAverageResult = json['weekoneSystolicePressureAverageResult'];
|
||||
weekoneDiastolicPressureAverageResult = json['weekoneDiastolicPressureAverageResult'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
weekDiastolicPressureAverageResult = json['WeekDiastolicPressureAverageResult'];
|
||||
weekSystolicePressureAverageResult = json['WeekSystolicePressureAverageResult'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['weekfourSystolicePressureAverageResult'] = weekfourSystolicePressureAverageResult;
|
||||
data['weekfourDiastolicPressureAverageResult'] = weekfourDiastolicPressureAverageResult;
|
||||
data['weekthreeSystolicePressureAverageResult'] = weekthreeSystolicePressureAverageResult;
|
||||
data['weekthreeDiastolicPressureAverageResult'] = weekthreeDiastolicPressureAverageResult;
|
||||
data['weektwoSystolicePressureAverageResult'] = weektwoSystolicePressureAverageResult;
|
||||
data['weektwoDiastolicPressureAverageResult'] = weektwoDiastolicPressureAverageResult;
|
||||
data['weekoneSystolicePressureAverageResult'] = weekoneSystolicePressureAverageResult;
|
||||
data['weekoneDiastolicPressureAverageResult'] = weekoneDiastolicPressureAverageResult;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
data['WeekDiastolicPressureAverageResult'] = weekDiastolicPressureAverageResult;
|
||||
data['WeekSystolicePressureAverageResult'] = weekSystolicePressureAverageResult;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class WeekBloodPressureResultAverage {
|
||||
int? dailySystolicePressureAverageResult;
|
||||
int? dailyDiastolicPressureAverageResult;
|
||||
DateTime? bloodPressureDate;
|
||||
|
||||
WeekBloodPressureResultAverage({this.dailySystolicePressureAverageResult, this.dailyDiastolicPressureAverageResult, this.bloodPressureDate});
|
||||
|
||||
WeekBloodPressureResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
dailySystolicePressureAverageResult = json['DailySystolicePressureAverageResult'];
|
||||
dailyDiastolicPressureAverageResult = json['DailyDiastolicPressureAverageResult'];
|
||||
bloodPressureDate = DateUtil.convertStringToDate(json['BloodPressureDate']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['DailySystolicePressureAverageResult'] = dailySystolicePressureAverageResult;
|
||||
data['DailyDiastolicPressureAverageResult'] = dailyDiastolicPressureAverageResult;
|
||||
data['BloodPressureDate'] = bloodPressureDate;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class YearBloodPressureResultAverage {
|
||||
int? monthSystolicePressureAverageResult;
|
||||
int? monthDiastolicPressureAverageResult;
|
||||
dynamic monthNumber;
|
||||
String? monthName;
|
||||
String? yearName;
|
||||
DateTime? date;
|
||||
|
||||
YearBloodPressureResultAverage({
|
||||
this.monthSystolicePressureAverageResult,
|
||||
this.monthDiastolicPressureAverageResult,
|
||||
this.monthNumber,
|
||||
this.monthName,
|
||||
this.yearName,
|
||||
});
|
||||
|
||||
YearBloodPressureResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
monthSystolicePressureAverageResult = json['monthSystolicePressureAverageResult'];
|
||||
monthDiastolicPressureAverageResult = json['monthDiastolicPressureAverageResult'];
|
||||
monthNumber = json['monthNumber'];
|
||||
monthName = json['monthName'];
|
||||
yearName = json['yearName'];
|
||||
date = DateUtil.getMonthDateTime(monthName!, yearName);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['monthSystolicePressureAverageResult'] = monthSystolicePressureAverageResult;
|
||||
data['monthDiastolicPressureAverageResult'] = monthDiastolicPressureAverageResult;
|
||||
data['monthNumber'] = monthNumber;
|
||||
data['monthName'] = monthName;
|
||||
data['yearName'] = yearName;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class DiabeticPatientResult {
|
||||
String? chartMonth;
|
||||
var chartYear;
|
||||
DateTime? dateChart;
|
||||
var description;
|
||||
var descriptionN;
|
||||
int? diabtecAvarage;
|
||||
bool? isActive;
|
||||
int? lineItemNo;
|
||||
var listMonth;
|
||||
var listWeek;
|
||||
int? measured;
|
||||
String? measuredDesc;
|
||||
var monthAverageResult;
|
||||
int? patientID;
|
||||
var remark;
|
||||
var resultDesc;
|
||||
dynamic resultValue;
|
||||
String? unit;
|
||||
var weekAverageResult;
|
||||
String? weekDesc;
|
||||
var yearAverageResult;
|
||||
|
||||
DiabeticPatientResult(
|
||||
{this.chartMonth,
|
||||
this.chartYear,
|
||||
this.dateChart,
|
||||
this.description,
|
||||
this.descriptionN,
|
||||
this.diabtecAvarage,
|
||||
this.isActive,
|
||||
this.lineItemNo,
|
||||
this.listMonth,
|
||||
this.listWeek,
|
||||
this.measured,
|
||||
this.measuredDesc,
|
||||
this.monthAverageResult,
|
||||
this.patientID,
|
||||
this.remark,
|
||||
this.resultDesc,
|
||||
this.resultValue,
|
||||
this.unit,
|
||||
this.weekAverageResult,
|
||||
this.weekDesc,
|
||||
this.yearAverageResult});
|
||||
|
||||
DiabeticPatientResult.fromJson(Map<String, dynamic> json) {
|
||||
chartMonth = json['ChartMonth'];
|
||||
chartYear = json['ChartYear'];
|
||||
dateChart = DateUtil.convertStringToDate(json['DateChart']);
|
||||
description = json['Description'];
|
||||
descriptionN = json['DescriptionN'];
|
||||
diabtecAvarage = json['DiabtecAvarage'];
|
||||
isActive = json['IsActive'];
|
||||
lineItemNo = json['LineItemNo'];
|
||||
listMonth = json['List_Month'];
|
||||
listWeek = json['List_Week'];
|
||||
measured = json['Measured'];
|
||||
measuredDesc = json['MeasuredDesc'];
|
||||
monthAverageResult = json['MonthAverageResult'];
|
||||
patientID = json['PatientID'];
|
||||
remark = json['Remark'];
|
||||
resultDesc = json['ResultDesc'];
|
||||
resultValue = json['ResultValue'];
|
||||
unit = json['Unit'];
|
||||
weekAverageResult = json['WeekAverageResult'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
yearAverageResult = json['YearAverageResult'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['ChartMonth'] = chartMonth;
|
||||
data['ChartYear'] = chartYear;
|
||||
data['DateChart'] = DateUtil.convertDateToString(dateChart!);
|
||||
data['Description'] = description;
|
||||
data['DescriptionN'] = descriptionN;
|
||||
data['DiabtecAvarage'] = diabtecAvarage;
|
||||
data['IsActive'] = isActive;
|
||||
data['LineItemNo'] = lineItemNo;
|
||||
data['List_Month'] = listMonth;
|
||||
data['List_Week'] = listWeek;
|
||||
data['Measured'] = measured;
|
||||
data['MeasuredDesc'] = measuredDesc;
|
||||
data['MonthAverageResult'] = monthAverageResult;
|
||||
data['PatientID'] = patientID;
|
||||
data['Remark'] = remark;
|
||||
data['ResultDesc'] = resultDesc;
|
||||
data['ResultValue'] = resultValue;
|
||||
data['Unit'] = unit;
|
||||
data['WeekAverageResult'] = weekAverageResult;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
data['YearAverageResult'] = yearAverageResult;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
class MonthDiabeticResultAverage {
|
||||
var weekfourAverageResult;
|
||||
var weekthreeAverageResult;
|
||||
var weektwoAverageResult;
|
||||
var weekoneAverageResult;
|
||||
dynamic weekAverageResult;
|
||||
String? weekDesc;
|
||||
|
||||
MonthDiabeticResultAverage(
|
||||
{this.weekfourAverageResult,
|
||||
this.weekthreeAverageResult,
|
||||
this.weektwoAverageResult,
|
||||
this.weekoneAverageResult,
|
||||
this.weekAverageResult,
|
||||
this.weekDesc});
|
||||
|
||||
MonthDiabeticResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
weekfourAverageResult = json['weekfourAverageResult'];
|
||||
weekthreeAverageResult = json['weekthreeAverageResult'];
|
||||
weektwoAverageResult = json['weektwoAverageResult'];
|
||||
weekoneAverageResult = json['weekoneAverageResult'];
|
||||
weekAverageResult = json['WeekAverageResult'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['weekfourAverageResult'] = weekfourAverageResult;
|
||||
data['weekthreeAverageResult'] = weekthreeAverageResult;
|
||||
data['weektwoAverageResult'] = weektwoAverageResult;
|
||||
data['weekoneAverageResult'] = weekoneAverageResult;
|
||||
data['WeekAverageResult'] = weekAverageResult;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class WeekDiabeticResultAverage {
|
||||
dynamic dailyAverageResult;
|
||||
DateTime? dateChart;
|
||||
|
||||
WeekDiabeticResultAverage({this.dailyAverageResult, this.dateChart});
|
||||
|
||||
WeekDiabeticResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
dailyAverageResult = json['DailyAverageResult'];
|
||||
dateChart = DateUtil.convertStringToDate(json['DateChart']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['DailyAverageResult'] = dailyAverageResult;
|
||||
data['DateChart'] = DateUtil.convertDateToString(dateChart!);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class YearDiabeticResultAverage {
|
||||
dynamic monthAverageResult;
|
||||
var monthNumber;
|
||||
String? monthName;
|
||||
String? yearName;
|
||||
DateTime? date;
|
||||
|
||||
YearDiabeticResultAverage({this.monthAverageResult, this.monthNumber, this.monthName, this.yearName});
|
||||
|
||||
YearDiabeticResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
monthAverageResult = json['monthAverageResult'];
|
||||
monthNumber = json['monthNumber'];
|
||||
monthName = json['monthName'];
|
||||
yearName = json['yearName'];
|
||||
date = DateUtil.getMonthDateTime(monthName!, yearName);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['monthAverageResult'] = monthAverageResult;
|
||||
data['monthNumber'] = monthNumber;
|
||||
data['monthName'] = monthName;
|
||||
data['yearName'] = yearName;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
class MonthWeightMeasurementResultAverage {
|
||||
dynamic weekfourAverageResult;
|
||||
dynamic weekthreeAverageResult;
|
||||
dynamic weektwoAverageResult;
|
||||
dynamic weekoneAverageResult;
|
||||
dynamic weekAverageResult;
|
||||
String? weekDesc;
|
||||
|
||||
MonthWeightMeasurementResultAverage(
|
||||
{this.weekfourAverageResult,
|
||||
this.weekthreeAverageResult,
|
||||
this.weektwoAverageResult,
|
||||
this.weekoneAverageResult,
|
||||
this.weekAverageResult,
|
||||
this.weekDesc});
|
||||
|
||||
MonthWeightMeasurementResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
weekfourAverageResult = json['weekfourAverageResult'];
|
||||
weekthreeAverageResult = json['weekthreeAverageResult'];
|
||||
weektwoAverageResult = json['weektwoAverageResult'];
|
||||
weekoneAverageResult = json['weekoneAverageResult'];
|
||||
weekAverageResult = json['WeekAverageResult'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['weekfourAverageResult'] = weekfourAverageResult;
|
||||
data['weekthreeAverageResult'] = weekthreeAverageResult;
|
||||
data['weektwoAverageResult'] = weektwoAverageResult;
|
||||
data['weekoneAverageResult'] = weekoneAverageResult;
|
||||
data['WeekAverageResult'] = weekAverageResult;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class WeekWeightMeasurementResultAverage {
|
||||
dynamic dailyAverageResult;
|
||||
DateTime? weightDate;
|
||||
|
||||
WeekWeightMeasurementResultAverage({this.dailyAverageResult, this.weightDate});
|
||||
|
||||
WeekWeightMeasurementResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
dailyAverageResult = json['DailyAverageResult'];
|
||||
weightDate = DateUtil.convertStringToDate(json['WeightDate']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['DailyAverageResult'] = dailyAverageResult;
|
||||
data['WeightDate'] = weightDate;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class WeightMeasurementResult {
|
||||
int? patientID;
|
||||
int? lineItemNo;
|
||||
int? weightMeasured;
|
||||
DateTime? weightDate;
|
||||
dynamic remark;
|
||||
bool? isActive;
|
||||
int? measured;
|
||||
dynamic unit;
|
||||
int? chartYear;
|
||||
dynamic chartMonth;
|
||||
double? yearAverageResult;
|
||||
dynamic monthAverageResult;
|
||||
dynamic weekAverageResult;
|
||||
dynamic weekDesc;
|
||||
|
||||
WeightMeasurementResult(
|
||||
{this.patientID,
|
||||
this.lineItemNo,
|
||||
this.weightMeasured,
|
||||
this.weightDate,
|
||||
this.remark,
|
||||
this.isActive,
|
||||
this.measured,
|
||||
this.unit,
|
||||
this.chartYear,
|
||||
this.chartMonth,
|
||||
this.yearAverageResult,
|
||||
this.monthAverageResult,
|
||||
this.weekAverageResult,
|
||||
this.weekDesc});
|
||||
|
||||
WeightMeasurementResult.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
patientID = json['PatientID'];
|
||||
lineItemNo = json['LineItemNo'];
|
||||
weightMeasured = json['WeightMeasured'];
|
||||
weightDate = DateUtil.convertStringToDate(json['WeightDate']);
|
||||
remark = json['Remark'];
|
||||
isActive = json['IsActive'];
|
||||
measured = json['Measured'];
|
||||
unit = json['Unit'];
|
||||
chartYear = json['ChartYear'];
|
||||
chartMonth = json['ChartMonth'];
|
||||
// Convert to double safely since API may return int
|
||||
yearAverageResult = json['YearAverageResult'] != null ? (json['YearAverageResult'] as num).toDouble() : null;
|
||||
monthAverageResult = json['MonthAverageResult'];
|
||||
weekAverageResult = json['WeekAverageResult'];
|
||||
weekDesc = json['WeekDesc'];
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['PatientID'] = patientID;
|
||||
data['LineItemNo'] = lineItemNo;
|
||||
data['WeightMeasured'] = weightMeasured;
|
||||
data['WeightDate'] = weightDate;
|
||||
data['Remark'] = remark;
|
||||
data['IsActive'] = isActive;
|
||||
data['Measured'] = measured;
|
||||
data['Unit'] = unit;
|
||||
data['ChartYear'] = chartYear;
|
||||
data['ChartMonth'] = chartMonth;
|
||||
data['YearAverageResult'] = yearAverageResult;
|
||||
data['MonthAverageResult'] = monthAverageResult;
|
||||
data['WeekAverageResult'] = weekAverageResult;
|
||||
data['WeekDesc'] = weekDesc;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
|
||||
class YearWeightMeasurementResultAverage {
|
||||
dynamic monthAverageResult;
|
||||
int? monthNumber;
|
||||
String? monthName;
|
||||
String? yearName;
|
||||
DateTime? date;
|
||||
|
||||
YearWeightMeasurementResultAverage({this.monthAverageResult, this.monthNumber, this.monthName, this.yearName});
|
||||
|
||||
YearWeightMeasurementResultAverage.fromJson(Map<String, dynamic> json) {
|
||||
monthAverageResult = json['monthAverageResult'];
|
||||
monthNumber = json['monthNumber'];
|
||||
monthName = json['monthName'];
|
||||
yearName = json['yearName'];
|
||||
date = DateUtil.getMonthDateTime(monthName!, yearName);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['monthAverageResult'] = monthAverageResult;
|
||||
data['monthNumber'] = monthNumber;
|
||||
data['monthName'] = monthName;
|
||||
data['yearName'] = yearName;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/api_consts.dart';
|
||||
import '../../core/common_models/generic_api_model.dart';
|
||||
import '../../core/exceptions/api_failure.dart';
|
||||
import '../../services/logger_service.dart';
|
||||
|
||||
abstract class MonthlyReportsRepo {
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> saveMonthlyReport({
|
||||
String? email,
|
||||
});
|
||||
}
|
||||
|
||||
class MonthlyReportsRepoImp implements MonthlyReportsRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
MonthlyReportsRepoImp({
|
||||
required this.loggerService,
|
||||
required this.apiClient,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<dynamic>>> saveMonthlyReport({
|
||||
String? email,
|
||||
}) async {
|
||||
try {
|
||||
Failure? failure;
|
||||
|
||||
GenericApiModel<dynamic>? reportApiResponse;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getMonthlyReports,
|
||||
body: <String, dynamic>{},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
reportApiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (reportApiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
|
||||
if ((reportApiResponse!.messageStatus ?? 0) != 1) {
|
||||
return Right(reportApiResponse!);
|
||||
}
|
||||
|
||||
GenericApiModel<dynamic>? emailApiResponse;
|
||||
|
||||
final Map<String, dynamic> emailRequest = <String, dynamic>{};
|
||||
|
||||
if (email != null && email.trim().isNotEmpty) {
|
||||
emailRequest["Email"] = email.trim();
|
||||
}
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.updatePatientEmail,
|
||||
body: emailRequest,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
emailApiResponse = GenericApiModel<dynamic>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: errorMessage,
|
||||
data: response,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (emailApiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
|
||||
return Right(emailApiResponse!);
|
||||
} catch (e) {
|
||||
loggerService.logError("MonthlyReportsRepo.saveMonthlyReport error: $e");
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
||||
import 'monthly_reports_repo.dart';
|
||||
class MonthlyReportsViewModel extends ChangeNotifier {
|
||||
final MonthlyReportsRepo monthlyReportsRepo;
|
||||
final ErrorHandlerService errorHandlerService;
|
||||
|
||||
bool isLoading = false;
|
||||
|
||||
MonthlyReportsViewModel({
|
||||
required this.monthlyReportsRepo,
|
||||
required this.errorHandlerService,
|
||||
});
|
||||
|
||||
Future<bool> saveMonthlyReport({String? email}) async {
|
||||
isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await monthlyReportsRepo.saveMonthlyReport(email: email);
|
||||
|
||||
final success = result.fold(
|
||||
(failure) {
|
||||
errorHandlerService.handleError(failure: failure);
|
||||
return false;
|
||||
},
|
||||
(apiResponse) => (apiResponse.messageStatus ?? 0) == 1,
|
||||
);
|
||||
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return success;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/api_consts.dart';
|
||||
import '../../core/exceptions/api_failure.dart';
|
||||
import '../../services/logger_service.dart';
|
||||
|
||||
abstract class TermsConditionsRepo {
|
||||
Future<Either<Failure, String>> getTermsConditions();
|
||||
}
|
||||
|
||||
class TermsConditionsRepoImp implements TermsConditionsRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
TermsConditionsRepoImp({
|
||||
required this.loggerService,
|
||||
required this.apiClient,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, String>> getTermsConditions() async {
|
||||
Failure? failure;
|
||||
String? html;
|
||||
|
||||
try {
|
||||
await apiClient.post(
|
||||
ApiConsts.getTermsConditions,
|
||||
body: <String, dynamic>{},
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType ?? ServerFailure(error.toString());
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
|
||||
final content = response['UserAgreementContent'];
|
||||
|
||||
if (content is String && content.isNotEmpty) {
|
||||
html = content;
|
||||
} else {
|
||||
failure = DataParsingFailure(
|
||||
'UserAgreementContent is null or not String');
|
||||
}
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
failure = UnknownFailure(e.toString());
|
||||
}
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (html == null || html!.isEmpty) {
|
||||
return Left(ServerFailure('No terms and conditions returned'));
|
||||
}
|
||||
|
||||
return Right(html!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/features/monthly_reports/terms_conditions_repo.dart';
|
||||
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
||||
|
||||
class TermsConditionsViewModel extends ChangeNotifier {
|
||||
final TermsConditionsRepo termsConditionsRepo;
|
||||
final ErrorHandlerService errorHandlerService;
|
||||
|
||||
String? termsConditionsHtml;
|
||||
bool isLoading = false;
|
||||
|
||||
TermsConditionsViewModel({
|
||||
required this.termsConditionsRepo,
|
||||
required this.errorHandlerService,
|
||||
});
|
||||
|
||||
Future<void> getTermsConditions({
|
||||
Function()? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await termsConditionsRepo.getTermsConditions();
|
||||
|
||||
result.fold(
|
||||
(failure) async {
|
||||
await errorHandlerService.handleError(failure: failure);
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
if (onError != null) {
|
||||
onError(failure.message ?? 'Something went wrong');
|
||||
}
|
||||
},
|
||||
(html) {
|
||||
termsConditionsHtml = html;
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
if (onSuccess != null) onSuccess();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
class NotificationResponseModel {
|
||||
int? id;
|
||||
int? recordId;
|
||||
int? patientID;
|
||||
bool? projectOutSA;
|
||||
String? deviceType;
|
||||
String? deviceToken;
|
||||
String? message;
|
||||
String? messageType;
|
||||
String? messageTypeData;
|
||||
String? videoURL;
|
||||
bool? isQueue;
|
||||
String? isQueueOn;
|
||||
String? createdOn;
|
||||
dynamic createdBy;
|
||||
String? notificationType;
|
||||
bool? isSent;
|
||||
String? isSentOn;
|
||||
bool? isRead;
|
||||
dynamic isReadOn;
|
||||
int? channelID;
|
||||
int? projectID;
|
||||
|
||||
NotificationResponseModel(
|
||||
{this.id,
|
||||
this.recordId,
|
||||
this.patientID,
|
||||
this.projectOutSA,
|
||||
this.deviceType,
|
||||
this.deviceToken,
|
||||
this.message,
|
||||
this.messageType,
|
||||
this.messageTypeData,
|
||||
this.videoURL,
|
||||
this.isQueue,
|
||||
this.isQueueOn,
|
||||
this.createdOn,
|
||||
this.createdBy,
|
||||
this.notificationType,
|
||||
this.isSent,
|
||||
this.isSentOn,
|
||||
this.isRead,
|
||||
this.isReadOn,
|
||||
this.channelID,
|
||||
this.projectID});
|
||||
|
||||
NotificationResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['Id'];
|
||||
recordId = json['RecordId'];
|
||||
patientID = json['PatientID'];
|
||||
projectOutSA = json['ProjectOutSA'];
|
||||
deviceType = json['DeviceType'];
|
||||
deviceToken = json['DeviceToken'];
|
||||
message = json['Message'];
|
||||
messageType = json['MessageType'];
|
||||
messageTypeData = json['MessageTypeData'];
|
||||
videoURL = json['VideoURL'];
|
||||
isQueue = json['IsQueue'];
|
||||
isQueueOn = json['IsQueueOn'];
|
||||
createdOn = json['CreatedOn'];
|
||||
createdBy = json['CreatedBy'];
|
||||
notificationType = json['NotificationType'];
|
||||
isSent = json['IsSent'];
|
||||
isSentOn = json['IsSentOn'];
|
||||
isRead = json['IsRead'];
|
||||
isReadOn = json['IsReadOn'];
|
||||
channelID = json['ChannelID'];
|
||||
projectID = json['ProjectID'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['Id'] = this.id;
|
||||
data['RecordId'] = this.recordId;
|
||||
data['PatientID'] = this.patientID;
|
||||
data['ProjectOutSA'] = this.projectOutSA;
|
||||
data['DeviceType'] = this.deviceType;
|
||||
data['DeviceToken'] = this.deviceToken;
|
||||
data['Message'] = this.message;
|
||||
data['MessageType'] = this.messageType;
|
||||
data['MessageTypeData'] = this.messageTypeData;
|
||||
data['VideoURL'] = this.videoURL;
|
||||
data['IsQueue'] = this.isQueue;
|
||||
data['IsQueueOn'] = this.isQueueOn;
|
||||
data['CreatedOn'] = this.createdOn;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['NotificationType'] = this.notificationType;
|
||||
data['IsSent'] = this.isSent;
|
||||
data['IsSentOn'] = this.isSentOn;
|
||||
data['IsRead'] = this.isRead;
|
||||
data['IsReadOn'] = this.isReadOn;
|
||||
data['ChannelID'] = this.channelID;
|
||||
data['ProjectID'] = this.projectID;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:hmg_patient_app_new/core/api/api_client.dart';
|
||||
import 'package:hmg_patient_app_new/core/api_consts.dart';
|
||||
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
|
||||
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
|
||||
import 'package:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/services/logger_service.dart';
|
||||
|
||||
abstract class NotificationsRepo {
|
||||
Future<Either<Failure, GenericApiModel<List<NotificationResponseModel>>>> getAllNotifications({
|
||||
required int notificationStatusID,
|
||||
required int pagingSize,
|
||||
required int currentPage,
|
||||
});
|
||||
}
|
||||
|
||||
class NotificationsRepoImp implements NotificationsRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
NotificationsRepoImp({required this.loggerService, required this.apiClient});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<List<NotificationResponseModel>>>> getAllNotifications({
|
||||
required int notificationStatusID,
|
||||
required int pagingSize,
|
||||
required int currentPage,
|
||||
}) async {
|
||||
Map<String, dynamic> mapDevice = {
|
||||
"NotificationStatusID": notificationStatusID,
|
||||
"pagingSize": pagingSize,
|
||||
"currentPage": currentPage,
|
||||
};
|
||||
|
||||
try {
|
||||
GenericApiModel<List<NotificationResponseModel>>? apiResponse;
|
||||
Failure? failure;
|
||||
await apiClient.post(
|
||||
GET_ALL_NOTIFICATIONS,
|
||||
body: mapDevice,
|
||||
onFailure: (error, statusCode, {messageStatus, failureType}) {
|
||||
failure = failureType;
|
||||
},
|
||||
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
|
||||
try {
|
||||
final list = response['List_GetAllNotificationsFromPool'];
|
||||
if (list == null || list.isEmpty) {
|
||||
// Return empty list if no notifications
|
||||
apiResponse = GenericApiModel<List<NotificationResponseModel>>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: null,
|
||||
data: [],
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final notifications = list.map((item) => NotificationResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<NotificationResponseModel>();
|
||||
|
||||
apiResponse = GenericApiModel<List<NotificationResponseModel>>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: null,
|
||||
data: notifications,
|
||||
);
|
||||
} catch (e) {
|
||||
failure = DataParsingFailure(e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/features/notifications/models/resp_models/notification_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/notifications/notifications_repo.dart';
|
||||
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
||||
|
||||
class NotificationsViewModel extends ChangeNotifier {
|
||||
bool isNotificationsLoading = false;
|
||||
bool hasMoreNotifications = true;
|
||||
|
||||
NotificationsRepo notificationsRepo;
|
||||
ErrorHandlerService errorHandlerService;
|
||||
|
||||
List<NotificationResponseModel> notificationsList = [];
|
||||
|
||||
int currentPage = 0;
|
||||
int pagingSize = 14;
|
||||
int notificationStatusID = 2; // Default to status 2 (e.g., unread)
|
||||
|
||||
NotificationsViewModel({
|
||||
required this.notificationsRepo,
|
||||
required this.errorHandlerService,
|
||||
});
|
||||
|
||||
initNotificationsViewModel({int? statusID}) {
|
||||
notificationsList.clear();
|
||||
currentPage = 0;
|
||||
hasMoreNotifications = true;
|
||||
isNotificationsLoading = true;
|
||||
// if (statusID != null) {
|
||||
// notificationStatusID = statusID;
|
||||
// }
|
||||
// getAllNotifications();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
setNotificationStatusID(int statusID) {
|
||||
notificationStatusID = statusID;
|
||||
notificationsList.clear();
|
||||
currentPage = 0;
|
||||
hasMoreNotifications = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getAllNotifications({
|
||||
Function(dynamic)? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
isNotificationsLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await notificationsRepo.getAllNotifications(
|
||||
notificationStatusID: notificationStatusID,
|
||||
pagingSize: pagingSize,
|
||||
currentPage: currentPage,
|
||||
);
|
||||
|
||||
result.fold(
|
||||
(failure) async {
|
||||
isNotificationsLoading = false;
|
||||
notifyListeners();
|
||||
await errorHandlerService.handleError(failure: failure);
|
||||
if (onError != null) {
|
||||
onError(failure.toString());
|
||||
}
|
||||
},
|
||||
(apiResponse) {
|
||||
isNotificationsLoading = false;
|
||||
if (apiResponse.messageStatus == 2) {
|
||||
notifyListeners();
|
||||
if (onError != null) {
|
||||
onError(apiResponse.errorMessage ?? "Unknown error");
|
||||
}
|
||||
} else if (apiResponse.messageStatus == 1) {
|
||||
final newNotifications = apiResponse.data ?? [];
|
||||
|
||||
if (newNotifications.isEmpty || newNotifications.length < pagingSize) {
|
||||
hasMoreNotifications = false;
|
||||
}
|
||||
|
||||
notificationsList.addAll(newNotifications);
|
||||
currentPage++;
|
||||
|
||||
notifyListeners();
|
||||
if (onSuccess != null) {
|
||||
onSuccess(apiResponse);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> refreshNotifications({
|
||||
Function(dynamic)? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
notificationsList.clear();
|
||||
currentPage = 0;
|
||||
hasMoreNotifications = true;
|
||||
await getAllNotifications(onSuccess: onSuccess, onError: onError);
|
||||
}
|
||||
|
||||
Future<void> loadMoreNotifications({
|
||||
Function(dynamic)? onSuccess,
|
||||
Function(String)? onError,
|
||||
}) async {
|
||||
await getAllNotifications(onSuccess: onSuccess, onError: onError);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
|
||||
|
||||
class QrParkingResponseModel {
|
||||
dynamic totalRecords;
|
||||
dynamic nRowID;
|
||||
int? qRParkingID;
|
||||
String? description;
|
||||
String? descriptionN;
|
||||
dynamic qRCompare;
|
||||
dynamic qRValue;
|
||||
String? imagePath;
|
||||
bool? isActive;
|
||||
int? parkingID;
|
||||
int? branchID;
|
||||
int? companyID;
|
||||
int? buildingID;
|
||||
int? rowID;
|
||||
int? gateID;
|
||||
int? floorID;
|
||||
dynamic imagePath1;
|
||||
int? createdBy;
|
||||
String? createdOn;
|
||||
dynamic editedBy;
|
||||
dynamic editedOn;
|
||||
String? parkingDescription;
|
||||
String? parkingDescriptionN;
|
||||
String? gateDescription;
|
||||
String? gateDescriptionN;
|
||||
String? branchDescription;
|
||||
String? branchDescriptionN;
|
||||
String? companyDescription;
|
||||
String? companyDescriptionN;
|
||||
String? rowDescription;
|
||||
String? rowDescriptionN;
|
||||
String? floorDescription;
|
||||
String? floorDescriptionN;
|
||||
String? buildingDescription;
|
||||
String? buildingDescriptionN;
|
||||
String? qRParkingCode;
|
||||
String? parkingCode;
|
||||
double? latitude;
|
||||
double? longitude;
|
||||
String? qRImageStr;
|
||||
|
||||
QrParkingResponseModel({
|
||||
this.totalRecords,
|
||||
this.nRowID,
|
||||
this.qRParkingID,
|
||||
this.description,
|
||||
this.descriptionN,
|
||||
this.qRCompare,
|
||||
this.qRValue,
|
||||
this.imagePath,
|
||||
this.isActive,
|
||||
this.parkingID,
|
||||
this.branchID,
|
||||
this.companyID,
|
||||
this.buildingID,
|
||||
this.rowID,
|
||||
this.gateID,
|
||||
this.floorID,
|
||||
this.imagePath1,
|
||||
this.createdBy,
|
||||
this.createdOn,
|
||||
this.editedBy,
|
||||
this.editedOn,
|
||||
this.parkingDescription,
|
||||
this.parkingDescriptionN,
|
||||
this.gateDescription,
|
||||
this.gateDescriptionN,
|
||||
this.branchDescription,
|
||||
this.branchDescriptionN,
|
||||
this.companyDescription,
|
||||
this.companyDescriptionN,
|
||||
this.rowDescription,
|
||||
this.rowDescriptionN,
|
||||
this.floorDescription,
|
||||
this.floorDescriptionN,
|
||||
this.buildingDescription,
|
||||
this.buildingDescriptionN,
|
||||
this.qRParkingCode,
|
||||
this.parkingCode,
|
||||
this.latitude,
|
||||
this.longitude,
|
||||
this.qRImageStr,
|
||||
});
|
||||
|
||||
QrParkingResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
totalRecords = json['TotalRecords'];
|
||||
nRowID = json['nRowID'];
|
||||
qRParkingID = json['QRParkingID'];
|
||||
description = json['Description'];
|
||||
descriptionN = json['DescriptionN'];
|
||||
qRCompare = json['QRCompare'];
|
||||
qRValue = json['QRValue'];
|
||||
imagePath = json['ImagePath'];
|
||||
isActive = json['IsActive'];
|
||||
parkingID = json['ParkingID'];
|
||||
branchID = json['BranchID'];
|
||||
companyID = json['CompanyID'];
|
||||
buildingID = json['BuildingID'];
|
||||
rowID = json['RowID'];
|
||||
gateID = json['GateID'];
|
||||
floorID = json['FloorID'];
|
||||
imagePath1 = json['ImagePath1'];
|
||||
createdBy = json['CreatedBy'];
|
||||
createdOn = json['CreatedOn'];
|
||||
editedBy = json['EditedBy'];
|
||||
editedOn = json['EditedOn'];
|
||||
parkingDescription = json['ParkingDescription'];
|
||||
parkingDescriptionN = json['ParkingDescriptionN'];
|
||||
gateDescription = json['GateDescription'];
|
||||
gateDescriptionN = json['GateDescriptionN'];
|
||||
branchDescription = json['BranchDescription'];
|
||||
branchDescriptionN = json['BranchDescriptionN'];
|
||||
companyDescription = json['CompanyDescription'];
|
||||
companyDescriptionN = json['CompanyDescriptionN'];
|
||||
rowDescription = json['RowDescription'];
|
||||
rowDescriptionN = json['RowDescriptionN'];
|
||||
floorDescription = json['FloorDescription'];
|
||||
floorDescriptionN = json['FloorDescriptionN'];
|
||||
buildingDescription = json['BuildingDescription'];
|
||||
buildingDescriptionN = json['BuildingDescriptionN'];
|
||||
qRParkingCode = json['QRParkingCode'];
|
||||
parkingCode = json['ParkingCode'];
|
||||
latitude = _toDouble(json['Latitude']);
|
||||
longitude = _toDouble(json['Longitude']);
|
||||
qRImageStr = json['QRImageStr'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['TotalRecords'] = totalRecords;
|
||||
data['nRowID'] = nRowID;
|
||||
data['QRParkingID'] = qRParkingID;
|
||||
data['Description'] = description;
|
||||
data['DescriptionN'] = descriptionN;
|
||||
data['QRCompare'] = qRCompare;
|
||||
data['QRValue'] = qRValue;
|
||||
data['ImagePath'] = imagePath;
|
||||
data['IsActive'] = isActive;
|
||||
data['ParkingID'] = parkingID;
|
||||
data['BranchID'] = branchID;
|
||||
data['CompanyID'] = companyID;
|
||||
data['BuildingID'] = buildingID;
|
||||
data['RowID'] = rowID;
|
||||
data['GateID'] = gateID;
|
||||
data['FloorID'] = floorID;
|
||||
data['ImagePath1'] = imagePath1;
|
||||
data['CreatedBy'] = createdBy;
|
||||
data['CreatedOn'] = createdOn;
|
||||
data['EditedBy'] = editedBy;
|
||||
data['EditedOn'] = editedOn;
|
||||
data['ParkingDescription'] = parkingDescription;
|
||||
data['ParkingDescriptionN'] = parkingDescriptionN;
|
||||
data['GateDescription'] = gateDescription;
|
||||
data['GateDescriptionN'] = gateDescriptionN;
|
||||
data['BranchDescription'] = branchDescription;
|
||||
data['BranchDescriptionN'] = branchDescriptionN;
|
||||
data['CompanyDescription'] = companyDescription;
|
||||
data['CompanyDescriptionN'] = companyDescriptionN;
|
||||
data['RowDescription'] = rowDescription;
|
||||
data['RowDescriptionN'] = rowDescriptionN;
|
||||
data['FloorDescription'] = floorDescription;
|
||||
data['FloorDescriptionN'] = floorDescriptionN;
|
||||
data['BuildingDescription'] = buildingDescription;
|
||||
data['BuildingDescriptionN'] = buildingDescriptionN;
|
||||
data['QRParkingCode'] = qRParkingCode;
|
||||
data['ParkingCode'] = parkingCode;
|
||||
data['Latitude'] = latitude;
|
||||
data['Longitude'] = longitude;
|
||||
data['QRImageStr'] = qRImageStr;
|
||||
return data;
|
||||
}
|
||||
|
||||
static double? _toDouble(dynamic v) {
|
||||
if (v == null) return null;
|
||||
if (v is double) return v;
|
||||
if (v is int) return v.toDouble();
|
||||
return double.tryParse(v.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:hmg_patient_app_new/features/qr_parking/models/qr_parking_response_model.dart';
|
||||
import '../../core/api/api_client.dart';
|
||||
import '../../core/api_consts.dart';
|
||||
import '../../core/common_models/generic_api_model.dart';
|
||||
import '../../core/exceptions/api_failure.dart';
|
||||
import '../../services/logger_service.dart';
|
||||
|
||||
|
||||
abstract class QrParkingRepo {
|
||||
Future<Either<Failure, GenericApiModel<List<QrParkingResponseModel>>>>
|
||||
getQrParking({
|
||||
required int qrParkingId,
|
||||
});
|
||||
}
|
||||
|
||||
class QrParkingRepoImp implements QrParkingRepo {
|
||||
final ApiClient apiClient;
|
||||
final LoggerService loggerService;
|
||||
|
||||
QrParkingRepoImp({
|
||||
required this.loggerService,
|
||||
required this.apiClient,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GenericApiModel<List<QrParkingResponseModel>>>>
|
||||
getQrParking({required int qrParkingId}) async {
|
||||
try {
|
||||
GenericApiModel<List<QrParkingResponseModel>>? apiResponse;
|
||||
Failure? failure;
|
||||
|
||||
await apiClient.post(
|
||||
ApiConsts.getQrParkingDetails, // GetQRParkingByID
|
||||
body: {'QRParkingID': qrParkingId},
|
||||
onFailure: (error, statusCode,
|
||||
{messageStatus, failureType}) {
|
||||
failure = failureType ??
|
||||
StatusCodeFailure("$error ($statusCode)");
|
||||
},
|
||||
onSuccess: (response, statusCode,
|
||||
{messageStatus, errorMessage}) {
|
||||
final list =
|
||||
(response['List_SWP_QRParkingModel'] as List?) ?? [];
|
||||
|
||||
final res = list
|
||||
.map((e) => QrParkingResponseModel.fromJson(
|
||||
Map<String, dynamic>.from(e),
|
||||
))
|
||||
.toList();
|
||||
|
||||
apiResponse = GenericApiModel<List<QrParkingResponseModel>>(
|
||||
messageStatus: messageStatus,
|
||||
statusCode: statusCode,
|
||||
errorMessage: null,
|
||||
data: res,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (failure != null) return Left(failure!);
|
||||
if (apiResponse == null) {
|
||||
return Left(ServerFailure("Unknown error"));
|
||||
}
|
||||
|
||||
return Right(apiResponse!);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,144 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||
import 'package:hmg_patient_app_new/features/qr_parking/qr_parking_repo.dart';
|
||||
|
||||
import '../../services/cache_service.dart';
|
||||
import '../../services/error_handler_service.dart';
|
||||
import 'models/qr_parking_response_model.dart';
|
||||
|
||||
|
||||
class QrParkingViewModel extends ChangeNotifier {
|
||||
final QrParkingRepo qrParkingRepo;
|
||||
final ErrorHandlerService errorHandlerService;
|
||||
final CacheService cacheService;
|
||||
String IS_GO_TO_PARKING = 'IS_GO_TO_PARKING';
|
||||
|
||||
bool isLoading = false;
|
||||
String? error;
|
||||
|
||||
bool isSavePark = false;
|
||||
QrParkingResponseModel? qrParkingModel;
|
||||
List<QrParkingResponseModel> qrParkingList = [];
|
||||
|
||||
QrParkingViewModel({
|
||||
required this.qrParkingRepo,
|
||||
required this.errorHandlerService,
|
||||
required this.cacheService,
|
||||
});
|
||||
|
||||
|
||||
Future<QrParkingResponseModel?> scanAndGetParking() async {
|
||||
try {
|
||||
error = null;
|
||||
isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await BarcodeScanner.scan();
|
||||
|
||||
if (result.type != ResultType.Barcode) {
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
|
||||
final raw = result.rawContent.trim();
|
||||
if (raw.isEmpty) {
|
||||
error = "Invalid QR Code";
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
|
||||
final qrParkingId = _extractQrParkingId(raw);
|
||||
if (qrParkingId == null) {
|
||||
error = "Invalid QR Code";
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
|
||||
final apiResult =
|
||||
await qrParkingRepo.getQrParking(qrParkingId: qrParkingId);
|
||||
|
||||
final model = apiResult.fold(
|
||||
(failure) {
|
||||
errorHandlerService.handleError(failure: failure);
|
||||
error = failure.toString();
|
||||
return null;
|
||||
},
|
||||
(apiResponse) {
|
||||
qrParkingList = apiResponse.data ?? [];
|
||||
if (qrParkingList.isNotEmpty) {
|
||||
return qrParkingList.first;
|
||||
}
|
||||
error = "Invalid Qr Code";
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
if (model != null) {
|
||||
qrParkingModel = model;
|
||||
isSavePark = true;
|
||||
|
||||
await cacheService.saveObject(
|
||||
key: IS_GO_TO_PARKING,
|
||||
value: model.toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return model;
|
||||
} catch (e) {
|
||||
error = "Scan error";
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Load saved parking
|
||||
Future<void> getIsSaveParking() async {
|
||||
isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
final parking =
|
||||
await cacheService.getObject(key: IS_GO_TO_PARKING);
|
||||
|
||||
if (parking != null) {
|
||||
isSavePark = true;
|
||||
qrParkingModel = QrParkingResponseModel.fromJson(
|
||||
Map<String, dynamic>.from(parking),
|
||||
);
|
||||
} else {
|
||||
isSavePark = false;
|
||||
qrParkingModel = null;
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Reset parking
|
||||
Future<void> clearParking() async {
|
||||
await cacheService.remove(key: IS_GO_TO_PARKING);
|
||||
isSavePark = false;
|
||||
qrParkingModel = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
int? _extractQrParkingId(String raw) {
|
||||
try {
|
||||
if (raw.startsWith("{")) {
|
||||
final data = jsonDecode(raw);
|
||||
return int.tryParse(data['QRParkingID'].toString());
|
||||
}
|
||||
return int.tryParse(raw);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,188 @@
|
||||
class SymptomsUserDetailsResponseModel {
|
||||
final TokenDetails? tokenDetails;
|
||||
final UserDetails? userDetails;
|
||||
final String? sessionId;
|
||||
|
||||
SymptomsUserDetailsResponseModel({
|
||||
this.tokenDetails,
|
||||
this.userDetails,
|
||||
this.sessionId,
|
||||
});
|
||||
|
||||
factory SymptomsUserDetailsResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
return SymptomsUserDetailsResponseModel(
|
||||
tokenDetails: json['tokenDetails'] != null ? TokenDetails.fromJson(json['tokenDetails']) : null,
|
||||
userDetails: json['userDetails'] != null ? UserDetails.fromJson(json['userDetails']) : null,
|
||||
sessionId: json['sessionId'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'tokenDetails': tokenDetails?.toJson(),
|
||||
'userDetails': userDetails?.toJson(),
|
||||
'sessionId': sessionId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TokenDetails {
|
||||
final String? id;
|
||||
final String? authToken;
|
||||
final int? expiresIn;
|
||||
|
||||
TokenDetails({
|
||||
this.id,
|
||||
this.authToken,
|
||||
this.expiresIn,
|
||||
});
|
||||
|
||||
factory TokenDetails.fromJson(Map<String, dynamic> json) {
|
||||
return TokenDetails(
|
||||
id: json['id'],
|
||||
authToken: json['auth_token'],
|
||||
expiresIn: json['expires_in'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'auth_token': authToken,
|
||||
'expires_in': expiresIn,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class UserDetails {
|
||||
final String? fileNo;
|
||||
final String? nationalId;
|
||||
final String? email;
|
||||
final String? dateOfBirth;
|
||||
final String? dateOfBirthHijri;
|
||||
final int? age;
|
||||
final UserName? name;
|
||||
final int? maritalStatus;
|
||||
final String? maritalStatusCode;
|
||||
final String? nationality;
|
||||
final String? nationalityIsoCode;
|
||||
final String? occupation;
|
||||
final int? idType;
|
||||
final int? gender;
|
||||
final String? jwtToken;
|
||||
final String? countryDialCode;
|
||||
final String? phoneNo;
|
||||
|
||||
UserDetails({
|
||||
this.fileNo,
|
||||
this.nationalId,
|
||||
this.email,
|
||||
this.dateOfBirth,
|
||||
this.dateOfBirthHijri,
|
||||
this.age,
|
||||
this.name,
|
||||
this.maritalStatus,
|
||||
this.maritalStatusCode,
|
||||
this.nationality,
|
||||
this.nationalityIsoCode,
|
||||
this.occupation,
|
||||
this.idType,
|
||||
this.gender,
|
||||
this.jwtToken,
|
||||
this.countryDialCode,
|
||||
this.phoneNo,
|
||||
});
|
||||
|
||||
factory UserDetails.fromJson(Map<String, dynamic> json) {
|
||||
return UserDetails(
|
||||
fileNo: json['FileNo'],
|
||||
nationalId: json['national_id'],
|
||||
email: json['email'],
|
||||
dateOfBirth: json['date_of_birth'],
|
||||
dateOfBirthHijri: json['date_of_birth_hijri'],
|
||||
age: json['age'],
|
||||
name: json['name'] != null ? UserName.fromJson(json['name']) : null,
|
||||
maritalStatus: json['marital_status'],
|
||||
maritalStatusCode: json['marital_status_code'],
|
||||
nationality: json['nationality'],
|
||||
nationalityIsoCode: json['nationality_iso_code'],
|
||||
occupation: json['occupation'],
|
||||
idType: json['id_type'],
|
||||
gender: json['gender'],
|
||||
jwtToken: json['jwt_token'],
|
||||
countryDialCode: json['country_dial_code'],
|
||||
phoneNo: json['phone_no'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'FileNo': fileNo,
|
||||
'national_id': nationalId,
|
||||
'email': email,
|
||||
'date_of_birth': dateOfBirth,
|
||||
'date_of_birth_hijri': dateOfBirthHijri,
|
||||
'age': age,
|
||||
'name': name?.toJson(),
|
||||
'marital_status': maritalStatus,
|
||||
'marital_status_code': maritalStatusCode,
|
||||
'nationality': nationality,
|
||||
'nationality_iso_code': nationalityIsoCode,
|
||||
'occupation': occupation,
|
||||
'id_type': idType,
|
||||
'gender': gender,
|
||||
'jwt_token': jwtToken,
|
||||
'country_dial_code': countryDialCode,
|
||||
'phone_no': phoneNo,
|
||||
};
|
||||
}
|
||||
|
||||
// Helper method to get full name
|
||||
String getFullName(bool isArabic) {
|
||||
if (name == null) return '';
|
||||
if (isArabic) {
|
||||
return '${name!.firstNameAr ?? ''} ${name!.middleNameAr ?? ''} ${name!.lastNameAr ?? ''}'.trim();
|
||||
}
|
||||
return '${name!.firstName ?? ''} ${name!.middleName ?? ''} ${name!.lastName ?? ''}'.trim();
|
||||
}
|
||||
}
|
||||
|
||||
class UserName {
|
||||
final String? firstName;
|
||||
final String? middleName;
|
||||
final String? lastName;
|
||||
final String? firstNameAr;
|
||||
final String? middleNameAr;
|
||||
final String? lastNameAr;
|
||||
|
||||
UserName({
|
||||
this.firstName,
|
||||
this.middleName,
|
||||
this.lastName,
|
||||
this.firstNameAr,
|
||||
this.middleNameAr,
|
||||
this.lastNameAr,
|
||||
});
|
||||
|
||||
factory UserName.fromJson(Map<String, dynamic> json) {
|
||||
return UserName(
|
||||
firstName: json['first_name'],
|
||||
middleName: json['middle_name'],
|
||||
lastName: json['last_name'],
|
||||
firstNameAr: json['first_name_ar'],
|
||||
middleNameAr: json['middle_name_ar'],
|
||||
lastNameAr: json['last_name_ar'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'first_name': firstName,
|
||||
'middle_name': middleName,
|
||||
'last_name': lastName,
|
||||
'first_name_ar': firstNameAr,
|
||||
'middle_name_ar': middleNameAr,
|
||||
'last_name_ar': lastNameAr,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,209 @@
|
||||
class TriageDataDetails {
|
||||
final TriageQuestion? question;
|
||||
final List<TriageCondition>? conditions;
|
||||
final bool? hasEmergencyEvidence;
|
||||
final bool? shouldStop;
|
||||
final String? interviewToken;
|
||||
final String? message;
|
||||
final List<String>? errorList;
|
||||
final int? id;
|
||||
final String? language;
|
||||
final String? generalId;
|
||||
final String? createDate;
|
||||
final String? lastEditDate;
|
||||
final String? createdBy;
|
||||
final String? lastEditBy;
|
||||
final bool? active;
|
||||
final int? sortOrder;
|
||||
final int? userType;
|
||||
final String? userId;
|
||||
|
||||
TriageDataDetails({
|
||||
this.question,
|
||||
this.conditions,
|
||||
this.hasEmergencyEvidence,
|
||||
this.shouldStop,
|
||||
this.interviewToken,
|
||||
this.message,
|
||||
this.errorList,
|
||||
this.id,
|
||||
this.language,
|
||||
this.generalId,
|
||||
this.createDate,
|
||||
this.lastEditDate,
|
||||
this.createdBy,
|
||||
this.lastEditBy,
|
||||
this.active,
|
||||
this.sortOrder,
|
||||
this.userType,
|
||||
this.userId,
|
||||
});
|
||||
|
||||
factory TriageDataDetails.fromJson(Map<String, dynamic> json) {
|
||||
return TriageDataDetails(
|
||||
question: json['question'] != null ? TriageQuestion.fromJson(json['question']) : null,
|
||||
conditions: json['conditions'] != null ? (json['conditions'] as List).map((item) => TriageCondition.fromJson(item)).toList() : null,
|
||||
hasEmergencyEvidence: json['has_emergency_evidence'],
|
||||
shouldStop: json['should_stop'],
|
||||
interviewToken: json['interview_token'],
|
||||
message: json['Message'],
|
||||
errorList: json['ErrorList'] != null ? List<String>.from(json['ErrorList']) : null,
|
||||
id: json['Id'],
|
||||
language: json['language'],
|
||||
generalId: json['generalId'],
|
||||
createDate: json['CreateDate'],
|
||||
lastEditDate: json['LastEditDate'],
|
||||
createdBy: json['CreatedBy'],
|
||||
lastEditBy: json['LastEditBy'],
|
||||
active: json['Active'],
|
||||
sortOrder: json['SortOrder'],
|
||||
userType: json['userType'],
|
||||
userId: json['userId'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'question': question?.toJson(),
|
||||
'conditions': conditions?.map((item) => item.toJson()).toList(),
|
||||
'has_emergency_evidence': hasEmergencyEvidence,
|
||||
'should_stop': shouldStop,
|
||||
'interview_token': interviewToken,
|
||||
'Message': message,
|
||||
'ErrorList': errorList,
|
||||
'Id': id,
|
||||
'language': language,
|
||||
'generalId': generalId,
|
||||
'CreateDate': createDate,
|
||||
'LastEditDate': lastEditDate,
|
||||
'CreatedBy': createdBy,
|
||||
'LastEditBy': lastEditBy,
|
||||
'Active': active,
|
||||
'SortOrder': sortOrder,
|
||||
'userType': userType,
|
||||
'userId': userId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TriageQuestion {
|
||||
final int? type;
|
||||
final String? text;
|
||||
final List<TriageQuestionItem>? items;
|
||||
|
||||
TriageQuestion({
|
||||
this.type,
|
||||
this.text,
|
||||
this.items,
|
||||
});
|
||||
|
||||
factory TriageQuestion.fromJson(Map<String, dynamic> json) {
|
||||
return TriageQuestion(
|
||||
type: json['type'],
|
||||
text: json['text'],
|
||||
items: json['items'] != null ? (json['items'] as List).map((item) => TriageQuestionItem.fromJson(item)).toList() : null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'type': type,
|
||||
'text': text,
|
||||
'items': items?.map((item) => item.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TriageQuestionItem {
|
||||
final String? id;
|
||||
final String? name;
|
||||
final List<TriageChoice>? choices;
|
||||
|
||||
TriageQuestionItem({
|
||||
this.id,
|
||||
this.name,
|
||||
this.choices,
|
||||
});
|
||||
|
||||
factory TriageQuestionItem.fromJson(Map<String, dynamic> json) {
|
||||
return TriageQuestionItem(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
choices: json['choices'] != null ? (json['choices'] as List).map((item) => TriageChoice.fromJson(item)).toList() : null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'choices': choices?.map((item) => item.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TriageChoice {
|
||||
final String? id;
|
||||
final String? label;
|
||||
|
||||
TriageChoice({
|
||||
this.id,
|
||||
this.label,
|
||||
});
|
||||
|
||||
factory TriageChoice.fromJson(Map<String, dynamic> json) {
|
||||
return TriageChoice(
|
||||
id: json['id'],
|
||||
label: json['label'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'label': label,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TriageCondition {
|
||||
final String? id;
|
||||
final String? name;
|
||||
final String? commonName;
|
||||
final double? probability;
|
||||
final dynamic conditionDetails;
|
||||
|
||||
TriageCondition({
|
||||
this.id,
|
||||
this.name,
|
||||
this.commonName,
|
||||
this.probability,
|
||||
this.conditionDetails,
|
||||
});
|
||||
|
||||
factory TriageCondition.fromJson(Map<String, dynamic> json) {
|
||||
return TriageCondition(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
commonName: json['common_name'],
|
||||
probability: json['probability']?.toDouble(),
|
||||
conditionDetails: json['condition_details'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'common_name': commonName,
|
||||
'probability': probability,
|
||||
'condition_details': conditionDetails,
|
||||
};
|
||||
}
|
||||
|
||||
/// Get probability as percentage
|
||||
String getProbabilityPercentage() {
|
||||
if (probability == null) return '0%';
|
||||
return '${(probability! * 100).toStringAsFixed(1)}%';
|
||||
}
|
||||
}
|
||||