Compare commits

...

12 Commits

Author SHA1 Message Date
05a6ad2d84 Enhance weekly summary functionality to accept optional date range parameters in CardService, TransactionService, JuniorService, and JuniorController. Update API documentation to reflect new query parameters for start and end dates. 2025-10-28 11:20:49 +03:00
bbeece9e03 git checkout -b ZOD-349-weekly-spending-data-not-displaying-in-the-child-profile-parent-view 2025-10-26 13:14:35 +03:00
596562f6dc Merge pull request #48 from HamzaSha1/feat/neoleap-integration
Feat/neoleap integration
2025-10-21 14:56:38 +03:00
10de8f69c9 Merge pull request #47 from HamzaSha1/ZOD-341-junior-a-child-can-edit-their-email-to-an-existing-email-causing-multiple-child-accounts-to-share-the-same-login
Remove duplicate email cleanup logic and add unique constraint to use…
2025-10-21 14:15:03 +03:00
8a6b1cc900 Remove duplicate email cleanup logic and add unique constraint to user email 2025-10-21 14:10:14 +03:00
d16ae66252 Merge pull request #46 from HamzaSha1/ZOD-341-junior-a-child-can-edit-their-email-to-an-existing-email-causing-multiple-child-accounts-to-share-the-same-login
ZOD-341-Add unique constraint to user email and clean up duplicates
2025-10-21 10:51:12 +03:00
e966f95463 ZOD-341-Add unique constraint to user email and clean up duplicates 2025-10-21 10:49:43 +03:00
2714255dd1 Merge pull request #45 from HamzaSha1/ZOD-341-junior-a-child-can-edit-their-email-to-an-existing-email-causing-multiple-child-accounts-to-share-the-same-login
ZOD-341 Add email uniqueness validation to prevent duplicate emails
2025-10-20 14:31:11 +03:00
39a0b131b8 Merge pull request #44 from HamzaSha1/ZOD-341-junior-a-child-can-edit-their-email-to-an-existing-email-causing-multiple-child-accounts-to-share-the-same-login
Zod 341 junior a child can edit their email to an existing email causing multiple child accounts to share the same login
2025-10-20 14:27:40 +03:00
7bfc14f0d9 Merge pull request #42 from HamzaSha1/ZOD-204-view-spending-from-child-login
ZOD-204-view-spending-from-child-login
2025-10-19 15:44:16 +03:00
f3282a680b Merge pull request #40 from HamzaSha1/ZOD-339-child-profile-gender-update-is-not-reflected-after-editing
Zod 339 child profile gender update is not reflected after editing
2025-10-19 11:02:40 +03:00
d70ab09960 Merge pull request #38 from HamzaSha1/ZOD-333-junior-incorrect-relationship-label-displayed-as-child-instead-of-daughter-or-son-in-child-confirmation-details-after-the-scan-the-qr-code
Zod 333 junior incorrect relationship label displayed as child instead of daughter or son in child confirmation details after the scan the qr code
2025-10-19 09:58:57 +03:00
8 changed files with 47 additions and 12 deletions

View File

