From c750ed5feec01cae125935f1469b192635be4c7d Mon Sep 17 00:00:00 2001 From: Thanaphon Frappet Date: Fri, 7 Mar 2025 15:54:25 +0700 Subject: [PATCH] feat: show profit --- src/pages/14_report/MainPage.vue | 143 ++++++++++++++++++++++++++++++- src/pages/14_report/constants.ts | 92 ++++++++++++++++++++ src/stores/report/index.ts | 29 +++++++ src/stores/report/types.ts | 13 +++ 4 files changed, 276 insertions(+), 1 deletion(-) diff --git a/src/pages/14_report/MainPage.vue b/src/pages/14_report/MainPage.vue index cdd287d2..2ee6b411 100644 --- a/src/pages/14_report/MainPage.vue +++ b/src/pages/14_report/MainPage.vue @@ -1,6 +1,6 @@ + + diff --git a/src/pages/14_report/constants.ts b/src/pages/14_report/constants.ts index 6a37b9f5..2ff3a22c 100644 --- a/src/pages/14_report/constants.ts +++ b/src/pages/14_report/constants.ts @@ -14,6 +14,7 @@ export enum ViewMode { Receipt = 'receipt', Product = 'product', Sale = 'sale', + Profit = 'profit', } type ColumnsSale = { @@ -28,6 +29,25 @@ type ColumnsBySale = ColumnsSale & { gender?: string; }; +type ColumnsProfix = { + title: string; + amount: number; +}; + +type ColumnsProfixByMonth = { + month: string; + netProfit: number; + expenses: number; + income: number; +}; + +type ColumnsProfixByYear = Omit & { + year: string; + netProfit: number; + expenses: number; + income: number; +}; + export const colReportQuotation = [ { name: 'code', @@ -169,9 +189,81 @@ export const colReportBySale = [ }, ] as const satisfies QTableProps['columns']; +export const colProfit = [ + { + name: 'title', + align: 'left', + label: '', + field: (data: ColumnsProfix) => data.title, + }, + { + name: 'amount', + align: 'left', + label: '', + field: (data: ColumnsProfix) => formatNumberDecimal(data.amount, 2), + }, +] as const satisfies QTableProps['columns']; + +export const colProfitByMoth = [ + { + name: '#title', + align: 'left', + label: 'report.profit.month', + field: '', + }, + { + name: 'netProfit', + align: 'left', + label: 'report.profit.netProfit', + field: (data: ColumnsProfixByMonth) => + formatNumberDecimal(data.netProfit, 2), + }, + { + name: 'expenses', + align: 'left', + label: 'report.profit.expenses', + field: (data: ColumnsProfixByMonth) => + formatNumberDecimal(data.expenses, 2), + }, + { + name: 'income', + align: 'left', + label: 'report.profit.income', + field: (data: ColumnsProfixByMonth) => formatNumberDecimal(data.income, 2), + }, +] as const satisfies QTableProps['columns']; + +export const colProfitByYear = [ + { + name: 'title', + align: 'left', + label: 'report.profit.year', + field: (data: ColumnsProfixByYear) => data.year, + }, + { + name: 'netProfit', + align: 'left', + label: 'report.profit.netProfit', + field: (data: ColumnsProfixByYear) => + formatNumberDecimal(data.netProfit, 2), + }, + { + name: 'expenses', + align: 'left', + label: 'report.profit.expenses', + field: (data: ColumnsProfixByYear) => formatNumberDecimal(data.expenses, 2), + }, + { + name: 'income', + align: 'left', + label: 'report.profit.income', + field: (data: ColumnsProfixByYear) => formatNumberDecimal(data.income, 2), + }, +] as const satisfies QTableProps['columns']; export const pageTabs = [ { label: 'Document', value: ViewMode.Document, by: ['user'] }, { label: 'Invoice', value: ViewMode.Invoice, by: ['user'] }, { label: 'Product', value: ViewMode.Product, by: ['user'] }, { label: 'Sale', value: ViewMode.Sale, by: ['admin'] }, + { label: 'Profit', value: ViewMode.Profit, by: ['admin'] }, ]; diff --git a/src/stores/report/index.ts b/src/stores/report/index.ts index 7bddfdf9..f23d62c6 100644 --- a/src/stores/report/index.ts +++ b/src/stores/report/index.ts @@ -7,6 +7,7 @@ import { ReportProduct, ReportQuotation, ReportSale, + ReportProfit, } from './types'; import { baseUrl } from '../utils'; import { getToken } from 'src/services/keycloak'; @@ -120,6 +121,31 @@ export async function getReportPayment(params?: { return null; } +export async function getReportProfit(params?: { + years?: number; + startDate?: string | Date; + endDate?: string | Date; +}) { + let opts = params || {}; + + if (params?.years) { + const currentYear = new Date().getFullYear(); + opts.startDate = new Date(currentYear - params.years, 0, 1); // ✅ 1 ม.ค. ของปีที่ต้องการ + opts.endDate = new Date(currentYear, 11, 31); // ✅ 31 ธ.ค. ของปีปัจจุบัน + } + + const res = await api.get(`/${ENDPOINT}/profit`, { + params: { + startDate: opts.startDate, + endDate: opts.endDate, + }, + }); + if (res.status < 400) { + return res.data; + } + return null; +} + export const useReportStore = defineStore('report-store', () => { const dataReportQuotation = ref([]); const dataReportInvoice = ref([]); @@ -127,6 +153,7 @@ export const useReportStore = defineStore('report-store', () => { const dataReportSale = ref(); const dataReportProduct = ref([]); const dataReportPayment = ref([]); + const dataReportProfit = ref(); return { dataReportQuotation, @@ -135,6 +162,7 @@ export const useReportStore = defineStore('report-store', () => { dataReportSale, dataReportProduct, dataReportPayment, + dataReportProfit, downloadReportQuotation, getReportQuotation, @@ -147,5 +175,6 @@ export const useReportStore = defineStore('report-store', () => { downloadReportProduct, getReportProduct, getReportPayment, + getReportProfit, }; }); diff --git a/src/stores/report/types.ts b/src/stores/report/types.ts index ab46b212..522c9ce3 100644 --- a/src/stores/report/types.ts +++ b/src/stores/report/types.ts @@ -50,3 +50,16 @@ export type ReportSale = { bySale: (User & { _count: number })[]; byProductGroup: (Omit & { _count: number })[]; }; + +export type ReportProfit = { + dataset: { + netProfit: number; + expenses: number; + income: number; + year: number; + month: number; + }[]; + netProfit: number; + expenses: number; + income: number; +};