Payout, payin , moves between wallets in same user, childScreens, transactions , card children block and unblock

This commit is contained in:
2026-02-17 20:54:14 +01:00
parent a221b7a71e
commit 2ba83a22ac
206 changed files with 23790 additions and 2216 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_PayinResponseModel _$PayinResponseModelFromJson(Map<String, dynamic> json) =>
_PayinResponseModel(
state: json['state'] as String,
status: json['status'] as String,
forwardUrl: json['forwardUrl'] as String?,
transactionReference: json['transactionReference'] as String,
capturedAmount: (json['capturedAmount'] as num).toDouble(),
orderId: json['orderId'] as String,
);
Map<String, dynamic> _$PayinResponseModelToJson(_PayinResponseModel instance) =>
<String, dynamic>{
'state': instance.state,
'status': instance.status,
'forwardUrl': instance.forwardUrl,
'transactionReference': instance.transactionReference,
'capturedAmount': instance.capturedAmount,
'orderId': instance.orderId,
};

View File

@@ -349,6 +349,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "intl",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/intl-0.20.2",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "io",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/io-1.0.5",
@@ -565,6 +571,54 @@
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "sf_localizations",
"rootUri": "../../sf_localizations",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "shared_preferences",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences-2.5.4",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "shared_preferences_android",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.20",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "shared_preferences_foundation",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "shared_preferences_linux",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "shared_preferences_platform_interface",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_platform_interface-2.4.1",
"packageUri": "lib/",
"languageVersion": "3.2"
},
{
"name": "shared_preferences_web",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "shared_preferences_windows",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "shelf",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shelf-1.4.2",

View File

@@ -19,6 +19,7 @@
"json_serializable",
"navigation",
"sf_infrastructure",
"sf_localizations",
"webview_flutter"
],
"devDependencies": [
@@ -36,6 +37,16 @@
"flutter"
]
},
{
"name": "sf_localizations",
"version": "0.0.1",
"dependencies": [
"build_runner",
"flutter",
"intl",
"utils"
]
},
{
"name": "sf_infrastructure",
"version": "0.0.1",
@@ -45,7 +56,8 @@
"dio_cookie_manager",
"flutter",
"get_it",
"path_provider"
"path_provider",
"shared_preferences"
]
},
{
@@ -286,6 +298,28 @@
"vector_math"
]
},
{
"name": "intl",
"version": "0.20.2",
"dependencies": [
"clock",
"meta",
"path"
]
},
{
"name": "shared_preferences",
"version": "2.5.4",
"dependencies": [
"flutter",
"shared_preferences_android",
"shared_preferences_foundation",
"shared_preferences_linux",
"shared_preferences_platform_interface",
"shared_preferences_web",
"shared_preferences_windows"
]
},
{
"name": "path_provider",
"version": "2.1.5",
@@ -886,6 +920,64 @@
"version": "1.4.0",
"dependencies": []
},
{
"name": "shared_preferences_windows",
"version": "2.4.1",
"dependencies": [
"file",
"flutter",
"path",
"path_provider_platform_interface",
"path_provider_windows",
"shared_preferences_platform_interface"
]
},
{
"name": "shared_preferences_web",
"version": "2.4.3",
"dependencies": [
"flutter",
"flutter_web_plugins",
"shared_preferences_platform_interface",
"web"
]
},
{
"name": "shared_preferences_platform_interface",
"version": "2.4.1",
"dependencies": [
"flutter",
"plugin_platform_interface"
]
},
{
"name": "shared_preferences_linux",
"version": "2.4.1",
"dependencies": [
"file",
"flutter",
"path",
"path_provider_linux",
"path_provider_platform_interface",
"shared_preferences_platform_interface"
]
},
{
"name": "shared_preferences_foundation",
"version": "2.5.6",
"dependencies": [
"flutter",
"shared_preferences_platform_interface"
]
},
{
"name": "shared_preferences_android",
"version": "2.4.20",
"dependencies": [
"flutter",
"shared_preferences_platform_interface"
]
},
{
"name": "path_provider_windows",
"version": "2.3.0",

View File

@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.11/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-02-12 15:07:32.166699","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.20/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.11/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-02-15 14:38:33.512667","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}

View File

@@ -2,5 +2,8 @@ export 'src/features/topup_cards/presentation/hipay_webview_builder.dart';
export 'src/features/topup_cards/presentation/hipay_webview_screen.dart';
export 'src/core/domain/entities/hipay_result.dart';
export 'src/core/domain/entities/payment_card_entity.dart';
export 'src/core/domain/entities/payin_response_entity.dart';
export 'src/core/domain/repositories/hipay_repository.dart';
export 'src/core/providers/hipay_repository_provider.dart';
export 'src/features/payin/presentation/show_payin_bottom_sheet.dart';
export 'src/features/payin/providers/payin_providers.dart';

View File

