From e43ccfa489184ecce1a6d9f7161b0e7c33244b61 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 01/35] Back cdr : Endpoint to get total of validated payments --- app/modules/cdr/cruds_cdr.py | 46 ++++++++++++++++++++++++++- app/modules/cdr/endpoints_cdr.py | 54 ++++++++++++++++++++++++++++++++ app/modules/cdr/schemas_cdr.py | 4 +++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index ad1de7fa42..46fe3870f5 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -1,7 +1,7 @@ from collections.abc import Sequence from uuid import UUID -from sqlalchemy import delete, func, select, update +from sqlalchemy import delete, select, update, func from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import noload, selectinload @@ -901,6 +901,50 @@ async def delete_payment( ), ) +async def get_payment_products_by_seller( + db: AsyncSession, +): + result = (await db.execute( + select( + models_cdr.Seller.name, + func.sum(models_cdr.ProductVariant.price * models_cdr.Purchase.quantity).label("total_amount") + ) + .join(models_cdr.CdrProduct, models_cdr.Seller.id == models_cdr.CdrProduct.seller_id) + .join(models_cdr.ProductVariant, models_cdr.ProductVariant.product_id == models_cdr.CdrProduct.id) + .join(models_cdr.Purchase, models_cdr.Purchase.product_variant_id == models_cdr.ProductVariant.id) + .where(models_cdr.Purchase.validated == True) + .group_by(models_cdr.Seller.id) + ) + ) + + return [ + schemas_cdr.TotalPurchaseValidatedBySeller( + total_validated=row.total_amount, + name=row.name, + ) + for row in result.all() + ] + +async def get_total_payment_types( + db: AsyncSession, +): + result = (await db.execute( + select( + models_cdr.Payment.payment_type, + func.sum(models_cdr.Payment.total).label("total") + ) + .group_by(models_cdr.Payment.payment_type) + ) + ) + + return [ + schemas_cdr.PaymentBase( + total=row.total, + payment_type=row.payment_type, + ) + for row in result.all() + ] + def create_action( db: AsyncSession, diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 874ead8657..d7bc32e98a 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -2753,6 +2753,60 @@ async def delete_curriculum_membership( ) +@module.router.get( + "/cdr/users/total_payments_by_seller/", + response_model=list[schemas_cdr.PaymentComplete], + status_code=200, +) +async def get_total_payments( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.manage_cdr]), + ), +): + """ + Get a user's payments. + + **User must a CDR Admin to use this endpoint** + """ + if not ( + await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db) + ): + raise HTTPException( + status_code=403, + detail="You're not allowed to see this.", + ) + return await cruds_cdr.get_payment_products_by_sell( + db=db, + ) + +@module.router.get( + "/cdr/users/total_payments/", + response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], + status_code=200, +) +async def get_total_payments( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.manage_cdr]), + ), +): + """ + Get a user's payments. + + **User must a CDR Admin to use this endpoint** + """ + if not ( + await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db) + ): + raise HTTPException( + status_code=403, + detail="You're not allowed to see this.", + ) + return await cruds_cdr.get_total_payment_types( + db=db, + ) + @module.router.get( "/cdr/users/{user_id}/payments/", response_model=list[schemas_cdr.PaymentComplete], diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index 381c9031df..8a99f50517 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -341,3 +341,7 @@ class BatchValidation(BaseModel): user_emails: list[str] product_variant_id: UUID validated: bool + +class TotalPurchaseValidatedBySeller(BaseModel): + name : str + total_validated: int \ No newline at end of file From c88b8001935300696a02c1f79835b88e380613e4 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 02/35] Adding the year of cdr as a param in the endpoint --- app/modules/cdr/cruds_cdr.py | 9 ++++++--- app/modules/cdr/endpoints_cdr.py | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 46fe3870f5..4eb17ad05c 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -903,7 +903,8 @@ async def delete_payment( async def get_payment_products_by_seller( db: AsyncSession, -): + cdr_year: int, +) -> list[schemas_cdr.TotalPurchaseValidatedBySeller]: result = (await db.execute( select( models_cdr.Seller.name, @@ -912,7 +913,7 @@ async def get_payment_products_by_seller( .join(models_cdr.CdrProduct, models_cdr.Seller.id == models_cdr.CdrProduct.seller_id) .join(models_cdr.ProductVariant, models_cdr.ProductVariant.product_id == models_cdr.CdrProduct.id) .join(models_cdr.Purchase, models_cdr.Purchase.product_variant_id == models_cdr.ProductVariant.id) - .where(models_cdr.Purchase.validated == True) + .where(models_cdr.Purchase.validated == True and models_cdr.ProductVariant.year == cdr_year) .group_by(models_cdr.Seller.id) ) ) @@ -927,12 +928,14 @@ async def get_payment_products_by_seller( async def get_total_payment_types( db: AsyncSession, -): + cdr_year: int, +) -> list[schemas_cdr.PaymentBase]: result = (await db.execute( select( models_cdr.Payment.payment_type, func.sum(models_cdr.Payment.total).label("total") ) + .where(models_cdr.Payment.year == cdr_year) .group_by(models_cdr.Payment.payment_type) ) ) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index d7bc32e98a..962e9efbac 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -2763,6 +2763,7 @@ async def get_total_payments( user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ Get a user's payments. @@ -2778,6 +2779,7 @@ async def get_total_payments( ) return await cruds_cdr.get_payment_products_by_sell( db=db, + cdr_year=cdr_year.year ) @module.router.get( @@ -2790,6 +2792,7 @@ async def get_total_payments( user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ Get a user's payments. @@ -2805,6 +2808,7 @@ async def get_total_payments( ) return await cruds_cdr.get_total_payment_types( db=db, + cdr_year=cdr_year.year ) @module.router.get( From 0831dfd3d714742def97be351c70a608deae9443 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 03/35] Lint and ruff format --- app/modules/cdr/cruds_cdr.py | 62 +++++++++++++++++++------------- app/modules/cdr/endpoints_cdr.py | 22 ++++++------ app/modules/cdr/schemas_cdr.py | 5 +-- 3 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 4eb17ad05c..eb5312f52b 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -1,7 +1,7 @@ from collections.abc import Sequence from uuid import UUID -from sqlalchemy import delete, select, update, func +from sqlalchemy import delete, func, select, update from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import noload, selectinload @@ -901,23 +901,37 @@ async def delete_payment( ), ) + async def get_payment_products_by_seller( db: AsyncSession, cdr_year: int, ) -> list[schemas_cdr.TotalPurchaseValidatedBySeller]: - result = (await db.execute( - select( - models_cdr.Seller.name, - func.sum(models_cdr.ProductVariant.price * models_cdr.Purchase.quantity).label("total_amount") - ) - .join(models_cdr.CdrProduct, models_cdr.Seller.id == models_cdr.CdrProduct.seller_id) - .join(models_cdr.ProductVariant, models_cdr.ProductVariant.product_id == models_cdr.CdrProduct.id) - .join(models_cdr.Purchase, models_cdr.Purchase.product_variant_id == models_cdr.ProductVariant.id) - .where(models_cdr.Purchase.validated == True and models_cdr.ProductVariant.year == cdr_year) - .group_by(models_cdr.Seller.id) - ) - ) - + result = await db.execute( + select( + models_cdr.Seller.name, + func.sum( + models_cdr.ProductVariant.price * models_cdr.Purchase.quantity, + ).label("total_amount"), + ) + .join( + models_cdr.CdrProduct, + models_cdr.Seller.id == models_cdr.CdrProduct.seller_id, + ) + .join( + models_cdr.ProductVariant, + models_cdr.ProductVariant.product_id == models_cdr.CdrProduct.id, + ) + .join( + models_cdr.Purchase, + models_cdr.Purchase.product_variant_id == models_cdr.ProductVariant.id, + ) + .where( + models_cdr.Purchase.validated + and models_cdr.ProductVariant.year == cdr_year, + ) + .group_by(models_cdr.Seller.id), + ) + return [ schemas_cdr.TotalPurchaseValidatedBySeller( total_validated=row.total_amount, @@ -926,20 +940,20 @@ async def get_payment_products_by_seller( for row in result.all() ] + async def get_total_payment_types( db: AsyncSession, cdr_year: int, ) -> list[schemas_cdr.PaymentBase]: - result = (await db.execute( - select( - models_cdr.Payment.payment_type, - func.sum(models_cdr.Payment.total).label("total") - ) - .where(models_cdr.Payment.year == cdr_year) - .group_by(models_cdr.Payment.payment_type) - ) - ) - + result = await db.execute( + select( + models_cdr.Payment.payment_type, + func.sum(models_cdr.Payment.total).label("total"), + ) + .where(models_cdr.Payment.year == cdr_year) + .group_by(models_cdr.Payment.payment_type), + ) + return [ schemas_cdr.PaymentBase( total=row.total, diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 962e9efbac..e558861fe5 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -2758,7 +2758,7 @@ async def delete_curriculum_membership( response_model=list[schemas_cdr.PaymentComplete], status_code=200, ) -async def get_total_payments( +async def get_total_payments_by_seller( db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), @@ -2766,22 +2766,21 @@ async def get_total_payments( cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ - Get a user's payments. + Get the total of payments done in the CDR by each seller. **User must a CDR Admin to use this endpoint** """ - if not ( - await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db) - ): + if not (await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db)): raise HTTPException( status_code=403, detail="You're not allowed to see this.", ) - return await cruds_cdr.get_payment_products_by_sell( + return await cruds_cdr.get_payment_products_by_seller( db=db, - cdr_year=cdr_year.year + cdr_year=cdr_year.year, ) + @module.router.get( "/cdr/users/total_payments/", response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], @@ -2795,22 +2794,21 @@ async def get_total_payments( cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ - Get a user's payments. + Get the total of payments done in the CDR. **User must a CDR Admin to use this endpoint** """ - if not ( - await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db) - ): + if not (await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db)): raise HTTPException( status_code=403, detail="You're not allowed to see this.", ) return await cruds_cdr.get_total_payment_types( db=db, - cdr_year=cdr_year.year + cdr_year=cdr_year.year, ) + @module.router.get( "/cdr/users/{user_id}/payments/", response_model=list[schemas_cdr.PaymentComplete], diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index 8a99f50517..aa894c47f6 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -342,6 +342,7 @@ class BatchValidation(BaseModel): product_variant_id: UUID validated: bool + class TotalPurchaseValidatedBySeller(BaseModel): - name : str - total_validated: int \ No newline at end of file + name: str + total_validated: int From 2eff11ac5bb9888c5add128567aa1d0494e75cdc Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 04/35] modified: app/modules/cdr/endpoints_cdr.py --- app/modules/cdr/endpoints_cdr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index e558861fe5..0037121cbf 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -2770,7 +2770,7 @@ async def get_total_payments_by_seller( **User must a CDR Admin to use this endpoint** """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db)): + if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): raise HTTPException( status_code=403, detail="You're not allowed to see this.", @@ -2798,7 +2798,7 @@ async def get_total_payments( **User must a CDR Admin to use this endpoint** """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr_cdr, db)): + if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): raise HTTPException( status_code=403, detail="You're not allowed to see this.", From 2d5c39586d50950f50334baaad189a81179ae745 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 05/35] New changes on the endpoint to handle them more easily in Enceladus --- app/modules/cdr/cruds_cdr.py | 20 +++- app/modules/cdr/endpoints_cdr.py | 180 +++++++++++++++++++++---------- app/modules/cdr/schemas_cdr.py | 9 ++ 3 files changed, 151 insertions(+), 58 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index eb5312f52b..21b0d74d2b 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -926,8 +926,8 @@ async def get_payment_products_by_seller( models_cdr.Purchase.product_variant_id == models_cdr.ProductVariant.id, ) .where( - models_cdr.Purchase.validated - and models_cdr.ProductVariant.year == cdr_year, + models_cdr.Purchase.validated, + models_cdr.ProductVariant.year == cdr_year, ) .group_by(models_cdr.Seller.id), ) @@ -963,6 +963,22 @@ async def get_total_payment_types( ] +async def get_total_payment( + db: AsyncSession, + cdr_year: int, +) -> int: + + result = await db.execute( + select( + func.sum(models_cdr.Payment.total).label("total"), + ).where(models_cdr.Payment.year == cdr_year), + ) + try: + return result.all()[0].total / 100 + except IndexError: + return 0 + + def create_action( db: AsyncSession, action: models_cdr.CdrAction, diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 0037121cbf..eb20050337 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -131,6 +131,45 @@ async def get_cdr_users( return list(users.values()) +@module.router.get( + "/cdr/users/problematic_payments/", + response_model=list[schemas_cdr.CdrUserPreview], + status_code=200, +) +async def get_cdr_users_problematic_payments( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.access_cdr]), + ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), +): + """ + Get all users with problematic payments. + + **User must be part of a seller group to use this endpoint** + """ + if not ( + await has_user_permission(user, CdrPermissions.manage_cdr, db) + or await cruds_cdr.get_sellers_by_group_ids( + db=db, + group_ids=[g.id for g in user.groups], + ) + ): + raise HTTPException( + status_code=403, + detail="You must be a seller to use this endpoint.", + ) + users = { + u.user_id: u.__dict__ + for u in await cruds_cdr.get_users_with_problematic_payments( + db=db, cdr_year=cdr_year.year + ) + } + hyperion_error_logger.info(list(users.values())) + + return list(users.values()) + + @module.router.get( "/cdr/users/pending/", response_model=list[schemas_cdr.CdrUserPreview], @@ -191,6 +230,91 @@ async def get_cdr_users_pending_validation( ] +@module.router.get( + "/cdr/users/total_payments_by_seller/", + response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], + status_code=200, +) +async def get_total_payments_by_seller( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.manage_cdr]), + ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), +): + """ + Get the total of payments done in the CDR by each seller. + + **User must a CDR Admin to use this endpoint** + """ + if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): + raise HTTPException( + status_code=403, + detail="You're not allowed to see this.", + ) + return await cruds_cdr.get_payment_products_by_seller( + db=db, + cdr_year=cdr_year.year, + ) + + +@module.router.get( + "/cdr/users/total_payments_per_type/", + response_model=list[schemas_cdr.PaymentBase], + status_code=200, +) +async def get_total_payments_types( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.manage_cdr]), + ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), +): + """ + Get the total of payments done in the CDR. + + **User must a CDR Admin to use this endpoint** + """ + if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): + raise HTTPException( + status_code=403, + detail="You're not allowed to see this.", + ) + return await cruds_cdr.get_total_payment_types( + db=db, + cdr_year=cdr_year.year, + ) + + +@module.router.get( + "/cdr/users/total_payments/", + response_model=int, + status_code=200, +) +async def get_total_payments( + db: AsyncSession = Depends(get_db), + user: models_users.CoreUser = Depends( + is_user_allowed_to([CdrPermissions.manage_cdr]), + ), + cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), +): + """ + Get the total of payments done in the CDR. + + **User must a CDR Admin to use this endpoint** + """ + if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): + raise HTTPException( + status_code=403, + detail="You're not allowed to see this.", + ) + + return await cruds_cdr.get_total_payment( + db=db, + cdr_year=cdr_year.year, + ) + + @module.router.get( "/cdr/users/{user_id}/", response_model=schemas_cdr.CdrUser, @@ -2753,62 +2877,6 @@ async def delete_curriculum_membership( ) -@module.router.get( - "/cdr/users/total_payments_by_seller/", - response_model=list[schemas_cdr.PaymentComplete], - status_code=200, -) -async def get_total_payments_by_seller( - db: AsyncSession = Depends(get_db), - user: models_users.CoreUser = Depends( - is_user_allowed_to([CdrPermissions.manage_cdr]), - ), - cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), -): - """ - Get the total of payments done in the CDR by each seller. - - **User must a CDR Admin to use this endpoint** - """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): - raise HTTPException( - status_code=403, - detail="You're not allowed to see this.", - ) - return await cruds_cdr.get_payment_products_by_seller( - db=db, - cdr_year=cdr_year.year, - ) - - -@module.router.get( - "/cdr/users/total_payments/", - response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], - status_code=200, -) -async def get_total_payments( - db: AsyncSession = Depends(get_db), - user: models_users.CoreUser = Depends( - is_user_allowed_to([CdrPermissions.manage_cdr]), - ), - cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), -): - """ - Get the total of payments done in the CDR. - - **User must a CDR Admin to use this endpoint** - """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): - raise HTTPException( - status_code=403, - detail="You're not allowed to see this.", - ) - return await cruds_cdr.get_total_payment_types( - db=db, - cdr_year=cdr_year.year, - ) - - @module.router.get( "/cdr/users/{user_id}/payments/", response_model=list[schemas_cdr.PaymentComplete], diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index aa894c47f6..75f2557c25 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -346,3 +346,12 @@ class BatchValidation(BaseModel): class TotalPurchaseValidatedBySeller(BaseModel): name: str total_validated: int + + +class UserPaymentStatus(BaseModel): + user_id: str + total_purchased: int + total_paid: int + has_unvalidated_purchase: bool + is_overcharged: bool + is_undercharged: bool From 3f02d2ef8ce1c139dc04658ea4eab4abdc70c738 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 06/35] Lint check --- app/modules/cdr/endpoints_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index eb20050337..0931e8b56f 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -162,7 +162,7 @@ async def get_cdr_users_problematic_payments( users = { u.user_id: u.__dict__ for u in await cruds_cdr.get_users_with_problematic_payments( - db=db, cdr_year=cdr_year.year + db=db, cdr_year=cdr_year.year, ) } hyperion_error_logger.info(list(users.values())) From 587cca5a7998c64c4c5afbcb6d0407fdeec93510 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 07/35] Resolving lint --- app/modules/cdr/endpoints_cdr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 0931e8b56f..8d452e2d49 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -162,7 +162,8 @@ async def get_cdr_users_problematic_payments( users = { u.user_id: u.__dict__ for u in await cruds_cdr.get_users_with_problematic_payments( - db=db, cdr_year=cdr_year.year, + db=db, + cdr_year=cdr_year.year, ) } hyperion_error_logger.info(list(users.values())) From 4fc6fd3a832640bff05bac1428be10636fc84993 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 08/35] resolving mypy --- app/modules/cdr/cruds_cdr.py | 4 ++-- app/modules/cdr/endpoints_cdr.py | 40 -------------------------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 21b0d74d2b..46dd86f6f6 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -966,7 +966,7 @@ async def get_total_payment_types( async def get_total_payment( db: AsyncSession, cdr_year: int, -) -> int: +): result = await db.execute( select( @@ -974,7 +974,7 @@ async def get_total_payment( ).where(models_cdr.Payment.year == cdr_year), ) try: - return result.all()[0].total / 100 + return result.all()[0].total // 100 except IndexError: return 0 diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 8d452e2d49..7f8e33ff0c 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -131,46 +131,6 @@ async def get_cdr_users( return list(users.values()) -@module.router.get( - "/cdr/users/problematic_payments/", - response_model=list[schemas_cdr.CdrUserPreview], - status_code=200, -) -async def get_cdr_users_problematic_payments( - db: AsyncSession = Depends(get_db), - user: models_users.CoreUser = Depends( - is_user_allowed_to([CdrPermissions.access_cdr]), - ), - cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), -): - """ - Get all users with problematic payments. - - **User must be part of a seller group to use this endpoint** - """ - if not ( - await has_user_permission(user, CdrPermissions.manage_cdr, db) - or await cruds_cdr.get_sellers_by_group_ids( - db=db, - group_ids=[g.id for g in user.groups], - ) - ): - raise HTTPException( - status_code=403, - detail="You must be a seller to use this endpoint.", - ) - users = { - u.user_id: u.__dict__ - for u in await cruds_cdr.get_users_with_problematic_payments( - db=db, - cdr_year=cdr_year.year, - ) - } - hyperion_error_logger.info(list(users.values())) - - return list(users.values()) - - @module.router.get( "/cdr/users/pending/", response_model=list[schemas_cdr.CdrUserPreview], From e6e161b6c834c861ba087098d003dd86160034e6 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 09/35] (Unnecessary schema) --- app/modules/cdr/schemas_cdr.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index 75f2557c25..aa894c47f6 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -346,12 +346,3 @@ class BatchValidation(BaseModel): class TotalPurchaseValidatedBySeller(BaseModel): name: str total_validated: int - - -class UserPaymentStatus(BaseModel): - user_id: str - total_purchased: int - total_paid: int - has_unvalidated_purchase: bool - is_overcharged: bool - is_undercharged: bool From f394425f2415a29b50061808873c15452372ee29 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 10/35] Renaming and adding description in cruds and endpoints --- app/modules/cdr/cruds_cdr.py | 8 ++++---- app/modules/cdr/endpoints_cdr.py | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 46dd86f6f6..73bc2ca0c0 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -902,7 +902,7 @@ async def delete_payment( ) -async def get_payment_products_by_seller( +async def get_payment_total_by_seller( db: AsyncSession, cdr_year: int, ) -> list[schemas_cdr.TotalPurchaseValidatedBySeller]: @@ -941,7 +941,7 @@ async def get_payment_products_by_seller( ] -async def get_total_payment_types( +async def get_payment_total_by_type( db: AsyncSession, cdr_year: int, ) -> list[schemas_cdr.PaymentBase]: @@ -963,10 +963,10 @@ async def get_total_payment_types( ] -async def get_total_payment( +async def get_payment_total( db: AsyncSession, cdr_year: int, -): +) -> int: result = await db.execute( select( diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 7f8e33ff0c..a67d6b56d5 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -192,11 +192,11 @@ async def get_cdr_users_pending_validation( @module.router.get( - "/cdr/users/total_payments_by_seller/", + "/cdr/stats/total_payments_by_seller/", response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], status_code=200, ) -async def get_total_payments_by_seller( +async def get_payment_total_by_seller( db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), @@ -204,27 +204,27 @@ async def get_total_payments_by_seller( cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ - Get the total of payments done in the CDR by each seller. + Get the total of all payments made in the CDR for each seller. - **User must a CDR Admin to use this endpoint** + **User must be a CDR Admin to use this endpoint** """ if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): raise HTTPException( status_code=403, detail="You're not allowed to see this.", ) - return await cruds_cdr.get_payment_products_by_seller( + return await cruds_cdr.get_payment_total_by_seller( db=db, cdr_year=cdr_year.year, ) @module.router.get( - "/cdr/users/total_payments_per_type/", + "/cdr/stats/total_payments_per_type/", response_model=list[schemas_cdr.PaymentBase], status_code=200, ) -async def get_total_payments_types( +async def get_payment_total_by_type( db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), @@ -232,7 +232,7 @@ async def get_total_payments_types( cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ - Get the total of payments done in the CDR. + Get the total of all payments made in the CDR for each payment type. **User must a CDR Admin to use this endpoint** """ @@ -241,18 +241,18 @@ async def get_total_payments_types( status_code=403, detail="You're not allowed to see this.", ) - return await cruds_cdr.get_total_payment_types( + return await cruds_cdr.get_payment_total_by_type( db=db, cdr_year=cdr_year.year, ) @module.router.get( - "/cdr/users/total_payments/", + "/cdr/stats/total_payments/", response_model=int, status_code=200, ) -async def get_total_payments( +async def get_payment_total( db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), @@ -260,7 +260,7 @@ async def get_total_payments( cdr_year: coredata_cdr.CdrYear = Depends(get_current_cdr_year), ): """ - Get the total of payments done in the CDR. + Get the total of all payments made in the CDR. **User must a CDR Admin to use this endpoint** """ @@ -270,7 +270,7 @@ async def get_total_payments( detail="You're not allowed to see this.", ) - return await cruds_cdr.get_total_payment( + return await cruds_cdr.get_payment_total( db=db, cdr_year=cdr_year.year, ) From a62e3dbfc4ba5727675ddaf8f3abffe7934137e4 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 11/35] mypy . --- app/modules/cdr/cruds_cdr.py | 7 +++---- app/modules/cdr/endpoints_cdr.py | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 73bc2ca0c0..3e8e73cb9d 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -973,10 +973,9 @@ async def get_payment_total( func.sum(models_cdr.Payment.total).label("total"), ).where(models_cdr.Payment.year == cdr_year), ) - try: - return result.all()[0].total // 100 - except IndexError: - return 0 + total = result.scalar() + + return total // 100 if total is not None else 0 def create_action( diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index a67d6b56d5..99b3536763 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -192,7 +192,7 @@ async def get_cdr_users_pending_validation( @module.router.get( - "/cdr/stats/total_payments_by_seller/", + "/cdr/stats/payment_total_by_seller/", response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], status_code=200, ) @@ -220,7 +220,7 @@ async def get_payment_total_by_seller( @module.router.get( - "/cdr/stats/total_payments_per_type/", + "/cdr/stats/payment_total_per_type/", response_model=list[schemas_cdr.PaymentBase], status_code=200, ) @@ -248,7 +248,7 @@ async def get_payment_total_by_type( @module.router.get( - "/cdr/stats/total_payments/", + "/cdr/stats/payment_total/", response_model=int, status_code=200, ) From cc24f74f6fb646deb565cd869350c8489171c4ce Mon Sep 17 00:00:00 2001 From: Bombefire <71712683+Bombefire@users.noreply.github.com> Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 12/35] Update app/modules/cdr/endpoints_cdr.py Co-authored-by: Armand Didierjean <95971503+armanddidierjean@users.noreply.github.com> --- app/modules/cdr/endpoints_cdr.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 99b3536763..5e570acc6a 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -208,11 +208,6 @@ async def get_payment_total_by_seller( **User must be a CDR Admin to use this endpoint** """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): - raise HTTPException( - status_code=403, - detail="You're not allowed to see this.", - ) return await cruds_cdr.get_payment_total_by_seller( db=db, cdr_year=cdr_year.year, From cbf2ce2d13cc0a87bf6d843a52ceb9cbb5f87f91 Mon Sep 17 00:00:00 2001 From: Bombefire <71712683+Bombefire@users.noreply.github.com> Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 13/35] Update app/modules/cdr/endpoints_cdr.py Co-authored-by: Armand Didierjean <95971503+armanddidierjean@users.noreply.github.com> --- app/modules/cdr/endpoints_cdr.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 5e570acc6a..e9545f5925 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -259,12 +259,6 @@ async def get_payment_total( **User must a CDR Admin to use this endpoint** """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): - raise HTTPException( - status_code=403, - detail="You're not allowed to see this.", - ) - return await cruds_cdr.get_payment_total( db=db, cdr_year=cdr_year.year, From 20aa50d14e7b500b3b1a565ba9d33cffac998c15 Mon Sep 17 00:00:00 2001 From: Bombefire <71712683+Bombefire@users.noreply.github.com> Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 14/35] Update app/modules/cdr/endpoints_cdr.py Co-authored-by: Armand Didierjean <95971503+armanddidierjean@users.noreply.github.com> --- app/modules/cdr/endpoints_cdr.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index e9545f5925..000f3fd52d 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -231,11 +231,6 @@ async def get_payment_total_by_type( **User must a CDR Admin to use this endpoint** """ - if not (await has_user_permission(user, CdrPermissions.manage_cdr, db)): - raise HTTPException( - status_code=403, - detail="You're not allowed to see this.", - ) return await cruds_cdr.get_payment_total_by_type( db=db, cdr_year=cdr_year.year, From 8248c110d6b97dc9397a29a9b3678b259520df1f Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 15/35] Adding tests and fixes --- app/modules/cdr/cruds_cdr.py | 20 ++++++++------- app/modules/cdr/endpoints_cdr.py | 4 +-- app/modules/cdr/schemas_cdr.py | 8 ++++-- tests/modules/cdr/test_cdr.py | 43 ++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 3e8e73cb9d..70986be129 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -905,7 +905,7 @@ async def delete_payment( async def get_payment_total_by_seller( db: AsyncSession, cdr_year: int, -) -> list[schemas_cdr.TotalPurchaseValidatedBySeller]: +) -> schemas_cdr.TotalPaymentBySeller: result = await db.execute( select( models_cdr.Seller.name, @@ -932,13 +932,15 @@ async def get_payment_total_by_seller( .group_by(models_cdr.Seller.id), ) - return [ - schemas_cdr.TotalPurchaseValidatedBySeller( - total_validated=row.total_amount, - name=row.name, - ) - for row in result.all() - ] + return schemas_cdr.TotalPaymentBySeller( + total_amounts=[ + schemas_cdr.TotalPaymentOfSeller( + total_amount=row.total_amount, + name=row.name, + ) + for row in result.all() + ], + ) async def get_payment_total_by_type( @@ -975,7 +977,7 @@ async def get_payment_total( ) total = result.scalar() - return total // 100 if total is not None else 0 + return total if total is not None else 0 def create_action( diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index 000f3fd52d..aa73132491 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -193,7 +193,7 @@ async def get_cdr_users_pending_validation( @module.router.get( "/cdr/stats/payment_total_by_seller/", - response_model=list[schemas_cdr.TotalPurchaseValidatedBySeller], + response_model=schemas_cdr.TotalPaymentBySeller, status_code=200, ) async def get_payment_total_by_seller( @@ -219,7 +219,7 @@ async def get_payment_total_by_seller( response_model=list[schemas_cdr.PaymentBase], status_code=200, ) -async def get_payment_total_by_type( +async def get_payment_total_per_type( db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([CdrPermissions.manage_cdr]), diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index aa894c47f6..4f686cd8e1 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -343,6 +343,10 @@ class BatchValidation(BaseModel): validated: bool -class TotalPurchaseValidatedBySeller(BaseModel): +class TotalPaymentOfSeller(BaseModel): name: str - total_validated: int + total_amount: int + + +class TotalPaymentBySeller(BaseModel): + total_amounts: list[TotalPaymentOfSeller] diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 8a73517068..2a945817d3 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2981,3 +2981,46 @@ def test_pay_other_user_forbidden(client: TestClient): ) assert response.status_code == 403 + assert response.status_code == 404 + + +async def test_get_payment_total(client: TestClient, user_id: uuid.UUID): + response = client.get( + f"/cdr/users/{user_id}/payments/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + + response = client.get( + f"/cdr/users/{user_id}/payments/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + + +async def test_get_payment_total_by_seller(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_by_seller/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + + response = client.get( + "/cdr/stats/payment_total_by_seller/,", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + + +async def test_get_payment_total_per_type(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_per_type/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + + response = client.get( + "/cdr/stats/payment_total_per_type/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 From ea937112f994d925ca17aebd5be2f6bcba389a7c Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 16/35] Fix --- tests/modules/cdr/test_cdr.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 2a945817d3..c650c8eb45 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2986,17 +2986,11 @@ def test_pay_other_user_forbidden(client: TestClient): async def test_get_payment_total(client: TestClient, user_id: uuid.UUID): response = client.get( - f"/cdr/users/{user_id}/payments/", + f"//cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - response = client.get( - f"/cdr/users/{user_id}/payments/", - headers={"Authorization": f"Bearer {token_user}"}, - ) - assert response.status_code == 403 - async def test_get_payment_total_by_seller(client: TestClient): response = client.get( From 427b98d7d14344be67d50affaf03c69663d1da03 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 17/35] lint --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index c650c8eb45..25122b25df 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2986,7 +2986,7 @@ def test_pay_other_user_forbidden(client: TestClient): async def test_get_payment_total(client: TestClient, user_id: uuid.UUID): response = client.get( - f"//cdr/stats/payment_total/", + "//cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 From 3bb1a028f5e9b8d7ad9ba762dcb5c5f87e2f0938 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 18/35] Why are we still here just to suffer ? --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 25122b25df..4fd4b56acd 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2984,7 +2984,7 @@ def test_pay_other_user_forbidden(client: TestClient): assert response.status_code == 404 -async def test_get_payment_total(client: TestClient, user_id: uuid.UUID): +async def test_get_payment_total(client: TestClient): response = client.get( "//cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, From edaea354d9997041cc6cd8b56920c858d5347bf2 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 19/35] Fix --- tests/modules/cdr/test_cdr.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 4fd4b56acd..35f8ae5633 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2981,12 +2981,11 @@ def test_pay_other_user_forbidden(client: TestClient): ) assert response.status_code == 403 - assert response.status_code == 404 async def test_get_payment_total(client: TestClient): response = client.get( - "//cdr/stats/payment_total/", + "/cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 From 2f3e3b1743ad1bfc27480d47c3b22dbaca0f8126 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 20/35] Fix --- tests/modules/cdr/test_cdr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 35f8ae5633..c5fbc6a7d7 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -3002,7 +3002,7 @@ async def test_get_payment_total_by_seller(client: TestClient): "/cdr/stats/payment_total_by_seller/,", headers={"Authorization": f"Bearer {token_user}"}, ) - assert response.status_code == 403 + assert response.status_code == 404 async def test_get_payment_total_per_type(client: TestClient): @@ -3016,4 +3016,4 @@ async def test_get_payment_total_per_type(client: TestClient): "/cdr/stats/payment_total_per_type/", headers={"Authorization": f"Bearer {token_user}"}, ) - assert response.status_code == 403 + assert response.status_code == 404 From 5cfb86c8f66abed6c7e33a96b8327e0b247f9603 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 21/35] .... --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index c5fbc6a7d7..bfea293df0 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -3016,4 +3016,4 @@ async def test_get_payment_total_per_type(client: TestClient): "/cdr/stats/payment_total_per_type/", headers={"Authorization": f"Bearer {token_user}"}, ) - assert response.status_code == 404 + assert response.status_code == 403 From 7e143f556dde1c15fedc2a667336392720c700c1 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 22/35] Seperating tests --- tests/modules/cdr/test_cdr.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index bfea293df0..4fc4ebd134 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2983,7 +2983,7 @@ def test_pay_other_user_forbidden(client: TestClient): assert response.status_code == 403 -async def test_get_payment_total(client: TestClient): +async def test_get_payment_total_as_admin(client: TestClient): response = client.get( "/cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, @@ -2991,27 +2991,39 @@ async def test_get_payment_total(client: TestClient): assert response.status_code == 200 -async def test_get_payment_total_by_seller(client: TestClient): +async def test_get_payment_total_as_user(client: TestClient): + response = client.get( + "/cdr/stats/payment_total/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + + +async def test_get_payment_total_by_seller_as_admin(client: TestClient): response = client.get( "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + +async def test_get_payment_total_by_seller_as_user(client: TestClient): response = client.get( "/cdr/stats/payment_total_by_seller/,", headers={"Authorization": f"Bearer {token_user}"}, ) - assert response.status_code == 404 + assert response.status_code == 403 -async def test_get_payment_total_per_type(client: TestClient): +async def test_get_payment_total_per_type_as_admin(client: TestClient): response = client.get( "/cdr/stats/payment_total_per_type/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + +async def test_get_payment_total_per_type_as_user(client: TestClient): response = client.get( "/cdr/stats/payment_total_per_type/", headers={"Authorization": f"Bearer {token_user}"}, From 2799daa385076e9a227b39400437cb18e312ecf5 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 23/35] ... --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 4fc4ebd134..33e0756a3a 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -3009,7 +3009,7 @@ async def test_get_payment_total_by_seller_as_admin(client: TestClient): async def test_get_payment_total_by_seller_as_user(client: TestClient): response = client.get( - "/cdr/stats/payment_total_by_seller/,", + "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_user}"}, ) assert response.status_code == 403 From 01af78a99257c9ffb6e8618a610cff214fbe94cc Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 24/35] =?UTF-8?q?Test=20compl=C3=A9mentaire=20n=C2=B01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/modules/cdr/test_cdr.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 33e0756a3a..162d5a5d5f 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -2989,6 +2989,7 @@ async def test_get_payment_total_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + assert response.json() == {5000} async def test_get_payment_total_as_user(client: TestClient): @@ -3005,6 +3006,7 @@ async def test_get_payment_total_by_seller_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} async def test_get_payment_total_by_seller_as_user(client: TestClient): @@ -3021,6 +3023,7 @@ async def test_get_payment_total_per_type_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + assert response.json() == {"total": 5000, "payment_type": "card"} async def test_get_payment_total_per_type_as_user(client: TestClient): From 7f037a7798ab33dbe94f2e421d8545870be6a8ce Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 25/35] Put it up the tests --- tests/modules/cdr/test_cdr.py | 99 ++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 162d5a5d5f..b8847beebc 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -478,6 +478,56 @@ async def init_objects(): ) await add_object_to_db(ticket) +def test_get_payment_total_as_admin(client: TestClient): + response = client.get( + "/cdr/stats/payment_total/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + assert response.json() == {5000} + + +def test_get_payment_total_as_user(client: TestClient): + response = client.get( + "/cdr/stats/payment_total/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + + +def test_get_payment_total_by_seller_as_admin(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_by_seller/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} + + +def test_get_payment_total_by_seller_as_user(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_by_seller/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + + +def test_get_payment_total_per_type_as_admin(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_per_type/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) + assert response.status_code == 200 + assert response.json() == {"total": 5000, "payment_type": "card"} + + +def test_get_payment_total_per_type_as_user(client: TestClient): + response = client.get( + "/cdr/stats/payment_total_per_type/", + headers={"Authorization": f"Bearer {token_user}"}, + ) + assert response.status_code == 403 + def test_get_all_cdr_users_seller(client: TestClient): response = client.get( @@ -2983,52 +3033,3 @@ def test_pay_other_user_forbidden(client: TestClient): assert response.status_code == 403 -async def test_get_payment_total_as_admin(client: TestClient): - response = client.get( - "/cdr/stats/payment_total/", - headers={"Authorization": f"Bearer {token_admin}"}, - ) - assert response.status_code == 200 - assert response.json() == {5000} - - -async def test_get_payment_total_as_user(client: TestClient): - response = client.get( - "/cdr/stats/payment_total/", - headers={"Authorization": f"Bearer {token_user}"}, - ) - assert response.status_code == 403 - - -async def test_get_payment_total_by_seller_as_admin(client: TestClient): - response = client.get( - "/cdr/stats/payment_total_by_seller/", - headers={"Authorization": f"Bearer {token_admin}"}, - ) - assert response.status_code == 200 - assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} - - -async def test_get_payment_total_by_seller_as_user(client: TestClient): - response = client.get( - "/cdr/stats/payment_total_by_seller/", - headers={"Authorization": f"Bearer {token_user}"}, - ) - assert response.status_code == 403 - - -async def test_get_payment_total_per_type_as_admin(client: TestClient): - response = client.get( - "/cdr/stats/payment_total_per_type/", - headers={"Authorization": f"Bearer {token_admin}"}, - ) - assert response.status_code == 200 - assert response.json() == {"total": 5000, "payment_type": "card"} - - -async def test_get_payment_total_per_type_as_user(client: TestClient): - response = client.get( - "/cdr/stats/payment_total_per_type/", - headers={"Authorization": f"Bearer {token_user}"}, - ) - assert response.status_code == 403 From ef0fd51ab6618491906a14e209512d0f288eca12 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 26/35] Only one error left --- tests/modules/cdr/test_cdr.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index b8847beebc..424a9d5246 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -478,13 +478,14 @@ async def init_objects(): ) await add_object_to_db(ticket) + def test_get_payment_total_as_admin(client: TestClient): response = client.get( "/cdr/stats/payment_total/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json() == {5000} + assert response.json() == 5000 def test_get_payment_total_as_user(client: TestClient): @@ -518,7 +519,7 @@ def test_get_payment_total_per_type_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json() == {"total": 5000, "payment_type": "card"} + assert response.json() == {"total": 5000, "payment_type": "cash"} def test_get_payment_total_per_type_as_user(client: TestClient): @@ -3031,5 +3032,3 @@ def test_pay_other_user_forbidden(client: TestClient): ) assert response.status_code == 403 - - From 60d8cbbff7f0f4d070c63957f08a961f0eeb7a3d Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 27/35] Fix test --- tests/modules/cdr/test_cdr.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 424a9d5246..0200cf5c9f 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -502,7 +502,11 @@ def test_get_payment_total_by_seller_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 + assert response.json() == {"total_amounts": []} + + purchase.validated = True assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} + purchase.validated = False def test_get_payment_total_by_seller_as_user(client: TestClient): @@ -519,7 +523,7 @@ def test_get_payment_total_per_type_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json() == {"total": 5000, "payment_type": "cash"} + assert response.json() == [{"total": 5000, "payment_type": "cash"}] def test_get_payment_total_per_type_as_user(client: TestClient): From b11fed6c4a7b16f900c57d792ae42904cbcefd99 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 28/35] Fix --- tests/modules/cdr/test_cdr.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 0200cf5c9f..3f43f89ac7 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -505,6 +505,10 @@ def test_get_payment_total_by_seller_as_admin(client: TestClient): assert response.json() == {"total_amounts": []} purchase.validated = True + response = client.get( + "/cdr/stats/payment_total_by_seller/", + headers={"Authorization": f"Bearer {token_admin}"}, + ) assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} purchase.validated = False From 56351e38e47d911db0deebc1c9829072243bdb9f Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 29/35] Test --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 3f43f89ac7..f4d35919cb 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -404,7 +404,7 @@ async def init_objects(): user_id=user.id, product_variant_id=variant.id, quantity=1, - validated=False, + validated=True, purchased_on=datetime.now(UTC), ) await add_object_to_db(purchase) From 7d1f7712704faf9be2ff0d02b24d7bbbbd0b4809 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 30/35] Fix --- tests/commons.py | 19 +++++++++++++++++++ tests/modules/cdr/test_cdr.py | 7 +++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/commons.py b/tests/commons.py index 9f67fb2ff6..48a511834d 100644 --- a/tests/commons.py +++ b/tests/commons.py @@ -44,6 +44,10 @@ class FailedToAddObjectToDB(Exception): """Exception raised when an object cannot be added to the database.""" +class FailedToUpdateObjectInDB(Exception): + """Exception raised when an object cannot be updated in the database.""" + + async def override_init_state( app: FastAPI, settings: Settings, @@ -327,6 +331,21 @@ async def add_object_to_db(db_object: Base) -> None: await db.close() +async def update_object_in_db(db_object: Base) -> None: + """ + Update an existing object in the database + """ + async with TestingSessionLocal() as db: + try: + await db.merge(db_object) + await db.commit() + except Exception as error: + await db.rollback() + raise FailedToUpdateObjectInDB from error + finally: + await db.close() + + async def add_coredata_to_db( core_data: core_data.BaseCoreData, ) -> None: diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index f4d35919cb..d407792f37 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -28,6 +28,7 @@ create_user_with_groups, get_TestingSessionLocal, mocked_checkout_id, + update_object_in_db, ) year = datetime.now(UTC).year @@ -404,7 +405,7 @@ async def init_objects(): user_id=user.id, product_variant_id=variant.id, quantity=1, - validated=True, + validated=False, purchased_on=datetime.now(UTC), ) await add_object_to_db(purchase) @@ -496,7 +497,7 @@ def test_get_payment_total_as_user(client: TestClient): assert response.status_code == 403 -def test_get_payment_total_by_seller_as_admin(client: TestClient): +async def test_get_payment_total_by_seller_as_admin(client: TestClient): response = client.get( "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_admin}"}, @@ -505,12 +506,14 @@ def test_get_payment_total_by_seller_as_admin(client: TestClient): assert response.json() == {"total_amounts": []} purchase.validated = True + await update_object_in_db(purchase) response = client.get( "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} purchase.validated = False + await update_object_in_db(purchase) def test_get_payment_total_by_seller_as_user(client: TestClient): From 5a6921ebd8e24aff47cd49e730d2b4668d839f82 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Wed, 9 Sep 2026 03:57:01 +0200 Subject: [PATCH 31/35] Finish --- tests/commons.py | 2 +- tests/modules/cdr/test_cdr.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/commons.py b/tests/commons.py index 48a511834d..2f32c55bf7 100644 --- a/tests/commons.py +++ b/tests/commons.py @@ -344,7 +344,7 @@ async def update_object_in_db(db_object: Base) -> None: raise FailedToUpdateObjectInDB from error finally: await db.close() - + async def add_coredata_to_db( core_data: core_data.BaseCoreData, diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index d407792f37..deec472ba2 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -511,7 +511,7 @@ async def test_get_payment_total_by_seller_as_admin(client: TestClient): "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_admin}"}, ) - assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 5000}]} + assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 100}]} purchase.validated = False await update_object_in_db(purchase) From 344d61d325c993fd0f2fc33c7e9076d738e7b42f Mon Sep 17 00:00:00 2001 From: Ilyass Date: Fri, 11 Sep 2026 13:44:57 +0200 Subject: [PATCH 32/35] feat: More tests --- tests/modules/cdr/test_cdr.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index deec472ba2..c0edeaff70 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -511,7 +511,13 @@ async def test_get_payment_total_by_seller_as_admin(client: TestClient): "/cdr/stats/payment_total_by_seller/", headers={"Authorization": f"Bearer {token_admin}"}, ) - assert response.json() == {"total_amounts": [{"name": "BDE", "total_amount": 100}]} + + data = response.json() + assert len(data["total_amounts"]) == 1 + first_data = data["total_amounts"][0] + assert first_data["name"] == "BDE" + assert first_data["total_amount"] == 100 + purchase.validated = False await update_object_in_db(purchase) @@ -530,7 +536,11 @@ def test_get_payment_total_per_type_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json() == [{"total": 5000, "payment_type": "cash"}] + data = response.json() + assert len(data) == 1 + first_data = data[0] + assert first_data["payment_type"] == "cash" + assert first_data["total"] == 5000 def test_get_payment_total_per_type_as_user(client: TestClient): From aeefa368d9b89567e5bb878d8938c2f801538434 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Sun, 13 Sep 2026 13:55:29 +0200 Subject: [PATCH 33/35] Schemas for total payment --- app/modules/cdr/cruds_cdr.py | 2 +- app/modules/cdr/endpoints_cdr.py | 2 +- app/modules/cdr/schemas_cdr.py | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 70986be129..5e8e9afc39 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -977,7 +977,7 @@ async def get_payment_total( ) total = result.scalar() - return total if total is not None else 0 + return schemas_cdr.TotalPayment(total_amount=total if total is not None else 0) def create_action( diff --git a/app/modules/cdr/endpoints_cdr.py b/app/modules/cdr/endpoints_cdr.py index aa73132491..7d26af7cb9 100644 --- a/app/modules/cdr/endpoints_cdr.py +++ b/app/modules/cdr/endpoints_cdr.py @@ -239,7 +239,7 @@ async def get_payment_total_per_type( @module.router.get( "/cdr/stats/payment_total/", - response_model=int, + response_model=schemas_cdr.TotalPayment, status_code=200, ) async def get_payment_total( diff --git a/app/modules/cdr/schemas_cdr.py b/app/modules/cdr/schemas_cdr.py index 4f686cd8e1..ffe2e295dc 100644 --- a/app/modules/cdr/schemas_cdr.py +++ b/app/modules/cdr/schemas_cdr.py @@ -350,3 +350,7 @@ class TotalPaymentOfSeller(BaseModel): class TotalPaymentBySeller(BaseModel): total_amounts: list[TotalPaymentOfSeller] + + +class TotalPayment(BaseModel): + total_amount: int From ea1a9a216cb63dfec59f496247156e9d125a572c Mon Sep 17 00:00:00 2001 From: Ilyass Date: Sun, 13 Sep 2026 14:22:28 +0200 Subject: [PATCH 34/35] Stash --- app/modules/cdr/cruds_cdr.py | 2 +- tests/modules/cdr/test_cdr.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/modules/cdr/cruds_cdr.py b/app/modules/cdr/cruds_cdr.py index 5e8e9afc39..95403bfde4 100644 --- a/app/modules/cdr/cruds_cdr.py +++ b/app/modules/cdr/cruds_cdr.py @@ -968,7 +968,7 @@ async def get_payment_total_by_type( async def get_payment_total( db: AsyncSession, cdr_year: int, -) -> int: +) -> schemas_cdr.TotalPayment: result = await db.execute( select( diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index c0edeaff70..8c9d607d45 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -486,7 +486,7 @@ def test_get_payment_total_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json() == 5000 + assert response.json().total_amount == 5000 def test_get_payment_total_as_user(client: TestClient): From 019bb3c690c3c4c0d6eee0a56608454b64ceaaf7 Mon Sep 17 00:00:00 2001 From: Ilyass Date: Sun, 13 Sep 2026 14:37:53 +0200 Subject: [PATCH 35/35] Schemas for total payment --- tests/modules/cdr/test_cdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/cdr/test_cdr.py b/tests/modules/cdr/test_cdr.py index 8c9d607d45..c77b7bbbb5 100644 --- a/tests/modules/cdr/test_cdr.py +++ b/tests/modules/cdr/test_cdr.py @@ -486,7 +486,7 @@ def test_get_payment_total_as_admin(client: TestClient): headers={"Authorization": f"Bearer {token_admin}"}, ) assert response.status_code == 200 - assert response.json().total_amount == 5000 + assert response.json()["total_amount"] == 5000 def test_get_payment_total_as_user(client: TestClient):