Advertisement
kidto1412

loan form

May 15th, 2025
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <template>
  2.   <div class="tw-grid tw-grid-cols-12 tw-gap-x-4">
  3.     <div class="tw-col-span-12 md:tw-col-span-6">
  4.       <k-select-parameter
  5.         v-model="form.purpose_of_use"
  6.         parameter-type="TUJUAN_KREDIT"
  7.         required
  8.         t-label="purposeOfApplicant"
  9.       />
  10.     </div>
  11.  
  12.     <div class="tw-col-span-12 md:tw-col-span-6">
  13.       <k-select
  14.         ref="kSelectRef"
  15.         v-model="form.tenor"
  16.         type="number"
  17.         required
  18.         t-label="tenor"
  19.         @focus="() => onLoadShowOption()"
  20.         :loading="loading"
  21.         :error-message="errorMessage"
  22.         :options="options"
  23.       />
  24.     </div>
  25.  
  26.     <div class="tw-col-span-12 md:tw-col-span-6">
  27.       <k-currency-input
  28.         v-model="form.credit_amount"
  29.         required
  30.         t-label="creditRequested"
  31.         :type="'text'"
  32.         :is-amount="true"
  33.         :istNetIncome="false"
  34.         :maxAmount="LOAN_MAX_AMOUN"
  35.         :minAmount="LOAN_MIN_AMOUN"
  36.         :rules="[validateMinAmount]"
  37.         :is-white="false"
  38.       />
  39.     </div>
  40.   </div>
  41. </template>
  42. <script setup lang="ts">
  43. import { ApplicantDataRequest } from 'src/common/entities/applicant.entity'
  44. import { computed, onMounted, ref, watch } from 'vue'
  45. import KSelect from 'src/components/ui/KSelect.vue'
  46. import { GetErrorMessage } from 'src/common/utils/error.utils'
  47. import { useParameterEndpoint } from 'src/common/endpoints/parameter.endpoint'
  48. import { parseCurrency } from 'src/common/utils/converter.utils'
  49. import { FormaterCurrency } from 'src/common/utils/currency'
  50. import { Notify } from 'quasar'
  51. import { toNumber } from 'lodash'
  52. import { useParameterStore } from 'src/stores/parameter.store'
  53.  
  54. interface Props {
  55.   modelValue: ApplicantDataRequest
  56. }
  57.  
  58. interface Emits {
  59.   (event: 'update:model-value', value: Props['modelValue']): void
  60. }
  61.  
  62. const props = withDefaults(defineProps<Props>(), {})
  63.  
  64. const emit = defineEmits<Emits>()
  65.  
  66. const form = computed({
  67.   get: () => props.modelValue,
  68.   set: (value) => emit('update:model-value', value),
  69. })
  70. const parameterService = useParameterEndpoint()
  71.  
  72. const options = ref<readonly unknown[] | undefined>([])
  73. const errorMessage = ref<string | undefined>()
  74. const loadParameter = async (callback: (result: unknown) => void = () => null) => {
  75.   if (hasLoadData.value) return
  76.   try {
  77.     loading.value = true
  78.     errorMessage.value = undefined
  79.     const data = (
  80.       await parameterService.getParam({
  81.         paramName: form.value.vehicle_type == 'MOBIL' ? 'LOAN_TENOR' : 'LOAN_TENOR_MOTOR',
  82.       })
  83.     ).data
  84.     const results = data.map((item) => {
  85.       return {
  86.         name: item.value,
  87.         id: item.value,
  88.       }
  89.     })
  90.     const sortResult = results.sort((a, b) => Number(a.name) - Number(b.name))
  91.     hasLoadData.value = true
  92.     options.value = sortResult
  93.  
  94.     if (typeof callback === 'function') {
  95.       callback(results)
  96.     }
  97.   } catch (error) {
  98.     errorMessage.value = GetErrorMessage(error as Error)
  99.   } finally {
  100.     loading.value = false
  101.   }
  102. }
  103. function reload() {
  104.   hasLoadData.value = false
  105.   loadParameter()
  106. }
  107.  
  108. const kSelectRef = ref<InstanceType<typeof KSelect>>()
  109.  
  110. function showPopup() {
  111.   kSelectRef.value?.showPopup()
  112. }
  113.  
  114. function onLoadShowOption() {
  115.   loadParameter(() => setTimeout(() => showPopup(), 100))
  116. }
  117.  
  118. const hasLoadData = ref(false)
  119. const loading = ref(false)
  120. defineExpose({
  121.   reload,
  122. })
  123.  
  124. watch(
  125.   () => props.modelValue,
  126.   (value) => {
  127.     if (value) loadParameter()
  128.   },
  129.   {
  130.     immediate: true,
  131.   }
  132. )
  133.  
  134. watch(
  135.   () => props.modelValue,
  136.   (val) => {
  137.     if (val.credit_amount) {
  138.       const parseAmount = parseCurrency(form.value.credit_amount)
  139.  
  140.       form.value.credit_amount = FormaterCurrency.format(Number(parseAmount))
  141.     }
  142.   },
  143.   { immediate: true }
  144. )
  145.  
  146. const parameterEndpoint = useParameterEndpoint()
  147. const LOAN_MIN_AMOUN = ref<number | null>(null)
  148. const LOAN_MAX_AMOUN = ref<number | null>(null)
  149.  
  150. const parameterStore = useParameterStore()
  151.  
  152. function validateMinAmount(value: string | number): string | true {
  153.   const numericValue = typeof value === 'string' ? toNumber(parseCurrency(value)) : value
  154.   const MIN_AMOUNT = LOAN_MIN_AMOUN.value
  155.  
  156.   if (numericValue <= 0) {
  157.     parameterStore.setIsCreditValid(false)
  158.     return 'Nilai tidak boleh kosong atau kurang dari 0.'
  159.   }
  160.  
  161.   if (numericValue < MIN_AMOUNT!) {
  162.     parameterStore.setIsCreditValid(false)
  163.     return `Nilai minimal adalah ${FormaterCurrency.format(MIN_AMOUNT!)}.`
  164.   }
  165.  
  166.   parameterStore.setIsCreditValid(true)
  167.   return true
  168. }
  169.  
  170. const getLoanMinAmount = async () => {
  171.   try {
  172.     const response = await parameterEndpoint.getParam({ paramName: 'LOAN_MIN_AMOUNT' })
  173.     LOAN_MIN_AMOUN.value = toNumber(response.data[0].value)
  174.   } catch (error) {
  175.     Notify.create({
  176.       message: GetErrorMessage(error as Error),
  177.       type: 'negative',
  178.     })
  179.   }
  180. }
  181.  
  182. const getLoanMaxAmount = async () => {
  183.   try {
  184.     const response = await parameterEndpoint.getParam({
  185.       paramName: form.value.vehicle_type == 'MOTOR' ? 'LOW_MC_MAX_AMOUNT' : 'LOW_CAR_MAX_AMOUNT',
  186.     })
  187.     LOAN_MAX_AMOUN.value = toNumber(response.data[0].value)
  188.   } catch (error) {
  189.     Notify.create({
  190.       message: GetErrorMessage(error as Error),
  191.       type: 'negative',
  192.     })
  193.   }
  194. }
  195.  
  196. onMounted(() => {
  197.   getLoanMinAmount()
  198.   getLoanMaxAmount()
  199.   if (form.value.credit_amount) {
  200.     const numericValue =
  201.       typeof form.value.credit_amount === 'string'
  202.         ? toNumber(parseCurrency(form.value.credit_amount))
  203.         : form.value.credit_amount
  204.  
  205.     if (numericValue <= 0) {
  206.       parameterStore.setIsCreditValid(false)
  207.     }
  208.  
  209.     if (numericValue < LOAN_MIN_AMOUN.value!) {
  210.       parameterStore.setIsCreditValid(false)
  211.     }
  212.  
  213.     parameterStore.setIsCreditValid(true)
  214.   }
  215. })
  216. </script>
  217.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement