feature/research-di #1
@ -41,6 +41,7 @@ export async function fetchCardData() {
|
|||||||
const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
|
const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
|
||||||
const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;
|
const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;
|
||||||
const invoiceStatusPromise = sql`SELECT
|
const invoiceStatusPromise = sql`SELECT
|
||||||
|
id,
|
||||||
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
|
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
|
||||||
SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
|
SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
|
||||||
FROM invoices`;
|
FROM invoices`;
|
||||||
@ -53,7 +54,7 @@ export async function fetchCardData() {
|
|||||||
|
|
||||||
const invoices = data[0] as postgres.RowList<Invoice[]>
|
const invoices = data[0] as postgres.RowList<Invoice[]>
|
||||||
const customres = data[1] as postgres.RowList<Customer[]>
|
const customres = data[1] as postgres.RowList<Customer[]>
|
||||||
const invoiceStatus = data[2] as postgres.RowList<({paid: string, pending: string})[]>
|
const invoiceStatus = data[2] as postgres.RowList<({id: string; paid: string, pending: string})[]>
|
||||||
const numberOfInvoices = Number(invoices.count ?? '0');
|
const numberOfInvoices = Number(invoices.count ?? '0');
|
||||||
const numberOfCustomers = Number(customres.count ?? '0');
|
const numberOfCustomers = Number(customres.count ?? '0');
|
||||||
const totalPaidInvoices = formatCurrency(Number(invoiceStatus.at(0)?.paid ?? '0'));
|
const totalPaidInvoices = formatCurrency(Number(invoiceStatus.at(0)?.paid ?? '0'));
|
||||||
|
@ -4,7 +4,7 @@ import fetchCustomerInvoicesUsecase from "@/feature/customer-invoice/domain/usec
|
|||||||
import CustomerDbRepo from "@/feature/customer/data/repo/customer-db-repo";
|
import CustomerDbRepo from "@/feature/customer/data/repo/customer-db-repo";
|
||||||
import { DependencyContainer } from "tsyringe";
|
import { DependencyContainer } from "tsyringe";
|
||||||
|
|
||||||
export default function getCustomerInvoiceInvoiceDi(): DependencyContainer {
|
export default function getCustomerInvoiceDi(): DependencyContainer {
|
||||||
const customerInvoiceDi = di.createChildContainer()
|
const customerInvoiceDi = di.createChildContainer()
|
||||||
|
|
||||||
customerInvoiceDi.register(fetchCustomerInvoicesUsecase.name, {
|
customerInvoiceDi.register(fetchCustomerInvoicesUsecase.name, {
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
import di from "@/bootstrap/di/init-di";
|
import di from "@/bootstrap/di/init-di";
|
||||||
import invoiceDbRepo from "@/feature/invoice/data/repo/invoice-db-repo";
|
import invoiceDbRepo from "@/feature/invoice/data/repo/invoice-db-repo";
|
||||||
import { invoiceRepoKey } from "@/feature/invoice/domain/i-repo/invoice-repo";
|
import { invoiceRepoKey } from "@/feature/invoice/domain/i-repo/invoice-repo";
|
||||||
import fetchAllInvoicesAmountUsecase from "@/feature/invoice/domain/usecase/fetch-all-invoices-amount-usecase";
|
|
||||||
import { DependencyContainer } from "tsyringe";
|
import { DependencyContainer } from "tsyringe";
|
||||||
|
|
||||||
export default function getInvoiceDi(): DependencyContainer {
|
export default function getInvoiceDi(): DependencyContainer {
|
||||||
const invoiceDi = di.createChildContainer()
|
const invoiceDi = di.createChildContainer()
|
||||||
|
|
||||||
invoiceDi.register(fetchAllInvoicesAmountUsecase.name, {
|
|
||||||
useValue: fetchAllInvoicesAmountUsecase
|
|
||||||
})
|
|
||||||
|
|
||||||
invoiceDi.register(invoiceRepoKey, invoiceDbRepo)
|
invoiceDi.register(invoiceRepoKey, invoiceDbRepo)
|
||||||
return invoiceDi
|
return invoiceDi
|
||||||
}
|
}
|
@ -1,11 +1,31 @@
|
|||||||
|
import { formatCurrency } from "@/app/lib/utils";
|
||||||
import { sql } from "@/bootstrap/db/db";
|
import { sql } from "@/bootstrap/db/db";
|
||||||
import InvoiceRepo from "@/feature/invoice/domain/i-repo/invoice-repo";
|
import InvoiceRepo from "@/feature/invoice/domain/i-repo/invoice-repo";
|
||||||
|
import InvoiceStatusSummary from "@/feature/invoice/domain/value-object/invoice-status";
|
||||||
import postgres from "postgres";
|
import postgres from "postgres";
|
||||||
|
|
||||||
|
type InvoiceSummaryDbResponse = {paid: string, pending: string}
|
||||||
export default class InvoiceDbRepo implements InvoiceRepo {
|
export default class InvoiceDbRepo implements InvoiceRepo {
|
||||||
async fetchAllInvoicesAmount(): Promise<number> {
|
async fetchAllInvoicesAmount(): Promise<number> {
|
||||||
const data = await sql`SELECT COUNT(*) FROM invoices` as postgres.RowList<unknown[]>;
|
const data = await sql`SELECT COUNT(*) FROM invoices` as postgres.RowList<unknown[]>;
|
||||||
|
|
||||||
return data.count ?? 0
|
return data.count ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary> {
|
||||||
|
const invoiceStatusPromise = await sql`SELECT
|
||||||
|
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
|
||||||
|
SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
|
||||||
|
FROM invoices` as postgres.RowList<InvoiceSummaryDbResponse[]>;
|
||||||
|
|
||||||
|
return this.invoiceSummaryDto(invoiceStatusPromise.at(0))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private invoiceSummaryDto(dbResponse?: InvoiceSummaryDbResponse): InvoiceStatusSummary {
|
||||||
|
return new InvoiceStatusSummary({
|
||||||
|
paid: formatCurrency(Number(dbResponse?.paid ?? '0')),
|
||||||
|
pending: formatCurrency(Number(dbResponse?.pending ?? '0'))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
|
import InvoiceStatusSummary from "@/feature/invoice/domain/value-object/invoice-status"
|
||||||
|
|
||||||
export default interface InvoiceRepo {
|
export default interface InvoiceRepo {
|
||||||
fetchAllInvoicesAmount(): Promise<number>
|
fetchAllInvoicesAmount(): Promise<number>
|
||||||
|
fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const invoiceRepoKey = "invoiceRepoKey"
|
export const invoiceRepoKey = "invoiceRepoKey"
|
@ -0,0 +1,9 @@
|
|||||||
|
import serverDi from "@/feature/common/server-di";
|
||||||
|
import InvoiceRepo, { invoiceRepoKey } from "@/feature/invoice/domain/i-repo/invoice-repo";
|
||||||
|
import InvoiceStatusSummary from "@/feature/invoice/domain/value-object/invoice-status";
|
||||||
|
import { invoiceModuleKey } from "@/feature/invoice/invoice-module-key";
|
||||||
|
|
||||||
|
export default function fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary> {
|
||||||
|
const repo = serverDi(invoiceModuleKey).resolve<InvoiceRepo>(invoiceRepoKey)
|
||||||
|
return repo.fetchInvoicesStatusSummary()
|
||||||
|
}
|
12
src/feature/invoice/domain/value-object/invoice-status.ts
Normal file
12
src/feature/invoice/domain/value-object/invoice-status.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export default class InvoiceStatusSummary {
|
||||||
|
paid: string;
|
||||||
|
pending: string;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
paid,
|
||||||
|
pending
|
||||||
|
}: InvoiceStatusSummary) {
|
||||||
|
this.paid = paid;
|
||||||
|
this.pending = pending;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user