@@ -1,3 +1,4 @@
import 'package:payments/src/core/data/models/payin_response_model.dart';
import 'package:payments/src/core/data/models/payment_card_model.dart';
import 'package:payments/src/core/data/models/topup_cards_response_model.dart';
@@ -6,4 +7,5 @@ abstract class HiPayRemoteDatasource {
Future<bool> getProcessCard(String url);
Future<List<PaymentCardModel>> getTopupCards();
Future<void> deleteTopupCard(String topupCardId);
Future<PayinResponseModel> payin({required String topupCardId, required double amount});
}

View File

@@ -1,4 +1,5 @@
import 'package:dio/dio.dart';
import 'package:payments/src/core/data/models/payin_response_model.dart';
import 'package:payments/src/core/data/models/payment_card_model.dart';
import 'package:payments/src/core/data/models/topup_cards_response_model.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';
@@ -72,4 +73,24 @@ class HiPayRemoteDatasourceImpl implements HiPayRemoteDatasource {
throw Exception(msg);
}
}
@override
Future<PayinResponseModel> payin({required String topupCardId, required double amount}) async {
try {
final response = await _repository.post<Map<String, dynamic>>(
'/payments/topup-cards/$topupCardId/payin',
body: {'amount': amount},
);
final data = response.data;
if (data == null || data.isEmpty) {
throw Exception('Empty response from payin');
}
return PayinResponseModel.fromJson(data);
} on DioException catch (error) {
final msg = error.message ?? 'Error in payin';
throw Exception(msg);
}
}
}

View File

@@ -0,0 +1,32 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:payments/src/core/domain/entities/payin_response_entity.dart';
part 'payin_response_model.freezed.dart';
part 'payin_response_model.g.dart';
@freezed
abstract class PayinResponseModel with _$PayinResponseModel {
const factory PayinResponseModel({
required String state,
required String status,
String? forwardUrl,
required String transactionReference,
required double capturedAmount,
required String orderId,
}) = _PayinResponseModel;
factory PayinResponseModel.fromJson(Map<String, dynamic> json) =>
_$PayinResponseModelFromJson(json);
}
extension PayinResponseModelMapper on PayinResponseModel {
PayinResponseEntity toEntity() {
return PayinResponseEntity(
state: state,
status: status,
transactionReference: transactionReference,
capturedAmount: capturedAmount,
orderId: orderId,
);
}
}

View File

