This commit is contained in:
@@ -51,6 +51,18 @@ export class AdminController {
|
|||||||
return this.adminService.getDashboardCounts();
|
return this.adminService.getDashboardCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('admin/home/stats')
|
||||||
|
@ApiOperation({ summary: 'Get home page stats for admin panel' })
|
||||||
|
getHomeStats() {
|
||||||
|
return this.adminService.getHomeStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('admin/home/weekly-orders')
|
||||||
|
@ApiOperation({ summary: 'Get weekly order counts for admin home page chart' })
|
||||||
|
getWeeklyOrders() {
|
||||||
|
return this.adminService.getWeeklyOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Patch('admin/admins/:adminId')
|
@Patch('admin/admins/:adminId')
|
||||||
@Permissions(PermissionEnum.MANAGE_ADMINS)
|
@Permissions(PermissionEnum.MANAGE_ADMINS)
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ import { RoleRepository } from 'src/modules/roles/respository/role.repository';
|
|||||||
import { PermissionEnum } from 'src/common/enums/permission.enum';
|
import { PermissionEnum } from 'src/common/enums/permission.enum';
|
||||||
import { Request } from 'src/modules/request/entities/request.entity';
|
import { Request } from 'src/modules/request/entities/request.entity';
|
||||||
import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
||||||
|
import { InvoiceConfirmStatusEnum } from 'src/modules/invoice/enum/invoice-confirm-status.enum';
|
||||||
import { Order } from 'src/modules/order/entities/order.entity';
|
import { Order } from 'src/modules/order/entities/order.entity';
|
||||||
|
import { OrderStatusEnum } from 'src/modules/order/interface/order.interface';
|
||||||
import { Payment } from 'src/modules/payment/entities/payment.entity';
|
import { Payment } from 'src/modules/payment/entities/payment.entity';
|
||||||
|
import { User } from 'src/modules/user/entities/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdminService {
|
export class AdminService {
|
||||||
@@ -172,4 +175,73 @@ export class AdminService {
|
|||||||
paymentsCount,
|
paymentsCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getWeeklyOrders(weeksCount = 8) {
|
||||||
|
const knex = this.em.getConnection().getKnex();
|
||||||
|
const startDate = this.getWeekStartMonday(new Date());
|
||||||
|
startDate.setDate(startDate.getDate() - (weeksCount - 1) * 7);
|
||||||
|
|
||||||
|
const rows = (await knex('orders')
|
||||||
|
.select(knex.raw("date_trunc('week', created_at) as week_start"))
|
||||||
|
.count('* as count')
|
||||||
|
.whereNull('deleted_at')
|
||||||
|
.where('created_at', '>=', startDate)
|
||||||
|
.groupBy('week_start')
|
||||||
|
.orderBy('week_start', 'asc')) as unknown as Array<{ week_start: Date; count: string }>;
|
||||||
|
|
||||||
|
const countByWeek = new Map<string, number>();
|
||||||
|
for (const row of rows) {
|
||||||
|
const weekStart = this.getWeekStartMonday(new Date(row.week_start));
|
||||||
|
countByWeek.set(weekStart.toISOString(), Number(row.count));
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: Array<{ weekStart: string; count: number }> = [];
|
||||||
|
const cursor = new Date(startDate);
|
||||||
|
|
||||||
|
for (let i = 0; i < weeksCount; i++) {
|
||||||
|
const weekStart = this.getWeekStartMonday(cursor);
|
||||||
|
result.push({
|
||||||
|
weekStart: weekStart.toISOString(),
|
||||||
|
count: countByWeek.get(weekStart.toISOString()) ?? 0,
|
||||||
|
});
|
||||||
|
cursor.setDate(cursor.getDate() + 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getWeekStartMonday(date: Date): Date {
|
||||||
|
const d = new Date(date);
|
||||||
|
d.setHours(0, 0, 0, 0);
|
||||||
|
const day = d.getDay();
|
||||||
|
const diff = day === 0 ? -6 : 1 - day;
|
||||||
|
d.setDate(d.getDate() + diff);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getHomeStats() {
|
||||||
|
const [
|
||||||
|
requestsCount,
|
||||||
|
unconfirmedInvoicesCount,
|
||||||
|
inProgressOrdersCount,
|
||||||
|
completedOrdersCount,
|
||||||
|
customersCount,
|
||||||
|
] = await Promise.all([
|
||||||
|
this.em.count(Request),
|
||||||
|
this.em.count(Invoice, { confirmStatus: InvoiceConfirmStatusEnum.PENDING }),
|
||||||
|
this.em.count(Order, {
|
||||||
|
status: { $nin: [OrderStatusEnum.FINISHED, OrderStatusEnum.CANCELED] },
|
||||||
|
}),
|
||||||
|
this.em.count(Order, { status: OrderStatusEnum.FINISHED }),
|
||||||
|
this.em.count(User),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
requestsCount,
|
||||||
|
unconfirmedInvoicesCount,
|
||||||
|
inProgressOrdersCount,
|
||||||
|
completedOrdersCount,
|
||||||
|
customersCount,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Collection, Entity, ManyToOne, OptionalProps, Property, OneToMany, Opt, Index } from '@mikro-orm/core';
|
import { Entity, ManyToOne, OptionalProps, Property, OneToOne, Opt, Index } from '@mikro-orm/core';
|
||||||
import { Product } from 'src/modules/product/entities/product.entity';
|
import { Product } from 'src/modules/product/entities/product.entity';
|
||||||
import { BaseEntity } from 'src/common/entities/base.entity';
|
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||||
import { Invoice } from './invoice.entity';
|
import { Invoice } from './invoice.entity';
|
||||||
@@ -16,8 +16,8 @@ export class InvoiceItem extends BaseEntity {
|
|||||||
@ManyToOne(() => Product)
|
@ManyToOne(() => Product)
|
||||||
product!: Product;
|
product!: Product;
|
||||||
|
|
||||||
@OneToMany(() => Order, order => order.invoiceItem)
|
@OneToOne(() => Order, order => order.invoiceItem, { mappedBy: 'invoiceItem' })
|
||||||
orders = new Collection<Order>(this);
|
order?: Order;
|
||||||
|
|
||||||
|
|
||||||
@Property({ type: 'int' })
|
@Property({ type: 'int' })
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { OrderDesigner } from './order-designer.entity';
|
|||||||
export class Order extends BaseEntity {
|
export class Order extends BaseEntity {
|
||||||
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'orderNumber'
|
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'orderNumber'
|
||||||
|
|
||||||
@ManyToOne(() => InvoiceItem, { nullable: true })
|
@OneToOne(() => InvoiceItem, (invoiceItem) => invoiceItem.order, { owner: true, nullable: true })
|
||||||
invoiceItem?: InvoiceItem
|
invoiceItem?: InvoiceItem
|
||||||
|
|
||||||
@ManyToOne(() => Product, { nullable: true })
|
@ManyToOne(() => Product, { nullable: true })
|
||||||
|
|||||||
Reference in New Issue
Block a user