@ -163,8 +163,8 @@ export class CardService {
return finalAmount.toNumber();
}
getWeeklySummary(juniorId: string) {
return this.transactionService.getWeeklySummary(juniorId);
getWeeklySummary(juniorId: string, startDate?: Date, endDate?: Date) {
return this.transactionService.getWeeklySummary(juniorId, startDate, endDate);
}
fundIban(iban: string, amount: number) {

View File

@ -84,15 +84,28 @@ export class TransactionService {
return existingTransaction;
}
async getWeeklySummary(juniorId: string) {
const startOfWeek = moment().startOf('week').toDate();
const endOfWeek = moment().endOf('week').toDate();
async getWeeklySummary(juniorId: string, startDate?: Date, endDate?: Date) {
let startOfWeek: Date;
let endOfWeek: Date;
if (startDate && endDate) {
startOfWeek = startDate;
endOfWeek = endDate;
} else {
const now = moment();
const dayOfWeek = now.day();
startOfWeek = moment().subtract(dayOfWeek, 'days').startOf('day').toDate();
endOfWeek = moment().add(6 - dayOfWeek, 'days').endOf('day').toDate();
}
const transactions = await this.transactionRepository.getTransactionsForCardWithinDateRange(
juniorId,
startOfWeek,
endOfWeek,
);
const summary = {
startOfWeek: startOfWeek,
endOfWeek: endOfWeek,

View File

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddUniqueConstraintToUserEmail1761032305682 implements MigrationInterface {
name = 'AddUniqueConstraintToUserEmail1761032305682'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" ADD CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email")`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" DROP CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3"`);
}
}

View File

@ -5,3 +5,4 @@ export * from './1757349525708-create-money-requests-table';
export * from './1757433339849-add-reservation-amount-to-account-entity';
export * from './1757915357218-add-deleted-at-column-to-junior';
export * from './1760869651296-AddMerchantInfoToTransactions';
export * from './1761032305682-AddUniqueConstraintToUserEmail';

View File

@ -151,11 +151,17 @@ export class JuniorController {
@UseGuards(RolesGuard)
@AllowedRoles(Roles.GUARDIAN)
@ApiDataResponse(WeeklySummaryResponseDto)
@ApiQuery({ name: 'startUtc', required: false, type: String, example: '2025-10-20T00:00:00.000Z', description: 'Start date (defaults to start of current week)' })
@ApiQuery({ name: 'endUtc', required: false, type: String, example: '2025-10-26T23:59:59.999Z', description: 'End date (defaults to end of current week)' })
async getWeeklySummary(
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
@AuthenticatedUser() user: IJwtPayload,
@Query('startUtc') startUtc?: string,
@Query('endUtc') endUtc?: string,
) {
const summary = await this.juniorService.getWeeklySummary(juniorId, user.sub);
const startDate = startUtc ? new Date(startUtc) : undefined;
const endDate = endUtc ? new Date(endUtc) : undefined;
const summary = await this.juniorService.getWeeklySummary(juniorId, user.sub, startDate, endDate);
return ResponseFactory.data(summary);
}

View File

@ -212,8 +212,8 @@ export class JuniorService {
this.logger.log(`Junior ${juniorId} deleted successfully`);
}
getWeeklySummary(juniorId: string, guardianId: string) {
const doesBelong = this.doesJuniorBelongToGuardian(guardianId, juniorId);
async getWeeklySummary(juniorId: string, guardianId: string, startDate?: Date, endDate?: Date) {
const doesBelong = await this.doesJuniorBelongToGuardian(guardianId, juniorId);
if (!doesBelong) {
this.logger.error(`Junior ${juniorId} does not belong to guardian ${guardianId}`);
@ -221,7 +221,7 @@ export class JuniorService {
}
this.logger.log(`Getting weekly summary for junior ${juniorId}`);
return this.cardService.getWeeklySummary(juniorId);
return this.cardService.getWeeklySummary(juniorId, startDate, endDate);
}
async getJuniorHome(juniorId: string, userId: string, size: number): Promise<JuniorHomeResponseDto> {

View File

@ -28,7 +28,7 @@ export class User extends BaseEntity {
@Column('varchar', { length: 255, name: 'last_name', nullable: false })
lastName!: string;
@Column('varchar', { length: 255, name: 'email', nullable: true })
@Column('varchar', { length: 255, name: 'email', nullable: true, unique: true })
email!: string;
@Column('varchar', { length: 255, name: 'phone_number', nullable: true })

View File

@ -222,7 +222,7 @@ export class UserService {
}
async updateUserEmail(userId: string, email: string) {
const userWithEmail = await this.findUser({ email, isEmailVerified: true });
const userWithEmail = await this.findUser({ email });
if (userWithEmail) {
if (userWithEmail.id === userId) {