@@ -0,0 +1,292 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'payin_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PayinResponseModel {
String get state; String get status; String? get forwardUrl; String get transactionReference; double get capturedAmount; String get orderId;
/// Create a copy of PayinResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PayinResponseModelCopyWith<PayinResponseModel> get copyWith => _$PayinResponseModelCopyWithImpl<PayinResponseModel>(this as PayinResponseModel, _$identity);
/// Serializes this PayinResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PayinResponseModel&&(identical(other.state, state) || other.state == state)&&(identical(other.status, status) || other.status == status)&&(identical(other.forwardUrl, forwardUrl) || other.forwardUrl == forwardUrl)&&(identical(other.transactionReference, transactionReference) || other.transactionReference == transactionReference)&&(identical(other.capturedAmount, capturedAmount) || other.capturedAmount == capturedAmount)&&(identical(other.orderId, orderId) || other.orderId == orderId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,state,status,forwardUrl,transactionReference,capturedAmount,orderId);
@override
String toString() {
return 'PayinResponseModel(state: $state, status: $status, forwardUrl: $forwardUrl, transactionReference: $transactionReference, capturedAmount: $capturedAmount, orderId: $orderId)';
}
}
/// @nodoc
abstract mixin class $PayinResponseModelCopyWith<$Res> {
factory $PayinResponseModelCopyWith(PayinResponseModel value, $Res Function(PayinResponseModel) _then) = _$PayinResponseModelCopyWithImpl;
@useResult
$Res call({
String state, String status, String? forwardUrl, String transactionReference, double capturedAmount, String orderId
});
}
/// @nodoc
class _$PayinResponseModelCopyWithImpl<$Res>
implements $PayinResponseModelCopyWith<$Res> {
_$PayinResponseModelCopyWithImpl(this._self, this._then);
final PayinResponseModel _self;
final $Res Function(PayinResponseModel) _then;
/// Create a copy of PayinResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? state = null,Object? status = null,Object? forwardUrl = freezed,Object? transactionReference = null,Object? capturedAmount = null,Object? orderId = null,}) {
return _then(_self.copyWith(
state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,forwardUrl: freezed == forwardUrl ? _self.forwardUrl : forwardUrl // ignore: cast_nullable_to_non_nullable
as String?,transactionReference: null == transactionReference ? _self.transactionReference : transactionReference // ignore: cast_nullable_to_non_nullable
as String,capturedAmount: null == capturedAmount ? _self.capturedAmount : capturedAmount // ignore: cast_nullable_to_non_nullable
as double,orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [PayinResponseModel].
extension PayinResponseModelPatterns on PayinResponseModel {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PayinResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PayinResponseModel() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PayinResponseModel value) $default,){
final _that = this;
switch (_that) {
case _PayinResponseModel():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PayinResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _PayinResponseModel() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String state, String status, String? forwardUrl, String transactionReference, double capturedAmount, String orderId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PayinResponseModel() when $default != null:
return $default(_that.state,_that.status,_that.forwardUrl,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String state, String status, String? forwardUrl, String transactionReference, double capturedAmount, String orderId) $default,) {final _that = this;
switch (_that) {
case _PayinResponseModel():
return $default(_that.state,_that.status,_that.forwardUrl,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String state, String status, String? forwardUrl, String transactionReference, double capturedAmount, String orderId)? $default,) {final _that = this;
switch (_that) {
case _PayinResponseModel() when $default != null:
return $default(_that.state,_that.status,_that.forwardUrl,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _PayinResponseModel implements PayinResponseModel {
const _PayinResponseModel({required this.state, required this.status, this.forwardUrl, required this.transactionReference, required this.capturedAmount, required this.orderId});
factory _PayinResponseModel.fromJson(Map<String, dynamic> json) => _$PayinResponseModelFromJson(json);
@override final String state;
@override final String status;
@override final String? forwardUrl;
@override final String transactionReference;
@override final double capturedAmount;
@override final String orderId;
/// Create a copy of PayinResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PayinResponseModelCopyWith<_PayinResponseModel> get copyWith => __$PayinResponseModelCopyWithImpl<_PayinResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$PayinResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PayinResponseModel&&(identical(other.state, state) || other.state == state)&&(identical(other.status, status) || other.status == status)&&(identical(other.forwardUrl, forwardUrl) || other.forwardUrl == forwardUrl)&&(identical(other.transactionReference, transactionReference) || other.transactionReference == transactionReference)&&(identical(other.capturedAmount, capturedAmount) || other.capturedAmount == capturedAmount)&&(identical(other.orderId, orderId) || other.orderId == orderId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,state,status,forwardUrl,transactionReference,capturedAmount,orderId);
@override
String toString() {
return 'PayinResponseModel(state: $state, status: $status, forwardUrl: $forwardUrl, transactionReference: $transactionReference, capturedAmount: $capturedAmount, orderId: $orderId)';
}
}
/// @nodoc
abstract mixin class _$PayinResponseModelCopyWith<$Res> implements $PayinResponseModelCopyWith<$Res> {
factory _$PayinResponseModelCopyWith(_PayinResponseModel value, $Res Function(_PayinResponseModel) _then) = __$PayinResponseModelCopyWithImpl;
@override @useResult
$Res call({
String state, String status, String? forwardUrl, String transactionReference, double capturedAmount, String orderId
});
}
/// @nodoc
class __$PayinResponseModelCopyWithImpl<$Res>
implements _$PayinResponseModelCopyWith<$Res> {
__$PayinResponseModelCopyWithImpl(this._self, this._then);
final _PayinResponseModel _self;
final $Res Function(_PayinResponseModel) _then;
/// Create a copy of PayinResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? state = null,Object? status = null,Object? forwardUrl = freezed,Object? transactionReference = null,Object? capturedAmount = null,Object? orderId = null,}) {
return _then(_PayinResponseModel(
state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,forwardUrl: freezed == forwardUrl ? _self.forwardUrl : forwardUrl // ignore: cast_nullable_to_non_nullable
as String?,transactionReference: null == transactionReference ? _self.transactionReference : transactionReference // ignore: cast_nullable_to_non_nullable
as String,capturedAmount: null == capturedAmount ? _self.capturedAmount : capturedAmount // ignore: cast_nullable_to_non_nullable
as double,orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'payin_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_PayinResponseModel _$PayinResponseModelFromJson(Map<String, dynamic> json) =>
_PayinResponseModel(
state: json['state'] as String,
status: json['status'] as String,
forwardUrl: json['forwardUrl'] as String?,
transactionReference: json['transactionReference'] as String,
capturedAmount: (json['capturedAmount'] as num).toDouble(),
orderId: json['orderId'] as String,
);
Map<String, dynamic> _$PayinResponseModelToJson(_PayinResponseModel instance) =>
<String, dynamic>{
'state': instance.state,
'status': instance.status,
'forwardUrl': instance.forwardUrl,
'transactionReference': instance.transactionReference,
'capturedAmount': instance.capturedAmount,
'orderId': instance.orderId,
};

View File

@@ -1,6 +1,8 @@
import 'package:payments/src/core/data/datasource/hipay_remote_datasource.dart';
import 'package:payments/src/core/data/models/payin_response_model.dart';
import 'package:payments/src/core/data/models/payment_card_model.dart';
import 'package:payments/src/core/data/models/topup_cards_response_model.dart';
import 'package:payments/src/core/domain/entities/payin_response_entity.dart';
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
import 'package:payments/src/core/domain/entities/topup_cards_entity.dart';
import 'package:payments/src/core/domain/repositories/hipay_repository.dart';
@@ -31,4 +33,10 @@ class HiPayRepositoryImpl implements HiPayRepository {
Future<void> deleteTopupCard(String topupCardId) {
return _remote.deleteTopupCard(topupCardId);
}
@override
Future<PayinResponseEntity> payin({required String topupCardId, required double amount}) async {
final model = await _remote.payin(topupCardId: topupCardId, amount: amount);
return model.toEntity();
}
}

View File

@@ -0,0 +1,14 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'payin_response_entity.freezed.dart';
@freezed
abstract class PayinResponseEntity with _$PayinResponseEntity {
const factory PayinResponseEntity({
required String state,
required String status,
required String transactionReference,
required double capturedAmount,
required String orderId,
}) = _PayinResponseEntity;
}

View File

@@ -0,0 +1,283 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'payin_response_entity.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PayinResponseEntity {
String get state; String get status; String get transactionReference; double get capturedAmount; String get orderId;
/// Create a copy of PayinResponseEntity
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PayinResponseEntityCopyWith<PayinResponseEntity> get copyWith => _$PayinResponseEntityCopyWithImpl<PayinResponseEntity>(this as PayinResponseEntity, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PayinResponseEntity&&(identical(other.state, state) || other.state == state)&&(identical(other.status, status) || other.status == status)&&(identical(other.transactionReference, transactionReference) || other.transactionReference == transactionReference)&&(identical(other.capturedAmount, capturedAmount) || other.capturedAmount == capturedAmount)&&(identical(other.orderId, orderId) || other.orderId == orderId));
}
@override
int get hashCode => Object.hash(runtimeType,state,status,transactionReference,capturedAmount,orderId);
@override
String toString() {
return 'PayinResponseEntity(state: $state, status: $status, transactionReference: $transactionReference, capturedAmount: $capturedAmount, orderId: $orderId)';
}
}
/// @nodoc
abstract mixin class $PayinResponseEntityCopyWith<$Res> {
factory $PayinResponseEntityCopyWith(PayinResponseEntity value, $Res Function(PayinResponseEntity) _then) = _$PayinResponseEntityCopyWithImpl;
@useResult
$Res call({
String state, String status, String transactionReference, double capturedAmount, String orderId
});
}
/// @nodoc
class _$PayinResponseEntityCopyWithImpl<$Res>
implements $PayinResponseEntityCopyWith<$Res> {
_$PayinResponseEntityCopyWithImpl(this._self, this._then);
final PayinResponseEntity _self;
final $Res Function(PayinResponseEntity) _then;
/// Create a copy of PayinResponseEntity
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? state = null,Object? status = null,Object? transactionReference = null,Object? capturedAmount = null,Object? orderId = null,}) {
return _then(_self.copyWith(
state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,transactionReference: null == transactionReference ? _self.transactionReference : transactionReference // ignore: cast_nullable_to_non_nullable
as String,capturedAmount: null == capturedAmount ? _self.capturedAmount : capturedAmount // ignore: cast_nullable_to_non_nullable
as double,orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [PayinResponseEntity].
extension PayinResponseEntityPatterns on PayinResponseEntity {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PayinResponseEntity value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PayinResponseEntity() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PayinResponseEntity value) $default,){
final _that = this;
switch (_that) {
case _PayinResponseEntity():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PayinResponseEntity value)? $default,){
final _that = this;
switch (_that) {
case _PayinResponseEntity() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String state, String status, String transactionReference, double capturedAmount, String orderId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PayinResponseEntity() when $default != null:
return $default(_that.state,_that.status,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String state, String status, String transactionReference, double capturedAmount, String orderId) $default,) {final _that = this;
switch (_that) {
case _PayinResponseEntity():
return $default(_that.state,_that.status,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String state, String status, String transactionReference, double capturedAmount, String orderId)? $default,) {final _that = this;
switch (_that) {
case _PayinResponseEntity() when $default != null:
return $default(_that.state,_that.status,_that.transactionReference,_that.capturedAmount,_that.orderId);case _:
return null;
}
}
}
/// @nodoc
class _PayinResponseEntity implements PayinResponseEntity {
const _PayinResponseEntity({required this.state, required this.status, required this.transactionReference, required this.capturedAmount, required this.orderId});
@override final String state;
@override final String status;
@override final String transactionReference;
@override final double capturedAmount;
@override final String orderId;
/// Create a copy of PayinResponseEntity
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PayinResponseEntityCopyWith<_PayinResponseEntity> get copyWith => __$PayinResponseEntityCopyWithImpl<_PayinResponseEntity>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PayinResponseEntity&&(identical(other.state, state) || other.state == state)&&(identical(other.status, status) || other.status == status)&&(identical(other.transactionReference, transactionReference) || other.transactionReference == transactionReference)&&(identical(other.capturedAmount, capturedAmount) || other.capturedAmount == capturedAmount)&&(identical(other.orderId, orderId) || other.orderId == orderId));
}
@override
int get hashCode => Object.hash(runtimeType,state,status,transactionReference,capturedAmount,orderId);
@override
String toString() {
return 'PayinResponseEntity(state: $state, status: $status, transactionReference: $transactionReference, capturedAmount: $capturedAmount, orderId: $orderId)';
}
}
/// @nodoc
abstract mixin class _$PayinResponseEntityCopyWith<$Res> implements $PayinResponseEntityCopyWith<$Res> {
factory _$PayinResponseEntityCopyWith(_PayinResponseEntity value, $Res Function(_PayinResponseEntity) _then) = __$PayinResponseEntityCopyWithImpl;
@override @useResult
$Res call({
String state, String status, String transactionReference, double capturedAmount, String orderId
});
}
/// @nodoc
class __$PayinResponseEntityCopyWithImpl<$Res>
implements _$PayinResponseEntityCopyWith<$Res> {
__$PayinResponseEntityCopyWithImpl(this._self, this._then);
final _PayinResponseEntity _self;
final $Res Function(_PayinResponseEntity) _then;
/// Create a copy of PayinResponseEntity
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? state = null,Object? status = null,Object? transactionReference = null,Object? capturedAmount = null,Object? orderId = null,}) {
return _then(_PayinResponseEntity(
state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,transactionReference: null == transactionReference ? _self.transactionReference : transactionReference // ignore: cast_nullable_to_non_nullable
as String,capturedAmount: null == capturedAmount ? _self.capturedAmount : capturedAmount // ignore: cast_nullable_to_non_nullable
as double,orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

View File

@@ -1,3 +1,4 @@
import 'package:payments/src/core/domain/entities/payin_response_entity.dart';
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
import 'package:payments/src/core/domain/entities/topup_cards_entity.dart';
@@ -6,4 +7,5 @@ abstract class HiPayRepository {
Future<bool> getProcessCard(String url);
Future<List<PaymentCardEntity>> getTopupCards();
Future<void> deleteTopupCard(String topupCardId);
Future<PayinResponseEntity> payin({required String topupCardId, required double amount});
}

View File

@@ -0,0 +1,14 @@
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
import 'package:payments/src/core/domain/repositories/hipay_repository.dart';
abstract class GetPaymentCardsUseCase {
Future<List<PaymentCardEntity>> call();
}
class GetPaymentCardsUseCaseImpl implements GetPaymentCardsUseCase {
GetPaymentCardsUseCaseImpl(this._repository);
final HiPayRepository _repository;
@override
Future<List<PaymentCardEntity>> call() => _repository.getTopupCards();
}

View File

@@ -0,0 +1,16 @@
import 'package:payments/src/core/domain/entities/payin_response_entity.dart';
import 'package:payments/src/core/domain/repositories/hipay_repository.dart';
abstract class PayinUseCase {
Future<PayinResponseEntity> call({required String topupCardId, required double amount});
}
class PayinUseCaseImpl implements PayinUseCase {
PayinUseCaseImpl(this._repository);
final HiPayRepository _repository;
@override
Future<PayinResponseEntity> call({required String topupCardId, required double amount}) {
return _repository.payin(topupCardId: topupCardId, amount: amount);
}
}

View File

@@ -0,0 +1,178 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:navigation/navigation.dart';
import 'package:payments/src/core/domain/entities/hipay_result.dart';
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
import 'package:payments/src/features/payin/presentation/payin_view_model.dart';
import 'package:payments/src/features/topup_cards/presentation/hipay_webview_screen.dart';
import 'package:sf_localizations/sf_localizations.dart';
class PayinBottomSheet extends ConsumerStatefulWidget {
final double amount;
final NavigationContract navigation;
const PayinBottomSheet({
super.key,
required this.amount,
required this.navigation,
});
@override
ConsumerState<PayinBottomSheet> createState() => _PayinBottomSheetState();
}
class _PayinBottomSheetState extends ConsumerState<PayinBottomSheet> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(payinViewModelProvider.notifier).loadCards();
});
}
Future<void> _addCard() async {
final result = await Navigator.of(context).push<HiPayResult>(
MaterialPageRoute(
builder: (_) => HiPayWebViewScreen(navigationContract: widget.navigation),
),
);
if (result == HiPayResult.success && mounted) {
ref.read(payinViewModelProvider.notifier).loadCards();
}
}
@override
Widget build(BuildContext context) {
final theme = ref.watch(themePortProvider);
final viewState = ref.watch(payinViewModelProvider);
ref.listen(payinViewModelProvider, (prev, next) {
if (next.success && !(prev?.success ?? false)) {
Navigator.of(context).pop(true);
}
if (next.errorMessage.isNotEmpty && next.errorMessage != (prev?.errorMessage ?? '')) {
showTopSnackbar(context, message: context.translate(I18n.payinError), type: MessageType.error);
}
});
return SafeArea(
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: 24,
right: 24,
top: 24,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
context.translate(I18n.payinSelectCard),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
const SizedBox(height: 16),
if (viewState.isLoadingCards)
const Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Center(child: CircularProgressIndicator()),
)
else if (viewState.cards.isEmpty)
_buildNoCards(context, theme)
else
_buildCardList(context, theme, viewState.cards, viewState.selectedCard),
if (viewState.cards.isNotEmpty) ...[
const SizedBox(height: 8),
TextButton(
onPressed: _addCard,
child: Text(context.translate(I18n.payinAddCard)),
),
const SizedBox(height: 12),
PrimaryButton(
onPressed: viewState.selectedCard != null && !viewState.isProcessing
? () => ref.read(payinViewModelProvider.notifier).executePayin(widget.amount)
: null,
text: viewState.isProcessing
? context.translate(I18n.payinProcessing)
: context.translate(I18n.payinDeposit),
color: theme.getColorFor(ThemeCode.buttonPrimary),
),
],
const SizedBox(height: 16),
],
),
),
);
}
Widget _buildNoCards(BuildContext context, ThemePort theme) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 24),
child: Text(
context.translate(I18n.payinNoCards),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
),
PrimaryButton(
onPressed: _addCard,
text: context.translate(I18n.payinAddCard),
color: theme.getColorFor(ThemeCode.buttonPrimary),
),
],
);
}
Widget _buildCardList(
BuildContext context,
ThemePort theme,
List<PaymentCardEntity> cards,
PaymentCardEntity? selectedCard,
) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: 250),
child: ListView.separated(
shrinkWrap: true,
itemCount: cards.length,
separatorBuilder: (_, __) => const Divider(height: 1),
itemBuilder: (context, index) {
final card = cards[index];
final isSelected = selectedCard?.topupCardId == card.topupCardId;
return ListTile(
leading: Icon(
Icons.credit_card,
size: 32,
color: theme.getColorFor(ThemeCode.textPrimary),
),
title: Text(
card.maskedPan,
style: TextStyle(
fontWeight: FontWeight.w500,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
subtitle: Text(
card.cardHolder,
style: TextStyle(color: theme.getColorFor(ThemeCode.textPrimary)),
),
trailing: isSelected
? Icon(Icons.check_circle, color: theme.getColorFor(ThemeCode.buttonPrimary))
: null,
selected: isSelected,
onTap: () => ref.read(payinViewModelProvider.notifier).selectCard(card),
);
},
),
);
}
}

