Refactor billing repository interface and update usage

Renamed IBillingRepository to BillingRepository and updated all references across data, domain, and use case layers for consistency. Improved documentation and comments for repository and use cases. Adjusted typography letter spacing in design system and made minor UI tweaks to the spending breakdown card.
This commit is contained in:
Achintha Isuru
2026-01-23 14:47:06 -05:00
parent ff9ad58b8c
commit 597028436d
10 changed files with 55 additions and 28 deletions

View File

@@ -236,7 +236,7 @@ class UiTypography {
fontWeight: FontWeight.w500,
fontSize: 14,
height: 1.5,
letterSpacing: 0.7,
letterSpacing: 0.4,
color: UiColors.textPrimary,
);
@@ -245,7 +245,7 @@ class UiTypography {
fontWeight: FontWeight.w500,
fontSize: 12,
height: 1.5,
letterSpacing: 1.5,
letterSpacing: 0.7,
color: UiColors.textPrimary,
);
@@ -254,7 +254,7 @@ class UiTypography {
fontWeight: FontWeight.w500,
fontSize: 11,
height: 1.5,
letterSpacing: 2.2,
letterSpacing: 0.7,
color: UiColors.textPrimary,
);
@@ -263,7 +263,7 @@ class UiTypography {
fontWeight: FontWeight.w700,
fontSize: 11,
height: 1.5,
letterSpacing: 2.2,
letterSpacing: 0.7,
color: UiColors.textPrimary,
);

View File

