@openmrs/esm-billing-app 1.1.2-pre.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/.turbo/cache/31f1dfc7f71601df-meta.json +1 -0
  2. package/.turbo/cache/31f1dfc7f71601df.tar.zst +0 -0
  3. package/.turbo/turbo-build.log +13 -42
  4. package/__mocks__/bills.mock.ts +3 -2
  5. package/dist/1480.js +1 -0
  6. package/dist/1480.js.map +1 -0
  7. package/dist/1564.js +1 -0
  8. package/dist/1564.js.map +1 -0
  9. package/dist/1578.js +1 -0
  10. package/dist/1578.js.map +1 -0
  11. package/dist/1646.js +1 -0
  12. package/dist/1646.js.map +1 -0
  13. package/dist/1869.js +1 -0
  14. package/dist/1869.js.map +1 -0
  15. package/dist/1877.js +1 -0
  16. package/dist/1877.js.map +1 -0
  17. package/dist/1899.js +1 -0
  18. package/dist/1899.js.map +1 -0
  19. package/dist/196.js +2 -0
  20. package/dist/196.js.map +1 -0
  21. package/dist/2250.js +43 -0
  22. package/dist/2250.js.map +1 -0
  23. package/dist/2269.js +1 -0
  24. package/dist/2269.js.map +1 -0
  25. package/dist/2317.js +1 -0
  26. package/dist/2317.js.map +1 -0
  27. package/dist/2416.js +1 -0
  28. package/dist/2416.js.map +1 -0
  29. package/dist/2489.js +1 -0
  30. package/dist/2489.js.map +1 -0
  31. package/dist/282.js +1 -0
  32. package/dist/282.js.map +1 -0
  33. package/dist/2881.js +1 -0
  34. package/dist/2881.js.map +1 -0
  35. package/dist/2997.js +1 -0
  36. package/dist/2997.js.map +1 -0
  37. package/dist/3378.js +1 -0
  38. package/dist/3378.js.map +1 -0
  39. package/dist/3379.js +1 -0
  40. package/dist/3379.js.map +1 -0
  41. package/dist/3784.js +1 -0
  42. package/dist/3784.js.map +1 -0
  43. package/dist/3963.js +1 -0
  44. package/dist/3963.js.map +1 -0
  45. package/dist/4106.js +1 -0
  46. package/dist/4106.js.map +1 -0
  47. package/dist/4111.js +1 -0
  48. package/dist/4111.js.map +1 -0
  49. package/dist/434.js +1 -0
  50. package/dist/434.js.map +1 -0
  51. package/dist/4348.js +1 -0
  52. package/dist/4348.js.map +1 -0
  53. package/dist/4383.js +1 -0
  54. package/dist/4383.js.map +1 -0
  55. package/dist/4658.js +1 -0
  56. package/dist/4658.js.map +1 -0
  57. package/dist/4870.js +1 -0
  58. package/dist/4870.js.map +1 -0
  59. package/dist/4928.js +1 -0
  60. package/dist/4928.js.map +1 -0
  61. package/dist/5098.js +1 -0
  62. package/dist/5098.js.map +1 -0
  63. package/dist/5117.js +1 -0
  64. package/dist/5117.js.map +1 -0
  65. package/dist/5132.js +1 -0
  66. package/dist/5132.js.map +1 -0
  67. package/dist/5145.js +1 -0
  68. package/dist/5145.js.map +1 -0
  69. package/dist/5390.js +1 -0
  70. package/dist/5390.js.map +1 -0
  71. package/dist/5503.js +1 -0
  72. package/dist/5503.js.map +1 -0
  73. package/dist/556.js +1 -0
  74. package/dist/556.js.map +1 -0
  75. package/dist/5644.js +1 -0
  76. package/dist/5644.js.map +1 -0
  77. package/dist/5898.js +1 -0
  78. package/dist/5898.js.map +1 -0
  79. package/dist/5940.js +1 -0
  80. package/dist/5940.js.map +1 -0
  81. package/dist/6047.js +1 -0
  82. package/dist/6047.js.map +1 -0
  83. package/dist/6237.js +1 -0
  84. package/dist/6237.js.map +1 -0
  85. package/dist/6362.js +1 -0
  86. package/dist/6362.js.map +1 -0
  87. package/dist/6371.js +1 -0
  88. package/dist/6371.js.map +1 -0
  89. package/dist/6377.js +1 -0
  90. package/dist/6377.js.map +1 -0
  91. package/dist/6444.js +1 -0
  92. package/dist/6444.js.map +1 -0
  93. package/dist/6508.js +1 -0
  94. package/dist/6508.js.map +1 -0
  95. package/dist/6594.js +1 -0
  96. package/dist/6594.js.map +1 -0
  97. package/dist/6724.js +1 -0
  98. package/dist/6724.js.map +1 -0
  99. package/dist/6904.js +1 -0
  100. package/dist/6904.js.map +1 -0
  101. package/dist/7045.js +1 -0
  102. package/dist/7045.js.map +1 -0
  103. package/dist/7175.js +1 -0
  104. package/dist/7175.js.map +1 -0
  105. package/dist/7182.js +1 -0
  106. package/dist/7182.js.map +1 -0
  107. package/dist/7247.js +1 -0
  108. package/dist/7247.js.map +1 -0
  109. package/dist/7742.js +1 -0
  110. package/dist/7742.js.map +1 -0
  111. package/dist/7912.js +1 -0
  112. package/dist/7912.js.map +1 -0
  113. package/dist/8358.js +1 -0
  114. package/dist/8358.js.map +1 -0
  115. package/dist/8359.js +1 -0
  116. package/dist/8359.js.map +1 -0
  117. package/dist/8695.js +1 -0
  118. package/dist/8695.js.map +1 -0
  119. package/dist/903.js +1 -0
  120. package/dist/903.js.map +1 -0
  121. package/dist/9072.js +1 -0
  122. package/dist/9072.js.map +1 -0
  123. package/dist/9414.js +1 -0
  124. package/dist/9414.js.map +1 -0
  125. package/dist/9655.js +11 -0
  126. package/dist/9655.js.map +1 -0
  127. package/dist/9806.js +1 -0
  128. package/dist/9806.js.map +1 -0
  129. package/dist/990.js +1 -0
  130. package/dist/990.js.map +1 -0
  131. package/dist/main.js +17 -2
  132. package/dist/main.js.map +1 -1
  133. package/dist/openmrs-esm-billing-app.js +6 -1
  134. package/dist/openmrs-esm-billing-app.js.buildmanifest.json +643 -436
  135. package/dist/openmrs-esm-billing-app.js.map +1 -1
  136. package/dist/routes.json +1 -1
  137. package/e2e/commands/billing-operations.ts +21 -0
  138. package/e2e/commands/types.ts +9 -1
  139. package/e2e/pages/discounts-page.ts +75 -0
  140. package/e2e/pages/index.ts +1 -0
  141. package/e2e/pages/invoice-page.ts +7 -7
  142. package/e2e/specs/bill-discounts.spec.ts +255 -0
  143. package/e2e/specs/billing-dashboard.spec.ts +3 -3
  144. package/e2e/specs/billing-patient-chart.spec.ts +2 -2
  145. package/package.json +13 -22
  146. package/rspack.config.js +1 -0
  147. package/src/bill-history/bill-action-menu.component.tsx +20 -2
  148. package/src/bill-history/bill-history.test.tsx +23 -22
  149. package/src/bill-item-actions/edit-bill-item.modal.tsx +1 -1
  150. package/src/bill-item-actions/edit-bill-item.test.tsx +29 -27
  151. package/src/billable-services/billable-service-form/billable-service-form.test.tsx +74 -73
  152. package/src/billable-services/billable-services-home.component.tsx +4 -2
  153. package/src/billable-services/billable-services.test.tsx +8 -7
  154. package/src/billable-services/dashboard/dashboard.test.tsx +3 -2
  155. package/src/billable-services-admin-card-link.test.tsx +2 -1
  156. package/src/billing-dashboard/billing-dashboard.test.tsx +19 -3
  157. package/src/billing-form/billing-checkin-form.component.tsx +7 -3
  158. package/src/billing-form/billing-checkin-form.test.tsx +22 -21
  159. package/src/billing-form/billing-form.resource.test.ts +7 -6
  160. package/src/billing-form/billing-form.test.tsx +77 -40
  161. package/src/billing-form/billing-form.workspace.tsx +25 -6
  162. package/src/billing-form/visit-attributes/visit-attributes-form.component.tsx +6 -2
  163. package/src/billing.resource.test.ts +43 -41
  164. package/src/billing.resource.ts +65 -16
  165. package/src/bills-table/bills-table.component.tsx +15 -4
  166. package/src/bills-table/bills-table.test.tsx +72 -71
  167. package/src/config-schema.ts +0 -7
  168. package/src/discounts/admin/discount-requests-left-panel-link.component.tsx +43 -0
  169. package/src/discounts/admin/discount-requests.component.tsx +316 -0
  170. package/src/discounts/admin/discount-requests.scss +133 -0
  171. package/src/discounts/admin/discount-requests.test.tsx +104 -0
  172. package/src/discounts/admin/review-bill-discounts/bill-line-items-table/bill-line-items-table.component.tsx +42 -0
  173. package/src/discounts/admin/review-bill-discounts/bill-line-items-table/bill-line-items-table.scss +76 -0
  174. package/src/discounts/admin/review-bill-discounts/bill-payments-table/bill-payments-table.component.tsx +50 -0
  175. package/src/discounts/admin/review-bill-discounts/bill-payments-table/bill-payments-table.scss +63 -0
  176. package/src/discounts/admin/review-bill-discounts/bill-receipt-rail/bill-receipt-rail.component.tsx +73 -0
  177. package/src/discounts/admin/review-bill-discounts/bill-receipt-rail/bill-receipt-rail.scss +54 -0
  178. package/src/discounts/admin/review-bill-discounts/bill-totals-summary/bill-totals-summary.component.tsx +95 -0
  179. package/src/discounts/admin/review-bill-discounts/bill-totals-summary/bill-totals-summary.scss +128 -0
  180. package/src/discounts/admin/review-bill-discounts/discount-card/discount-card.component.tsx +158 -0
  181. package/src/discounts/admin/review-bill-discounts/discount-card/discount-card.scss +164 -0
  182. package/src/discounts/admin/review-bill-discounts/discount-review-stack/discount-review-stack.component.tsx +86 -0
  183. package/src/discounts/admin/review-bill-discounts/discount-review-stack/discount-review-stack.scss +40 -0
  184. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.scss +14 -0
  185. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.test.tsx +153 -0
  186. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.modal.tsx +167 -0
  187. package/src/discounts/admin/review-bill-discounts/review-bill-discounts.utils.ts +42 -0
  188. package/src/discounts/discounts-table.component.tsx +109 -0
  189. package/src/discounts/discounts-table.scss +37 -0
  190. package/src/discounts/discounts-table.test.tsx +67 -0
  191. package/src/discounts/discounts.resource.ts +71 -0
  192. package/src/discounts/request-discount.modal.scss +88 -0
  193. package/src/discounts/request-discount.modal.test.tsx +161 -0
  194. package/src/discounts/request-discount.modal.tsx +253 -0
  195. package/src/index.ts +52 -21
  196. package/src/invoice/invoice-table.component.tsx +116 -18
  197. package/src/invoice/invoice-table.test.tsx +165 -13
  198. package/src/invoice/invoice.component.tsx +111 -7
  199. package/src/invoice/invoice.test.tsx +366 -66
  200. package/src/invoice/line-item-action-menu.component.tsx +31 -1
  201. package/src/invoice/payments/payment-form/payment-form.test.tsx +20 -19
  202. package/src/invoice/payments/payment-history/payment-history.test.tsx +13 -10
  203. package/src/invoice/payments/payments.component.tsx +20 -6
  204. package/src/invoice/payments/payments.test.tsx +88 -23
  205. package/src/invoice/printable-invoice/print-receipt.test.tsx +10 -28
  206. package/src/invoice/printable-invoice/printable-footer.test.tsx +5 -4
  207. package/src/invoice/printable-invoice/printable-invoice-header.component.tsx +3 -3
  208. package/src/invoice/printable-invoice/printable-invoice-header.test.tsx +26 -11
  209. package/src/invoice/printable-invoice/printable-invoice.component.tsx +38 -15
  210. package/src/left-panel-link.test.tsx +3 -3
  211. package/src/metrics-cards/metrics-cards.test.tsx +11 -10
  212. package/src/modal/delete-bill-confirmation.modal.test.tsx +134 -0
  213. package/src/modal/delete-bill-confirmation.modal.tsx +98 -0
  214. package/src/modal/delete-line-item-confirmation.modal.test.tsx +11 -9
  215. package/src/modal/finalize-bill-confirmation.modal.test.tsx +10 -8
  216. package/src/modal/require-payment-modal.test.tsx +12 -11
  217. package/src/payment-status-tag/payment-status-tag.component.tsx +50 -0
  218. package/src/payment-status-tag/payment-status-tag.scss +6 -0
  219. package/src/payment-status-tag/payment-status-tag.test.tsx +113 -0
  220. package/src/refunds/admin/refund-requests-left-panel-link.component.tsx +43 -0
  221. package/src/refunds/admin/refund-requests.component.tsx +324 -0
  222. package/src/refunds/admin/refund-requests.scss +133 -0
  223. package/src/refunds/admin/refund-requests.test.tsx +99 -0
  224. package/src/refunds/admin/review-bill-refunds/bill-line-items-table/bill-line-items-table.component.tsx +42 -0
  225. package/src/refunds/admin/review-bill-refunds/bill-line-items-table/bill-line-items-table.scss +76 -0
  226. package/src/refunds/admin/review-bill-refunds/bill-payments-table/bill-payments-table.component.tsx +50 -0
  227. package/src/refunds/admin/review-bill-refunds/bill-payments-table/bill-payments-table.scss +63 -0
  228. package/src/refunds/admin/review-bill-refunds/bill-receipt-rail/bill-receipt-rail.component.tsx +84 -0
  229. package/src/refunds/admin/review-bill-refunds/bill-receipt-rail/bill-receipt-rail.scss +54 -0
  230. package/src/refunds/admin/review-bill-refunds/bill-totals-summary/bill-totals-summary.component.tsx +83 -0
  231. package/src/refunds/admin/review-bill-refunds/bill-totals-summary/bill-totals-summary.scss +65 -0
  232. package/src/refunds/admin/review-bill-refunds/refund-card/refund-card.component.tsx +170 -0
  233. package/src/refunds/admin/review-bill-refunds/refund-card/refund-card.scss +155 -0
  234. package/src/refunds/admin/review-bill-refunds/refund-review-stack/refund-review-stack.component.tsx +86 -0
  235. package/src/refunds/admin/review-bill-refunds/refund-review-stack/refund-review-stack.scss +40 -0
  236. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.scss +14 -0
  237. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.test.tsx +313 -0
  238. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.modal.tsx +188 -0
  239. package/src/refunds/admin/review-bill-refunds/review-bill-refunds.utils.ts +66 -0
  240. package/src/refunds/refunds-table.component.tsx +137 -0
  241. package/src/refunds/refunds-table.scss +37 -0
  242. package/src/refunds/refunds-table.test.tsx +105 -0
  243. package/src/refunds/refunds.resource.test.ts +44 -0
  244. package/src/refunds/refunds.resource.ts +42 -0
  245. package/src/refunds/refunds.types.test.ts +15 -0
  246. package/src/refunds/request-refund.modal.scss +84 -0
  247. package/src/refunds/request-refund.modal.test.tsx +204 -0
  248. package/src/refunds/request-refund.modal.tsx +218 -0
  249. package/src/routes.json +36 -2
  250. package/src/types/index.ts +116 -1
  251. package/src/visit-bills/visit-bills-panel.component.tsx +151 -0
  252. package/src/visit-bills/visit-bills-panel.scss +31 -0
  253. package/src/visit-bills/visit-bills-panel.test.tsx +113 -0
  254. package/tools/empty-module.ts +1 -0
  255. package/tools/setup-tests.ts +9 -9
  256. package/translations/am.json +154 -16
  257. package/translations/ar.json +154 -16
  258. package/translations/ar_SY.json +154 -16
  259. package/translations/bn.json +154 -16
  260. package/translations/cs.json +154 -16
  261. package/translations/de.json +154 -16
  262. package/translations/en.json +154 -16
  263. package/translations/en_US.json +154 -16
  264. package/translations/es.json +154 -16
  265. package/translations/es_MX.json +154 -16
  266. package/translations/fr.json +154 -16
  267. package/translations/he.json +154 -16
  268. package/translations/hi.json +154 -16
  269. package/translations/hi_IN.json +154 -16
  270. package/translations/id.json +154 -16
  271. package/translations/it.json +154 -16
  272. package/translations/ka.json +154 -16
  273. package/translations/km.json +154 -16
  274. package/translations/ku.json +154 -16
  275. package/translations/ky.json +154 -16
  276. package/translations/lg.json +154 -16
  277. package/translations/ne.json +154 -16
  278. package/translations/pl.json +154 -16
  279. package/translations/pt.json +154 -16
  280. package/translations/pt_BR.json +154 -16
  281. package/translations/qu.json +154 -16
  282. package/translations/ro_RO.json +154 -16
  283. package/translations/ru_RU.json +154 -16
  284. package/translations/si.json +154 -16
  285. package/translations/sq.json +154 -16
  286. package/translations/sw.json +154 -16
  287. package/translations/sw_KE.json +154 -16
  288. package/translations/tr.json +154 -16
  289. package/translations/tr_TR.json +154 -16
  290. package/translations/uk.json +154 -16
  291. package/translations/uz.json +154 -16
  292. package/translations/uz@Latn.json +154 -16
  293. package/translations/uz_UZ.json +154 -16
  294. package/translations/vi.json +154 -16
  295. package/translations/zh.json +154 -16
  296. package/translations/zh_CN.json +179 -41
  297. package/translations/zh_TW.json +154 -16
  298. package/tsconfig.json +3 -3
  299. package/vitest.config.js +28 -0
  300. package/.turbo/cache/6c998b0f30a031ab-meta.json +0 -1
  301. package/.turbo/cache/6c998b0f30a031ab.tar.zst +0 -0
  302. package/dist/1119.js +0 -1
  303. package/dist/1197.js +0 -1
  304. package/dist/1435.js +0 -1
  305. package/dist/1435.js.map +0 -1
  306. package/dist/1807.js +0 -1
  307. package/dist/1807.js.map +0 -1
  308. package/dist/2146.js +0 -1
  309. package/dist/2177.js +0 -2
  310. package/dist/2177.js.LICENSE.txt +0 -9
  311. package/dist/2177.js.map +0 -1
  312. package/dist/2690.js +0 -1
  313. package/dist/2704.js +0 -1
  314. package/dist/2704.js.map +0 -1
  315. package/dist/3002.js +0 -1
  316. package/dist/3002.js.map +0 -1
  317. package/dist/3041.js +0 -1
  318. package/dist/3041.js.map +0 -1
  319. package/dist/3099.js +0 -1
  320. package/dist/3184.js +0 -2
  321. package/dist/3184.js.LICENSE.txt +0 -14
  322. package/dist/3184.js.map +0 -1
  323. package/dist/3584.js +0 -1
  324. package/dist/4055.js +0 -1
  325. package/dist/4132.js +0 -1
  326. package/dist/4225.js +0 -1
  327. package/dist/4225.js.map +0 -1
  328. package/dist/4300.js +0 -1
  329. package/dist/4335.js +0 -1
  330. package/dist/439.js +0 -1
  331. package/dist/4618.js +0 -1
  332. package/dist/4652.js +0 -1
  333. package/dist/4944.js +0 -1
  334. package/dist/5173.js +0 -1
  335. package/dist/5241.js +0 -1
  336. package/dist/5422.js +0 -1
  337. package/dist/5422.js.map +0 -1
  338. package/dist/5442.js +0 -1
  339. package/dist/5661.js +0 -1
  340. package/dist/6022.js +0 -1
  341. package/dist/6404.js +0 -1
  342. package/dist/6404.js.map +0 -1
  343. package/dist/6468.js +0 -1
  344. package/dist/6540.js +0 -2
  345. package/dist/6540.js.LICENSE.txt +0 -9
  346. package/dist/6540.js.map +0 -1
  347. package/dist/6589.js +0 -1
  348. package/dist/6606.js +0 -1
  349. package/dist/6606.js.map +0 -1
  350. package/dist/6679.js +0 -1
  351. package/dist/6792.js +0 -1
  352. package/dist/6792.js.map +0 -1
  353. package/dist/6840.js +0 -1
  354. package/dist/6859.js +0 -1
  355. package/dist/7097.js +0 -1
  356. package/dist/7159.js +0 -1
  357. package/dist/723.js +0 -1
  358. package/dist/7255.js +0 -1
  359. package/dist/7255.js.map +0 -1
  360. package/dist/7617.js +0 -1
  361. package/dist/795.js +0 -1
  362. package/dist/8163.js +0 -1
  363. package/dist/8341.js +0 -2
  364. package/dist/8341.js.LICENSE.txt +0 -52
  365. package/dist/8341.js.map +0 -1
  366. package/dist/8349.js +0 -1
  367. package/dist/8371.js +0 -1
  368. package/dist/8421.js +0 -1
  369. package/dist/8421.js.map +0 -1
  370. package/dist/8618.js +0 -1
  371. package/dist/890.js +0 -1
  372. package/dist/9214.js +0 -1
  373. package/dist/9538.js +0 -1
  374. package/dist/9569.js +0 -1
  375. package/dist/961.js +0 -2
  376. package/dist/961.js.LICENSE.txt +0 -19
  377. package/dist/961.js.map +0 -1
  378. package/dist/986.js +0 -1
  379. package/dist/9879.js +0 -1
  380. package/dist/9895.js +0 -1
  381. package/dist/9900.js +0 -1
  382. package/dist/9913.js +0 -1
  383. package/dist/main.js.LICENSE.txt +0 -62
  384. package/src/billable-services/bill-waiver/bill-selection.component.tsx +0 -76
  385. package/src/billable-services/bill-waiver/bill-waiver-form.component.tsx +0 -107
  386. package/src/billable-services/bill-waiver/bill-waiver-form.scss +0 -34
  387. package/src/billable-services/bill-waiver/bill-waiver.component.tsx +0 -34
  388. package/src/billable-services/bill-waiver/bill-waiver.scss +0 -10
  389. package/src/billable-services/bill-waiver/patient-bills.component.tsx +0 -134
  390. package/webpack.config.js +0 -1