View File

@@ -0,0 +1,49 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
import 'package:payments/src/features/payin/presentation/payin_view_state.dart';
import 'package:payments/src/features/payin/providers/payin_providers.dart';
final payinViewModelProvider =
NotifierProvider.autoDispose<PayinViewModel, PayinViewState>(PayinViewModel.new);
class PayinViewModel extends Notifier<PayinViewState> {
@override
PayinViewState build() {
return const PayinViewState();
}
Future<void> loadCards() async {
state = state.copyWith(isLoadingCards: true, errorMessage: '');
try {
final allCards = await ref.read(getPaymentCardsUseCaseProvider).call();
if (!ref.mounted) return;
final cards = allCards.where((c) => c.status.toLowerCase() == 'validated').toList();
state = state.copyWith(isLoadingCards: false, cards: cards);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(isLoadingCards: false, errorMessage: e.toString());
}
}
void selectCard(PaymentCardEntity card) {
state = state.copyWith(selectedCard: card, errorMessage: '');
}
Future<void> executePayin(double amount) async {
final card = state.selectedCard;
if (card == null) return;
state = state.copyWith(isProcessing: true, errorMessage: '');
try {
await ref.read(payinUseCaseProvider).call(
topupCardId: card.topupCardId,
amount: amount,
);
if (!ref.mounted) return;
state = state.copyWith(isProcessing: false, success: true);
} catch (e) {
if (!ref.mounted) return;
state = state.copyWith(isProcessing: false, errorMessage: e.toString());
}
}
}

