799 lines
29 KiB
Vue
799 lines
29 KiB
Vue
<template>
|
|
<div
|
|
v-if="productData"
|
|
class="grid px-3"
|
|
>
|
|
<div class="cell is-col-span-12">
|
|
<div id="schedule-content">
|
|
<div
|
|
v-if="selectedPolicy"
|
|
id="print-area"
|
|
:class="{ 'is-loading': isLoading }"
|
|
>
|
|
<!-- Header -->
|
|
<div class="is-flex is-justify-content-space-between is-align-items-center">
|
|
<h3 class="title is-4 has-text-primary mb-1">
|
|
{{ selectedPolicy.name }}
|
|
</h3>
|
|
<div>
|
|
<span class="button is-white">
|
|
<span class="has-text-weight-semibold">Đơn vị: VNĐ</span>
|
|
</span>
|
|
<button
|
|
class="button is-light"
|
|
@click="$emit('print')"
|
|
id="ignore-print"
|
|
>
|
|
<span class="is-size-6">In</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<hr
|
|
class="my-4"
|
|
style="background-color: var(--bulma-background)"
|
|
/>
|
|
|
|
<!-- Summary Information -->
|
|
<div class="fixed-grid has-4-cols-mobile has-7-cols-desktop">
|
|
<div class="grid">
|
|
<div class="cell is-col-span-6-mobile is-col-span-1-desktop">
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Sản phẩm</p>
|
|
<p class="has-text-primary has-text-weight-medium">
|
|
{{ productData.trade_code || productData.code }}
|
|
<a
|
|
class="ml-4"
|
|
id="ignore"
|
|
@click="$copyToClipboard(productData.trade_code)"
|
|
>
|
|
<SvgIcon
|
|
name="copy.svg"
|
|
type="primary"
|
|
:size="18"
|
|
/>
|
|
</a>
|
|
</p>
|
|
</div>
|
|
<div class="cell is-col-span-6-mobile is-col-span-1-desktop">
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Giá niêm yết</p>
|
|
<p class="has-text-primary">
|
|
{{ $numtoString(calculatorData.originPrice) }}
|
|
</p>
|
|
</div>
|
|
|
|
<div class="cell is-col-span-6-mobile is-col-span-1-desktop">
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Tổng chiết khấu</p>
|
|
<p class="has-text-danger has-text-weight-bold">
|
|
{{ $numtoString(calculatorData.totalDiscount) }}
|
|
</p>
|
|
</div>
|
|
<div class="cell is-col-span-6-mobile is-col-span-1-desktop">
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Giá sau chiết khấu</p>
|
|
<p class="has-text-black has-text-weight-bold">
|
|
{{ $numtoString(calculatorData.salePrice) }}
|
|
</p>
|
|
</div>
|
|
<div
|
|
v-if="selectedPolicy.contract_allocation_percentage < 100"
|
|
class="cell is-col-span-6-mobile is-col-span-1-desktop"
|
|
>
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Giá trị bảo đảm</p>
|
|
<p class="has-text-primary">
|
|
{{ $numtoString(calculatorData.allocatedPrice) }}
|
|
</p>
|
|
</div>
|
|
<div
|
|
v-if="totalPaid === 0"
|
|
class="cell is-col-span-6-mobile is-col-span-1-desktop"
|
|
>
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Đặt cọc</p>
|
|
<p class="has-text-primary">
|
|
{{ $numtoString(selectedPolicy.deposit) }}
|
|
</p>
|
|
</div>
|
|
<div class="cell is-col-span-6-mobile is-col-span-1-desktop">
|
|
<p class="is-size-6 has-text-weight-bold mb-1">Khách hàng</p>
|
|
<p
|
|
v-if="selectedCustomer"
|
|
class="has-text-primary has-text-weight-medium"
|
|
>
|
|
{{ selectedCustomer.code }} - {{ selectedCustomer.fullname }}
|
|
</p>
|
|
<p
|
|
v-else
|
|
class="has-text-grey is-italic is-size-6"
|
|
>
|
|
Chưa chọn
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr
|
|
class="my-4"
|
|
style="background-color: var(--bulma-background)"
|
|
/>
|
|
|
|
<!-- Detailed Discounts -->
|
|
<div
|
|
v-if="calculatorData.detailedDiscounts && calculatorData.detailedDiscounts.length > 0"
|
|
class="mt-4 mb-4"
|
|
>
|
|
<p class="has-text-weight-bold is-size-5 mb-2 has-text-primary is-underlined">CHI TIẾT CHIẾT KHẤU:</p>
|
|
<table class="table is-fullwidth is-hoverable is-size-6">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
colspan="2"
|
|
>
|
|
Diễn giải chiết khấu
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
width="15%"
|
|
>
|
|
Giá trị
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
width="20%"
|
|
>
|
|
Thành tiền
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
width="20%"
|
|
>
|
|
Còn lại
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr
|
|
style="border-bottom: 1px solid #f5f5f5"
|
|
class="has-text-grey-light"
|
|
>
|
|
<td
|
|
colspan="4"
|
|
class="has-text-right pt-1 pb-1"
|
|
>
|
|
Giá gốc
|
|
</td>
|
|
<td class="has-text-right has-text-weight-bold pt-1 pb-1">
|
|
{{ $numtoString(calculatorData.originPrice) }}
|
|
</td>
|
|
</tr>
|
|
<tr
|
|
v-for="(item, idx) in calculatorData.detailedDiscounts"
|
|
:key="`discount-${idx}`"
|
|
style="border-bottom: 1px solid #f5f5f5"
|
|
>
|
|
<td
|
|
width="5%"
|
|
class="has-text-centered"
|
|
>
|
|
{{ idx + 1 }}
|
|
</td>
|
|
<td>
|
|
<span class="has-text-weight-semibold">{{ item.name }}</span>
|
|
<span class="tag is-primary has-text-white is-rounded border ml-1">{{ item.code }}</span>
|
|
</td>
|
|
<td class="has-text-right">
|
|
{{ item.customType === 1 ? item.customValue + "%" : $numtoString(item.customValue) }}
|
|
</td>
|
|
<td class="has-text-right has-text-danger">-{{ $numtoString(item.amount) }}</td>
|
|
<td class="has-text-right has-text-primary">
|
|
{{ $numtoString(item.remaining) }}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Early Payment Details -->
|
|
<div
|
|
v-if="isEarlyPaymentActive"
|
|
class="mt-4 mb-4"
|
|
>
|
|
<!-- Original Schedule -->
|
|
<p class="has-text-weight-bold is-size-5 mb-2 has-text-primary is-underlined">
|
|
LỊCH THANH TOÁN GỐC (THEO CHÍNH SÁCH)
|
|
</p>
|
|
<div class="table-container schedule-container mb-4">
|
|
<table class="table is-fullwidth is-hoverable is-size-6">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Đợt
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Tỷ lệ
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Số tiền (VND)
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Ngày bắt đầu
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Ngày đến hạn
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Số ngày
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr
|
|
v-for="(plan, index) in calculatorData.originalPaymentSchedule"
|
|
:key="`orig-plan-${index}`"
|
|
style="border-bottom: 1px solid #f5f5f5"
|
|
>
|
|
<td class="has-text-weight-semibold">Đợt {{ plan.cycle }}</td>
|
|
<td class="has-text-right">
|
|
{{ plan.type === 1 ? `${plan.value}%` : "-" }}
|
|
</td>
|
|
<td class="has-text-right">
|
|
{{ $numtoString(plan.amount) }}
|
|
</td>
|
|
<td>{{ formatDate(plan.from_date) }}</td>
|
|
<td>{{ formatDate(plan.to_date) }}</td>
|
|
<td class="has-text-right">{{ plan.days }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Early Discount Calculation Details -->
|
|
<p class="has-text-weight-bold is-size-5 mb-2 has-text-primary is-underlined">
|
|
DIỄN GIẢI CHIẾT KHẤU THANH TOÁN SỚM
|
|
</p>
|
|
<div class="table-container schedule-container">
|
|
<table class="table is-fullwidth is-hoverable is-size-6">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Đợt
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Hạn TT Gốc
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Ngày TT Thực Tế
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Số tiền gốc
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Số ngày TT sớm
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Tỷ lệ CK (%/ngày)
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Tiền chiết khấu
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr
|
|
v-for="(item, idx) in calculatorData.earlyDiscountDetails"
|
|
:key="`early-discount-${idx}`"
|
|
style="border-bottom: 1px solid #f5f5f5"
|
|
>
|
|
<td>Đợt {{ item.cycle }}</td>
|
|
<td>{{ formatDate(item.original_payment_date) }}</td>
|
|
<td>{{ formatDate(item.actual_payment_date) }}</td>
|
|
<td class="has-text-right">
|
|
{{ $numtoString(item.original_amount) }}
|
|
</td>
|
|
<td class="has-text-right">{{ item.early_days }}</td>
|
|
<td class="has-text-right">{{ item.discount_rate }}</td>
|
|
<td class="has-text-right has-text-danger">-{{ $numtoString(item.discount_amount) }}</td>
|
|
</tr>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="has-background-light">
|
|
<th
|
|
colspan="6"
|
|
class="has-text-right has-text-weight-bold"
|
|
>
|
|
Tổng chiết khấu thanh toán sớm
|
|
</th>
|
|
<th class="has-text-right has-text-weight-bold has-text-danger">
|
|
-{{ $numtoString(totalEarlyDiscount) }}
|
|
</th>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Payment Schedule Table -->
|
|
<div
|
|
v-if="displaySchedule.length > 0"
|
|
class="mt-4"
|
|
>
|
|
<div class="level m-0 mb-2 is-mobile">
|
|
<div class="level-left">
|
|
<p class="has-text-weight-bold is-size-5 has-text-primary is-underlined">
|
|
<span v-if="isEarlyPaymentActive">LỊCH THANH TOÁN CUỐI CÙNG</span>
|
|
<span v-else>LỊCH THANH TOÁN</span>
|
|
</p>
|
|
</div>
|
|
<div
|
|
class="level-right"
|
|
id="ignore-print"
|
|
>
|
|
<div class="buttons are-small has-addons">
|
|
<button
|
|
class="button"
|
|
@click="viewMode = 'table'"
|
|
:class="viewMode === 'table' ? 'is-link is-selected' : 'is-light'"
|
|
>
|
|
<span class="is-size-6">Bảng</span>
|
|
</button>
|
|
<button
|
|
class="button"
|
|
@click="viewMode = 'list'"
|
|
:class="viewMode === 'list' ? 'is-link is-selected' : 'is-light'"
|
|
>
|
|
<span class="is-size-6">Thẻ</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table View -->
|
|
<div
|
|
v-if="viewMode === 'table'"
|
|
class="table-container schedule-container"
|
|
>
|
|
<table class="table is-fullwidth is-hoverable is-size-6">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Đợt thanh toán
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Số tiền (VND)
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Đã thanh toán
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal has-text-right"
|
|
style="border: none"
|
|
>
|
|
Còn phải TT
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Ngày bắt đầu
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Ngày đến hạn
|
|
</th>
|
|
<th
|
|
class="has-background-primary has-text-white has-font-weight-normal"
|
|
style="border: none"
|
|
>
|
|
Trạng thái
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr
|
|
v-for="(plan, index) in displaySchedule"
|
|
:key="`plan-${index}`"
|
|
style="border-bottom: 1px solid #f5f5f5"
|
|
:class="plan.is_merged ? 'has-background-warning-light' : ''"
|
|
>
|
|
<td
|
|
class="has-text-weight-semibold"
|
|
:class="plan.is_merged ? 'has-text-warning' : ''"
|
|
>
|
|
Đợt {{ plan.cycle }}
|
|
<span
|
|
v-if="plan.is_merged"
|
|
class="tag is-warning is-light ml-1 is-size-7"
|
|
>GỘP SỚM</span
|
|
>
|
|
</td>
|
|
<td class="has-text-right">
|
|
<div
|
|
v-if="plan.is_merged"
|
|
class="has-text-right"
|
|
>
|
|
<p
|
|
class="has-text-grey"
|
|
title="Tổng các đợt gốc"
|
|
>
|
|
{{ $numtoString(totalOriginalEarlyAmount) }}
|
|
</p>
|
|
<p
|
|
class="has-text-danger"
|
|
title="Chiết khấu thanh toán sớm"
|
|
>
|
|
- {{ $numtoString(totalEarlyDiscount) }}
|
|
</p>
|
|
<hr
|
|
class="my-1"
|
|
style="background: hsla(0, 0%, 0%, 0.2); margin-left: auto; width: 50%"
|
|
/>
|
|
<p class="has-text-weight-bold">
|
|
{{ $numtoString(plan.amount) }}
|
|
</p>
|
|
</div>
|
|
<span v-else>{{ $numtoString(plan.amount) }}</span>
|
|
</td>
|
|
<td class="has-text-right has-text-success">
|
|
{{ $numtoString(plan.paid_amount) }}
|
|
</td>
|
|
<td class="has-text-right has-text-danger">
|
|
{{ $numtoString(plan.remain_amount) }}
|
|
</td>
|
|
<td>{{ formatDate(plan.from_date) }}</td>
|
|
<td>{{ formatDate(plan.to_date) }}</td>
|
|
<td>
|
|
<span
|
|
v-if="plan.status === 2"
|
|
class="tag is-success"
|
|
>Đã thanh toán</span
|
|
>
|
|
<span
|
|
v-else
|
|
class="tag is-warning"
|
|
>Chờ thanh toán</span
|
|
>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="has-background-light">
|
|
<th class="has-text-right has-text-weight-bold">Tổng cộng</th>
|
|
<th class="has-text-right has-text-weight-bold">
|
|
{{ $numtoString(totalAmount) }}
|
|
</th>
|
|
<th class="has-text-right has-text-weight-bold has-text-success">
|
|
{{ $numtoString(totalPaid) }}
|
|
</th>
|
|
<th class="has-text-right has-text-weight-bold has-text-danger">
|
|
{{ $numtoString(calculatorData.totalRemaining) }}
|
|
</th>
|
|
<th colspan="3"></th>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- List View (Card) -->
|
|
<div
|
|
v-else-if="viewMode === 'list'"
|
|
class="schedule-container"
|
|
>
|
|
<div
|
|
v-for="(plan, index) in displaySchedule"
|
|
:key="`card-${index}`"
|
|
class="card mb-4"
|
|
:class="plan.is_merged ? 'has-background-warning-light' : ''"
|
|
>
|
|
<div class="card-content">
|
|
<div class="level is-mobile mb-5">
|
|
<div class="level-left">
|
|
<div class="level-item">
|
|
<span
|
|
class="tag is-primary"
|
|
:class="plan.is_merged ? 'is-warning' : ''"
|
|
>Đợt {{ plan.cycle }}</span
|
|
>
|
|
<span
|
|
v-if="plan.is_merged"
|
|
class="tag is-warning is-light ml-1 is-size-7"
|
|
>GỘP SỚM</span
|
|
>
|
|
</div>
|
|
</div>
|
|
<div class="level-right">
|
|
<div class="level-item has-text-weight-bold">
|
|
<div
|
|
v-if="plan.is_merged"
|
|
class="has-text-right"
|
|
>
|
|
<p
|
|
class="has-text-grey"
|
|
title="Tổng các đợt gốc"
|
|
>
|
|
{{ $numtoString(totalOriginalEarlyAmount) }}
|
|
</p>
|
|
<p
|
|
class="has-text-danger"
|
|
title="Chiết khấu thanh toán sớm"
|
|
>
|
|
- {{ $numtoString(totalEarlyDiscount) }}
|
|
</p>
|
|
<hr
|
|
class="my-1"
|
|
style="background: hsla(0, 0%, 0%, 0.2); margin-left: auto"
|
|
/>
|
|
<p class="has-text-weight-bold">
|
|
{{ $numtoString(plan.amount) }}
|
|
</p>
|
|
</div>
|
|
<span v-else>{{ $numtoString(plan.amount) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="level is-mobile mb-1">
|
|
<div class="level-left">Đã thanh toán:</div>
|
|
<div class="level-right has-text-success">
|
|
{{ $numtoString(plan.paid_amount) }}
|
|
</div>
|
|
</div>
|
|
<div class="level is-mobile mb-1">
|
|
<div class="level-left">Còn phải TT:</div>
|
|
<div class="level-right has-text-danger">
|
|
{{ $numtoString(plan.remain_amount) }}
|
|
</div>
|
|
</div>
|
|
<div class="level is-mobile mb-1">
|
|
<div class="level-left">Từ ngày:</div>
|
|
<div class="level-right">
|
|
{{ formatDate(plan.from_date) }}
|
|
</div>
|
|
</div>
|
|
<div class="level is-mobile mb-1">
|
|
<div class="level-left">Đến hạn:</div>
|
|
<div class="level-right">
|
|
{{ formatDate(plan.to_date) }}
|
|
</div>
|
|
</div>
|
|
<div class="level is-mobile">
|
|
<div class="level-left">Trạng thái:</div>
|
|
<div class="level-right">
|
|
<span
|
|
v-if="plan.status === 2"
|
|
class="tag is-success"
|
|
>Đã thanh toán</span
|
|
>
|
|
<span
|
|
v-else
|
|
class="tag is-warning"
|
|
>Chờ thanh toán</span
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Summary Footer -->
|
|
<div
|
|
class=""
|
|
style="border-top: 1px solid #eee"
|
|
>
|
|
<div class="level is-mobile is-size-6 my-4">
|
|
<div class="level-right">
|
|
<div class="level-item">
|
|
<span class="is-uppercase is-size-4 has-text-weight-semibold">Tổng cộng: </span>
|
|
<span class="has-text-success has-text-weight-bold is-size-4">
|
|
{{ $numtoString(calculatorData.allocatedPrice) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from "vue";
|
|
import dayjs from "dayjs";
|
|
|
|
// Props - CHỈ NHẬN DỮ LIỆU ĐÃ TÍNH TOÁN
|
|
const props = defineProps({
|
|
productData: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
selectedPolicy: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
selectedCustomer: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
calculatorData: {
|
|
type: Object,
|
|
required: true,
|
|
// Cấu trúc:
|
|
// {
|
|
// originPrice: number,
|
|
// totalDiscount: number,
|
|
// salePrice: number,
|
|
// allocatedPrice: number,
|
|
// originalPaymentSchedule: array,
|
|
// finalPaymentSchedule: array,
|
|
// earlyDiscountDetails: array,
|
|
// totalRemaining: number,
|
|
// detailedDiscounts: array,
|
|
// baseDate: Date
|
|
// }
|
|
},
|
|
isLoading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
});
|
|
|
|
// Emits
|
|
const emit = defineEmits(["print"]);
|
|
|
|
// Local state
|
|
const viewMode = ref("table");
|
|
|
|
// Computed - CHỈ HIỂN THỊ, KHÔNG TÍNH TOÁN
|
|
const displaySchedule = computed(() => {
|
|
return props.calculatorData?.finalPaymentSchedule || [];
|
|
});
|
|
|
|
const isEarlyPaymentActive = computed(() => {
|
|
return props.calculatorData.earlyDiscountDetails && props.calculatorData.earlyDiscountDetails.length > 0;
|
|
});
|
|
|
|
const totalEarlyDiscount = computed(() => {
|
|
return props.calculatorData.earlyDiscountDetails?.reduce((sum, item) => sum + item.discount_amount, 0) || 0;
|
|
});
|
|
|
|
const totalOriginalEarlyAmount = computed(() => {
|
|
return props.calculatorData.earlyDiscountDetails?.reduce((sum, item) => sum + item.original_amount, 0) || 0;
|
|
});
|
|
|
|
const totalAmount = computed(() => {
|
|
return displaySchedule.value.reduce((sum, plan) => sum + plan.amount, 0);
|
|
});
|
|
|
|
const totalPaid = computed(() => {
|
|
return displaySchedule.value.reduce((sum, plan) => sum + plan.paid_amount, 0);
|
|
});
|
|
|
|
const formatDate = (date) => {
|
|
if (!date) return "-";
|
|
return dayjs(date).format("DD/MM/YYYY");
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.table-container.schedule-container thead th {
|
|
position: sticky;
|
|
top: 0;
|
|
background: white;
|
|
z-index: 2;
|
|
border-bottom: 1px solid #dbdbdb !important;
|
|
}
|
|
|
|
.table-container {
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.border {
|
|
border: 1px solid #dbdbdb;
|
|
}
|
|
|
|
li.is-active a,
|
|
li a:hover {
|
|
color: white !important;
|
|
background-color: #204853 !important;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.content {
|
|
display: block;
|
|
}
|
|
|
|
.content p {
|
|
margin: 0;
|
|
}
|
|
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.3s;
|
|
}
|
|
|
|
.fade-enter-from,
|
|
.fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
|
|
tr,
|
|
td,
|
|
th,
|
|
.card {
|
|
page-break-inside: avoid !important;
|
|
}
|
|
|
|
@media print {
|
|
.schedule-container {
|
|
max-height: none;
|
|
overflow: visible;
|
|
}
|
|
|
|
.table-container.schedule-container thead th {
|
|
position: static;
|
|
}
|
|
|
|
#ignore-print {
|
|
display: none !important;
|
|
}
|
|
|
|
tr,
|
|
td,
|
|
th {
|
|
page-break-inside: avoid !important;
|
|
}
|
|
}
|
|
</style>
|