@@ -0,0 +1,253 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ Button,
4
+ FormGroup,
5
+ InlineLoading,
6
+ ModalBody,
7
+ ModalFooter,
8
+ ModalHeader,
9
+ NumberInput,
10
+ RadioButton,
11
+ RadioButtonGroup,
12
+ Stack,
13
+ TextArea,
14
+ } from '@carbon/react';
15
+ import { useTranslation } from 'react-i18next';
16
+ import { getCoreTranslation, showSnackbar, useConfig } from '@openmrs/esm-framework';
17
+ import type { BillingConfig } from '../config-schema';
18
+ import { convertToCurrency } from '../helpers';
19
+ import { BillDiscountType } from '../types';
20
+ import { requestDiscount } from './discounts.resource';
21
+ import styles from './request-discount.modal.scss';
22
+
23
+ interface Props {
24
+ closeModal: () => void;
25
+ bill: {
26
+ uuid: string;
27
+ total: number;
28
+ amountDue: number;
29
+ receiptNumber?: string;
30
+ lineItemCount?: number;
31
+ };
32
+ lineItem?: {
33
+ uuid: string;
34
+ display: string;
35
+ total: number;
36
+ quantity?: number;
37
+ price?: number;
38
+ };
39
+ onMutate?: () => void;
40
+ }
41
+
42
+ const RequestDiscountModal: React.FC<Props> = ({ closeModal, bill, lineItem, onMutate }) => {
43
+ const { t } = useTranslation();
44
+ const { defaultCurrency } = useConfig<BillingConfig>();
45
+ const [discountType, setDiscountType] = useState<BillDiscountType>(BillDiscountType.PERCENTAGE);
46
+ const [value, setValue] = useState<number | null>(null);
47
+ const [justification, setJustification] = useState('');
48
+ const [submitting, setSubmitting] = useState(false);
49
+
50
+ const isLineItem = !!lineItem;
51
+ const scopeTotal = lineItem?.total ?? bill.total;
52
+
53
+ const trimmedJustification = justification.trim();
54
+
55
+ const discountAmount =
56
+ value != null && !Number.isNaN(value) && value > 0
57
+ ? discountType === BillDiscountType.PERCENTAGE
58
+ ? (scopeTotal * value) / 100
59
+ : value
60
+ : null;
61
+
62
+ const justificationPlaceholder = isLineItem
63
+ ? t('lineItemJustificationPlaceholder', 'e.g., damaged item, wrong quantity billed, expired stock')
64
+ : t('billJustificationPlaceholder', 'e.g., hardship assistance, charity case, write-off');
65
+
66
+ const justificationError =
67
+ justification.length > 1000 ? t('justificationTooLong', 'Justification cannot exceed 1000 characters') : null;
68
+
69
+ const valueError = (() => {
70
+ if (value == null || Number.isNaN(value)) return null;
71
+ if (value <= 0) return t('valueMustBePositive', 'Value must be greater than 0');
72
+ if (discountType === BillDiscountType.PERCENTAGE && value > 100)
73
+ return t('percentageTooHigh', 'Percentage cannot exceed 100');
74
+ if (discountAmount == null) return null;
75
+ if (discountAmount > bill.amountDue) return t('discountExceedsAmountDue', 'Discount cannot exceed the amount due');
76
+ if (lineItem && discountAmount > lineItem.total)
77
+ return t('discountExceedsLineTotal', 'Discount cannot exceed the line item total');
78
+ return null;
79
+ })();
80
+
81
+ const canSubmit =
82
+ !submitting && value != null && trimmedJustification.length > 0 && !justificationError && !valueError;
83
+
84
+ const handleSubmit = async () => {
85
+ if (!canSubmit || value == null) return;
86
+ setSubmitting(true);
87
+ try {
88
+ await requestDiscount({
89
+ bill: bill.uuid,
90
+ lineItem: lineItem?.uuid,
91
+ discountType,
92
+ discountValue: value,
93
+ justification: trimmedJustification,
94
+ });
95
+ onMutate?.();
96
+ showSnackbar({
97
+ title: t('discountRequested', 'Discount request submitted'),
98
+ subtitle: t('discountPendingReview', 'An admin will review your request'),
99
+ kind: 'success',
100
+ });
101
+ closeModal();
102
+ } catch (err: unknown) {
103
+ const subtitle = (err as any)?.responseBody?.error?.message ?? (err instanceof Error ? err.message : undefined);
104
+ showSnackbar({
105
+ title: t('discountRequestFailed', 'Could not submit discount request'),
106
+ subtitle,
107
+ kind: 'error',
108
+ });
109
+ } finally {
110
+ setSubmitting(false);
111
+ }
112
+ };
113
+
114
+ return (
115
+ <>
116
+ <ModalHeader closeModal={closeModal} title={t('requestDiscount', 'Request discount')} />
117
+ <ModalBody className={styles.modalBody}>
118
+ <Stack gap={5}>
119
+ <section className={styles.scopePanel} aria-label={t('discountScope', 'Discount scope')}>
120
+ <div className={styles.scopePrimary}>
121
+ {isLineItem ? lineItem.display : t('wholeBillScope', 'Whole bill')}
122
+ </div>
123
+ <ul className={styles.scopeMeta}>
124
+ {bill.receiptNumber && <li>{t('invoiceLabel', 'Invoice {{number}}', { number: bill.receiptNumber })}</li>}
125
+ {isLineItem && lineItem.quantity != null && lineItem.price != null && (
126
+ <li>
127
+ {t('qtyTimesPrice', 'Qty {{quantity}} × {{price}}', {
128
+ quantity: lineItem.quantity,
129
+ price: convertToCurrency(lineItem.price, defaultCurrency),
130
+ })}
131
+ </li>
132
+ )}
133
+ {!isLineItem && bill.lineItemCount != null && (
134
+ <li>{t('lineItemCount', '{{count}} line items', { count: bill.lineItemCount })}</li>
135
+ )}
136
+ <li className={styles.scopeTotal}>
137
+ {isLineItem
138
+ ? t('lineTotalLabel', 'Line total {{total}}', {
139
+ total: convertToCurrency(scopeTotal, defaultCurrency),
140
+ })
141
+ : t('billTotalLabel', 'Bill total {{total}}', {
142
+ total: convertToCurrency(scopeTotal, defaultCurrency),
143
+ })}
144
+ </li>
145
+ </ul>
146
+ </section>
147
+
148
+ <FormGroup legendText={t('discount', 'Discount')} className={styles.discountGroup}>
149
+ <Stack gap={4}>
150
+ <RadioButtonGroup
151
+ legendText=""
152
+ name="discount-type"
153
+ valueSelected={discountType}
154
+ onChange={(v) => setDiscountType(v as BillDiscountType)}>
155
+ <RadioButton labelText={t('percentage', 'Percentage')} value={BillDiscountType.PERCENTAGE} />
156
+ <RadioButton labelText={t('fixedAmount', 'Fixed amount')} value={BillDiscountType.FIXED_AMOUNT} />
157
+ </RadioButtonGroup>
158
+
159
+ <NumberInput
160
+ id="discount-value"
161
+ label={
162
+ discountType === BillDiscountType.PERCENTAGE
163
+ ? t('valuePercentLabel', 'Value (%)')
164
+ : t('valueAmountLabel', 'Value ({{currency}})', { currency: defaultCurrency })
165
+ }
166
+ allowEmpty
167
+ min={0}
168
+ value={value ?? ''}
169
+ invalid={!!valueError}
170
+ invalidText={valueError ?? ''}
171
+ onChange={(_e, { value: v }) => {
172
+ if (v === '' || v == null) {
173
+ setValue(null);
174
+ return;
175
+ }
176
+ const n = typeof v === 'string' ? parseFloat(v) : v;
177
+ setValue(Number.isNaN(n) ? null : n);
178
+ }}
179
+ />
180
+ </Stack>
181
+ </FormGroup>
182
+
183
+ {discountAmount != null && (
184
+ <section className={styles.summaryCard} aria-label={t('discountSummary', 'Discount summary')}>
185
+ <span className={styles.summaryLabel}>
186
+ {isLineItem ? t('lineTotal', 'Line total') : t('billTotal', 'Bill total')}
187
+ </span>
188
+ <span className={styles.summaryValue}>{convertToCurrency(scopeTotal, defaultCurrency)}</span>
189
+
190
+ <span className={styles.summaryLabel}>
191
+ {discountType === BillDiscountType.PERCENTAGE && value != null
192
+ ? t('discountWithPercent', 'Discount ({{percent}}%)', { percent: value })
193
+ : t('discountLabel', 'Discount')}
194
+ </span>
195
+ <span className={`${styles.summaryValue} ${styles.summaryDiscount}`}>
196
+ −{convertToCurrency(discountAmount, defaultCurrency)}
197
+ </span>
198
+
199
+ {isLineItem && (
200
+ <>
201
+ <span className={styles.summaryLabel}>{t('lineAfterDiscount', 'Line after discount')}</span>
202
+ <span className={styles.summaryValue}>
203
+ {convertToCurrency(scopeTotal - discountAmount, defaultCurrency)}
204
+ </span>
205
+ </>
206
+ )}
207
+
208
+ <span className={styles.summaryDivider} aria-hidden="true" />
209
+
210
+ <span className={styles.summaryLabel}>{t('outstanding', 'Outstanding')}</span>
211
+ <span className={styles.summaryValue}>{convertToCurrency(bill.amountDue, defaultCurrency)}</span>
212
+
213
+ <span className={styles.summaryTotalLabel}>
214
+ {t('amountDueOnBillAfterDiscount', 'Amount due on bill after discount')}
215
+ </span>
216
+ <span className={styles.summaryTotalValue}>
217
+ {convertToCurrency(bill.amountDue - discountAmount, defaultCurrency)}
218
+ </span>
219
+ </section>
220
+ )}
221
+
222
+ <TextArea
223
+ id="discount-justification"
224
+ labelText={t('justification', 'Justification')}
225
+ placeholder={justificationPlaceholder}
226
+ maxCount={1000}
227
+ enableCounter
228
+ required
229
+ rows={3}
230
+ value={justification}
231
+ invalid={!!justificationError}
232
+ invalidText={justificationError ?? ''}
233
+ onChange={(e) => setJustification(e.target.value)}
234
+ />
235
+ </Stack>
236
+ </ModalBody>
237
+ <ModalFooter>
238
+ <Button kind="secondary" onClick={closeModal}>
239
+ {getCoreTranslation('cancel')}
240
+ </Button>
241
+ <Button kind="primary" onClick={handleSubmit} disabled={!canSubmit}>
242
+ {submitting ? (
243
+ <InlineLoading description={t('submitting', 'Submitting') + '...'} />
244
+ ) : (
245
+ <span>{t('submitRequest', 'Submit request')}</span>
246
+ )}
247
+ </Button>
248
+ </ModalFooter>
249
+ </>
250
+ );
251
+ };
252
+
253
+ export default RequestDiscountModal;
package/src/index.ts CHANGED
@@ -1,22 +1,27 @@
1
- import { configSchema } from './config-schema';
1
+ import { FinancialAssets, Settings, TagGroup, Wallet } from '@carbon/react/icons';
2
2
  import { createDashboard, defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework';
3
3
  import { createLeftPanelLink } from './left-panel-link.component';
4
- import { dashboardMeta } from './dashboard.meta';
5
- import { Settings, Wallet } from '@carbon/react/icons';
6
4
  import { createBillableServicesLeftPanelLink } from './billable-services/billable-services-left-panel-link.component';
7
5
  import { createBillableServicesLeftPanelMenu } from './billable-services/billable-services-left-panel-menu.component';
8
- import AddCashPointModal from './billable-services/cash-point/add-cash-point.modal';
6
+ import { createDiscountRequestsLeftPanelLink } from './discounts/admin/discount-requests-left-panel-link.component';
7
+ import { createRefundRequestsLeftPanelLink } from './refunds/admin/refund-requests-left-panel-link.component';
9
8
  import appMenu from './billable-services/billable-services-menu-item/item.component';
10
9
  import BillableServiceHome from './billable-services/billable-services-home.component';
11
10
  import BillableServicesCardLink from './billable-services-admin-card-link.component';
12
11
  import BillHistory from './bill-history/bill-history.component';
13
12
  import BillingCheckInForm from './billing-form/billing-checkin-form.component';
13
+ import VisitAttributeTags from './invoice/payments/visit-tags/visit-attribute.component';
14
14
  import DeletePaymentModeModal from './billable-services/payment-modes/delete-payment-mode.modal';
15
15
  import EditBillLineItemModal from './bill-item-actions/edit-bill-item.modal';
16
16
  import PaymentModeFormModal from './billable-services/payment-modes/payment-mode-form.modal';
17
17
  import RequirePaymentModal from './modal/require-payment.modal';
18
+ import AddCashPointModal from './billable-services/cash-point/add-cash-point.modal';
19
+ import RequestDiscountModal from './discounts/request-discount.modal';
20
+ import ReviewBillDiscountsModal from './discounts/admin/review-bill-discounts/review-bill-discounts.modal';
18
21
  import RootComponent from './root.component';
19
- import VisitAttributeTags from './invoice/payments/visit-tags/visit-attribute.component';
22
+ import PaymentStatusTag from './payment-status-tag/payment-status-tag.component';
23
+ import { configSchema } from './config-schema';
24
+ import { dashboardMeta } from './dashboard.meta';
20
25
 
21
26
  const moduleName = '@openmrs/esm-billing-app';
22
27
 
@@ -54,6 +59,8 @@ export const billingCheckInForm = getSyncLifecycle(BillingCheckInForm, options);
54
59
 
55
60
  export const billingPatientSummary = getSyncLifecycle(BillHistory, options);
56
61
 
62
+ export const visitBillsPanel = getAsyncLifecycle(() => import('./visit-bills/visit-bills-panel.component'), options);
63
+
57
64
  export const requirePaymentModal = getSyncLifecycle(RequirePaymentModal, options);
58
65
 
59
66
  export const paymentModeFormModal = getSyncLifecycle(PaymentModeFormModal, options);
@@ -68,6 +75,8 @@ export const root = getSyncLifecycle(RootComponent, options);
68
75
 
69
76
  export const visitAttributeTags = getSyncLifecycle(VisitAttributeTags, options);
70
77
 
78
+ export const patientPaymentStatusTag = getSyncLifecycle(PaymentStatusTag, options);
79
+
71
80
  export const billingFormWorkspace = getAsyncLifecycle(() => import('./billing-form/billing-form.workspace'), options);
72
81
 
73
82
  export const billableServiceFormWorkspace = getAsyncLifecycle(
@@ -86,22 +95,6 @@ export const billableServicesLeftPanelLink = getSyncLifecycle(
86
95
  options,
87
96
  );
88
97
 
89
- // t('billWaiver', 'Bill waiver')
90
- // Bill waiver feature disabled - O3-5057
91
- // The following export is commented out along with:
92
- // - BillWaiver component import and route in billable-services-home.component.tsx
93
- // - bill-waiver-left-panel-link extension removed from routes.json
94
- // export const billWaiverLeftPanelLink = getSyncLifecycle(
95
- // createBillableServicesLeftPanelLink({
96
- // name: 'bill-waiver',
97
- // title: 'billWaiver',
98
- // path: 'waive-bill',
99
- // icon: Money,
100
- // privilege: 'coreapps.systemAdministration',
101
- // }),
102
- // options,
103
- // );
104
-
105
98
  // t('billingSettings', 'Billing settings')
106
99
  // t('cashPointConfig', 'Cash point configuration')
107
100
  // t('paymentModesConfig', 'Payment modes configuration')
@@ -135,3 +128,41 @@ export const finalizeBillConfirmationModal = getAsyncLifecycle(
135
128
  () => import('./modal/finalize-bill-confirmation.modal'),
136
129
  options,
137
130
  );
131
+
132
+ export const deleteBillConfirmationModal = getAsyncLifecycle(
133
+ () => import('./modal/delete-bill-confirmation.modal'),
134
+ options,
135
+ );
136
+
137
+ export const requestDiscountModal = getSyncLifecycle(RequestDiscountModal, options);
138
+
139
+ export const reviewBillDiscountsModal = getSyncLifecycle(ReviewBillDiscountsModal, options);
140
+
141
+ // t('discountRequests', 'Discount requests')
142
+ export const discountRequestsLeftPanelLink = getSyncLifecycle(
143
+ createDiscountRequestsLeftPanelLink({
144
+ name: 'discount-requests',
145
+ title: 'discountRequests',
146
+ path: 'discount-requests',
147
+ icon: TagGroup,
148
+ }),
149
+ options,
150
+ );
151
+
152
+ export const requestRefundModal = getAsyncLifecycle(() => import('./refunds/request-refund.modal'), options);
153
+
154
+ export const reviewBillRefundsModal = getAsyncLifecycle(
155
+ () => import('./refunds/admin/review-bill-refunds/review-bill-refunds.modal'),
156
+ options,
157
+ );
158
+
159
+ // t('refundRequests', 'Refund requests')
160
+ export const refundRequestsLeftPanelLink = getSyncLifecycle(
161
+ createRefundRequestsLeftPanelLink({
162
+ name: 'refund-requests',
163
+ title: 'refundRequests',
164
+ path: 'refund-requests',
165
+ icon: FinancialAssets,
166
+ }),
167
+ options,
168
+ );
@@ -16,20 +16,30 @@ import {
16
16
  TableToolbarSearch,
17
17
  Tile,
18
18
  } from '@carbon/react';
19
- import { getCoreTranslation, isDesktop, useConfig, useDebounce, useLayoutType } from '@openmrs/esm-framework';
20
- import { type LineItem, type MappedBill } from '../types';
19
+ import {
20
+ getCoreTranslation,
21
+ isDesktop,
22
+ showModal,
23
+ useConfig,
24
+ useDebounce,
25
+ useLayoutType,
26
+ } from '@openmrs/esm-framework';
27
+ import LineItemActionMenu from './line-item-action-menu.component';
21
28
  import { convertToCurrency } from '../helpers';
22
29
  import type { BillingConfig } from '../config-schema';
23
- import LineItemActionMenu from './line-item-action-menu.component';
30
+ import { BillStatus, RefundStatus, type LineItem, type MappedBill } from '../types';
24
31
  import styles from './invoice-table.scss';
25
32
 
33
+ const getLineItemTotal = (item: LineItem) => (item.price ?? 0) * (item.quantity ?? 0);
34
+
26
35
  type InvoiceTableProps = {
27
36
  bill: MappedBill;
28
37
  isLoadingBill?: boolean;
29
38
  onMutate?: () => void;
39
+ viewOnly?: boolean;
30
40
  };
31
41
 
32
- const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMutate }) => {
42
+ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMutate, viewOnly }) => {
33
43
  const { t } = useTranslation();
34
44
  const { defaultCurrency } = useConfig<BillingConfig>();
35
45
  const layout = useLayoutType();
@@ -38,6 +48,78 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
38
48
  const [searchTerm, setSearchTerm] = useState('');
39
49
  const debouncedSearchTerm = useDebounce(searchTerm);
40
50
 
51
+ const discounts = useMemo(() => (bill?.discounts ?? []).filter((d) => !d.voided), [bill?.discounts]);
52
+ const billStatusEligible = bill?.status === BillStatus.PENDING || bill?.status === BillStatus.POSTED;
53
+ const hasBillLevelDiscount = discounts.some((d) => !d.lineItemUuid);
54
+
55
+ const billRefunds = useMemo(() => (bill?.refunds ?? []).filter((r) => !r.voided), [bill?.refunds]);
56
+ const billStatusRefundEligible =
57
+ bill?.status === BillStatus.PAID ||
58
+ bill?.status === BillStatus.PARTIALLY_REFUNDED ||
59
+ bill?.status === BillStatus.REFUND_REQUESTED;
60
+ const activeRefunds = billRefunds.filter(
61
+ (r) => r.status === RefundStatus.REQUESTED || r.status === RefundStatus.APPROVED,
62
+ );
63
+ const activeBillLevelRefund = activeRefunds.some((r) => !r.lineItemUuid);
64
+
65
+ const lineHasActiveRefund = (lineItemUuid: string) => activeRefunds.some((r) => r.lineItemUuid === lineItemUuid);
66
+
67
+ const showLineItemRefundRequest = (lineItem: LineItem) =>
68
+ billStatusRefundEligible && !activeBillLevelRefund && !lineHasActiveRefund(lineItem.uuid ?? '') && !!lineItem.uuid;
69
+
70
+ const lineHasActiveDiscount = (lineItemUuid: string) => discounts.some((d) => d.lineItemUuid === lineItemUuid);
71
+
72
+ const showLineItemRequest = (lineItem: LineItem) =>
73
+ billStatusEligible && !hasBillLevelDiscount && !lineHasActiveDiscount(lineItem.uuid);
74
+
75
+ const handleLineItemRefundRequest = (item: LineItem) => {
76
+ if (!item.uuid) return;
77
+ const lineTotal = getLineItemTotal(item);
78
+ const lineCommittedRefunds = billRefunds.filter(
79
+ (r) =>
80
+ r.lineItemUuid === item.uuid && (r.status === RefundStatus.APPROVED || r.status === RefundStatus.COMPLETED),
81
+ );
82
+ const remaining = lineTotal - lineCommittedRefunds.reduce((s, r) => s + r.refundAmount, 0);
83
+ const dispose = showModal('request-refund-modal', {
84
+ bill: {
85
+ uuid: bill.uuid,
86
+ total: bill.totalAmount ?? 0,
87
+ amountAfterDiscount: bill.netAmount ?? bill.totalAmount ?? 0,
88
+ },
89
+ lineItem: {
90
+ uuid: item.uuid,
91
+ display: item.item || item.billableService || '--',
92
+ total: lineTotal,
93
+ quantity: item.quantity,
94
+ price: item.price,
95
+ },
96
+ remainingRefundable: Math.max(0, remaining),
97
+ onMutate: () => onMutate?.(),
98
+ closeModal: () => dispose(),
99
+ });
100
+ };
101
+
102
+ const handleLineItemRequest = (lineItem: LineItem) => {
103
+ const dispose = showModal('request-discount-modal', {
104
+ bill: {
105
+ uuid: bill.uuid,
106
+ total: bill.totalAmount ?? 0,
107
+ amountDue: Math.max(0, (bill.netAmount ?? bill.totalAmount ?? 0) - (bill.tenderedAmount ?? 0)),
108
+ receiptNumber: bill.receiptNumber,
109
+ lineItemCount: lineItems.length,
110
+ },
111
+ lineItem: {
112
+ uuid: lineItem.uuid,
113
+ display: lineItem.item || lineItem.billableService || '--',
114
+ total: getLineItemTotal(lineItem),
115
+ quantity: lineItem.quantity,
116
+ price: lineItem.price,
117
+ },
118
+ onMutate: () => onMutate?.(),
119
+ closeModal: () => dispose(),
120
+ });
121
+ };
122
+
41
123
  const filteredLineItems = useMemo(() => {
42
124
  if (!debouncedSearchTerm) {
43
125
  return lineItems;
@@ -68,10 +150,10 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
68
150
  no: `${index + 1}`,
69
151
  id: `${item.uuid}`,
70
152
  billItem: item.billableService ? item.billableService : item?.item,
71
- status: item.paymentStatus,
153
+ status: item.status,
72
154
  quantity: item.quantity,
73
155
  price: convertToCurrency(item.price, defaultCurrency),
74
- total: convertToCurrency(item.price * item.quantity, defaultCurrency),
156
+ total: convertToCurrency(getLineItemTotal(item), defaultCurrency),
75
157
  })) ?? [],
76
158
  [filteredLineItems, defaultCurrency],
77
159
  );
