240 lines
5.5 KiB
TypeScript
240 lines
5.5 KiB
TypeScript
import { ref } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
|
|
import { api } from 'src/boot/axios';
|
|
|
|
import {
|
|
Quotation,
|
|
QuotationFull,
|
|
QuotationPayload,
|
|
QuotationPaymentData,
|
|
QuotationStats,
|
|
PaymentPayload,
|
|
QuotationStatus,
|
|
QuotationAddWorkerPayload,
|
|
} from './types';
|
|
import { PaginationResult } from 'src/types';
|
|
|
|
import { manageAttachment } from '../utils';
|
|
|
|
export const useQuotationStore = defineStore('quotation-store', () => {
|
|
const data = ref<Quotation[]>([]);
|
|
const page = ref<number>(1);
|
|
const pageMax = ref<number>(1);
|
|
const pageSize = ref<number>(30);
|
|
const stats = ref<QuotationStats>({
|
|
issued: 0,
|
|
accepted: 0,
|
|
expired: 0,
|
|
paymentInProcess: 0,
|
|
paymentSuccess: 0,
|
|
processComplete: 0,
|
|
canceled: 0,
|
|
});
|
|
|
|
async function getQuotationStats(params?: {
|
|
startDate: string | Date;
|
|
endDate: string | Date;
|
|
}) {
|
|
const res = await api.get<QuotationStats>('/quotation/stats', { params });
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function getQuotation(id: string) {
|
|
const res = await api.get<QuotationFull>(`/quotation/${id}`);
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function getQuotationList(params?: {
|
|
page?: number;
|
|
pageSize?: number;
|
|
payCondition?:
|
|
| 'Full'
|
|
| 'Split'
|
|
| 'SplitCustom'
|
|
| 'BillFull'
|
|
| 'BillSplit'
|
|
| 'BillSplitCustom';
|
|
status?:
|
|
| 'Issued'
|
|
| 'Accepted'
|
|
| 'Expired'
|
|
| 'PaymentPending'
|
|
| 'PaymentInProcess'
|
|
| 'PaymentSuccess'
|
|
| 'ProcessComplete'
|
|
| 'Canceled';
|
|
urgentFirst?: boolean;
|
|
query?: string;
|
|
hasCancel?: boolean;
|
|
includeRegisteredBranch?: boolean;
|
|
forDebitNote?: boolean;
|
|
cancelIncludeDebitNote?: boolean;
|
|
}) {
|
|
const res = await api.get<PaginationResult<Quotation>>('/quotation', {
|
|
params,
|
|
});
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function createQuotation(data: QuotationPayload) {
|
|
const { _count, quotationStatus, ...payload } = data;
|
|
|
|
const res = await api.post('/quotation', {
|
|
...payload,
|
|
paySplit: data.paySplit.map((v) => ({
|
|
name: v.name,
|
|
amount: v.amount,
|
|
})),
|
|
productServiceList: data.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,
|
|
installmentNo: v.installmentNo,
|
|
workerIndex: v.workerIndex,
|
|
})),
|
|
});
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
async function editQuotation(data: QuotationPayload & { id: string }) {
|
|
const { _count, agentPrice, ...payload } = data;
|
|
const res = await api.put(`/quotation/${data.id}`, {
|
|
...payload,
|
|
quotationStatus:
|
|
payload.quotationStatus !== 'Accepted' ? undefined : 'Accepted',
|
|
paySplit: data.paySplit.map((v) => ({
|
|
name: v.name,
|
|
amount: v.amount,
|
|
})),
|
|
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,
|
|
workerIndex: v.workerIndex,
|
|
installmentNo: v.installmentNo,
|
|
})),
|
|
id: undefined,
|
|
});
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function deleteQuotation(id: string) {
|
|
const res = await api.delete(`/quotation/${id}`);
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** 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;
|
|
}
|
|
|
|
const fileManager = manageAttachment(api, 'quotation');
|
|
|
|
return {
|
|
data,
|
|
page,
|
|
pageSize,
|
|
pageMax,
|
|
stats,
|
|
getQuotationStats,
|
|
getQuotation,
|
|
getQuotationList,
|
|
createQuotation,
|
|
editQuotation,
|
|
deleteQuotation,
|
|
changeStatus,
|
|
addQuotationWorker,
|
|
|
|
...fileManager,
|
|
};
|
|
});
|
|
|
|
/**
|
|
* @deprecated Please use payment store instead.
|
|
*/
|
|
export const useQuotationPayment = defineStore('quotation-payment', () => {
|
|
async function getQuotationPayment(params: {
|
|
quotationId?: string;
|
|
debitNoteId?: string;
|
|
debitNoteOnly?: boolean;
|
|
quotationOnly?: boolean;
|
|
}) {
|
|
const res = await api.get<PaginationResult<QuotationPaymentData>>(
|
|
'/payment',
|
|
{ params },
|
|
);
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function updateQuotationPayment(
|
|
paymentId: string,
|
|
payload: PaymentPayload,
|
|
) {
|
|
const res = await api.put<PaymentPayload & { id: string }>(
|
|
`/payment/${paymentId}`,
|
|
payload,
|
|
);
|
|
if (res.status < 400) {
|
|
return res.data;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const fileManager = manageAttachment(api, 'payment');
|
|
|
|
return {
|
|
getQuotationPayment,
|
|
updateQuotationPayment,
|
|
|
|
...fileManager,
|
|
};
|
|
});
|
|
|
|
export * from './types.ts';
|