@@ -1,7 +1,7 @@
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'data/repositories_impl/billing_repository_impl.dart';
import 'domain/repositories/i_billing_repository.dart';
import 'domain/repositories/billing_repository.dart';
import 'domain/usecases/get_current_bill_amount.dart';
import 'domain/usecases/get_invoice_history.dart';
import 'domain/usecases/get_pending_invoices.dart';
@@ -19,7 +19,7 @@ class BillingModule extends Module {
i.addSingleton(FinancialRepositoryMock.new);
// Repositories
i.addSingleton<IBillingRepository>(
i.addSingleton<BillingRepository>(
() => BillingRepositoryImpl(
financialRepository: i.get<FinancialRepositoryMock>(),
),

View File

@@ -1,14 +1,16 @@
import 'package:krow_data_connect/krow_data_connect.dart' as data_connect;
import 'package:krow_domain/krow_domain.dart';
import '../../domain/repositories/i_billing_repository.dart';
import '../../domain/repositories/billing_repository.dart';
/// Implementation of [IBillingRepository].
/// Implementation of [BillingRepository] in the Data layer.
///
/// Delegates data access to [FinancialRepositoryMock] from the data connect package.
/// This class is responsible for retrieving billing data from the [FinancialRepositoryMock]
/// (which represents the Data Connect layer) and mapping it to Domain entities.
///
/// In a real implementation, this would likely inject `krow_data_connect` classes.
/// Since we are using mocks exposed by `krow_data_connect`, we use them directly.
class BillingRepositoryImpl implements IBillingRepository {
/// It strictly adheres to the Clean Architecture data layer responsibilities:
/// - No business logic (except necessary data transformation/filtering).
/// - Delegates to data sources.
class BillingRepositoryImpl implements BillingRepository {
/// Creates a [BillingRepositoryImpl].
///
/// Requires the [financialRepository] to fetch financial data.
@@ -18,6 +20,7 @@ class BillingRepositoryImpl implements IBillingRepository {
final data_connect.FinancialRepositoryMock _financialRepository;
/// Fetches the current bill amount by aggregating open invoices.
@override
Future<double> getCurrentBillAmount() async {
// In a real app, this might be an aggregate query.
@@ -33,6 +36,7 @@ class BillingRepositoryImpl implements IBillingRepository {
);
}
/// Fetches the history of paid invoices.
@override
Future<List<Invoice>> getInvoiceHistory() async {
final List<Invoice> invoices = await _financialRepository.getInvoices(
@@ -43,6 +47,7 @@ class BillingRepositoryImpl implements IBillingRepository {
.toList();
}
/// Fetches pending invoices (Open or Disputed).
@override
Future<List<Invoice>> getPendingInvoices() async {
final List<Invoice> invoices = await _financialRepository.getInvoices(
@@ -57,6 +62,7 @@ class BillingRepositoryImpl implements IBillingRepository {
.toList();
}
/// Fetches the estimated savings amount.
@override
Future<double> getSavingsAmount() async {
// Simulating savings calculation (e.g., comparing to market rates).
@@ -64,6 +70,7 @@ class BillingRepositoryImpl implements IBillingRepository {
return 320.00;
}
/// Fetches the breakdown of spending.
@override
Future<List<InvoiceItem>> getSpendingBreakdown() async {
// Assuming breakdown is based on the current period's invoice items.

View File

@@ -2,8 +2,10 @@ import 'package:krow_domain/krow_domain.dart';
/// Repository interface for billing related operations.
///
/// This repository handles fetching invoices, financial summaries, and breakdowns.
abstract class IBillingRepository {
/// This interface defines the contract for accessing billing-related data,
/// acting as a boundary between the Domain and Data layers.
/// It allows the Domain layer to remain independent of specific data sources.
abstract class BillingRepository {
/// Fetches invoices that are pending approval or payment.
Future<List<Invoice>> getPendingInvoices();

View File

@@ -1,12 +1,15 @@
import 'package:krow_core/core.dart';
import '../repositories/i_billing_repository.dart';
import '../repositories/billing_repository.dart';
/// Use case for fetching the current bill amount.
///
/// This use case encapsulates the logic for retrieving the total amount due for the current billing period.
/// It delegates the data retrieval to the [BillingRepository].
class GetCurrentBillAmountUseCase extends NoInputUseCase<double> {
/// Creates a [GetCurrentBillAmountUseCase].
GetCurrentBillAmountUseCase(this._repository);
final IBillingRepository _repository;
final BillingRepository _repository;
@override
Future<double> call() => _repository.getCurrentBillAmount();

View File

@@ -1,13 +1,16 @@
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../repositories/i_billing_repository.dart';
import '../repositories/billing_repository.dart';
/// Use case for fetching the invoice history.
///
/// This use case encapsulates the logic for retrieving the list of past paid invoices.
/// It delegates the data retrieval to the [BillingRepository].
class GetInvoiceHistoryUseCase extends NoInputUseCase<List<Invoice>> {
/// Creates a [GetInvoiceHistoryUseCase].
GetInvoiceHistoryUseCase(this._repository);
final IBillingRepository _repository;
final BillingRepository _repository;
@override
Future<List<Invoice>> call() => _repository.getInvoiceHistory();

View File

@@ -1,13 +1,16 @@
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../repositories/i_billing_repository.dart';
import '../repositories/billing_repository.dart';
/// Use case for fetching the pending invoices.
///
/// This use case encapsulates the logic for retrieving invoices that are currently open or disputed.
/// It delegates the data retrieval to the [BillingRepository].
class GetPendingInvoicesUseCase extends NoInputUseCase<List<Invoice>> {
/// Creates a [GetPendingInvoicesUseCase].
GetPendingInvoicesUseCase(this._repository);
final IBillingRepository _repository;
final BillingRepository _repository;
@override
Future<List<Invoice>> call() => _repository.getPendingInvoices();

View File

@@ -1,12 +1,15 @@
import 'package:krow_core/core.dart';
import '../repositories/i_billing_repository.dart';
import '../repositories/billing_repository.dart';
/// Use case for fetching the savings amount.
///
/// This use case encapsulates the logic for retrieving the estimated savings for the client.
/// It delegates the data retrieval to the [BillingRepository].
class GetSavingsAmountUseCase extends NoInputUseCase<double> {
/// Creates a [GetSavingsAmountUseCase].
GetSavingsAmountUseCase(this._repository);
final IBillingRepository _repository;
final BillingRepository _repository;
@override
Future<double> call() => _repository.getSavingsAmount();

View File

@@ -1,13 +1,16 @@
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../repositories/i_billing_repository.dart';
import '../repositories/billing_repository.dart';
/// Use case for fetching the spending breakdown items.
///
/// This use case encapsulates the logic for retrieving the spending breakdown by category or item.
/// It delegates the data retrieval to the [BillingRepository].
class GetSpendingBreakdownUseCase extends NoInputUseCase<List<InvoiceItem>> {
/// Creates a [GetSpendingBreakdownUseCase].
GetSpendingBreakdownUseCase(this._repository);
final IBillingRepository _repository;
final BillingRepository _repository;
@override
Future<List<InvoiceItem>> call() => _repository.getSpendingBreakdown();

View File

@@ -59,12 +59,15 @@ class _SpendingBreakdownCardState extends State<SpendingBreakdownCard>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
t.client_billing.period_breakdown,
style: UiTypography.title2b.textPrimary,
Expanded(
child: Text(
t.client_billing.period_breakdown,
style: UiTypography.title2b.textPrimary,
),
),
const SizedBox(width: UiConstants.space2),
Container(
height: 28,
height: 32,
decoration: BoxDecoration(
color: UiColors.bgSecondary,
borderRadius: BorderRadius.circular(6),