View File

@@ -0,0 +1,16 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:payments/src/core/domain/entities/payment_card_entity.dart';
part 'payin_view_state.freezed.dart';
@freezed
abstract class PayinViewState with _$PayinViewState {
const factory PayinViewState({
@Default(true) bool isLoadingCards,
@Default([]) List<PaymentCardEntity> cards,
PaymentCardEntity? selectedCard,
@Default(false) bool isProcessing,
@Default('') String errorMessage,
@Default(false) bool success,
}) = _PayinViewState;
}

View File

@@ -0,0 +1,316 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'payin_view_state.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PayinViewState {
bool get isLoadingCards; List<PaymentCardEntity> get cards; PaymentCardEntity? get selectedCard; bool get isProcessing; String get errorMessage; bool get success;
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PayinViewStateCopyWith<PayinViewState> get copyWith => _$PayinViewStateCopyWithImpl<PayinViewState>(this as PayinViewState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PayinViewState&&(identical(other.isLoadingCards, isLoadingCards) || other.isLoadingCards == isLoadingCards)&&const DeepCollectionEquality().equals(other.cards, cards)&&(identical(other.selectedCard, selectedCard) || other.selectedCard == selectedCard)&&(identical(other.isProcessing, isProcessing) || other.isProcessing == isProcessing)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.success, success) || other.success == success));
}
@override
int get hashCode => Object.hash(runtimeType,isLoadingCards,const DeepCollectionEquality().hash(cards),selectedCard,isProcessing,errorMessage,success);
@override
String toString() {
return 'PayinViewState(isLoadingCards: $isLoadingCards, cards: $cards, selectedCard: $selectedCard, isProcessing: $isProcessing, errorMessage: $errorMessage, success: $success)';
}
}
/// @nodoc
abstract mixin class $PayinViewStateCopyWith<$Res> {
factory $PayinViewStateCopyWith(PayinViewState value, $Res Function(PayinViewState) _then) = _$PayinViewStateCopyWithImpl;
@useResult
$Res call({
bool isLoadingCards, List<PaymentCardEntity> cards, PaymentCardEntity? selectedCard, bool isProcessing, String errorMessage, bool success
});
$PaymentCardEntityCopyWith<$Res>? get selectedCard;
}
/// @nodoc
class _$PayinViewStateCopyWithImpl<$Res>
implements $PayinViewStateCopyWith<$Res> {
_$PayinViewStateCopyWithImpl(this._self, this._then);
final PayinViewState _self;
final $Res Function(PayinViewState) _then;
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isLoadingCards = null,Object? cards = null,Object? selectedCard = freezed,Object? isProcessing = null,Object? errorMessage = null,Object? success = null,}) {
return _then(_self.copyWith(
isLoadingCards: null == isLoadingCards ? _self.isLoadingCards : isLoadingCards // ignore: cast_nullable_to_non_nullable
as bool,cards: null == cards ? _self.cards : cards // ignore: cast_nullable_to_non_nullable
as List<PaymentCardEntity>,selectedCard: freezed == selectedCard ? _self.selectedCard : selectedCard // ignore: cast_nullable_to_non_nullable
as PaymentCardEntity?,isProcessing: null == isProcessing ? _self.isProcessing : isProcessing // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
as bool,
));
}
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PaymentCardEntityCopyWith<$Res>? get selectedCard {
if (_self.selectedCard == null) {
return null;
}
return $PaymentCardEntityCopyWith<$Res>(_self.selectedCard!, (value) {
return _then(_self.copyWith(selectedCard: value));
});
}
}
/// Adds pattern-matching-related methods to [PayinViewState].
extension PayinViewStatePatterns on PayinViewState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PayinViewState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PayinViewState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PayinViewState value) $default,){
final _that = this;
switch (_that) {
case _PayinViewState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PayinViewState value)? $default,){
final _that = this;
switch (_that) {
case _PayinViewState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isLoadingCards, List<PaymentCardEntity> cards, PaymentCardEntity? selectedCard, bool isProcessing, String errorMessage, bool success)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PayinViewState() when $default != null:
return $default(_that.isLoadingCards,_that.cards,_that.selectedCard,_that.isProcessing,_that.errorMessage,_that.success);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isLoadingCards, List<PaymentCardEntity> cards, PaymentCardEntity? selectedCard, bool isProcessing, String errorMessage, bool success) $default,) {final _that = this;
switch (_that) {
case _PayinViewState():
return $default(_that.isLoadingCards,_that.cards,_that.selectedCard,_that.isProcessing,_that.errorMessage,_that.success);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isLoadingCards, List<PaymentCardEntity> cards, PaymentCardEntity? selectedCard, bool isProcessing, String errorMessage, bool success)? $default,) {final _that = this;
switch (_that) {
case _PayinViewState() when $default != null:
return $default(_that.isLoadingCards,_that.cards,_that.selectedCard,_that.isProcessing,_that.errorMessage,_that.success);case _:
return null;
}
}
}
/// @nodoc
class _PayinViewState implements PayinViewState {
const _PayinViewState({this.isLoadingCards = true, final List<PaymentCardEntity> cards = const [], this.selectedCard, this.isProcessing = false, this.errorMessage = '', this.success = false}): _cards = cards;
@override@JsonKey() final bool isLoadingCards;
final List<PaymentCardEntity> _cards;
@override@JsonKey() List<PaymentCardEntity> get cards {
if (_cards is EqualUnmodifiableListView) return _cards;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_cards);
}
@override final PaymentCardEntity? selectedCard;
@override@JsonKey() final bool isProcessing;
@override@JsonKey() final String errorMessage;
@override@JsonKey() final bool success;
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PayinViewStateCopyWith<_PayinViewState> get copyWith => __$PayinViewStateCopyWithImpl<_PayinViewState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PayinViewState&&(identical(other.isLoadingCards, isLoadingCards) || other.isLoadingCards == isLoadingCards)&&const DeepCollectionEquality().equals(other._cards, _cards)&&(identical(other.selectedCard, selectedCard) || other.selectedCard == selectedCard)&&(identical(other.isProcessing, isProcessing) || other.isProcessing == isProcessing)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.success, success) || other.success == success));
}
@override
int get hashCode => Object.hash(runtimeType,isLoadingCards,const DeepCollectionEquality().hash(_cards),selectedCard,isProcessing,errorMessage,success);
@override
String toString() {
return 'PayinViewState(isLoadingCards: $isLoadingCards, cards: $cards, selectedCard: $selectedCard, isProcessing: $isProcessing, errorMessage: $errorMessage, success: $success)';
}
}
/// @nodoc
abstract mixin class _$PayinViewStateCopyWith<$Res> implements $PayinViewStateCopyWith<$Res> {
factory _$PayinViewStateCopyWith(_PayinViewState value, $Res Function(_PayinViewState) _then) = __$PayinViewStateCopyWithImpl;
@override @useResult
$Res call({
bool isLoadingCards, List<PaymentCardEntity> cards, PaymentCardEntity? selectedCard, bool isProcessing, String errorMessage, bool success
});
@override $PaymentCardEntityCopyWith<$Res>? get selectedCard;
}
/// @nodoc
class __$PayinViewStateCopyWithImpl<$Res>
implements _$PayinViewStateCopyWith<$Res> {
__$PayinViewStateCopyWithImpl(this._self, this._then);
final _PayinViewState _self;
final $Res Function(_PayinViewState) _then;
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isLoadingCards = null,Object? cards = null,Object? selectedCard = freezed,Object? isProcessing = null,Object? errorMessage = null,Object? success = null,}) {
return _then(_PayinViewState(
isLoadingCards: null == isLoadingCards ? _self.isLoadingCards : isLoadingCards // ignore: cast_nullable_to_non_nullable
as bool,cards: null == cards ? _self._cards : cards // ignore: cast_nullable_to_non_nullable
as List<PaymentCardEntity>,selectedCard: freezed == selectedCard ? _self.selectedCard : selectedCard // ignore: cast_nullable_to_non_nullable
as PaymentCardEntity?,isProcessing: null == isProcessing ? _self.isProcessing : isProcessing // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
as bool,
));
}
/// Create a copy of PayinViewState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PaymentCardEntityCopyWith<$Res>? get selectedCard {
if (_self.selectedCard == null) {
return null;
}
return $PaymentCardEntityCopyWith<$Res>(_self.selectedCard!, (value) {
return _then(_self.copyWith(selectedCard: value));
});
}
}
// dart format on

