import 'dart:developer'; import 'package:dartz/dartz.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/analytic/analytic.dart'; import '../../../domain/analytic/repositories/i_analytic_repository.dart'; import '../../auth/datasources/local_data_provider.dart'; import '../../outlet/datasource/local_data_provider.dart'; import '../datasource/remote_data_provider.dart'; @Injectable(as: IAnalyticRepository) class AnalyticRepository implements IAnalyticRepository { final AnalyticRemoteDataProvider _dataProvider; final AuthLocalDataProvider _authLocalDataProvider; final OutletLocalDataProvider _outletLocalDataProvider; final String _logName = 'AnalyticRepository'; AnalyticRepository( this._dataProvider, this._authLocalDataProvider, this._outletLocalDataProvider, ); /// Resolves outlet_id: pakai param jika ada, fallback ke shared pref String? _resolveOutletId(String? outletId) { return outletId ?? _outletLocalDataProvider.getSelectedOutletId(); } @override Future> getSales({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchSales( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getSalesError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getProfitLoss({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchProfitLoss( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getProfitLossError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getCategory({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchCategory( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getCategoryError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getInventory({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final currentUser = await _authLocalDataProvider.currentUser(); final resolvedId = _resolveOutletId(outletId) ?? currentUser.outletId; final result = await _dataProvider.fetchInventory( outletId: resolvedId, dateFrom: dateFrom, dateTo: dateTo, ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getInventoryError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getDashboard({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchDashboard( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getDashboardError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getProduct({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchProduct( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getProductError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } @override Future> getPaymentMethod({ required DateTime dateFrom, required DateTime dateTo, String? outletId, }) async { try { final result = await _dataProvider.fetchPaymentMethod( dateFrom: dateFrom, dateTo: dateTo, outletId: _resolveOutletId(outletId), ); if (result.hasError) return left(result.error!); return right(result.data!.toDomain()); } catch (e, s) { log('getPaymentMethodError', name: _logName, error: e, stackTrace: s); return left(const AnalyticFailure.unexpectedError()); } } }