2024-09-30 12:04:58 +07:00
|
|
|
import { ref } from 'vue';
|
|
|
|
|
import { defineStore } from 'pinia';
|
|
|
|
|
|
|
|
|
|
import { api } from 'src/boot/axios';
|
|
|
|
|
|
2024-10-07 16:58:45 +07:00
|
|
|
import {
|
|
|
|
|
Quotation,
|
|
|
|
|
QuotationFull,
|
|
|
|
|
QuotationPayload,
|
2024-10-16 17:21:30 +07:00
|
|
|
QuotationPaymentData,
|
2024-10-07 16:58:45 +07:00
|
|
|
QuotationStats,
|
2024-10-21 15:17:27 +07:00
|
|
|
PaymentPayload,
|
2024-10-28 08:57:41 +07:00
|
|
|
QuotationStatus,
|
2024-12-17 14:22:22 +07:00
|
|
|
QuotationAddWorkerPayload,
|
2024-10-07 16:58:45 +07:00
|
|
|
} from './types';
|
2024-09-30 12:04:58 +07:00
|
|
|
import { PaginationResult } from 'src/types';
|
2024-10-21 15:17:27 +07:00
|
|
|
|
2024-10-24 13:57:22 +07:00
|
|
|
import { manageAttachment } from '../utils';
|
2024-09-30 12:04:58 +07:00
|
|
|
|
2024-09-30 14:16:16 +07:00
|
|
|
export const useQuotationStore = defineStore('quotation-store', () => {
|
2024-09-30 12:04:58 +07:00
|
|
|
const data = ref<Quotation[]>([]);
|
|
|
|
|
const page = ref<number>(1);
|
|
|
|
|
const pageMax = ref<number>(1);
|
2024-09-30 15:03:36 +07:00
|
|
|
const pageSize = ref<number>(30);
|
2024-10-07 16:58:45 +07:00
|
|
|
const stats = ref<QuotationStats>({
|
2024-11-07 14:22:13 +07:00
|
|
|
issued: 0,
|
|
|
|
|
accepted: 0,
|
|
|
|
|
expired: 0,
|
|
|
|
|
paymentInProcess: 0,
|
|
|
|
|
paymentSuccess: 0,
|
|
|
|
|
processComplete: 0,
|
2024-12-26 12:00:25 +07:00
|
|
|
canceled: 0,
|
2024-10-07 16:58:45 +07:00
|
|
|
});
|
|
|
|
|
|
2025-03-06 13:26:50 +07:00
|
|
|
async function getQuotationStats(params?: {
|
|
|
|
|
startDate: string | Date;
|
|
|
|
|
endDate: string | Date;
|
|
|
|
|
}) {
|
|
|
|
|
const res = await api.get<QuotationStats>('/quotation/stats', { params });
|
2024-10-07 16:58:45 +07:00
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-09-30 12:04:58 +07:00
|
|
|
|
|
|
|
|
async function getQuotation(id: string) {
|
|
|
|
|
const res = await api.get<QuotationFull>(`/quotation/${id}`);
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-24 16:37:05 +07:00
|
|
|
async function getQuotationList(params?: {
|
2024-09-30 15:03:36 +07:00
|
|
|
page?: number;
|
|
|
|
|
pageSize?: number;
|
2024-10-29 10:19:47 +07:00
|
|
|
payCondition?:
|
|
|
|
|
| 'Full'
|
|
|
|
|
| 'Split'
|
|
|
|
|
| 'SplitCustom'
|
|
|
|
|
| 'BillFull'
|
|
|
|
|
| 'BillSplit'
|
|
|
|
|
| 'BillSplitCustom';
|
2024-11-07 12:51:15 +07:00
|
|
|
status?:
|
|
|
|
|
| 'Issued'
|
|
|
|
|
| 'Accepted'
|
2024-11-07 14:23:10 +07:00
|
|
|
| 'Expired'
|
2024-11-07 12:51:15 +07:00
|
|
|
| 'PaymentPending'
|
|
|
|
|
| 'PaymentInProcess'
|
|
|
|
|
| 'PaymentSuccess'
|
|
|
|
|
| 'ProcessComplete'
|
|
|
|
|
| 'Canceled';
|
2024-11-07 14:23:10 +07:00
|
|
|
urgentFirst?: boolean;
|
2024-10-21 13:33:36 +07:00
|
|
|
query?: string;
|
2025-01-14 09:08:31 +07:00
|
|
|
hasCancel?: boolean;
|
|
|
|
|
includeRegisteredBranch?: boolean;
|
2025-01-30 16:40:35 +07:00
|
|
|
forDebitNote?: boolean;
|
2025-02-24 16:49:13 +07:00
|
|
|
cancelIncludeDebitNote?: boolean;
|
2024-09-30 15:03:36 +07:00
|
|
|
}) {
|
2024-11-01 17:18:24 +07:00
|
|
|
const res = await api.get<PaginationResult<Quotation>>('/quotation', {
|
2024-10-24 16:37:05 +07:00
|
|
|
params,
|
|
|
|
|
});
|
2024-09-30 12:04:58 +07:00
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-07 17:04:12 +07:00
|
|
|
async function createQuotation(data: QuotationPayload) {
|
2024-10-28 08:53:34 +07:00
|
|
|
const { _count, quotationStatus, ...payload } = data;
|
2024-10-07 17:04:12 +07:00
|
|
|
|
2024-10-03 14:57:14 +07:00
|
|
|
const res = await api.post('/quotation', {
|
|
|
|
|
...payload,
|
2024-10-31 10:00:35 +07:00
|
|
|
paySplit: data.paySplit.map((v) => ({
|
2024-10-31 13:40:12 +07:00
|
|
|
name: v.name,
|
2024-10-31 10:00:35 +07:00
|
|
|
amount: v.amount,
|
|
|
|
|
})),
|
2024-10-07 17:04:12 +07:00
|
|
|
productServiceList: data.productServiceList.map((v) => ({
|
2024-10-03 14:57:14 +07:00
|
|
|
vat: v.vat,
|
|
|
|
|
amount: v.amount,
|
|
|
|
|
pricePerUnit: v.pricePerUnit,
|
|
|
|
|
discount: v.discount,
|
|
|
|
|
productId: v.product.id,
|
|
|
|
|
workId: v.work?.id,
|
|
|
|
|
serviceId: v.service?.id,
|
2024-10-29 18:00:59 +07:00
|
|
|
installmentNo: v.installmentNo,
|
2024-10-08 10:05:46 +07:00
|
|
|
workerIndex: v.workerIndex,
|
2024-10-03 14:57:14 +07:00
|
|
|
})),
|
|
|
|
|
});
|
2024-09-30 12:04:58 +07:00
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-28 08:57:41 +07:00
|
|
|
async function changeStatus(quotationId: string, status: QuotationStatus) {
|
|
|
|
|
const res = await api.put(`/quotation/${quotationId}`, {
|
|
|
|
|
quotationStatus: status,
|
|
|
|
|
});
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-10 13:34:27 +07:00
|
|
|
async function editQuotation(data: QuotationPayload & { id: string }) {
|
2025-01-30 14:05:20 +07:00
|
|
|
const { _count, agentPrice, ...payload } = data;
|
2024-10-10 13:34:27 +07:00
|
|
|
const res = await api.put(`/quotation/${data.id}`, {
|
2024-09-30 12:04:58 +07:00
|
|
|
...payload,
|
2024-11-01 14:31:10 +07:00
|
|
|
quotationStatus:
|
|
|
|
|
payload.quotationStatus !== 'Accepted' ? undefined : 'Accepted',
|
2024-10-31 10:00:35 +07:00
|
|
|
paySplit: data.paySplit.map((v) => ({
|
2024-10-31 13:40:12 +07:00
|
|
|
name: v.name,
|
2024-10-31 10:00:35 +07:00
|
|
|
amount: v.amount,
|
|
|
|
|
})),
|
2024-10-03 14:57:14 +07:00
|
|
|
productServiceList: payload.productServiceList.map((v) => ({
|
|
|
|
|
vat: v.vat,
|
|
|
|
|
amount: v.amount,
|
|
|
|
|
pricePerUnit: v.pricePerUnit,
|
|
|
|
|
discount: v.discount,
|
|
|
|
|
productId: v.product.id,
|
|
|
|
|
workId: v.work?.id,
|
|
|
|
|
serviceId: v.service?.id,
|
2024-10-10 17:53:12 +07:00
|
|
|
workerIndex: v.workerIndex,
|
2024-10-31 13:40:12 +07:00
|
|
|
installmentNo: v.installmentNo,
|
2024-10-03 14:57:14 +07:00
|
|
|
})),
|
2024-09-30 12:04:58 +07:00
|
|
|
id: undefined,
|
|
|
|
|
});
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-24 13:57:22 +07:00
|
|
|
async function deleteQuotation(id: string) {
|
2024-09-30 12:04:58 +07:00
|
|
|
const res = await api.delete(`/quotation/${id}`);
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-17 14:22:22 +07:00
|
|
|
/** This is meant to be use after quotation was accepted */
|
|
|
|
|
async function addQuotationWorker(
|
|
|
|
|
id: string,
|
|
|
|
|
payload: QuotationAddWorkerPayload,
|
|
|
|
|
) {
|
|
|
|
|
const res = await api.post(`/quotation/${id}/add-worker`, payload);
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-01 17:18:24 +07:00
|
|
|
const fileManager = manageAttachment(api, 'quotation');
|
|
|
|
|
|
2024-09-30 12:04:58 +07:00
|
|
|
return {
|
|
|
|
|
data,
|
|
|
|
|
page,
|
2024-09-30 15:03:36 +07:00
|
|
|
pageSize,
|
2024-09-30 12:04:58 +07:00
|
|
|
pageMax,
|
2024-10-07 16:58:45 +07:00
|
|
|
stats,
|
|
|
|
|
getQuotationStats,
|
2024-09-30 12:04:58 +07:00
|
|
|
getQuotation,
|
|
|
|
|
getQuotationList,
|
|
|
|
|
createQuotation,
|
|
|
|
|
editQuotation,
|
2024-10-24 13:57:22 +07:00
|
|
|
deleteQuotation,
|
2024-10-28 08:57:41 +07:00
|
|
|
changeStatus,
|
2024-12-17 14:22:22 +07:00
|
|
|
addQuotationWorker,
|
2024-11-01 17:18:24 +07:00
|
|
|
|
|
|
|
|
...fileManager,
|
2024-09-30 12:04:58 +07:00
|
|
|
};
|
|
|
|
|
});
|
2024-10-16 17:21:30 +07:00
|
|
|
|
2024-10-30 10:46:45 +07:00
|
|
|
/**
|
|
|
|
|
* @deprecated Please use payment store instead.
|
|
|
|
|
*/
|
2024-10-16 17:21:30 +07:00
|
|
|
export const useQuotationPayment = defineStore('quotation-payment', () => {
|
2025-01-27 09:04:08 +07:00
|
|
|
async function getQuotationPayment(params: {
|
|
|
|
|
quotationId?: string;
|
|
|
|
|
debitNoteId?: string;
|
|
|
|
|
debitNoteOnly?: boolean;
|
|
|
|
|
quotationOnly?: boolean;
|
|
|
|
|
}) {
|
2024-10-28 16:44:14 +07:00
|
|
|
const res = await api.get<PaginationResult<QuotationPaymentData>>(
|
2024-11-01 17:18:24 +07:00
|
|
|
'/payment',
|
2025-01-27 09:04:08 +07:00
|
|
|
{ params },
|
2024-10-28 16:44:14 +07:00
|
|
|
);
|
2024-10-16 17:21:30 +07:00
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-21 15:17:27 +07:00
|
|
|
async function updateQuotationPayment(
|
|
|
|
|
paymentId: string,
|
|
|
|
|
payload: PaymentPayload,
|
|
|
|
|
) {
|
|
|
|
|
const res = await api.put<PaymentPayload & { id: string }>(
|
2024-10-28 16:44:14 +07:00
|
|
|
`/payment/${paymentId}`,
|
2024-10-21 15:17:27 +07:00
|
|
|
payload,
|
|
|
|
|
);
|
|
|
|
|
if (res.status < 400) {
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-01 17:18:24 +07:00
|
|
|
const fileManager = manageAttachment(api, 'payment');
|
2024-10-21 15:17:27 +07:00
|
|
|
|
2024-10-16 17:21:30 +07:00
|
|
|
return {
|
|
|
|
|
getQuotationPayment,
|
2024-10-21 15:17:27 +07:00
|
|
|
updateQuotationPayment,
|
2024-10-28 16:44:14 +07:00
|
|
|
|
|
|
|
|
...fileManager,
|
2024-10-16 17:21:30 +07:00
|
|
|
};
|
|
|
|
|
});
|
2024-12-17 14:22:22 +07:00
|
|
|
|
|
|
|
|
export * from './types.ts';
|