feat: debit note (#172)

* feat: new file

* feat: function api debit

* feat: add route debit

* feat: new form page

* refactor: show menu debit

* refactor: add type debit note status

* feat: add i18n

* feat: add constants

* feat: add stores

* feat: layout

* feat: add function

* refactor: change name value

* feat: form select quotation

* refactor: change name url

* refactor: use form debit

* refactor: change src import

* refactor: move file form debit

* refactor: add i18n

* feat: add type debit note

* refactor: add columns

* refactor: bind value columns

* refactor: change name Table

* refactor: edit type

* refactor: bind type debit note

* refactor: bind value debit

* refactor: chame name function

* fix: calculate page

* refactor: delete table

* refactor: change name get list

* refactor: change i18n

* refactor: change name value

* refactor: bind navigate and trigger delete

* refactor: format number deciml

* refactor: add i18n

* feat: new page

* refactor: add color debit

* feat: Debit tab

#178

* feat: TableRequest

* refactor: edit type pay condition

* refactor: add i18n btn submit

* refactor: use type enum

* feat: edit layout product expansion

* refactor: bind function

* refactor: show code

* feat: add input search and select  status

* feat: paymentform

* refactor: edit type

* refactor: add manage file and edit end point

* feat: add form.ts

* refactor: send mode

* refactor: edit v-model of due date

* feat: submit create debit

* fix: status

* refactor: handle data not allow

* fix: call updateDebitNote in edit mode and simplify payload handling

* refactor: hide edit

* refactor: handle pay condition only full

* refactor: delete pay split

* refactor: add query

* refactor: handle is debit note

* refactor: handle is quotation

* refactor: add props hide

* refactor: tap payment and receipt

* refactor: add i18n

* feat: view document

* refactor: handle btn view doc

* refactor: use my remark

---------

Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
Co-authored-by: nwpptrs <jay02499@gmail.com>
Co-authored-by: aif912752 <siripak@chamomind.com>
This commit is contained in:
Methapon Metanipat 2025-01-27 09:04:08 +07:00 committed by GitHub
parent e3c781f857
commit 79240f53b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 4172 additions and 12 deletions

View file

@ -0,0 +1,94 @@
import {
DebitNote as Data,
DebitNoteStatus as Status,
DebitNotePayload as Payload,
} from './types.ts';
import { ref } from 'vue';
import { defineStore } from 'pinia';
import { api } from 'src/boot/axios.ts';
import { PaginationResult } from 'src/types.ts';
import { manageAttachment, manageFile } from '../utils/index.ts';
const ENDPOINT = 'debit-note';
export * from './types.ts';
export async function getDebitNoteStats() {
const res = await api.get<Record<Status, number>>(`/${ENDPOINT}/stats`);
if (res.status < 400) {
return res.data;
}
return null;
}
export async function getDebitNoteList(params?: {
page?: number;
pageSize?: number;
query?: string;
deebitNoteStatus?: Status;
includeRegisteredBranch?: boolean;
}) {
const res = await api.get<PaginationResult<Data>>(`/${ENDPOINT}`, {
params,
});
if (res.status < 400) return res.data;
return null;
}
export async function getDebitNote(id: string) {
const res = await api.get<Data>(`/${ENDPOINT}/${id}`);
if (res.status < 400) return res.data;
return null;
}
export async function createDebitNote(body: Payload) {
const res = await api.post<Data>(`/${ENDPOINT}`, body);
if (res.status < 400) return res.data;
return null;
}
export async function updateDebitNote(body: Payload) {
const { id, quotationId, ...payload } = body;
const res = await api.put<Data>(`/${ENDPOINT}/${id}`, payload);
if (res.status < 400) return res.data;
return null;
}
export async function deleteDebitNote(id: string) {
const res = await api.delete<Data>(`/${ENDPOINT}/${id}`);
if (res.status < 400) return res.data;
return null;
}
export const useDebitNote = defineStore('debit-note-store', () => {
const data = ref<Data[]>([]);
const page = ref<number>(1);
const pageMax = ref<number>(1);
const pageSize = ref<number>(30);
const stats = ref<Record<Status, number>>({
[Status.Pending]: 0,
[Status.Expire]: 0,
[Status.Payment]: 0,
[Status.Receipt]: 0,
[Status.Succeed]: 0,
});
return {
data,
page,
pageMax,
pageSize,
stats,
getDebitNoteStats,
getDebitNote,
getDebitNoteList,
createDebitNote,
updateDebitNote,
deleteDebitNote,
...manageAttachment(api, ENDPOINT),
...manageFile<'slip'>(api, ENDPOINT),
};
});

View file

@ -0,0 +1,94 @@
import {
Quotation,
QuotationFull,
QuotationStatus,
QuotationPayload,
PayCondition,
} from '../quotations';
import { RequestWork } from '../request-list';
import { CreatedBy, UpdatedBy } from '../types';
import { CustomerBranch } from '../customer';
import { Branch } from '../branch/types';
export type DebitNotePayload = Omit<
QuotationPayload & {
id?: string;
quotationId: string;
debitNoteQuotationId?: string;
reason?: string;
detail?: string;
agentPrice: boolean;
},
| 'customerBranchId'
| 'registeredBranchId'
| 'contactName'
| 'contactTel'
| '_count'
| 'urgent'
| 'workName'
| 'workerMax'
| 'productServiceList'
| 'paySplit'
> & {
productServiceList: {
installmentNo: number;
workerIndex: number[];
discount: number;
amount: number;
productId: string;
workId: string;
serviceId: string;
}[];
};
export type DebitNote = {
debitNoteQuotation?: QuotationFull;
updatedBy: UpdatedBy;
createdBy: CreatedBy;
productServiceList: QuotationFull['productServiceList'];
worker: QuotationFull['worker'];
paySplit: QuotationFull['paySplit'];
registeredBranch: Branch;
customerBranch: CustomerBranch;
_count: { worker: number };
updatedByUserId: string;
updatedAt: string;
createdByUserId: string;
createdAt: string;
debitNoteQuotationId: string;
isDebitNote: boolean;
finalPrice: number;
discount: number;
vatExcluded: number;
vat: number;
totalDiscount: number;
totalPrice: number;
agentPrice: boolean;
urgent: boolean;
workerMax: number;
payBillDate: string;
paySplitCount: number;
payCondition: PayCondition;
date: string;
dueDate: string;
contactTel: string;
contactName: string;
workName: string;
code: string;
remark: string;
quotationStatus: QuotationStatus;
statusOrder: number;
status: string;
customerBranchId: string;
registeredBranchId: string;
id: string;
};
export enum DebitNoteStatus {
Pending = 'Pending',
Expire = 'Expire',
Payment = 'Payment',
Receipt = 'Receipt',
Succeed = 'Succeed',
}

View file

@ -98,6 +98,9 @@ export const useReceipt = defineStore('receipt-store', () => {
pageSize?: number;
query?: string;
quotationId?: string;
debitNoteId?: string;
debitNoteOnly?: boolean;
quotationOnly?: boolean;
}) {
const res = await api.get<PaginationResult<Receipt>>('/receipt', {
params: opts,

View file

@ -192,10 +192,15 @@ export const useQuotationStore = defineStore('quotation-store', () => {
* @deprecated Please use payment store instead.
*/
export const useQuotationPayment = defineStore('quotation-payment', () => {
async function getQuotationPayment(quotationId: string) {
async function getQuotationPayment(params: {
quotationId?: string;
debitNoteId?: string;
debitNoteOnly?: boolean;
quotationOnly?: boolean;
}) {
const res = await api.get<PaginationResult<QuotationPaymentData>>(
'/payment',
{ params: { quotationId } },
{ params },
);
if (res.status < 400) {
return res.data;