From e4a49ec5f158b123380670d8c2d45f87b1a5b5bf Mon Sep 17 00:00:00 2001 From: konnofuente Date: Mon, 12 Aug 2024 12:09:04 +0100 Subject: [PATCH] feat(app): #15 complete tontine creation --- lib/app/core/utils/constants/app_api_key.dart | 2 +- .../firebase/tontine_data_source.dart | 132 +++++++++++------- .../create_tontine_controller.dart | 39 +++++- .../export_create_tonine_component.dart | 2 +- ....dart => verification_tontine_screen.dart} | 0 5 files changed, 114 insertions(+), 61 deletions(-) rename lib/presentation/pages/create_tontine/components/{verification_screen.dart => verification_tontine_screen.dart} (100%) diff --git a/lib/app/core/utils/constants/app_api_key.dart b/lib/app/core/utils/constants/app_api_key.dart index 6e900ba..ab4a5f2 100644 --- a/lib/app/core/utils/constants/app_api_key.dart +++ b/lib/app/core/utils/constants/app_api_key.dart @@ -2,5 +2,5 @@ class ApiKey { static const USER_KEY = "users"; static const ASSOCIATION_KEY = "associations"; static const MEDIA_KEY = "medias"; - static const TONTINE_KEY = "medias"; + static const TONTINE_KEY = "tontine"; } \ No newline at end of file diff --git a/lib/infrastructure/data_sources/firebase/tontine_data_source.dart b/lib/infrastructure/data_sources/firebase/tontine_data_source.dart index 4b783d6..00a14bb 100644 --- a/lib/infrastructure/data_sources/firebase/tontine_data_source.dart +++ b/lib/infrastructure/data_sources/firebase/tontine_data_source.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'package:uuid/uuid.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:manzon/infrastructure/models/cycle_model.dart'; @@ -12,27 +13,39 @@ class TontineDataSource { late final Function(String, String) contributionRef; TontineDataSource() { - tontineRef = FirebaseFirestore.instance.collection(ApiKey.TONTINE_KEY).withConverter( - fromFirestore: (snapshots, _) => TontineModel.fromJson(snapshots.data()!), - toFirestore: (tontine, _) => tontine.toJson(), - ); + tontineRef = FirebaseFirestore.instance + .collection(ApiKey.TONTINE_KEY) + .withConverter( + fromFirestore: (snapshots, _) => + TontineModel.fromJson(snapshots.data()!), + toFirestore: (tontine, _) => tontine.toJson(), + ); cycleRef = _createCycleRef; contributionRef = _createContributionRef; } CollectionReference _createCycleRef(String tontineId) { - return tontineRef.doc(tontineId).collection('cycles').withConverter( - fromFirestore: (snapshots, _) => CycleModel.fromJson(snapshots.data()!), - toFirestore: (cycle, _) => cycle.toJson(), - ); - } - - CollectionReference _createContributionRef(String tontineId, String cycleId) { - return cycleRef(tontineId).doc(cycleId).collection('contributions').withConverter( - fromFirestore: (snapshots, _) => TontineContributionModel.fromJson(snapshots.data()!), - toFirestore: (contribution, _) => contribution.toJson(), - ); + return tontineRef + .doc(tontineId) + .collection('cycles') + .withConverter( + fromFirestore: (snapshots, _) => + CycleModel.fromJson(snapshots.data()!), + toFirestore: (cycle, _) => cycle.toJson(), + ); + } + + CollectionReference _createContributionRef( + String tontineId, String cycleId) { + return cycleRef(tontineId) + .doc(cycleId) + .collection('contributions') + .withConverter( + fromFirestore: (snapshots, _) => + TontineContributionModel.fromJson(snapshots.data()!), + toFirestore: (contribution, _) => contribution.toJson(), + ); } Future addTontine(TontineModel tontineModel) async { @@ -76,61 +89,74 @@ class TontineDataSource { await cycleRef(tontineId).doc(cycleId).delete(); } - Future addContribution(String tontineId, String cycleId, TontineContributionModel contributionModel) async { - await contributionRef(tontineId, cycleId).doc(contributionModel.id).set(contributionModel); + Future addContribution(String tontineId, String cycleId, + TontineContributionModel contributionModel) async { + await contributionRef(tontineId, cycleId) + .doc(contributionModel.id) + .set(contributionModel); } - Future getContributionById(String tontineId, String cycleId, String contributionId) async { - final doc = await contributionRef(tontineId, cycleId).doc(contributionId).get(); + Future getContributionById( + String tontineId, String cycleId, String contributionId) async { + final doc = + await contributionRef(tontineId, cycleId).doc(contributionId).get(); if (doc.exists) { return doc.data(); } return null; } - Future updateContribution(String tontineId, String cycleId, TontineContributionModel contributionModel) async { - await contributionRef(tontineId, cycleId).doc(contributionModel.id).set(contributionModel); + Future updateContribution(String tontineId, String cycleId, + TontineContributionModel contributionModel) async { + await contributionRef(tontineId, cycleId) + .doc(contributionModel.id) + .set(contributionModel); } - Future deleteContribution(String tontineId, String cycleId, String contributionId) async { + Future deleteContribution( + String tontineId, String cycleId, String contributionId) async { await contributionRef(tontineId, cycleId).doc(contributionId).delete(); } -Future _generateCycles(TontineModel tontineModel) async { - final List cycles = []; - final int totalCycles = (tontineModel.members?.length ?? 0) * tontineModel.cycleDuration; - final DateTime now = DateTime.now(); - DateTime startDate = now; - - for (int i = 0; i < totalCycles; i++) { - final int currentMemberIndex = i ~/ tontineModel.cycleDuration; - final MemberEntity receiver = tontineModel.orderList![currentMemberIndex % tontineModel.orderList!.length]; - final DateTime endDate = startDate.add(_getDuration(ContributionFrequency.values.firstWhere((e) => e.toString() == tontineModel.contributionFrequency))); - - final cycle = CycleModel( - id: Uuid().v4(), - number: currentMemberIndex + 1, - sequenceNumber: i + 1, - tontineId: tontineModel.id, - receiver: MemberMapper.toModel(receiver), - startDate: startDate, - endDate: endDate, - isCompleted: false, - contributions: [], - ); + Future _generateCycles(TontineModel tontineModel) async { + log(tontineModel.contributionFrequency.toString()); + final List cycles = []; + final int totalCycles = + (tontineModel.members?.length ?? 0) * tontineModel.cycleDuration; + final DateTime now = DateTime.now(); + DateTime startDate = now; + + for (int i = 0; i < totalCycles; i++) { + final int currentMemberIndex = i ~/ tontineModel.cycleDuration; + final MemberEntity receiver = tontineModel + .orderList![currentMemberIndex % tontineModel.orderList!.length]; + + final DateTime endDate = + startDate.add(_getDuration(tontineModel.contributionFrequency)); + + final cycle = CycleModel( + id: Uuid().v4(), + number: currentMemberIndex + 1, + sequenceNumber: i + 1, + tontineId: tontineModel.id, + receiver: MemberMapper.toModel(receiver), + startDate: startDate, + endDate: endDate, + isCompleted: false, + contributions: [], + ); + + cycles.add(cycle); + startDate = endDate; + } - cycles.add(cycle); - startDate = endDate; - } + for (final cycle in cycles) { + await addCycle(tontineModel.id, cycle); + } - for (final cycle in cycles) { - await addCycle(tontineModel.id, cycle); + await updateTontine(tontineModel.copyWith(cycles: cycles)); } - await updateTontine(tontineModel.copyWith(cycles: cycles)); -} - - Duration _getDuration(ContributionFrequency frequency) { switch (frequency) { case ContributionFrequency.weekly: diff --git a/lib/presentation/controllers/create_tontine_controller.dart b/lib/presentation/controllers/create_tontine_controller.dart index 7892f80..0bea696 100644 --- a/lib/presentation/controllers/create_tontine_controller.dart +++ b/lib/presentation/controllers/create_tontine_controller.dart @@ -7,6 +7,7 @@ import 'package:contacts_service/contacts_service.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:manzon/app/config/routes/app_route_names.dart'; import 'package:manzon/presentation/widgets/export_widget.dart'; +import 'package:manzon/infrastructure/mappers/member_mapper.dart'; import 'package:manzon/domain/entities/export_domain_entities.dart'; import 'package:manzon/infrastructure/models/export_infrastruture_models.dart'; import 'package:manzon/infrastructure/data_sources/firebase/tontine_data_source.dart'; @@ -100,7 +101,9 @@ class CreateTontineController extends GetxController { id: Uuid().v4(), name: contact.displayName ?? '', role: 'Member', - userId: contact.identifier ?? '', + userId: contact.phones?.isNotEmpty ?? false + ? contact.phones!.first.value! + : contact.identifier!, phoneNumber: contact.phones?.isNotEmpty ?? false ? contact.phones!.first.value! : '', @@ -191,23 +194,47 @@ class CreateTontineController extends GetxController { receiverFrequency.value = value; } - void createTontine() async { +void createTontine() async { final tontine = TontineModel( id: Uuid().v4(), name: tontineNameController.text, contributionAmount: double.parse(individualAmountController.text), contributionFrequency: contributionFrequency.value, receiverFrequency: receiverFrequency.value, - members: selectedMembers.map((e) => e as MemberModel).toList(), + members: selectedMembers.map((e) => MemberMapper.toModel(e)).toList(), membersId: selectedMembers.map((m) => m.id).toList(), - orderList: selectedMembers.map((e) => e as MemberModel).toList(), + orderList: selectedMembers.map((e) => MemberMapper.toModel(e)).toList(), cycles: [], associationId: 'association_id', // Replace with actual association ID cycleDuration: 4, // Example value, replace with actual cycle duration currentCycle: 0, ); - await tontineDataSource.addTontine(tontine); - Get.back(); + // Printing all tontine values for debugging + print('Tontine Values:'); + print('ID: ${tontine.id}'); + print('Name: ${tontine.name}'); + print('Contribution Amount: ${tontine.contributionAmount}'); + print('Contribution Frequency: ${tontine.contributionFrequency}'); + print('Receiver Frequency: ${tontine.receiverFrequency}'); + print('Members: ${tontine.members}'); + print('Members ID: ${tontine.membersId}'); + print('Order List: ${tontine.orderList}'); + print('Cycles: ${tontine.cycles}'); + print('Association ID: ${tontine.associationId}'); + print('Cycle Duration: ${tontine.cycleDuration}'); + print('Current Cycle: ${tontine.currentCycle}'); + + try { + await tontineDataSource.addTontine(tontine); + ToastUtils.showSuccess(Get.context!, "Tontine", "Your Tontine was successfully created"); + } catch (e) { + // Handle any exceptions that occur during the execution of the code inside the try block + print('Error: $e'); + ToastUtils.showError(Get.context!, "Error", "An error occurred while creating the Tontine"); } + + Get.toNamed(AppRouteNames.associationPage); +} + } diff --git a/lib/presentation/pages/create_tontine/components/export_create_tonine_component.dart b/lib/presentation/pages/create_tontine/components/export_create_tonine_component.dart index a1cbf67..19dcdf6 100644 --- a/lib/presentation/pages/create_tontine/components/export_create_tonine_component.dart +++ b/lib/presentation/pages/create_tontine/components/export_create_tonine_component.dart @@ -1,4 +1,4 @@ export './financial_information.dart'; export './order_members.dart'; -export './verification_screen.dart'; +export 'verification_tontine_screen.dart'; export './tontine_information.dart'; \ No newline at end of file diff --git a/lib/presentation/pages/create_tontine/components/verification_screen.dart b/lib/presentation/pages/create_tontine/components/verification_tontine_screen.dart similarity index 100% rename from lib/presentation/pages/create_tontine/components/verification_screen.dart rename to lib/presentation/pages/create_tontine/components/verification_tontine_screen.dart