View File

@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
import 'package:navigation/navigation.dart';
import 'package:payments/src/features/payin/presentation/payin_bottom_sheet.dart';
Future<bool?> showPayinBottomSheet(
BuildContext context, {
required double amount,
required NavigationContract navigation,
}) {
return showModalBottomSheet<bool>(
context: context,
isScrollControlled: true,
builder: (_) => PayinBottomSheet(amount: amount, navigation: navigation),
);
}

View File

@@ -0,0 +1,12 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:payments/src/core/providers/hipay_repository_provider.dart';
import 'package:payments/src/features/payin/domain/use_cases/get_payment_cards_use_case.dart';
import 'package:payments/src/features/payin/domain/use_cases/payin_use_case.dart';
final payinUseCaseProvider = Provider.autoDispose<PayinUseCase>((ref) {
return PayinUseCaseImpl(ref.read(hipayRepositoryProvider));
});
final getPaymentCardsUseCaseProvider = Provider.autoDispose<GetPaymentCardsUseCase>((ref) {
return GetPaymentCardsUseCaseImpl(ref.read(hipayRepositoryProvider));
});

View File

@@ -454,6 +454,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.2"
intl:
dependency: transitive
description:
name: intl
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.20.2"
io:
dependency: transitive
description:
@@ -740,6 +748,69 @@ packages:
relative: true
source: path
version: "0.0.1"
sf_localizations:
dependency: "direct main"
description:
path: "../sf_localizations"
relative: true
source: path
version: "0.0.1"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f
url: "https://pub.dev"
source: hosted
version: "2.4.20"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
url: "https://pub.dev"
source: hosted
version: "2.5.6"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
url: "https://pub.dev"
source: hosted
version: "2.4.3"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shelf:
dependency: transitive
description:

View File

@@ -18,6 +18,8 @@ dependencies:
path: ../../packages/navigation
sf_infrastructure:
path: ../../packages/sf_infrastructure
sf_localizations:
path: ../../packages/sf_localizations
#dependencies go here
get_it: ^9.0.5
go_router: ^17.0.0

View File

@@ -1,4 +1,4 @@
# melos_managed_dependency_overrides: design_system,fonts,navigation,sf_infrastructure,utils
# melos_managed_dependency_overrides: design_system,fonts,navigation,sf_infrastructure,utils,sf_localizations
dependency_overrides:
design_system:
path: ../design_system
@@ -8,5 +8,7 @@ dependency_overrides:
path: ../navigation
sf_infrastructure:
path: ../sf_infrastructure
sf_localizations:
path: ../sf_localizations
utils:
path: ../utils