281 lines
7.6 KiB
Vue
281 lines
7.6 KiB
Vue
|
|
<script setup lang="ts">
|
||
|
|
import useOptionStore from 'src/stores/options';
|
||
|
|
import { formatNumberDecimal } from 'src/stores/utils';
|
||
|
|
import UploadFileSection from 'src/components/upload-file/UploadFileSection.vue';
|
||
|
|
import { computed, ref } from 'vue';
|
||
|
|
import { CreditNotePaybackStatus } from 'src/stores/credit-note/types';
|
||
|
|
|
||
|
|
const props = withDefaults(
|
||
|
|
defineProps<{
|
||
|
|
paybackType: 'Cash' | 'BankTransfer';
|
||
|
|
paybackBank: string;
|
||
|
|
paybackAccount: string;
|
||
|
|
paybackAccountName: string;
|
||
|
|
paybackStatus: CreditNotePaybackStatus;
|
||
|
|
readonly?: boolean;
|
||
|
|
|
||
|
|
total?: number;
|
||
|
|
paid?: number;
|
||
|
|
remain?: number;
|
||
|
|
transformUrl?: (url: string) => string | Promise<string>;
|
||
|
|
}>(),
|
||
|
|
{
|
||
|
|
paybackStatus: CreditNotePaybackStatus.Pending,
|
||
|
|
paybackType: 'Cash',
|
||
|
|
total: 0,
|
||
|
|
paid: 0,
|
||
|
|
remain: 0,
|
||
|
|
},
|
||
|
|
);
|
||
|
|
|
||
|
|
defineEmits<{
|
||
|
|
(e: 'changeStatus', status: CreditNotePaybackStatus): void;
|
||
|
|
(e: 'upload', file: FileList): void;
|
||
|
|
(e: 'remove', name: string): void;
|
||
|
|
}>();
|
||
|
|
|
||
|
|
const fileData = defineModel<
|
||
|
|
{
|
||
|
|
name: string;
|
||
|
|
progress: number;
|
||
|
|
loaded: number;
|
||
|
|
total: number;
|
||
|
|
url?: string;
|
||
|
|
}[]
|
||
|
|
>('fileData', { default: [] });
|
||
|
|
|
||
|
|
const currStatus = computed(() =>
|
||
|
|
refundOpts.value.find((v) => v.value === props.paybackStatus),
|
||
|
|
);
|
||
|
|
|
||
|
|
const refundOpts = ref<
|
||
|
|
{
|
||
|
|
icon: string;
|
||
|
|
value: CreditNotePaybackStatus;
|
||
|
|
color: string;
|
||
|
|
}[]
|
||
|
|
>([
|
||
|
|
{
|
||
|
|
value: CreditNotePaybackStatus.Pending,
|
||
|
|
icon: 'mdi-hand-coin-outline',
|
||
|
|
color: 'warning',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
value: CreditNotePaybackStatus.Verify,
|
||
|
|
icon: 'mdi-credit-card-clock-outline',
|
||
|
|
color: 'danger',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
value: CreditNotePaybackStatus.Done,
|
||
|
|
icon: 'mdi-check-decagram-outline',
|
||
|
|
color: 'positive',
|
||
|
|
},
|
||
|
|
]);
|
||
|
|
</script>
|
||
|
|
<template>
|
||
|
|
<div class="surface-1 rounded q-px-md q-py-sm">
|
||
|
|
<span
|
||
|
|
class="row items-center justify-between full-width text-medium text-body1"
|
||
|
|
style="min-height: 31.01px"
|
||
|
|
>
|
||
|
|
{{ $t('general.information', { msg: $t('creditNote.label.refund') }) }}
|
||
|
|
</span>
|
||
|
|
|
||
|
|
<section :class="{ row: $q.screen.gt.sm }">
|
||
|
|
<article
|
||
|
|
class="col column q-pr-md"
|
||
|
|
:class="{
|
||
|
|
'bordered-r': $q.screen.gt.sm,
|
||
|
|
'bordered-b q-pb-sm': $q.screen.lt.md,
|
||
|
|
}"
|
||
|
|
>
|
||
|
|
<div class="row">
|
||
|
|
<span class="app-text-muted q-mr-auto">
|
||
|
|
{{ $t('creditNote.label.refundMethod') }}
|
||
|
|
</span>
|
||
|
|
<q-badge>
|
||
|
|
{{ $t(`creditNote.label.${paybackType}`) }}
|
||
|
|
</q-badge>
|
||
|
|
</div>
|
||
|
|
<div class="row" v-if="paybackType === 'BankTransfer'">
|
||
|
|
<span class="app-text-muted q-mr-auto">
|
||
|
|
{{ $t('branch.form.bank') }}
|
||
|
|
</span>
|
||
|
|
<span>
|
||
|
|
<q-img
|
||
|
|
:src="`/img/bank/${paybackBank}.png`"
|
||
|
|
class="bordered q-mr-xs"
|
||
|
|
style="border-radius: 50%; width: 20px"
|
||
|
|
/>
|
||
|
|
{{ useOptionStore().mapOption(paybackBank) }}
|
||
|
|
{{ paybackAccount }}
|
||
|
|
{{ `${$t('creditNote.label.accountName')} ${paybackAccountName}` }}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</article>
|
||
|
|
|
||
|
|
<article
|
||
|
|
class="col row"
|
||
|
|
:class="{ 'q-pl-md': $q.screen.gt.sm, 'q-pt-sm': $q.screen.lt.md }"
|
||
|
|
>
|
||
|
|
<span class="col-12 app-text-muted">
|
||
|
|
{{ $t('creditNote.label.totalRefund') }}
|
||
|
|
</span>
|
||
|
|
<article
|
||
|
|
class="row col-12 items-center surface-1 q-py-sm rounded gradient-stat"
|
||
|
|
>
|
||
|
|
<span
|
||
|
|
class="row col rounded q-px-sm q-py-md info"
|
||
|
|
style="border: 1px solid hsl(var(--info-bg))"
|
||
|
|
>
|
||
|
|
{{ $t('creditNote.label.totalAmount') }}
|
||
|
|
<span class="q-ml-auto">
|
||
|
|
{{ formatNumberDecimal(total) }}
|
||
|
|
</span>
|
||
|
|
</span>
|
||
|
|
<span
|
||
|
|
class="row col rounded q-px-sm q-mx-md q-py-md positive"
|
||
|
|
style="border: 1px solid hsl(var(--positive-bg))"
|
||
|
|
>
|
||
|
|
{{ $t('creditNote.label.paid') }}
|
||
|
|
<span class="q-ml-auto">
|
||
|
|
{{ formatNumberDecimal(paid) }}
|
||
|
|
</span>
|
||
|
|
</span>
|
||
|
|
<span
|
||
|
|
class="row col rounded q-px-sm q-py-md warning"
|
||
|
|
style="border: 1px solid hsl(var(--warning-bg))"
|
||
|
|
>
|
||
|
|
{{ $t('creditNote.label.remain') }}
|
||
|
|
<span class="q-ml-auto">
|
||
|
|
{{ formatNumberDecimal(remain) }}
|
||
|
|
</span>
|
||
|
|
</span>
|
||
|
|
</article>
|
||
|
|
</article>
|
||
|
|
</section>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="surface-1 rounded">
|
||
|
|
<span
|
||
|
|
class="bordered-b q-px-md q-py-sm row items-center justify-between full-width text-medium text-body1"
|
||
|
|
style="min-height: 31.01px"
|
||
|
|
>
|
||
|
|
{{ $t('creditNote.label.refund') }}
|
||
|
|
<q-btn-dropdown
|
||
|
|
dense
|
||
|
|
unelevated
|
||
|
|
:label="$t(`creditNote.status.payback.${paybackStatus}`)"
|
||
|
|
class="text-capitalize text-weight-regular product-status rounded"
|
||
|
|
:class="{
|
||
|
|
warning: paybackStatus === CreditNotePaybackStatus.Pending,
|
||
|
|
danger: paybackStatus === CreditNotePaybackStatus.Verify,
|
||
|
|
'positive hide-dropdown q-pr-md':
|
||
|
|
paybackStatus === CreditNotePaybackStatus.Done,
|
||
|
|
}"
|
||
|
|
:menu-offset="[0, 8]"
|
||
|
|
dropdown-icon="mdi-chevron-down"
|
||
|
|
content-class="bordered rounded"
|
||
|
|
@click.stop
|
||
|
|
:icon="currStatus?.icon"
|
||
|
|
>
|
||
|
|
<q-list v-if="paybackStatus !== CreditNotePaybackStatus.Done" dense>
|
||
|
|
<q-item
|
||
|
|
v-for="(v, index) in paybackStatus ===
|
||
|
|
CreditNotePaybackStatus.Verify
|
||
|
|
? refundOpts.filter(
|
||
|
|
(v) => v.value === CreditNotePaybackStatus.Done,
|
||
|
|
)
|
||
|
|
: refundOpts.filter(
|
||
|
|
(v) => v.value !== CreditNotePaybackStatus.Pending,
|
||
|
|
)"
|
||
|
|
clickable
|
||
|
|
v-close-popup
|
||
|
|
class="items-center"
|
||
|
|
:key="index"
|
||
|
|
@click="$emit('changeStatus', v.value)"
|
||
|
|
>
|
||
|
|
<q-icon
|
||
|
|
:style="`color: hsl(var(--${v.color}-bg))`"
|
||
|
|
:name="v.icon"
|
||
|
|
class="q-pr-sm"
|
||
|
|
size="xs"
|
||
|
|
></q-icon>
|
||
|
|
{{ $t(`creditNote.status.payback.${v.value}`) }}
|
||
|
|
</q-item>
|
||
|
|
</q-list>
|
||
|
|
</q-btn-dropdown>
|
||
|
|
</span>
|
||
|
|
<section class="q-px-md q-py-sm">
|
||
|
|
<UploadFileSection
|
||
|
|
multiple
|
||
|
|
:layout="$q.screen.gt.sm ? 'column' : 'row'"
|
||
|
|
:readonly
|
||
|
|
:label="`${$t('general.upload', { msg: ' E-slip' })} ${$t(
|
||
|
|
'general.or',
|
||
|
|
{
|
||
|
|
msg: $t('general.upload', {
|
||
|
|
msg: $t('creditNote.label.refundDocs'),
|
||
|
|
}),
|
||
|
|
},
|
||
|
|
)}`"
|
||
|
|
:transform-url="transformUrl"
|
||
|
|
v-model:file-data="fileData"
|
||
|
|
@update:file="(f) => $emit('upload', f as unknown as FileList)"
|
||
|
|
@close="(v) => $emit('remove', v)"
|
||
|
|
/>
|
||
|
|
</section>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<style scoped>
|
||
|
|
.gradient-stat {
|
||
|
|
& .info {
|
||
|
|
background-image: linear-gradient(
|
||
|
|
to right,
|
||
|
|
hsl(var(--info-bg) / 0.15),
|
||
|
|
var(--surface-1)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
& .positive {
|
||
|
|
background-image: linear-gradient(
|
||
|
|
to right,
|
||
|
|
hsl(var(--positive-bg) / 0.15),
|
||
|
|
var(--surface-1)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
& .warning {
|
||
|
|
background-image: linear-gradient(
|
||
|
|
to right,
|
||
|
|
hsl(var(--warning-bg) / 0.15),
|
||
|
|
var(--surface-1)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.product-status {
|
||
|
|
padding-left: 8px;
|
||
|
|
border-radius: 20px;
|
||
|
|
color: hsl(var(--_color));
|
||
|
|
background: hsla(var(--_color) / 0.15);
|
||
|
|
|
||
|
|
&.warning {
|
||
|
|
--_color: var(--warning-bg);
|
||
|
|
}
|
||
|
|
&.danger {
|
||
|
|
--_color: var(--danger-bg);
|
||
|
|
}
|
||
|
|
&.positive {
|
||
|
|
--_color: var(--positive-bg);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
:deep(
|
||
|
|
.hide-dropdown
|
||
|
|
i.q-icon.mdi.mdi-chevron-down.q-btn-dropdown__arrow.q-btn-dropdown__arrow-container
|
||
|
|
) {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
</style>
|