Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 75 additions & 4 deletions lib/data/repository/transaction_repository_stub.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import 'package:moneyplus/data/repository/utils/fake_data.dart';
import 'package:moneyplus/data/service/supabase_service.dart';
import 'package:moneyplus/domain/entity/transaction.dart';
import 'package:moneyplus/domain/entity/transaction_category.dart';
import 'package:moneyplus/domain/entity/transaction_type.dart';
import 'package:moneyplus/domain/repository/model/top_spending_category.dart';
import 'package:moneyplus/domain/repository/transaction_repository.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class TransactionRepositoryStub implements TransactionRepository {
final SupabaseService service;

TransactionRepositoryStub(this.service);

@override
Future<bool> addTransaction({
required double amount,
Expand All @@ -30,8 +37,17 @@ class TransactionRepositoryStub implements TransactionRepository {
}

@override
Future<bool> deleteTransaction(int id) async {
throw UnimplementedError('deleteTransaction not implemented');
Future<void> deleteTransaction(String id) async {
final client = await service.getClient();

final response = await client.rpc(
'delete_transaction',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please consider extracting rpc functions names to constants, since it might be used in another functin

params: {'p_id': id},
);
print("respinse of deleting is : $response");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove the print statement

if(response == null || response['id'] == null){
throw Exception("cannot delete transaction with id: $id ");
}
}

@override
Expand All @@ -44,8 +60,63 @@ class TransactionRepositoryStub implements TransactionRepository {
}

@override
Future<Transaction> getTransactionDetails(int id) async {
throw UnimplementedError('getTransactionDetails not implemented');
Future<Transaction> getTransactionDetails(String id) async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using our Result class we created for error handling, you can find an example for its usage in LoginCubit, to unify our work for error handling

final client = await service.getClient();
final response = await client.rpc(
'get_transaction_details',
params: {'p_id': id},
);
final data = response as Map<String, dynamic>;
if (data.isEmpty) {
throw Exception("no transaction with that id: $id");
}
final transactionType = ((data['transaction_type'] as int) == 1)
? TransactionType.income
: TransactionType.expense;
return Transaction(
id: 0,
amount: (data['amount'] as num).toDouble(),
currency: await _getCurrencyAbbreviation(data['currency_id'] as int),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use join on backend to retrive what you need

type: transactionType,
date: DateTime.parse(data['created_at']).toLocal(),
category: TransactionCategory(
id: data['category_id'] as int,
name: await _getCategoryName((data['category_id'] as int).toString()),
),
note: data['note'] as String,
);
}

Future<String> _getCurrencyAbbreviation(int currencyId) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this function

final client = await service.getClient();

final response = await client
.from('currencies')
.select('abbreviation')
.eq('id', currencyId)
.maybeSingle();

if (response == null) {
throw Exception("No currency found with id: $currencyId");
}

return response['abbreviation'] as String;
}

Future<String> _getCategoryName(String categoryId) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same , use join delegate all of this to the backend

final client = await service.getClient();

final response = await client
.from('categories')
.select('name')
.eq('id', categoryId)
.maybeSingle();

if (response == null) {
throw Exception("No category found with id: $categoryId");
}

return response['name'] as String;
}

@override
Expand Down
30 changes: 29 additions & 1 deletion lib/data/repository/utils/fake_data.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import '../../../domain/entity/transaction.dart';
import '../../../domain/entity/transaction_category.dart';
import '../../../domain/entity/transaction_type.dart';
import '../../../domain/repository/model/top_spending_category.dart';

List<TopSpendingCategory> getFakeTopSpendingCategories() {
Expand All @@ -25,4 +27,30 @@ List<TopSpendingCategory> getFakeTopSpendingCategories() {
percentage: 10.0,
),
];
}
}

final fakeTransactionExpense = Transaction(
id: 1,
amount: 128.50,
currency: "USD",
type: TransactionType.expense,
date: DateTime.now(),
category: TransactionCategory(
id: 101,
name: "Food & Drinks",
),
note: "Lunch at café",
);

final fakeTransactionIncome = Transaction(
id: 2,
amount: 500.00,
currency: "USD",
type: TransactionType.income,
date: DateTime.now(),
category: TransactionCategory(
id: 201,
name: "Salary",
),
note: "Monthly paycheck",
);
7 changes: 6 additions & 1 deletion lib/di/injection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:get_it/get_it.dart';
import 'package:moneyplus/domain/repository/transaction_repository.dart';
import 'package:moneyplus/presentation/account_setup/cubit/account_setup_cubit.dart';
import 'package:moneyplus/presentation/transactions/cubit/transaction_cubit.dart';
import 'package:moneyplus/presentation/trasnaction_details/trasnaction_details_cubit.dart';

import '../data/repository/account_repository.dart';
import '../data/repository/authentication_repository.dart';
Expand Down Expand Up @@ -56,7 +57,7 @@ void initDI() {
);

getIt.registerLazySingleton<TransactionRepository>(
() => TransactionRepositoryStub(),
() => TransactionRepositoryStub(getIt<SupabaseService>()),
);

getIt.registerLazySingleton<AccountSetupCubit>(() => AccountSetupCubit(getIt<AccountRepository>()));
Expand All @@ -69,4 +70,8 @@ void initDI() {
() =>
TransactionCubit(transactionRepository: getIt<TransactionRepository>()),
);

getIt.registerFactory<TransactionDetailsCubit>(
() => TransactionDetailsCubit(transactionRepository: getIt<TransactionRepository>())
);
}
4 changes: 2 additions & 2 deletions lib/domain/repository/transaction_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ abstract class TransactionRepository {
String? note,
});

Future<bool> deleteTransaction(int id);
Future<void> deleteTransaction(String id);

Future<List<Transaction>> getTransactions({
TransactionType? type,
TransactionCategory? category,
DateTime? date,
});

Future<Transaction> getTransactionDetails(int id);
Future<Transaction> getTransactionDetails(String id);

Future<double> getTotalAmount({TransactionType? type});

Expand Down
13 changes: 13 additions & 0 deletions lib/presentation/navigation/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:moneyplus/presentation/login/screen/login_screen.dart';

import '../../di/injection.dart';
import '../login/cubit/login_cubit.dart';
import '../trasnaction_details/transaction_details_screen.dart';

part 'routes.g.dart';

Expand Down Expand Up @@ -55,3 +56,15 @@ class HomeRoute extends GoRouteData with $HomeRoute {
return HomeScreen();
}
}

@TypedGoRoute<TransactionDetailsRoute>(path: '/transaction_details')
@immutable
class TransactionDetailsRoute extends GoRouteData with $TransactionDetailsRoute {
final String transactionId;
TransactionDetailsRoute(this.transactionId);

@override
Widget build(BuildContext context, GoRouterState state) {
return TransactionDetailsScreen(transactionId: transactionId);
}
}
38 changes: 37 additions & 1 deletion lib/presentation/navigation/routes.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading