jws-frontend/src/pages/05_quotation/MainPage.vue

1396 lines
46 KiB
Vue
Raw Normal View History

2024-06-19 15:43:58 +07:00
<script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref, watch, computed } from 'vue';
2024-09-25 18:06:05 +07:00
import { storeToRefs } from 'pinia';
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
2024-10-01 14:46:34 +07:00
2024-10-03 11:22:21 +07:00
// NOTE: Import stores
import useCustomerStore from 'stores/customer';
2024-10-01 14:46:34 +07:00
import { useQuotationStore } from 'src/stores/quotations';
2025-04-10 17:21:29 +07:00
import { dialog, isRoleInclude, notify, setPrefixName } from 'stores/utils';
import { useNavigator } from 'src/stores/navigator';
2024-10-01 14:46:34 +07:00
import useFlowStore from 'src/stores/flow';
2024-10-02 14:05:36 +07:00
import useMyBranch from 'stores/my-branch';
2024-10-03 14:43:41 +07:00
import { useQuotationForm } from './form';
import { hslaColors } from './constants';
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
import { pageTabs, columnQuotation } from './constants';
2025-07-03 15:17:37 +07:00
import { toCamelCase, canAccess } from 'stores/utils';
import { getUserId } from 'src/services/keycloak';
2024-10-01 14:46:34 +07:00
2024-10-03 11:22:21 +07:00
// NOTE Import Types
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
import { CustomerBranchCreate, CustomerType } from 'stores/customer/types';
2024-10-01 14:46:34 +07:00
2024-10-03 11:22:21 +07:00
// NOTE: Import Components
2024-10-01 14:46:34 +07:00
import QuotationCard from 'src/components/05_quotation/QuotationCard.vue';
import PaginationComponent from 'src/components/PaginationComponent.vue';
import StatCardComponent from 'src/components/StatCardComponent.vue';
2024-10-30 09:34:46 +07:00
import FloatingActionButton from 'components/FloatingActionButton.vue';
2024-10-01 14:46:34 +07:00
import FormAbout from 'src/components/05_quotation/FormAbout.vue';
import CreateButton from 'src/components/AddButton.vue';
import ItemCard from 'src/components/ItemCard.vue';
import DialogForm from 'components/DialogForm.vue';
import SideMenu from 'components/SideMenu.vue';
import NoData from 'src/components/NoData.vue';
2024-10-04 17:01:24 +07:00
import { dialogCreateCustomerItem } from 'src/pages/03_customer-management/constant';
2024-10-04 17:01:24 +07:00
import { SaveButton } from 'components/button';
2024-09-25 18:06:05 +07:00
import ProfileBanner from 'components/ProfileBanner.vue';
import { AddressForm } from 'components/form';
import {
EmployerFormBusiness,
EmployerFormAbout,
EmployerFormBasicInfo,
EmployerFormBranch,
2024-09-25 18:06:05 +07:00
} from 'src/pages/03_customer-management/components';
2024-09-27 16:11:16 +07:00
2024-10-11 11:25:47 +07:00
import { useCustomerForm } from 'src/pages/03_customer-management/form';
2024-10-18 16:14:19 +07:00
import { Quotation } from 'src/stores/quotations/types';
2024-11-07 17:53:40 +07:00
import TableQuotation from 'src/components/05_quotation/TableQuotation.vue';
2024-11-15 11:36:51 +07:00
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import { DialogContainer, DialogHeader } from 'src/components/dialog';
import AdvanceSearch from 'src/components/shared/AdvanceSearch.vue';
2024-09-25 18:06:05 +07:00
const { t, locale } = useI18n();
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
const $q = useQuasar();
2024-10-03 14:43:41 +07:00
const quotationFormStore = useQuotationForm();
2024-10-01 14:46:34 +07:00
const customerFormStore = useCustomerForm();
2024-09-30 15:03:36 +07:00
const flowStore = useFlowStore();
2024-10-02 14:05:36 +07:00
const userBranch = useMyBranch();
const navigatorStore = useNavigator();
const customerStore = useCustomerStore();
const {
fetchListOfOptionBranch,
customerFormUndo,
deleteCustomerById,
validateTabField,
deleteCustomerBranchById,
} = customerFormStore;
2024-10-01 14:46:34 +07:00
const {
currentFormData: quotationFormData,
currentFormState: quotationFormState,
} = storeToRefs(quotationFormStore);
const {
state: customerFormState,
currentFormData: customerFormData,
2025-09-11 13:36:09 +07:00
currentBranchRootId,
registerAbleBranchOption,
tabFieldRequired,
} = storeToRefs(customerFormStore);
2024-10-02 14:05:36 +07:00
const { currentMyBranch } = storeToRefs(userBranch);
2024-10-01 14:46:34 +07:00
2024-11-07 17:53:40 +07:00
const fieldSelectedOption = computed(() => {
2025-01-08 17:17:12 +07:00
return columnQuotation
.filter((v) => v.name !== 'action')
.map((v) => ({
label: v.label,
value: v.name,
}));
2024-11-07 17:53:40 +07:00
});
2025-09-11 13:36:09 +07:00
const keyAddDialog = ref<number>(0);
2024-10-04 15:12:13 +07:00
const special = ref(false);
2024-10-03 11:14:12 +07:00
const branchId = ref('');
2024-10-04 14:39:05 +07:00
const agentPrice = ref<boolean>(false);
const emptyCreateDialog = ref(false);
2024-10-01 14:46:34 +07:00
const onCreateImageList = ref<{
selectedImage: string;
list: { url: string; imgFile: File | null; name: string }[];
}>({ selectedImage: '', list: [] });
2024-10-18 16:14:19 +07:00
const currentQuotationPayment = ref<Quotation>();
2024-10-01 14:46:34 +07:00
2024-09-27 16:11:16 +07:00
const pageState = reactive({
hideStat: false,
inputSearch: '',
2024-11-07 17:53:40 +07:00
fieldSelected: [''],
gridView: false,
total: 0,
sellerId: '',
2024-09-27 16:11:16 +07:00
2024-11-07 14:23:55 +07:00
currentTab: 'Issued',
2024-09-27 16:11:16 +07:00
addModal: false,
quotationModal: false,
employeeModal: false,
2024-10-17 13:23:53 +07:00
receiptModal: false,
searchDate: [],
2024-09-18 16:04:07 +07:00
});
2024-11-07 17:53:40 +07:00
pageState.fieldSelected = [...columnQuotation.map((v) => v.name)];
2024-10-07 16:58:45 +07:00
const CUSTOMER_BRANCH_DEFAULT: CustomerBranchCreate & {
id?: string;
branchCode?: string;
codeCustomer?: string;
} = {
customerCode: '',
customerId: '',
legalPersonNo: '',
citizenId: '',
namePrefix: '',
firstName: '',
lastName: '',
firstNameEN: '',
lastNameEN: '',
telephoneNo: '',
gender: '',
2024-10-02 14:05:36 +07:00
birthDate: new Date().toString(),
businessType: '',
jobPosition: '',
jobDescription: '',
payDate: '',
payDateEN: '',
wageRate: 0,
wageRateText: '',
homeCode: '',
employmentOffice: '',
employmentOfficeEN: '',
address: '',
addressEN: '',
street: '',
streetEN: '',
moo: '',
mooEN: '',
soi: '',
soiEN: '',
provinceId: '',
districtId: '',
subDistrictId: '',
contactName: '',
email: '',
contactTel: '',
officeTel: '',
2024-10-29 09:49:23 +07:00
agentUserId: undefined,
status: 'CREATED',
customerName: '',
registerName: '',
registerNameEN: '',
registerDate: new Date(),
authorizedCapital: '',
authorizedName: '',
authorizedNameEN: '',
code: '',
2024-10-07 16:58:45 +07:00
};
const formDataCustomerBranch = ref<
CustomerBranchCreate & {
id?: string;
branchCode?: string;
codeCustomer?: string;
}
>(structuredClone(CUSTOMER_BRANCH_DEFAULT));
2024-10-16 13:10:40 +07:00
function setDefaultCustomer() {
2024-10-07 16:58:45 +07:00
formDataCustomerBranch.value = structuredClone(CUSTOMER_BRANCH_DEFAULT);
}
2024-10-04 17:01:24 +07:00
async function submitCustomer() {
2024-10-02 14:05:36 +07:00
if (currentMyBranch.value === undefined) return;
const { code, customerCode, birthDate, ...payload } =
formDataCustomerBranch.value;
customerFormData.value.customerBranch = [{ ...payload }];
2024-10-04 17:01:24 +07:00
customerFormData.value.registeredBranchId = isRoleInclude(['system'])
? branchId.value
: currentMyBranch.value.id;
await customerFormStore.addCurrentCustomerBranch();
2024-10-04 17:01:24 +07:00
customerFormState.value.dialogModal = false;
// customerFormState.value.dialogType = 'info';
}
2024-10-08 14:05:43 +07:00
async function triggerDialogDeleteQuottaion(id: string) {
quotationFormStore.dialogDelete(async () => {
2024-10-24 13:57:22 +07:00
await quotationStore.deleteQuotation(id);
2024-10-08 14:05:43 +07:00
await fetchQuotationList();
});
}
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
function triggerCreateCustomerd(opts: { type: CustomerType }) {
2024-10-16 13:10:40 +07:00
setDefaultCustomer();
customerFormState.value.dialogType = 'create';
customerFormData.value.customerType = opts?.type;
customerFormState.value.dialogModal = true;
}
function triggerSelectTypeCustomerd() {
emptyCreateDialog.value = true;
}
2024-09-27 16:11:16 +07:00
function triggerAddQuotationDialog() {
pageState.addModal = true;
2024-11-27 15:16:32 +07:00
quotationFormStore.resetForm(true);
2024-09-27 16:11:16 +07:00
// TODO: form and state controll
}
2024-10-10 13:23:30 +07:00
function triggerQuotationDialog(opts: {
statusDialog: 'info' | 'edit' | 'create';
quotationId?: string;
branchId?: string;
}) {
2024-11-07 14:55:16 +07:00
const url = new URL(
`/quotation/${opts.statusDialog === 'create' ? 'add' : 'view'}`,
window.location.origin,
);
2024-10-04 15:12:13 +07:00
2024-10-21 11:13:34 +07:00
localStorage.setItem(
'new-quotation',
JSON.stringify({
customerBranchId: quotationFormData.value.customerBranchId,
branchId: opts.branchId ?? branchId.value,
agentPrice: agentPrice.value,
special: special.value,
statusDialog: opts.statusDialog,
quotationId: opts.quotationId,
}),
);
pageState.addModal = false;
2024-10-04 15:12:13 +07:00
window.open(url.toString(), '_blank');
2024-09-27 16:11:16 +07:00
}
2024-10-18 16:14:19 +07:00
function triggerReceiptDialog(data: Quotation) {
currentQuotationPayment.value = data;
2024-10-17 13:23:53 +07:00
pageState.receiptModal = true;
}
2024-09-30 15:03:36 +07:00
const quotationStore = useQuotationStore();
const {
data: quotationData,
page: quotationPage,
pageSize: quotationPageSize,
pageMax: quotationPageMax,
2024-10-07 16:58:45 +07:00
stats: quotationStats,
2024-09-30 15:03:36 +07:00
} = storeToRefs(quotationStore);
const customerNameInfo = computed(() => {
if (customerFormData.value.customerBranch === undefined) return;
const name =
locale.value === 'eng'
? `${customerFormData.value.customerBranch[0]?.firstNameEN} ${customerFormData.value.customerBranch[0]?.lastNameEN}`
: `${customerFormData.value.customerBranch[0]?.firstName} ${customerFormData.value.customerBranch[0]?.lastName}`;
return name || '-';
});
function handleWindowFocus() {
fetchQuotationList();
}
2024-09-27 16:11:16 +07:00
onMounted(async () => {
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
pageState.gridView = $q.screen.lt.md ? true : false;
navigatorStore.current.title = 'quotation.title';
navigatorStore.current.path = [
{
text: 'quotation.caption',
i18n: true,
handler: () => {
2024-11-07 14:23:55 +07:00
pageState.currentTab = 'Issued';
},
},
];
2024-09-30 15:03:36 +07:00
{
2024-10-07 16:58:45 +07:00
const ret = await quotationStore.getQuotationStats();
if (ret) {
quotationStats.value = Object.assign(quotationStats.value, ret);
}
2024-09-30 15:03:36 +07:00
}
{
const ret = await quotationStore.getQuotationList({
page: quotationPage.value,
pageSize: quotationPageSize.value,
2024-11-07 14:23:55 +07:00
status: 'Issued',
urgentFirst: true,
sellerId: pageState.sellerId || undefined,
2024-09-30 15:03:36 +07:00
});
if (ret) {
quotationData.value = ret.result;
2024-10-03 11:23:18 +07:00
quotationPageMax.value = Math.ceil(ret.total / quotationPageSize.value);
pageState.total = ret.total;
2024-09-30 15:03:36 +07:00
}
}
flowStore.rotate();
window.addEventListener('focus', handleWindowFocus);
});
onUnmounted(() => {
window.removeEventListener('focus', handleWindowFocus);
2024-09-27 16:11:16 +07:00
});
2024-09-30 15:03:36 +07:00
async function fetchQuotationList(mobileFetch?: boolean) {
{
const ret = await quotationStore.getQuotationList({
page: mobileFetch ? 1 : quotationPage.value,
pageSize: quotationPageSize.value,
2024-11-07 14:23:55 +07:00
status:
pageState.currentTab !== 'Issued'
? (
{
2024-11-07 14:23:55 +07:00
Accepted: 'Accepted',
Expired: 'Expired',
Invoice: 'PaymentInProcess',
PaymentSuccess: 'PaymentSuccess',
ProcessComplete: 'ProcessComplete',
2024-12-26 11:55:25 +07:00
Canceled: 'Canceled',
} as const
)[pageState.currentTab]
2024-11-07 14:23:55 +07:00
: 'Issued',
2024-10-21 13:34:12 +07:00
query: pageState.inputSearch,
2024-11-07 14:23:55 +07:00
urgentFirst: true,
startDate: pageState.searchDate[0],
endDate: pageState.searchDate[1],
sellerId: pageState.sellerId || undefined,
});
2024-09-30 15:03:36 +07:00
if (ret) {
quotationData.value =
$q.screen.xs && !mobileFetch
? [...quotationData.value, ...ret.result]
: ret.result;
quotationPageMax.value = Math.ceil(ret.total / quotationPageSize.value);
2024-10-25 16:22:58 +07:00
pageState.total = ret.total;
}
}
{
const ret = await quotationStore.getQuotationStats();
if (ret) {
quotationStats.value = Object.assign(quotationStats.value, ret);
}
2024-10-01 09:48:03 +07:00
}
2024-09-30 15:03:36 +07:00
2024-10-01 09:48:03 +07:00
flowStore.rotate();
}
2024-11-15 11:36:51 +07:00
watch(
[
() => pageState.currentTab,
() => pageState.inputSearch,
() => pageState.searchDate,
quotationPageSize,
],
() => {
quotationPage.value = 1;
quotationData.value = [];
fetchQuotationList();
},
2024-11-15 11:36:51 +07:00
);
async function storeDataLocal(id: string) {
await quotationFormStore.assignFormData(id, 'assign');
localStorage.setItem(
'quotation-preview',
2024-10-18 12:32:55 +07:00
JSON.stringify({
2024-11-27 16:22:40 +07:00
data: {
...quotationFormData.value,
},
2024-10-18 12:32:55 +07:00
meta: {
2024-11-27 16:22:40 +07:00
source: {
...quotationFormState.value.source,
code:
quotationFormState.value.mode === 'create'
? '-'
: quotationFormState.value?.source?.code,
createAt:
quotationFormState.value.mode === 'create'
? Date.now()
: quotationFormState.value?.source?.createdAt,
createBy: quotationFormState.value?.source?.createdBy,
payCondition: quotationFormData.value.payCondition,
contactName: quotationFormData.value.contactName,
contactTel: quotationFormData.value.contactTel,
workName: quotationFormData.value.workName,
dueDate: quotationFormData.value.dueDate,
},
selectedWorker: quotationFormData.value.worker,
2024-10-18 12:32:55 +07:00
createdBy: quotationFormState.value.createdBy('tha'),
},
}),
);
2024-11-28 10:48:34 +07:00
const url = new URL('/quotation/document-view', window.location.origin);
url.searchParams.append('type', pageState.currentTab.toLowerCase());
window.open(url, '_blank');
}
async function filterBySellerId() {
pageState.sellerId = pageState.sellerId ? '' : getUserId();
await fetchQuotationList();
}
2024-06-19 15:43:58 +07:00
</script>
<template>
2024-10-30 09:34:46 +07:00
<FloatingActionButton
2024-10-03 11:14:12 +07:00
hide-icon
style="z-index: 999"
@click.stop="triggerAddQuotationDialog"
2025-07-09 14:19:13 +07:00
v-if="canAccess('quotation', 'create')"
2024-10-03 11:14:12 +07:00
/>
2024-09-27 16:11:16 +07:00
<div class="column full-height no-wrap">
<!-- SEC: stat -->
<section class="text-body-2 q-mb-xs flex items-center">
{{ $t('general.dataSum') }}
<q-badge
rounded
class="q-ml-sm"
style="
background-color: hsla(var(--info-bg) / 0.15);
color: hsl(var(--info-bg));
"
>
{{ Object.values(quotationStats).reduce((a, c) => a + c, 0) }}
2024-09-27 16:11:16 +07:00
</q-badge>
<q-btn
class="q-ml-sm"
icon="mdi-pin-outline"
color="primary"
size="sm"
flat
dense
rounded
@click="pageState.hideStat = !pageState.hideStat"
:style="pageState.hideStat ? 'rotate: 90deg' : ''"
style="transition: 0.1s ease-in-out"
/>
</section>
<transition name="slide">
<div v-if="!pageState.hideStat" class="scroll q-mb-md">
<div style="display: inline-block">
<StatCardComponent
labelI18n
2024-10-07 16:58:45 +07:00
:branch="[
{
icon: 'material-symbols-light:receipt-long',
2024-11-07 14:23:55 +07:00
count: quotationStats.issued,
label: 'quotation.status.Issued',
color: 'orange',
hidden: pageState.currentTab !== 'Issued',
2024-10-07 16:58:45 +07:00
},
{
icon: 'mdi-hand-coin-outline',
2024-11-07 14:23:55 +07:00
count: quotationStats.accepted,
label: 'quotation.status.Accepted',
color: 'pink',
hidden: pageState.currentTab !== 'Accepted',
},
{
icon: 'pajamas:expire',
2024-11-07 14:23:55 +07:00
count: quotationStats.expired,
label: 'quotation.status.Expired',
color: 'cyan',
hidden: pageState.currentTab !== 'Expired',
2024-10-07 16:58:45 +07:00
},
{
icon: 'material-symbols-light:receipt-long',
2024-11-07 14:23:55 +07:00
count: quotationStats.paymentInProcess,
label: 'quotation.status.Invoice',
color: 'purple',
hidden: pageState.currentTab !== 'Invoice',
},
{
icon: 'fluent:receipt-money-16-regular',
2024-11-07 14:23:55 +07:00
count: quotationStats.paymentSuccess,
label: 'quotation.status.PaymentSuccess',
color: 'light-green',
2024-11-07 14:23:55 +07:00
hidden: pageState.currentTab !== 'PaymentSuccess',
},
{
icon: 'mdi-check-decagram-outline',
2024-11-07 14:23:55 +07:00
count: quotationStats.processComplete,
label: 'quotation.status.ProcessComplete',
color: 'blue',
hidden: pageState.currentTab !== 'ProcessComplete',
2024-10-07 16:58:45 +07:00
},
2024-12-26 11:55:25 +07:00
{
icon: 'mdi-cancel',
count: quotationStats.canceled,
label: 'general.cancel',
color: 'red',
hidden: pageState.currentTab !== 'Canceled',
},
2024-10-07 16:58:45 +07:00
]"
2024-09-27 16:11:16 +07:00
:dark="$q.dark.isActive"
/>
</div>
</div>
</transition>
<!-- SEC: header content -->
<header class="col surface-1 rounded bordered overflow-hidden">
2024-09-27 16:11:16 +07:00
<div class="column full-height">
<section
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
class="row surface-3 justify-between full-width bordered-b"
2024-09-27 16:11:16 +07:00
style="z-index: 1"
>
<div class="row q-py-sm q-px-md justify-between full-width">
<q-input
for="input-search"
outlined
dense
:label="$t('general.search')"
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
class="col col-md-3"
2024-09-27 16:11:16 +07:00
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
v-model="pageState.inputSearch"
debounce="200"
>
<template #prepend>
<q-icon name="mdi-magnify" />
</template>
<template v-slot:append>
<q-separator vertical inset class="q-mr-xs" />
<AdvanceSearch v-model="pageState.searchDate">
<template #prepend>
<div class="text-weight-medium q-mb-sm">
<q-checkbox
size="xs"
:model-value="!!pageState.sellerId"
@click="filterBySellerId"
/>
{{ $t('quotation.ownOnly') }}
</div>
</template>
</AdvanceSearch>
</template>
2024-09-27 16:11:16 +07:00
</q-input>
2024-09-18 16:52:46 +07:00
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
<div class="row col-md-5 justify-end" style="white-space: nowrap">
2024-09-27 16:11:16 +07:00
<q-select
v-if="!pageState.gridView"
id="select-field"
for="select-field"
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
class="col-md-5 q-ml-sm"
2024-09-27 16:11:16 +07:00
:options="
fieldSelectedOption.map((v) => ({
...v,
label: v.label && $t(v.label),
2024-09-27 16:11:16 +07:00
}))
"
:display-value="$t('general.displayField')"
:hide-dropdown-icon="$q.screen.lt.sm"
v-model="pageState.fieldSelected"
option-label="label"
option-value="value"
map-options
emit-value
outlined
multiple
dense
/>
2024-09-18 16:52:46 +07:00
2024-09-27 16:11:16 +07:00
<q-btn-toggle
id="btn-mode"
v-model="pageState.gridView"
dense
class="no-shadow bordered rounded surface-1 q-ml-sm"
:toggle-color="$q.dark.isActive ? 'grey-9' : 'grey-2'"
size="xs"
:options="[
{ value: true, slot: 'folder' },
{ value: false, slot: 'list' },
]"
>
<template v-slot:folder>
<q-icon
name="mdi-view-grid-outline"
size="16px"
class="q-px-sm q-py-xs rounded"
:style="{
color: $q.dark.isActive
? pageState.gridView
? '#C9D3DB '
: '#787B7C'
: pageState.gridView
? '#787B7C'
: '#C9D3DB',
}"
/>
</template>
<template v-slot:list>
<q-icon
name="mdi-format-list-bulleted"
class="q-px-sm q-py-xs rounded"
size="16px"
:style="{
color: $q.dark.isActive
? pageState.gridView === false
? '#C9D3DB'
: '#787B7C'
: pageState.gridView === false
? '#787B7C'
: '#C9D3DB',
}"
/>
</template>
</q-btn-toggle>
</div>
</div>
</section>
<nav class="surface-2 bordered-b q-px-md full-width">
<q-tabs
inline-label
mobile-arrows
dense
v-model="pageState.currentTab"
align="left"
class="full-width"
active-color="info"
>
<q-tab
v-for="tab in pageTabs"
:name="tab"
:key="tab"
@click="
2024-10-03 11:22:21 +07:00
() => {
quotationPage = 1;
2024-09-27 16:11:16 +07:00
pageState.currentTab = tab;
pageState.inputSearch = '';
flowStore.rotate();
}
"
>
<div
class="row text-capitalize"
:class="
pageState.currentTab === tab ? 'text-bold' : 'app-text-muted'
"
>
2024-11-07 14:23:55 +07:00
{{ $t(`quotation.status.${tab}`) }}
2024-09-27 16:11:16 +07:00
</div>
</q-tab>
</q-tabs>
</nav>
<!-- SEC: body content -->
2024-09-30 13:25:29 +07:00
<article
2024-10-03 11:14:12 +07:00
v-if="!quotationData || quotationData.length === 0"
2024-09-27 16:11:16 +07:00
class="col surface-2 flex items-center justify-center"
>
<NoData
2025-07-03 15:17:37 +07:00
v-if="
pageState.inputSearch ||
2025-07-09 14:19:13 +07:00
!canAccess('quotation', 'create') ||
2025-07-03 15:17:37 +07:00
pageState.currentTab !== 'Issued'
"
:not-found="!!pageState.inputSearch"
/>
2024-09-27 16:11:16 +07:00
<CreateButton
2025-07-03 15:17:37 +07:00
v-if="
!pageState.inputSearch &&
pageState.currentTab === 'Issued' &&
2025-07-09 14:19:13 +07:00
canAccess('quotation', 'create')
2025-07-03 15:17:37 +07:00
"
2024-09-27 16:11:16 +07:00
@click="triggerAddQuotationDialog"
label="general.add"
:i18n-args="{ text: $t('quotation.title') }"
/>
2024-09-30 13:25:29 +07:00
</article>
2024-11-07 18:14:38 +07:00
<article v-else class="col surface-2 full-width scroll">
<div class="q-pa-md">
<q-infinite-scroll
:key="pageState.currentTab"
:offset="100"
@load="
(_, done) => {
if ($q.screen.gt.xs) return;
quotationPage = quotationPage + 1;
fetchQuotationList().then(() => {
done(quotationPage >= quotationPageMax);
});
}
"
>
<TableQuotation
:page="quotationPage"
:page-size="quotationPageSize"
:columns="columnQuotation"
:rows="quotationData"
:visible-columns="pageState.fieldSelected"
:grid="pageState.gridView"
:hide-edit="pageState.currentTab !== 'Issued'"
2025-07-09 14:19:13 +07:00
:hide-action="!canAccess('quotation', 'edit')"
:hide-delete="!canAccess('quotation', 'delete')"
:hide-btn-preview="pageState.currentTab === 'PaymentSuccess'"
@preview="(id: any) => storeDataLocal(id)"
@view="
(item) => {
triggerQuotationDialog({
statusDialog: 'info',
quotationId: item.id,
branchId: item.customerBranch.customer.registeredBranchId,
});
}
"
@edit="
(item) =>
triggerQuotationDialog({
statusDialog: 'edit',
quotationId: item.id,
branchId: item.customerBranch.customer.registeredBranchId,
})
"
@delete="(id) => triggerDialogDeleteQuottaion(id)"
>
<template #grid="{ item }">
<div class="col-md-4 col-sm-6 col-12 column">
<QuotationCard
class="col"
2025-07-09 14:19:13 +07:00
:hide-action="!canAccess('quotation', 'edit')"
:hide-kebab-delete="!canAccess('quotation', 'delete')"
:hide-kebab-edit="!(pageState.currentTab === 'Issued')"
:hide-preview="pageState.currentTab === 'PaymentSuccess'"
:urgent="item.row.urgent"
:code="item.row.code"
:title="item.row.workName"
:created-at="
new Date(item.row.createdAt).toLocaleString('th-TH', {
2024-11-07 17:53:40 +07:00
hour12: false,
})
"
:valid-until="
(() => {
const date = new Date(item.row.dueDate);
date.setHours(23, 59, 59, 0);
return date.toLocaleString('th-TH', {
hour12: false,
});
})()
"
:status="
$t(`quotation.status.${item.row.quotationStatus}`)
"
:worker-count="item.row._count.worker"
:worker-max="item.row.workerMax || item.row._count.worker"
:customer-name="
2025-10-14 14:40:21 +07:00
item.row.customerBranch.customer.customerType === 'CORP'
? $i18n.locale === 'tha'
? item.row.customerBranch.registerName
: item.row.customerBranch.registerNameEN
: $i18n.locale === 'tha'
? `${item.row.customerBranch.firstName || '-'} ${item.row.customerBranch.lastName || ''}`
: `${item.row.customerBranch.firstNameEN || '-'} ${item.row.customerBranch.lastNameEN || ''}`
"
:reporter="
$i18n.locale === 'eng'
? item.row.createdBy.firstNameEN +
' ' +
item.row.createdBy.lastNameEN
: item.row.createdBy.firstName +
' ' +
item.row.createdBy.lastName
"
:total-price="item.row.finalPrice"
:badge-color="hslaColors[item.row.quotationStatus] || ''"
@preview="storeDataLocal(item.row.id)"
@view="
() => {
triggerQuotationDialog({
statusDialog: 'info',
quotationId: item.row.id,
branchId:
item.row.customerBranch.customer
.registeredBranchId,
});
}
"
@edit="
2024-11-07 17:53:40 +07:00
triggerQuotationDialog({
statusDialog: 'edit',
2024-11-07 17:53:40 +07:00
quotationId: item.row.id,
branchId:
item.row.customerBranch.customer.registeredBranchId,
})
"
@link="triggerReceiptDialog(item.row)"
@upload="console.log('upload')"
@delete="triggerDialogDeleteQuottaion(item.row.id)"
/>
</div>
</template>
</TableQuotation>
<template v-slot:loading>
<div
v-if="$q.screen.lt.sm && quotationPage !== quotationPageMax"
class="row justify-center"
>
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
2024-09-27 16:11:16 +07:00
</div>
2024-09-30 13:25:29 +07:00
</article>
2024-09-18 16:52:46 +07:00
2024-09-27 16:11:16 +07:00
<!-- SEC: footer content -->
<footer
class="row justify-between items-center q-px-md q-py-sm surface-2"
v-if="quotationPageMax > 0 && $q.screen.gt.xs"
2024-09-27 16:11:16 +07:00
>
<div class="col-4">
<div class="row items-center no-wrap">
<div class="app-text-muted q-mr-sm" v-if="$q.screen.gt.sm">
{{ $t('general.recordPerPage') }}
</div>
2024-11-15 11:36:51 +07:00
<div><PaginationPageSize v-model="quotationPageSize" /></div>
2024-09-27 16:11:16 +07:00
</div>
</div>
<div class="col-4 row justify-center app-text-muted">
{{
$q.screen.gt.sm
? $t('general.recordsPage', {
resultcurrentPage: quotationData.length,
total: pageState.inputSearch
? quotationData.length
: pageState.total,
})
: $t('general.ofPage', {
current: quotationData.length,
total: pageState.inputSearch
? quotationData.length
: pageState.total,
})
2024-09-27 16:11:16 +07:00
}}
</div>
<nav class="col-4 row justify-end">
<PaginationComponent
2024-10-01 09:48:03 +07:00
v-model:current-page="quotationPage"
v-model:max-page="quotationPageMax"
:fetch-data="() => fetchQuotationList()"
2024-09-27 16:11:16 +07:00
/>
</nav>
</footer>
</div>
</header>
2024-09-16 10:32:06 +07:00
</div>
2024-09-27 16:11:16 +07:00
2024-10-03 11:22:21 +07:00
<!-- NOTE: SEC START - Dialog -->
2024-10-04 15:12:13 +07:00
<!-- NOTE: START - Quotation Form, Add Quotation -->
2024-10-03 11:22:21 +07:00
2024-09-27 16:11:16 +07:00
<DialogForm
2025-09-11 13:36:09 +07:00
:key="keyAddDialog"
2024-09-27 16:11:16 +07:00
:title="$t('general.add', { text: $t('quotation.title') })"
v-model:modal="pageState.addModal"
:submit-label="$t('general.add', { text: $t('quotation.title') })"
submit-icon="mdi-check"
height="auto"
width="60vw"
:submit="
() => {
quotationFormState.mode = 'create';
2025-09-16 09:20:45 +07:00
quotationFormData.customerBranchId = currentBranchRootId;
2024-10-10 13:23:30 +07:00
triggerQuotationDialog({ statusDialog: 'create' });
}
"
2024-10-03 11:14:12 +07:00
:close="
() => {
branchId = '';
2025-09-11 13:36:09 +07:00
currentBranchRootId = '';
2024-10-03 11:14:12 +07:00
}
"
:beforeClose="
() => {
agentPrice = false;
special = false;
return false;
}
"
2024-08-02 16:13:07 +07:00
>
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
<header
:class="{
'q-mx-lg q-mt-md': $q.screen.gt.sm,
'q-mx-md q-mt-sm': $q.screen.lt.md,
}"
>
2024-09-27 16:11:16 +07:00
<ProfileBanner
2024-11-19 10:53:30 +07:00
prefix="dialog"
2024-09-27 16:11:16 +07:00
img="/images/quotation-bg-avatar.png"
fallback-cover="/images/quotation-banner.png"
bg-color="var(--surface-1)"
:title="$t('general.itemNo', { msg: $t('quotation.title') })"
hideActive
readonly
noImageAction
hideFade
/>
</header>
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
<section
class="col surface-1 rounded bordered row scroll"
:class="{
'q-mx-lg q-my-md': $q.screen.gt.sm,
'q-mx-md q-my-sm': $q.screen.lt.md,
}"
>
2024-09-27 16:11:16 +07:00
<div
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
class="col-12"
:class="{
'q-px-md q-py-lg': $q.screen.gt.sm,
'q-pa-sm': $q.screen.lt.md,
}"
2024-09-27 16:11:16 +07:00
id="customer-form-content"
style="height: 100%; max-height: 100%; overflow-y: auto"
>
<FormAbout
2024-10-04 09:45:05 +07:00
on-create
2024-10-04 15:12:13 +07:00
v-model:agent-price="agentPrice"
2024-10-03 11:14:12 +07:00
v-model:branch-id="branchId"
2024-10-04 15:12:13 +07:00
v-model:special="special"
2025-09-11 13:36:09 +07:00
v-model:customer-branch-id="currentBranchRootId"
@add-customer="triggerSelectTypeCustomerd()"
/>
2024-08-02 16:13:07 +07:00
</div>
2024-09-27 16:11:16 +07:00
</section>
</DialogForm>
2024-10-03 11:22:21 +07:00
<!-- NOTE: END - Quotation Form -->
2024-10-03 10:50:48 +07:00
<!-- NOTE: START - Customer / Employer Type Select Form -->
<DialogForm
v-model:modal="emptyCreateDialog"
:title="$t('customer.employerType')"
hide-footer
no-app-box
width="40vw"
height="250px"
:close="
() => {
emptyCreateDialog = false;
onCreateImageList = { selectedImage: '', list: [] };
}
"
>
<div class="full-height row q-pa-md">
<ItemCard
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
class="col q-mx-sm full-height cursor-pointer"
v-for="value in dialogCreateCustomerItem"
:key="value.text"
:icon="value.icon"
:text="value.text"
:icon-color="value.iconColor"
:bg-color="value.color"
2025-02-18 17:13:36 +07:00
:id="`btn-add-new-${value.text}`"
@trigger="
() => {
triggerCreateCustomerd({
type:
refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt <puriphat@frappet.com>
2025-01-27 10:39:53 +07:00
value.text === 'customer.employerLegalEntity'
? CustomerType.Corporate
: CustomerType.Person,
});
emptyCreateDialog = false;
}
2024-09-25 18:06:05 +07:00
"
/>
</div>
</DialogForm>
2024-09-25 18:06:05 +07:00
2024-10-03 10:50:48 +07:00
<!-- NOTE: END - Customer / Employer Type Form -->
<!-- NOTE: START - Customer / Employer Form -->
<DialogContainer
:model-value="customerFormState.dialogModal"
:on-open="
async () => {
customerFormStore.resetForm(customerFormState.dialogType === 'create');
onCreateImageList = { selectedImage: '', list: [] };
customerFormState.customerImageUrl = '';
await fetchListOfOptionBranch();
await customerFormStore.addCurrentCustomerBranch();
2024-10-02 14:05:36 +07:00
}
"
:on-close="
() => {
customerFormState.dialogModal = false;
onCreateImageList = { selectedImage: '', list: [] };
2025-09-11 13:36:09 +07:00
keyAddDialog++;
}
"
>
<template #header>
<DialogHeader
:title="
customerFormState.dialogType === 'create'
? $t(`general.add`, {
text: `${$t('customer.employer')} `,
})
: `${$t('customer.employer')} `
"
>
<template #title-after>
<span
:style="`color: hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
>
:
{{
customerFormData.customerType === 'CORP'
? $t('customer.employerLegalEntity')
: $t('customer.employerNaturalPerson')
}}
</span>
</template>
</DialogHeader>
</template>
<div
:class="{
'q-mx-lg q-my-md': $q.screen.gt.sm,
'q-mx-md q-my-sm': !$q.screen.gt.sm,
}"
>
2024-09-25 18:06:05 +07:00
<ProfileBanner
v-if="customerFormData.customerBranch !== undefined"
active
hide-fade
prefix="dialog"
2024-09-25 18:06:05 +07:00
:fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`"
:img="
customerFormState.customerImageUrl ||
`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`
"
:fallbackImg="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`"
:color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
:bg-color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/0.1)`"
:icon="
customerFormData.customerType === 'PERS'
? 'mdi-account-plus-outline'
: 'mdi-office-building-outline'
"
:title="
customerFormData.customerType === 'PERS'
2025-04-10 17:21:29 +07:00
? setPrefixName(
{
namePrefix: customerFormData.customerBranch[0]?.namePrefix,
firstName: customerFormData.customerBranch[0]?.firstName,
lastName: customerFormData.customerBranch[0]?.lastName,
firstNameEN: customerFormData.customerBranch[0]?.firstNameEN,
lastNameEN: customerFormData.customerBranch[0]?.lastNameEN,
},
{ locale },
)
: customerFormData.customerBranch[0]?.registerName
2024-09-25 18:06:05 +07:00
"
:caption="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstNameEN} ${customerFormData.customerBranch[0]?.lastNameEN}`
: customerFormData.customerBranch[0]?.registerNameEN
2024-09-25 18:06:05 +07:00
"
@view="
() => {
customerFormState.imageDialog = true;
customerFormState.isImageEdit = false;
}
"
@edit="
customerFormState.imageDialog = customerFormState.isImageEdit = true
"
/>
</div>
<div
style="flex: 1; width: 100%; overflow-y: auto"
id="customer-form"
:class="{
'q-px-lg q-pb-lg': $q.screen.gt.sm,
'q-px-md q-pb-sm': !$q.screen.gt.sm,
}"
2024-09-25 18:06:05 +07:00
>
<div class="col surface-1 full-height rounded bordered scroll row">
2024-09-25 18:06:05 +07:00
<div
class="col"
style="height: 100%; max-height: 100; overflow-y: auto"
v-if="$q.screen.gt.sm"
>
<div class="q-py-md q-pl-md q-pr-sm">
<SideMenu
:menu="[
{
name: $t('form.field.basicInformation'),
anchor: 'form-basic-info-customer',
},
{
name: $t('customer.form.group.branch'),
anchor: 'form-branch-customer-branch',
useBtn: true,
},
...(customerFormData.customerBranch?.map((v, i) => ({
name:
i === 0
? $t('customer.form.headQuarters.title')
: $t('customer.form.branch.title', {
name: i,
}),
anchor: `form-branch-customer-no-${i}`,
sub: true,
})) || []),
]"
background="transparent"
:active="{
background: 'hsla(var(--blue-6-hsl) / .2)',
foreground: 'var(--blue-6)',
}"
scroll-element="#customer-form-content"
>
<template v-slot:btn-form-branch-customer-branch>
<q-btn
dense
flat
icon="mdi-plus"
size="sm"
rounded
padding="0px 0px"
style="color: var(--stone-9)"
@click.stop="submitCustomer()"
v-if="
customerFormState.branchIndex === -1 &&
!!customerFormState.editCustomerId &&
customerFormState.dialogType !== 'create'
"
:disabled="!customerFormState.readonly"
/>
</template>
</SideMenu>
</div>
</div>
<div
class="col-12 col-md-10"
:class="{
'q-py-md q-pr-md ': $q.screen.gt.sm,
'q-pa-sm': !$q.screen.gt.sm,
}"
id="customer-form-content"
style="height: 100%; max-height: 100%; overflow-y: auto"
>
<EmployerFormBasicInfo
prefixId="form"
v-if="
customerFormData.customerBranch !== undefined &&
customerFormData.customerBranch.length > 0
"
class="q-mb-xl"
:readonly="
(customerFormState.dialogType === 'edit' &&
customerFormState.readonly === true) ||
customerFormState.dialogType === 'info'
"
:action-disabled="customerFormState.branchIndex !== -1"
id="form-basic-info-customer"
:onCreate="customerFormState.dialogType === 'create'"
@edit="
((customerFormState.dialogType = 'edit'),
(customerFormState.readonly = false))
"
@cancel="() => customerFormUndo(false)"
@delete="
customerFormState.editCustomerId &&
deleteCustomerById(customerFormState.editCustomerId)
"
:customer-type="customerFormData.customerType"
v-model:registered-branch-id="customerFormData.registeredBranchId"
v-model:customer-name="customerNameInfo"
v-model:register-name="
customerFormData.customerBranch[0].registerName
"
v-model:citizen-id="customerFormData.customerBranch[0].citizenId"
v-model:legal-person-no="
customerFormData.customerBranch[0].legalPersonNo
"
v-model:business-type="
2025-09-11 13:36:09 +07:00
customerFormData.customerBranch[0].businessTypeId
"
v-model:job-position="
customerFormData.customerBranch[0].jobPosition
"
v-model:telephone-no="
customerFormData.customerBranch[0].telephoneNo
"
v-model:branch-options="registerAbleBranchOption"
/>
<div class="row q-col-gutter-sm" id="form-branch-customer-branch">
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-briefcase-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customer.form.group.branch') }}</span>
</div>
2024-09-30 11:04:12 +07:00
<template
v-for="(_, idx) in customerFormData.customerBranch"
:key="idx"
>
<!-- v-if="customerFormData.customerBranch" -->
<q-form
class="full-width"
greedy
@submit.prevent="
async () => {
if (!customerFormData.customerBranch) return;
if (customerFormData.customerType === 'PERS') {
tabFieldRequired.main = [
'citizenId',
'namePrefix',
'firstName',
'firstNameEN',
'lastName',
'lastNameEN',
'gender',
'birthDate',
];
}
if (customerFormData.customerType === 'CORP') {
tabFieldRequired.main = ['legalPersonNo', 'registerName'];
}
let tapIsUndefined = validateTabField(
customerFormData.customerBranch?.[idx],
tabFieldRequired,
);
if (tapIsUndefined.length > 0) {
return dialog({
color: 'warning',
icon: 'mdi-alert',
title: t('dialog.title.incompleteDataEntry'),
actionText: t('general.ok'),
persistent: true,
message: t('dialog.message.incompleteDataEntry', {
tap: `${tapIsUndefined.map((v: string) => t(`customerBranch.tab.${v}`)).join(', ')}`,
}),
action: async () => {
return;
},
});
}
if (!customerFormData.customerBranch[idx].id) {
let res: any;
if (idx === 0) {
res =
await customerFormStore.submitFormCustomer(
onCreateImageList,
);
} else {
res = await customerStore.createBranch({
...customerFormData.customerBranch[idx],
customerId: customerFormState.editCustomerId || '',
});
}
if (res) {
customerFormState.readonly = true;
notify('create', $t('general.success'));
}
} else {
if (!customerFormState.editCustomerId) return;
await customerStore.editBranchById(
customerFormData.customerBranch[idx].id || '',
{
...customerFormData.customerBranch[idx],
id: undefined,
},
);
}
const uploadResult =
customerFormData.customerBranch[idx].file?.map(
async (v) => {
if (!v.file) return;
const ext = v.file.name.split('.').at(-1);
let filename = v.group + '-' + new Date().getTime();
if (ext) filename += `.${ext}`;
const res = await customerStore.putAttachment({
branchId:
customerFormData.customerBranch?.[idx].id || '',
file: v.file,
filename,
});
if (res) {
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
}
},
) || [];
for (const r of uploadResult) await r;
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
customerFormStore.resetForm();
}
"
>
<!-- v-if="!!customerFormState.editCustomerId" -->
<EmployerFormBranch
:index="idx"
prefixId="form"
v-if="customerFormData.customerBranch"
v-model:customer="customerFormData"
v-model:customer-branch="customerFormData.customerBranch[idx]"
:onCreate="customerFormState.dialogType === 'create'"
:customer-type="customerFormData.customerType"
:readonly="customerFormState.branchIndex !== idx"
:action-disabled="
!customerFormState.readonly ||
(customerFormState.branchIndex !== -1 &&
customerFormState.branchIndex !== idx)
"
@edit="() => (customerFormState.branchIndex = idx)"
@cancel="() => customerFormUndo(false)"
@delete="
async () => {
if (!customerFormState.editCustomerId) return;
if (idx === 0) {
deleteCustomerById(customerFormState.editCustomerId);
return;
}
if (!!customerFormData.customerBranch?.[idx].id) {
const action = await deleteCustomerBranchById(
customerFormData.customerBranch[idx].id || '',
);
if (action) {
await customerFormStore.assignFormData(
customerFormState.editCustomerId,
);
}
customerFormStore.resetForm();
}
}
"
@save="() => {}"
/>
</q-form>
</template>
</div>
2024-09-25 18:06:05 +07:00
</div>
</div>
</div>
</DialogContainer>
2024-06-19 15:43:58 +07:00
</template>
<style scoped></style>