@@ -104,13 +186,15 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
104
186
  </span>
105
187
  }
106
188
  title={t('lineItems', 'Line items')}>
107
- <TableToolbarSearch
108
- className={styles.searchbox}
109
- expanded
110
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchTerm(e.target.value)}
111
- placeholder={t('searchThisTable', 'Search this table')}
112
- size={responsiveSize}
113
- />
189
+ {!viewOnly && (
190
+ <TableToolbarSearch
191
+ className={styles.searchbox}
192
+ expanded
193
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSearchTerm(e.target.value)}
194
+ placeholder={t('searchThisTable', 'Search this table')}
195
+ size={responsiveSize}
196
+ />
197
+ )}
114
198
  <Table
115
199
  {...getTableProps()}
116
200
  aria-label={t('invoiceLineItems', 'Invoice line items')}
@@ -120,7 +204,7 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
120
204
  {headers.map((header) => (
121
205
  <TableHeader key={header.key}>{header.header}</TableHeader>
122
206
  ))}
123
- <TableHeader aria-label={getCoreTranslation('actions')} />
207
+ {!viewOnly && <TableHeader aria-label={getCoreTranslation('actions')} />}
124
208
  </TableRow>
125
209
  </TableHead>
126
210
  <TableBody>
@@ -131,9 +215,21 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
131
215
  {row.cells.map((cell) => (
132
216
  <TableCell key={cell.id}>{cell.value}</TableCell>
133
217
  ))}
