jws-frontend/src/pages/11_credit-note/expansion/PaymentExpansion.vue
Methapon Metanipat 5e2100eb8d
feat: credit note (#171)
* feat: add main page credit note

* feat: enable credit note route and update menu item states

* refactor: add i18n

* refactor: edit i18n status

* feat: add action column

* feat: add empty form page

* feat: add get data

* feat: add type credit note status

* refactor: add type name en

* refactor: add type credit note status in type credit note

* feat: add hsla colors

* refactor: add slot grid

* refactor: handle  hide kebab edit show only tab tssued

* feat: show grid card

* feat: i18n

* feat: add credit note form and dialog

* refactor: add props hide kebab deelete

* refactor: hide kebab

* style: update color segments to indigo theme

* feat: i18n

* fix: update labels for credit note fields

* refactor: add type

* feat: new select quotation

* refactor: use new select quotation

* feat: navigate to

* refactor: function trigger and navigate to

* feat: i18n bank

* feat: add payment expansion component and integrate into credit note form

* refactor: bind i18n pay condition

* refactor: navigate to get quotation id

* feat: i18n

* fix: update label for createdBy field in credit note form

* feat: add credit note information expansion component

* feat: add Credit Note expansion component and update form layout

* refactor: bind quotation id and send

* refactor: deelete duplicate type

* refactor: show state button

* refactor: handle show status

* feat: add function update payback status

* feat: add return and canceled reasons to credit note translations

* feat: enhance SelectReadyRequestWork component with credit note handling and fetch parameters

* feat: type

* feat: add status handling and optional display for employee table

* refactor: rename selectedQuotationId to quotationId in FormCredit component

* feat: set default opened state for CreditNoteExpansion and add reason options

* feat: update PaymentExpansion to handle payback type selection and clear fields for cash payments

* feat: enhance ProductExpansion to support credit note handling and adjust price calculations

* feat: implement product handling and price calculation in CreditNote form

* feat: add manage attachment function to store

* refactor: bind delete credit note

* feat: add credit note status and reference fields to types

* refactor: update task step handling and simplify request work structure in credit note form

* feat: add navigation to quotation from credit note form

* feat: enhance upload section layout based on file data

* feat: add readonly functionality to credit note form and related components

* refactor: remove console log

* feat: update i18n

* style: add rounded corners to complete view container in quotation form

* feat: add RefundInformation component and update credit note form status handling

* feat: i18n

* feat: update payback status endpoint and add paybackStatus to CreditNote type

* feat: enhance QuotationFormReceipt component with optional props and slot support

* feat: integrate payback status handling in RefundInformation and FormPage components

* feat: add external file group

* feat: update API endpoint paths for credit note operations

* feat: improve layout and styling in UploadFile components

* feat: implement file upload and management in Credit Note

* refactor: update upload to check if it is redirect or not

* feat: upload file slips

* feat: add payback date dispaly

* refactor: change module no

* fix: icon link to main page instead

* feat: add file dialog with image download functionality

* fix: view slip

* feat: add download button to image viewer

* feat: handle after submit

* feat: conditionally render bank transfer information

* feat: handle upload file on create

* feat: handle change payback status

* feat: payback type in credit note form

* fix: correct reference to quotation data in goToQuotation function

---------

Co-authored-by: Methapon2001 <61303214+Methapon2001@users.noreply.github.com>
Co-authored-by: puriphatt <puriphat@frappet.com>
Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
2025-01-14 09:08:31 +07:00

235 lines
6.6 KiB
Vue

<script lang="ts" setup>
import AppBox from 'src/components/app/AppBox.vue';
import useOptionStore from 'src/stores/options';
import SelectInput from 'src/components/shared/SelectInput.vue';
import { Icon } from '@iconify/vue/dist/iconify.js';
import { formatNumberDecimal } from 'src/stores/utils';
import { watch } from 'vue';
withDefaults(
defineProps<{
readonly?: boolean;
totalPrice?: number;
}>(),
{
totalPrice: 0,
},
);
const optionStore = useOptionStore();
const paybackType = defineModel<'BankTransfer' | 'Cash'>('paybackType');
const paybackBank = defineModel<string>('paybackBank');
const paybackAccount = defineModel<string>('paybackAccount');
const paybackAccountName = defineModel<string>('paybackAccountName');
watch(
() => paybackType.value,
() => {
if (paybackType.value === 'Cash') {
paybackBank.value = paybackAccount.value = paybackAccountName.value = '';
}
},
);
</script>
<template>
<q-expansion-item
dense
class="overflow-hidden bordered full-width"
switch-toggle-side
style="border-radius: var(--radius-2)"
expand-icon="mdi-chevron-down-circle"
header-class="surface-1 q-py-sm text-medium text-body1"
>
<template #header>
<span>
{{ $t('general.payment') }}
</span>
</template>
<main class="q-px-md q-py-sm surface-1">
<AppBox
no-padding
bordered
class="credit-note-color"
:class="{
row: $q.screen.gt.sm,
column: $q.screen.lt.md,
}"
>
<section class="col bordered-r">
<header
class="bordered-b q-px-md q-py-sm row bg-color-light items-center"
>
<div class="icon-wrapper bg-color q-mr-sm">
<q-icon name="mdi-bank-outline" />
</div>
<span class="text-weight-bold">
{{ $t('quotation.paymentCondition') }}
</span>
</header>
<div class="q-pa-sm">
<div class="row q-col-gutter-sm">
<SelectInput
for="select-credit-note-pay-type"
:label="$t('quotation.payType')"
dense
outlined
:readonly
class="col-md-4 col-12"
v-model="paybackType"
:option="[
{
label: $t('creditNote.label.Cash'),
value: 'Cash',
},
{
label: $t('creditNote.label.BankTransfer'),
value: 'BankTransfer',
},
]"
/>
<SelectInput
:disable="paybackType === 'Cash'"
for="select-credit-note-bank"
dense
outlined
fill-input
:hide-selected="false"
:readonly
class="col-md-8 col-12"
:label="$t('branch.form.bank')"
:option="optionStore.globalOption?.bankBook"
v-model="paybackBank"
clearable
>
<template #option="{ scope }">
<q-item
v-if="scope.opt"
v-bind="scope.itemProps"
class="row items-center"
>
<q-item-section avatar>
<q-img
:src="`/img/bank/${scope.opt.value}.png`"
class="bordered"
style="border-radius: 50%"
/>
</q-item-section>
<q-item-section>
{{ scope.opt.label }}
</q-item-section>
</q-item>
</template>
<template #selected-item="{ scope }">
<q-item-section v-if="scope.opt" avatar class="q-py-sm">
<q-img
:src="`/img/bank/${scope.opt.value}.png`"
class="bordered"
style="border-radius: 50%; width: 30px"
/>
</q-item-section>
</template>
</SelectInput>
<q-input
:disable="paybackType === 'Cash'"
for="input-credit-account-number"
v-model="paybackAccount"
dense
outlined
:readonly
class="col-md-4 col-12"
:label="$t('creditNote.label.accountNumber')"
/>
<q-input
:disable="paybackType === 'Cash'"
for="input-credit-account-name"
v-model="paybackAccountName"
dense
outlined
:readonly
class="col-md-8 col-12"
:label="$t('creditNote.label.accountName')"
/>
</div>
</div>
</section>
<section class="col column">
<header
class="bordered-b q-px-md q-py-sm row bg-color-light items-center"
>
<div class="icon-wrapper bg-color q-mr-sm">
<Icon icon="iconoir:coins" />
</div>
<span class="text-weight-bold">
{{ $t('quotation.summary') }}
</span>
</header>
<div class="q-pa-sm price-container col">
<div class="row">
{{ $t('general.total') }}
<span class="q-ml-auto">
{{ formatNumberDecimal(totalPrice) }}
฿
</span>
</div>
</div>
<div class="q-pa-sm row surface-2 items-center text-weight-bold">
{{ $t('quotation.totalPriceBaht') }}
<span class="q-ml-auto" style="color: var(--brand-1)">
{{ formatNumberDecimal(totalPrice) }}
฿
</span>
</div>
</section>
</AppBox>
</main>
</q-expansion-item>
</template>
<style scoped>
.icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
aspect-ratio: 1/1;
font-size: 1.5rem;
padding: var(--size-1);
border-radius: var(--radius-2);
}
:deep(.price-tag .q-field__control) {
display: flex;
align-items: center;
width: 90px;
height: 25px;
}
.credit-note-color {
--_color: var(--indigo-10-hsl);
}
.bg-color {
color: white;
background: hsla(var(--_color));
}
.dark .bg-color {
--_color: var(--orange-6-hsl);
}
.bg-color-light {
background: hsla(var(--_color) / 0.1);
}
.dark .bg-color-light {
--_color: var(--orange-6-hsl / 0.2);
}
.price-container > * {
padding: var(--size-1);
}
</style>