async searchMySalesStatistics(
userId: string,
option: SearchTrainerSaleManagementDTO
) {
return await this.prismaService.$transaction(async (tx) => {
const user = await tx.user.findUnique({
include: {
trainerProfile: true,
},
where: { id: userId },
});
if (!user || !user.trainerProfile || user.type !== UserType.TRAINER)
throw new BadRequestException('회원 정보가 존재하지 않습니다.');
const { timeRangeUnit, year, month } = option;
if (timeRangeUnit === TimeRangeUnit.YEAR) {
const list = await tx.trainerSaleManagement.findMany({
where: {
trainerId: user.trainerProfile.id,
createdAt: {
gte: new Date(`${year}-01-01`),
lt: new Date(`${year}-12-31`),
},
},
orderBy: { createdAt: 'asc' },
});
const monthlyList = Array.from({ length: 12 }, (_, i) => {
const month = (i + 1).toString().padStart(2, '0');
const amount = list
.filter((item) => item.createdAt.getMonth() + 1 === i + 1)
.reduce((acc, cur) => acc + cur.amount, 0);
return { amount, month, year };
});
return monthlyList;
} else if (timeRangeUnit === TimeRangeUnit.MONTH) {
const list = await tx.trainerSaleManagement.findMany({
where: {
trainerId: user.trainerProfile.id,
createdAt: {
gte: new Date(`${year}-${month}-01`),
lt: new Date(`${year}-${month}-31`),
},
},
orderBy: { createdAt: 'asc' },
});
const days = new Date(+year, +month, 0).getDate();
const dailyList = Array.from({ length: days }, (_, i) => {
const day = (i + 1).toString().padStart(2, '0');
const amount = list
.filter((item) => item.createdAt.getDate() === i + 1)
.reduce((acc, cur) => acc + cur.amount, 0);
return { amount, day, month, year };
});
return dailyList;
} else if (timeRangeUnit === TimeRangeUnit.WEEK) {
const today = dayjs().subtract(7, 'day');
const _year = today.year().toString();
const _month = today.month() + 1;
const firstDayOfMonth = dayjs(`${_year}-${_month}-01`);
const lastDayOfMonth = firstDayOfMonth.endOf('month');
const firstDayOfWeek = firstDayOfMonth.day();
const lastDayOfWeek = lastDayOfMonth.day();
const isSameWeek =
firstDayOfWeek <= lastDayOfWeek ||
lastDayOfWeek - firstDayOfWeek <= 3;
let startDate, endDate;
if (isSameWeek) {
startDate = firstDayOfMonth;
endDate = lastDayOfMonth;
} else {
startDate = firstDayOfMonth;
endDate = dayjs(new Date(Number(_year), Number(_month), 1)).subtract(
1,
'day'
);
}
const list = await tx.trainerSaleManagement.findMany({
where: {
trainerId: user.trainerProfile.id,
createdAt: {
gte: startDate.toDate(),
lt: endDate.toDate(),
},
},
orderBy: { createdAt: 'asc' },
});
const weeklyList = Array.from({ length: 7 }, (_, i) => {
const dayOfWeek = i;
const items = list.filter(
(item) => dayjs(item.createdAt).day() === i
);
const amount = items.reduce((acc, cur) => acc + cur.amount, 0);
let date;
let _month;
if (items.length > 0) {
const firstItem = items[0];
const firstItemDay = dayjs(firstItem.createdAt);
const diff = (dayOfWeek - firstItemDay.day() + 7) % 7;
date = firstItemDay.subtract(diff, 'day');
_month = date.month() + 1;
} else {
const targetDayOfWeek = (today.day() + 7 - dayOfWeek) % 7;
date = today.subtract(targetDayOfWeek, 'day');
_month = date.month() + 1;
}
return {
amount,
dayOfWeek: DayOfWeekWithNumber[dayOfWeek],
year: date.year().toString(),
month: _month.toString().padStart(2, '0'),
day: `${date.date()}`,
};
});
weeklyList.sort((a, b) => {
const dateA = dayjs(`${a.year}-${a.month}-${a.day}`);
const dateB = dayjs(`${b.year}-${b.month}-${b.day}`);
return dateA.valueOf() - dateB.valueOf();
});
return weeklyList;
}
});
}