Report.vue 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <script setup>
  2. import { watch, onMounted, ref } from 'vue'
  3. import { Inertia } from '@inertiajs/inertia'
  4. import { Head, useForm } from '@inertiajs/inertia-vue3'
  5. import dayjs from 'dayjs'
  6. import { pickBy } from 'lodash'
  7. import AppLayout from '@/layouts/AppLayout.vue'
  8. import AppPagination from '@/components/AppPagination.vue'
  9. import AppButton from '@/components/AppButton.vue'
  10. import TableHeader from './TableHeader'
  11. const props = defineProps({
  12. mutations: {
  13. type: Object,
  14. default: {
  15. details: {
  16. data: [],
  17. links: [],
  18. total: 0,
  19. },
  20. },
  21. },
  22. filters: Object,
  23. })
  24. const filterForm = useForm({
  25. dates: null,
  26. startDate: props.filters.startDate,
  27. endDate: props.filters.endDate,
  28. })
  29. onMounted(() => {
  30. if (props.filters.startDate || props.filters.endDate) {
  31. if (props.filters.endDate) {
  32. filterForm.dates = [new Date(props.filters.startDate), new Date(props.filters.endDate)]
  33. } else {
  34. filterForm.dates = [new Date(props.filters.startDate), null]
  35. }
  36. }
  37. })
  38. watch(filterForm, () => {
  39. if (filterForm.dates) {
  40. if (filterForm.dates[1]) {
  41. filterForm.startDate = dayjs(filterForm.dates[0]).format('YYYY-MM-DD')
  42. filterForm.endDate = dayjs(filterForm.dates[1]).format('YYYY-MM-DD')
  43. } else {
  44. filterForm.startDate = dayjs(filterForm.dates[0]).format('YYYY-MM-DD')
  45. filterForm.endDate = null
  46. }
  47. } else {
  48. filterForm.endDate = null
  49. filterForm.startDate = null
  50. }
  51. Inertia.reload({
  52. data: pickBy({
  53. startDate: filterForm.startDate,
  54. endDate: filterForm.endDate,
  55. }),
  56. only: ['mutations'],
  57. })
  58. const params = window.location.search
  59. exportExcelLink.value = `/reports/mutations/export/excel${params}`
  60. })
  61. const filterReset = () => {
  62. Inertia.get('/reports/mutations')
  63. }
  64. const linkReference = (data) => {
  65. if (data.topupId) {
  66. return route('top-ups.show', data.topUpId)
  67. } else if (data.expenseId) {
  68. return route('expenses.show', data.expenseId)
  69. } else {
  70. console.info('under construction')
  71. // return route('out-transactions.show', data.outTransactionId)
  72. }
  73. }
  74. const exportExcelLink = ref('/reports/mutations/export/excel')
  75. </script>
  76. <template>
  77. <AppLayout>
  78. <Head title="Laporan Mutasi" />
  79. <DataTable
  80. responsive-layout="scroll"
  81. column-resize-mode="expand"
  82. :value="mutations.details.data"
  83. :row-hover="true"
  84. :striped-rows="true"
  85. >
  86. <template #header>
  87. <h1>Laporan Mutasi</h1>
  88. <div class="grid">
  89. <div class="col-12 md:col-8">
  90. <div class="grid">
  91. <div class="col-12 md:col-4">
  92. <Calendar
  93. class="w-full"
  94. v-model="filterForm.dates"
  95. selection-mode="range"
  96. placeholder="filter waktu..."
  97. date-format="dd/mm/yy"
  98. :manual-input="false"
  99. />
  100. </div>
  101. <div class="col-auto mt-2 ml-2">
  102. <Button label="reset" class="p-button-link" @click="filterReset" />
  103. </div>
  104. </div>
  105. </div>
  106. <div class="col-12 md:col-4 flex flex-column md:flex-row justify-content-end">
  107. <AppButton
  108. v-if="mutations.details.total"
  109. label="Export excel"
  110. class-button="p-button-outlined md:w-16rem"
  111. icon="pi pi-file-excel"
  112. :inertia-link="false"
  113. :href="exportExcelLink"
  114. />
  115. </div>
  116. </div>
  117. <div v-if="mutations.totalAmount" class="grid mt-5 ml-1">
  118. <div class="col-auto mr-7">
  119. <h2>
  120. <span class="text-base"> <i class="pi pi-wallet" /> Pendapatan</span>
  121. <br />
  122. <span class="text-xl font-bold">{{ mutations.totalIncome }}</span>
  123. </h2>
  124. </div>
  125. <div class="col-auto mr-7">
  126. <h2>
  127. <span class="text-base"> <i class="pi pi-wallet" /> Pengeluaran</span>
  128. <br />
  129. <span class="text-xl font-bold">{{ mutations.totalExpense }}</span>
  130. </h2>
  131. </div>
  132. <div class="col-auto">
  133. <h2>
  134. <span class="text-base"> <i class="pi pi-wallet" /> Total </span>
  135. <br />
  136. <span class="text-xl font-bold">{{ mutations.totalAmount }}</span>
  137. </h2>
  138. </div>
  139. </div>
  140. </template>
  141. <Column
  142. v-for="tableHeader in TableHeader"
  143. :field="tableHeader.field"
  144. :header="tableHeader.header"
  145. :key="tableHeader.field"
  146. />
  147. <Column>
  148. <template #body="{ data }">
  149. <AppButton
  150. icon="pi pi-link"
  151. class="p-button-text p-button-icon-only p-button-rounded p-button-text"
  152. :href="linkReference(data)"
  153. />
  154. </template>
  155. </Column>
  156. </DataTable>
  157. <AppPagination :links="mutations.details.links" />
  158. </AppLayout>
  159. </template>