134
- <TableCell className="cds--table-column-menu">
135
- {item && <LineItemActionMenu bill={bill} item={item} onMutate={onMutate} />}
136
- </TableCell>
218
+ {!viewOnly && (
219
+ <TableCell className="cds--table-column-menu">
220
+ {item && (
221
+ <LineItemActionMenu
222
+ bill={bill}
223
+ item={item}
224
+ onMutate={onMutate}
225
+ showDiscountRequest={showLineItemRequest(item)}
226
+ onDiscountRequest={() => handleLineItemRequest(item)}
227
+ showRefundRequest={showLineItemRefundRequest(item)}
228
+ onRefundRequest={() => handleLineItemRefundRequest(item)}
229
+ />
230
+ )}
231
+ </TableCell>
232
+ )}
137
233
  </TableRow>
138
234
  );
139
235
  })}
@@ -149,7 +245,9 @@ const InvoiceTable: React.FC<InvoiceTableProps> = ({ bill, isLoadingBill, onMuta
149
245
  <p className={styles.filterEmptyStateContent}>
150
246
  {t('noMatchingItemsToDisplay', 'No matching items to display')}
151
247
  </p>
152
- <p className={styles.filterEmptyStateHelper}>{t('checkFilters', 'Check the filters above')}</p>
248
+ {!viewOnly && (
249
+ <p className={styles.filterEmptyStateHelper}>{t('checkFilters', 'Check the filters above')}</p>
250
+ )}
153
251
  </Tile>
154
252
  </Layer>
155
253
  </div>