jws-frontend/src/components/04_product-service/PriceDataComponent.vue
Methapon Metanipat d74a5e6ca5
fix: move package create button to top right (#43)
* fix: move package create button to top right

* fix: move product and product group save button

* fix: make button stick to top right

* fix: product => price input debounce

* fix: product => installmentNo default

---------

Co-authored-by: puriphatt <puriphat@frappet.com>
2024-11-01 14:30:33 +07:00

196 lines
5.3 KiB
Vue

<script setup lang="ts">
import { ref, watch } from 'vue';
import { commaInput } from 'stores/utils';
const serviceCharge = defineModel<number>('serviceCharge');
const agentPrice = defineModel<number>('agentPrice');
const price = defineModel<number>('price');
const vatIncluded = defineModel<boolean>('vatIncluded');
const calcVat = defineModel<boolean>('calcVat');
const price4Show = ref('');
const agentPrice4Show = ref('');
const serviceCharge4Show = ref('');
watch(calcVat, () => {
if (calcVat.value === false) vatIncluded.value = false;
});
withDefaults(
defineProps<{
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
isType?: boolean;
priceDisplay?: {
price: boolean;
agentPrice: boolean;
serviceCharge: boolean;
};
}>(),
{
priceDisplay: () => ({
price: true,
agentPrice: true,
serviceCharge: true,
}),
},
);
</script>
<template>
<div class="row col-12">
<div class="col-12 q-pb-sm row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-cash"
style="background-color: var(--surface-3)"
/>
<span class="text-body1 text-weight-bold">
{{ $t('productService.product.priceInformation') }}
</span>
<section class="q-px-md">
<input
id="input-calc-vat"
type="checkbox"
v-model="calcVat"
:disabled="readonly"
/>
<label
class="q-pl-sm"
for="input-calc-vat"
:style="{ opacity: readonly ? '.5' : undefined }"
>
{{ $t('general.calculateVat') }}
</label>
</section>
<div
class="surface-3 q-px-sm q-py-xs row text-caption app-text-muted"
style="border-radius: var(--radius-3)"
v-if="calcVat"
>
<span
id="btn-include-vat"
for="btn-include-vat"
class="q-px-sm q-mr-lg rounded cursor-pointer"
:class="{
dark: $q.dark.isActive,
'active-addr': vatIncluded,
'cursor-not-allowed': readonly,
}"
@click="readonly ? '' : (vatIncluded = true)"
>
{{ $t('productService.product.vatIncluded') }}
</span>
<span
id="btn-no-include-vat"
for="btn-no-include-vat"
class="q-px-sm rounded cursor-pointer"
:class="{
dark: $q.dark.isActive,
'active-addr': !vatIncluded,
'cursor-not-allowed': readonly,
}"
@click="readonly ? '' : (vatIncluded = false)"
>
{{ $t('productService.product.vatExcluded') }}
</span>
</div>
</div>
<div class="col-12 row q-col-gutter-sm">
<q-input
id="input-price"
for="input-price"
v-if="priceDisplay?.price"
:dense="dense"
outlined
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
debounce="500"
class="col-4"
:label="$t('productService.product.salePrice')"
:model-value="commaInput(price?.toString() || '0')"
@update:model-value="
(v) => {
if (typeof v === 'string') price4Show = commaInput(v);
const x = parseFloat(
price4Show && typeof price4Show === 'string'
? price4Show.replace(/,/g, '')
: '',
);
price = x;
}
"
/>
<q-input
id="input-agent-price"
for="input-agent-price"
v-if="priceDisplay?.agentPrice"
:dense="dense"
outlined
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
debounce="500"
class="col-4"
:label="$t('productService.product.agentPrice')"
:model-value="commaInput(agentPrice?.toString() || '0')"
@update:model-value="
(v) => {
if (typeof v === 'string') agentPrice4Show = commaInput(v);
const x = parseFloat(
agentPrice4Show && typeof agentPrice4Show === 'string'
? agentPrice4Show.replace(/,/g, '')
: '',
);
agentPrice = x;
}
"
/>
<q-input
id="input-service-charge"
for="input-service-charge"
v-if="priceDisplay?.serviceCharge"
:dense="dense"
outlined
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
debounce="500"
class="col-4"
:label="$t('productService.product.processingPrice')"
:model-value="commaInput(serviceCharge?.toString() || '0')"
@update:model-value="
(v) => {
if (typeof v === 'string') serviceCharge4Show = commaInput(v);
const x = parseFloat(
serviceCharge4Show && typeof serviceCharge4Show === 'string'
? serviceCharge4Show.replace(/,/g, '')
: '',
);
serviceCharge = x;
}
"
/>
</div>
</div>
</template>
<style scoped>
.active-addr {
color: hsl(var(--info-bg));
background-color: hsla(var(--info-bg) / 0.1);
border-radius: var(--radius-3);
&.dark {
background-color: var(--surface-1);
}
}
</style>