Initial commit
This commit is contained in:
203
app/components/transaction/AllocateItem.vue
Normal file
203
app/components/transaction/AllocateItem.vue
Normal file
@@ -0,0 +1,203 @@
|
||||
<script setup>
|
||||
import AllocateForm from '@/components/transaction/AllocateForm.vue';
|
||||
|
||||
const props = defineProps({
|
||||
paymentSchedule: Object,
|
||||
i: Number,
|
||||
});
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
const {
|
||||
$insertapi,
|
||||
$snackbar,
|
||||
$remove,
|
||||
} = useNuxtApp();
|
||||
|
||||
const allocations = ref([{}]);
|
||||
const showConfirmModal = ref();
|
||||
const isSubmitting = ref(false);
|
||||
const resetKey = ref(0);
|
||||
|
||||
function addAllocation() {
|
||||
allocations.value.push({});
|
||||
}
|
||||
|
||||
async function removeAllocation(index) {
|
||||
$remove(allocations.value, index);
|
||||
if (allocations.value.length === 0) {
|
||||
allocations.value = [{}];
|
||||
}
|
||||
}
|
||||
|
||||
function setAllo({ key, value, i }) {
|
||||
allocations.value[i][key] = value;
|
||||
}
|
||||
|
||||
function openConfirmModal() {
|
||||
showConfirmModal.value = {
|
||||
component: 'dialog/Confirm',
|
||||
title: 'Xác nhận',
|
||||
width: '600px',
|
||||
height: '150px',
|
||||
vbind: { content: `Xác nhận phân bổ tay cho lịch thanh toán ${props.paymentSchedule.code}?` },
|
||||
onConfirm: update
|
||||
}
|
||||
}
|
||||
|
||||
async function update() {
|
||||
const allocationsToSend = allocations.value
|
||||
.map(({ ref, date, type, amount }) => ({ ref, date, type, amount }));
|
||||
|
||||
const payload = {
|
||||
product: props.paymentSchedule.txn_detail__transaction__product,
|
||||
schedule_id: props.paymentSchedule.id,
|
||||
allocation_list: allocationsToSend,
|
||||
};
|
||||
|
||||
isSubmitting.value = true;
|
||||
const res = await $insertapi('manualallocate', payload);
|
||||
if (res.success) {
|
||||
emit('refresh');
|
||||
allocations.value = [{}];
|
||||
resetKey.value++;
|
||||
$snackbar(res.message);
|
||||
} else {
|
||||
$snackbar(res.message || "Đã có lỗi khi phân bổ tay");
|
||||
}
|
||||
|
||||
isSubmitting.value = false;
|
||||
}
|
||||
|
||||
const totalByRef = computed(() => {
|
||||
const map = {};
|
||||
for (const allo of allocations.value) {
|
||||
if (allo.ref) {
|
||||
map[allo.ref] = (map[allo.ref] || 0) + (allo.amount || 0);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
});
|
||||
|
||||
const formValid = computed(() => {
|
||||
if (allocations.value.some(allo => {
|
||||
if (Object.keys(allo).length === 0) return true;
|
||||
if (allo.amount === undefined || allo.type === undefined) return true;
|
||||
if (allo.ref && totalByRef.value[allo.ref] > allo.allocation_remain) return true;
|
||||
})) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="fs-15 is-flex is-gap-2">
|
||||
<div class="is-flex is-flex-direction-column is-align-items-center is-gap-1">
|
||||
<p class="fsb-17 is-flex is-justify-content-center is-align-items-center" style="
|
||||
border: 3px solid rgb(52, 92, 103);
|
||||
border-radius: 9999px;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
">
|
||||
{{ i + 1 }}
|
||||
</p>
|
||||
<div style="
|
||||
border: 3px solid #dddddd;
|
||||
border-radius: 9999px;
|
||||
flex-grow: 1;
|
||||
width: min-content;
|
||||
">
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-flex-grow-1">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<p><span class="has-text-weight-semibold">{{ paymentSchedule.code }}</span> - {{ paymentSchedule.type__name }}</p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<span class="has-text-weight-semibold">Từ ngày: </span>
|
||||
<FormatDate :date="paymentSchedule.from_date" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<span class="has-text-weight-semibold">Đến ngày: </span>
|
||||
<FormatDate :date="paymentSchedule.to_date" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<span class="has-text-weight-semibold">Ngày tính lãi: </span>
|
||||
<FormatDate :date="paymentSchedule.batch_date" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<span class="has-text-weight-semibold">Quá hạn: </span>
|
||||
<span>{{ paymentSchedule.ovd_days }} ngày</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Số tiền theo HĐ (Gốc)</p>
|
||||
<FormatNumber :value="paymentSchedule.amount" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Đã thu theo HĐ</p>
|
||||
<FormatNumber :value="paymentSchedule.paid_amount" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Số tiền còn theo HĐ</p>
|
||||
<FormatNumber :value="paymentSchedule.amount_remain" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Lãi phạt</p>
|
||||
<FormatNumber :value="paymentSchedule.penalty_amount" color="red" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Lãi còn lại</p>
|
||||
<FormatNumber :value="paymentSchedule.penalty_remain" color="red" />
|
||||
</div>
|
||||
<div class="column">
|
||||
<p class="has-text-weight-semibold">Tổng tiền còn lại</p>
|
||||
<FormatNumber :value="paymentSchedule.remain_amount" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<AllocateForm
|
||||
v-for="(allo, i) in allocations"
|
||||
:key="`${resetKey}-${i}`"
|
||||
v-bind="{
|
||||
allo,
|
||||
i,
|
||||
length: allocations.length,
|
||||
productId: paymentSchedule.txn_detail__transaction__product,
|
||||
amount_remain: paymentSchedule.amount_remain,
|
||||
totalByRef,
|
||||
onSetAllo: setAllo,
|
||||
onRemoveAllocation: removeAllocation,
|
||||
}"
|
||||
/>
|
||||
<button class="button is-pulled-right is-info is-light mb-4" @click="addAllocation">
|
||||
<span class="icon">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="12"
|
||||
width="12"
|
||||
viewBox="0 0 448 512"
|
||||
>
|
||||
<path
|
||||
d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
@click="openConfirmModal"
|
||||
:class="`button is-secondary ${isSubmitting ? 'is-loading' : ''}`"
|
||||
:disabled="isSubmitting || !formValid"
|
||||
>
|
||||
<span>Phân bổ</span>
|
||||
</button>
|
||||
<Modal
|
||||
v-bind="showConfirmModal"
|
||||
v-if="showConfirmModal"
|
||||
@close="showConfirmModal = undefined"
|
||||
/>
|
||||
<!-- <pre class="fs-12">{{ JSON.stringify(allocations, null, 2) }}</pre> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user