From 5e2100eb8d1f0a1505dfe536adaeb461488cd51b Mon Sep 17 00:00:00 2001 From: Methapon Metanipat <162551568+Methapon-Frappet@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:08:31 +0700 Subject: [PATCH] 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 Co-authored-by: Thanaphon Frappet --- src/components/05_quotation/QuotationCard.vue | 7 +- src/components/11_credit-note/FormCredit.vue | 39 + src/components/dialog/DialogViewFile.vue | 58 +- .../shared/select/SelectQuotation.vue | 212 +++++ src/components/upload-file/UploadFileCard.vue | 12 +- .../upload-file/UploadFileSection.vue | 8 +- src/i18n/eng.ts | 51 ++ src/i18n/tha.ts | 56 +- src/layouts/DrawerComponent.vue | 10 +- src/pages/05_quotation/MainPage.vue | 6 +- src/pages/05_quotation/QuotationForm.vue | 2 +- .../05_quotation/QuotationFormReceipt.vue | 39 +- .../08_request-list/TableRequestList.vue | 3 + .../09_task-order/SelectReadyRequestWork.vue | 27 +- src/pages/09_task-order/TableEmployee.vue | 49 +- .../expansion/AdditionalFileExpansion.vue | 1 + .../expansion/ProductExpansion.vue | 46 +- .../09_task-order/order_view/MainPage.vue | 1 + src/pages/11_credit-note/FormPage.vue | 822 ++++++++++++++++++ src/pages/11_credit-note/MainPage.vue | 468 ++++++++++ .../11_credit-note/RefundInformation.vue | 280 ++++++ src/pages/11_credit-note/TableCreditNote.vue | 87 ++ src/pages/11_credit-note/constants.ts | 78 ++ .../expansion/CreditNoteExpansion.vue | 51 ++ .../expansion/DocumentExpansion.vue | 108 +++ .../expansion/PaymentExpansion.vue | 235 +++++ src/router/routes.ts | 15 + src/stores/credit-note/index.ts | 103 +++ src/stores/credit-note/types.ts | 51 ++ src/stores/quotations/index.ts | 2 + src/stores/quotations/types.ts | 5 +- src/stores/request-list/index.ts | 2 + src/stores/request-list/types.ts | 2 + src/stores/utils/index.ts | 38 +- 34 files changed, 2897 insertions(+), 77 deletions(-) create mode 100644 src/components/11_credit-note/FormCredit.vue create mode 100644 src/components/shared/select/SelectQuotation.vue create mode 100644 src/pages/11_credit-note/FormPage.vue create mode 100644 src/pages/11_credit-note/MainPage.vue create mode 100644 src/pages/11_credit-note/RefundInformation.vue create mode 100644 src/pages/11_credit-note/TableCreditNote.vue create mode 100644 src/pages/11_credit-note/constants.ts create mode 100644 src/pages/11_credit-note/expansion/CreditNoteExpansion.vue create mode 100644 src/pages/11_credit-note/expansion/DocumentExpansion.vue create mode 100644 src/pages/11_credit-note/expansion/PaymentExpansion.vue create mode 100644 src/stores/credit-note/index.ts create mode 100644 src/stores/credit-note/types.ts diff --git a/src/components/05_quotation/QuotationCard.vue b/src/components/05_quotation/QuotationCard.vue index 1de73166..1cce142d 100644 --- a/src/components/05_quotation/QuotationCard.vue +++ b/src/components/05_quotation/QuotationCard.vue @@ -22,7 +22,9 @@ defineProps<{ badgeColor?: string; hideKebabView?: boolean; hideKebabEdit?: boolean; + hideKebabDelete?: boolean; hideAction?: boolean; + useCancel?: boolean; customData?: { label: string; @@ -39,6 +41,7 @@ defineEmits<{ (e: 'delete'): void; (e: 'example'): void; (e: 'preview'): void; + (e: 'cancel'): void; }>(); const rand = Math.random(); @@ -93,7 +96,8 @@ const rand = Math.random(); :idName="code" status="ACTIVE" hide-toggle - hide-delete + :use-cancel + :hide-delete="hideKebabDelete" :hide-view="hideKebabView" :hide-edit="hideKebabEdit" @view="$emit('view')" @@ -101,6 +105,7 @@ const rand = Math.random(); @link="$emit('link')" @upload="$emit('upload')" @delete="$emit('delete')" + @cancel="$emit('cancel')" /> diff --git a/src/components/11_credit-note/FormCredit.vue b/src/components/11_credit-note/FormCredit.vue new file mode 100644 index 00000000..68bb7ab2 --- /dev/null +++ b/src/components/11_credit-note/FormCredit.vue @@ -0,0 +1,39 @@ + + + diff --git a/src/components/dialog/DialogViewFile.vue b/src/components/dialog/DialogViewFile.vue index dd13f4d1..db574376 100644 --- a/src/components/dialog/DialogViewFile.vue +++ b/src/components/dialog/DialogViewFile.vue @@ -6,29 +6,57 @@ import DialogHeader from './DialogHeader.vue'; import MainButton from '../button/MainButton.vue'; import NoData from '../NoData.vue'; -defineProps<{ - title: string; +const props = defineProps<{ + title?: string; url?: string; + hideTab?: boolean; + download?: boolean; + transformUrl?: (url: string) => string | Promise; }>(); const open = defineModel({ default: false }); const state = reactive({ imageZoom: 100, + transformedUrl: props.url, }); -function openDialog() { +async function openDialog() { state.imageZoom = 100; + if (props.url && props.transformUrl) { + state.transformedUrl = await props.transformUrl(props.url); + } else { + state.transformedUrl = props.url; + } +} + +async function downloadImage(url: string | null) { + if (!url) return; + const res = await fetch(url); + const blob = await res.blob(); + + let extension = ''; + + if (blob.type === 'image/jpeg') extension = '.jpg'; + else if (blob.type === 'image/png') extension = '.png'; + else return; + + let a = document.createElement('a'); + a.download = `download${extension}`; + a.href = window.URL.createObjectURL(blob); + a.click(); + a.remove(); }