diff --git a/lib/ionia/ionia_api.dart b/lib/ionia/ionia_api.dart index c99a5e1ae..80280860e 100644 --- a/lib/ionia/ionia_api.dart +++ b/lib/ionia/ionia_api.dart @@ -159,9 +159,14 @@ class IoniaApi { final data = decodedBody['Data'] as List; return data.map((dynamic e) { - final element = e as Map; - return IoniaMerchant.fromJsonMap(element); - }).toList(); + try { + final element = e as Map; + return IoniaMerchant.fromJsonMap(element); + } catch(_) { + return null; + } + }).where((e) => e != null) + .toList(); } // Get Merchants By Filter @@ -208,9 +213,14 @@ class IoniaApi { final data = decodedBody['Data'] as List; return data.map((dynamic e) { - final element = e['Merchant'] as Map; - return IoniaMerchant.fromJsonMap(element); - }).toList(); + try { + final element = e['Merchant'] as Map; + return IoniaMerchant.fromJsonMap(element); + } catch(_) { + return null; + } + }).where((e) => e != null) + .toList(); } // Purchase Gift Card @@ -273,9 +283,14 @@ class IoniaApi { final data = decodedBody['Data'] as List; return data.map((dynamic e) { - final element = e as Map; - return IoniaGiftCard.fromJsonMap(element); - }).toList(); + try { + final element = e as Map; + return IoniaGiftCard.fromJsonMap(element); + } catch(e) { + return null; + } + }).where((e) => e != null) + .toList(); } // Charge Gift Card diff --git a/lib/ionia/ionia_gift_card.dart b/lib/ionia/ionia_gift_card.dart index cc8c3dbaa..ebe8084f8 100644 --- a/lib/ionia/ionia_gift_card.dart +++ b/lib/ionia/ionia_gift_card.dart @@ -1,20 +1,7 @@ import 'dart:convert'; - +import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart'; import 'package:flutter/foundation.dart'; -class IoniaGiftCardInstruction { - IoniaGiftCardInstruction(this.header, this.body); - - factory IoniaGiftCardInstruction.fromJsonMap(Map element) { - return IoniaGiftCardInstruction( - element['header'] as String, - element['body'] as String); - } - - final String header; - final String body; -} - class IoniaGiftCard { IoniaGiftCard({ @required this.id, @@ -24,10 +11,7 @@ class IoniaGiftCard { @required this.barcodeUrl, @required this.cardNumber, @required this.cardPin, - @required this.usageInstructions, - @required this.balanceInstructions, - @required this.paymentInstructions, - @required this.cardImageUrl, + @required this.instructions, @required this.tip, @required this.purchaseAmount, @required this.actualAmount, @@ -41,11 +25,6 @@ class IoniaGiftCard { @required this.logoUrl}); factory IoniaGiftCard.fromJsonMap(Map element) { - final decodedInstructions = json.decode(element['UsageInstructions'] as String) as Map; - final instruction = decodedInstructions['instruction'] as List; - final instructions = instruction - .map((dynamic e) =>IoniaGiftCardInstruction.fromJsonMap(e as Map)) - .toList(); return IoniaGiftCard( id: element['Id'] as int, merchantId: element['MerchantId'] as int, @@ -65,7 +44,7 @@ class IoniaGiftCard { logoUrl: element['LogoUrl'] as String, createdDateFormatted: element['CreatedDate'] as String, lastTransactionDateFormatted: element['LastTransactionDate'] as String, - usageInstructions: instructions); + instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String)); } final int id; @@ -75,10 +54,7 @@ class IoniaGiftCard { final String barcodeUrl; final String cardNumber; final String cardPin; - final List usageInstructions; - final Map balanceInstructions; - final Map paymentInstructions; - final String cardImageUrl; + final List instructions; final double tip; final double purchaseAmount; final double actualAmount; diff --git a/lib/ionia/ionia_gift_card_instruction.dart b/lib/ionia/ionia_gift_card_instruction.dart new file mode 100644 index 000000000..da1fdae1b --- /dev/null +++ b/lib/ionia/ionia_gift_card_instruction.dart @@ -0,0 +1,28 @@ +import 'dart:convert'; +import 'package:intl/intl.dart' show toBeginningOfSentenceCase; + +class IoniaGiftCardInstruction { + IoniaGiftCardInstruction(this.header, this.body); + + factory IoniaGiftCardInstruction.fromJsonMap(Map element) { + return IoniaGiftCardInstruction( + toBeginningOfSentenceCase(element['title'] as String ?? ''), + element['description'] as String); + } + + static List parseListOfInstructions(String instructionsJSON) { + List instructions = []; + + if (instructionsJSON.isNotEmpty) { + final decodedInstructions = json.decode(instructionsJSON) as List; + instructions = decodedInstructions + .map((dynamic e) =>IoniaGiftCardInstruction.fromJsonMap(e as Map)) + .toList(); + } + + return instructions; + } + + final String header; + final String body; +} \ No newline at end of file diff --git a/lib/ionia/ionia_merchant.dart b/lib/ionia/ionia_merchant.dart index 92ce0c03f..96e671652 100644 --- a/lib/ionia/ionia_merchant.dart +++ b/lib/ionia/ionia_merchant.dart @@ -1,4 +1,6 @@ import 'package:flutter/foundation.dart'; +import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart'; + class IoniaMerchant { IoniaMerchant({ @required this.id, @@ -48,7 +50,7 @@ class IoniaMerchant { @required this.isVoidable, @required this.receiptMessage, @required this.cssBorderCode, - @required this.paymentInstructions, + @required this.instructions, @required this.alderSku, @required this.ngcSku, @required this.acceptedCurrency, @@ -59,103 +61,112 @@ class IoniaMerchant { factory IoniaMerchant.fromJsonMap(Map element) { return IoniaMerchant( id: element["Id"] as int, - legalName: element["LegalName"] as String, - systemName: element["SystemName"] as String, - description: element["Description"] as String, - website: element["Website"] as String, - termsAndConditions: element["TermsAndConditions"] as String, - logoUrl: element["LogoUrl"] as String, - cardImageUrl: element["CardImageUrl"] as String, - cardholderAgreement: element["CardholderAgreement"] as String, - purchaseFee: element["PurchaseFee"] as double, - revenueShare: element["RevenueShare"] as double, - marketingFee: element["MarketingFee"] as double, - minimumDiscount: element["MinimumDiscount"] as double, - level1: element["Level1"] as double, - level2: element["Level2"] as double, - level3: element["Level3"] as double, - level4: element["Level4"] as double, - level5: element["Level5"] as double, - level6: element["Level6"] as double, - level7: element["Level7"] as double, - isActive: element["IsActive"] as bool, - isDeleted: element["IsDeleted"] as bool, - isOnline: element["IsOnline"] as bool, - isPhysical: element["IsPhysical"] as bool, - isVariablePurchase: element["IsVariablePurchase"] as bool, - minimumCardPurchase: element["MinimumCardPurchase"] as double, - maximumCardPurchase: element["MaximumCardPurchase"] as double, - acceptsTips: element["AcceptsTips"] as bool, - createdDateFormatted: element["CreatedDate"] as String, - createdBy: element["CreatedBy"] as int, - isRegional: element["IsRegional"] as bool, - modifiedDateFormatted: element["ModifiedDate"] as String, - modifiedBy: element["ModifiedBy"] as int, - usageInstructions: element["UsageInstructions"] as String, - usageInstructionsBak: element["UsageInstructionsBak"] as String, - paymentGatewayId: element["PaymentGatewayId"] as int, - giftCardGatewayId: element["GiftCardGatewayId"] as int , - isHtmlDescription: element["IsHtmlDescription"] as bool, - purchaseInstructions: element["PurchaseInstructions"] as String, - balanceInstructions: element["BalanceInstructions"] as String, - amountPerCard: element["AmountPerCard"] as double, - processingMessage: element["ProcessingMessage"] as String, - hasBarcode: element["HasBarcode"] as bool, - hasInventory: element["HasInventory"] as bool, - isVoidable: element["IsVoidable"] as bool, - receiptMessage: element["ReceiptMessage"] as String, - cssBorderCode: element["CssBorderCode"] as String, - paymentInstructions: element["PaymentInstructions"] as String, - alderSku: element["AlderSku"] as String, - ngcSku: element["NgcSku"] as String, - acceptedCurrency: element["AcceptedCurrency"] as String, - deepLink: element["DeepLink"] as String, - isPayLater: element["IsPayLater"] as bool); + legalName: element["LegalName"] as String, + systemName: element["SystemName"] as String, + description: element["Description"] as String, + website: element["Website"] as String, + termsAndConditions: element["TermsAndConditions"] as String, + logoUrl: element["LogoUrl"] as String, + cardImageUrl: element["CardImageUrl"] as String, + cardholderAgreement: element["CardholderAgreement"] as String, + purchaseFee: element["PurchaseFee"] as double, + revenueShare: element["RevenueShare"] as double, + marketingFee: element["MarketingFee"] as double, + minimumDiscount: element["MinimumDiscount"] as double, + level1: element["Level1"] as double, + level2: element["Level2"] as double, + level3: element["Level3"] as double, + level4: element["Level4"] as double, + level5: element["Level5"] as double, + level6: element["Level6"] as double, + level7: element["Level7"] as double, + isActive: element["IsActive"] as bool, + isDeleted: element["IsDeleted"] as bool, + isOnline: element["IsOnline"] as bool, + isPhysical: element["IsPhysical"] as bool, + isVariablePurchase: element["IsVariablePurchase"] as bool, + minimumCardPurchase: element["MinimumCardPurchase"] as double, + maximumCardPurchase: element["MaximumCardPurchase"] as double, + acceptsTips: element["AcceptsTips"] as bool, + createdDateFormatted: element["CreatedDate"] as String, + createdBy: element["CreatedBy"] as int, + isRegional: element["IsRegional"] as bool, + modifiedDateFormatted: element["ModifiedDate"] as String, + modifiedBy: element["ModifiedBy"] as int, + usageInstructions: element["UsageInstructions"] as String, + usageInstructionsBak: element["UsageInstructionsBak"] as String, + paymentGatewayId: element["PaymentGatewayId"] as int, + giftCardGatewayId: element["GiftCardGatewayId"] as int , + isHtmlDescription: element["IsHtmlDescription"] as bool, + purchaseInstructions: element["PurchaseInstructions"] as String, + balanceInstructions: element["BalanceInstructions"] as String, + amountPerCard: element["AmountPerCard"] as double, + processingMessage: element["ProcessingMessage"] as String, + hasBarcode: element["HasBarcode"] as bool, + hasInventory: element["HasInventory"] as bool, + isVoidable: element["IsVoidable"] as bool, + receiptMessage: element["ReceiptMessage"] as String, + cssBorderCode: element["CssBorderCode"] as String, + instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String), + alderSku: element["AlderSku"] as String, + ngcSku: element["NgcSku"] as String, + acceptedCurrency: element["AcceptedCurrency"] as String, + deepLink: element["DeepLink"] as String, + isPayLater: element["IsPayLater"] as bool); } - final int id; final String legalName; final String systemName; final String description; final String website; final String termsAndConditions; final String logoUrl; final String cardImageUrl; final String cardholderAgreement; final double purchaseFee; - final double revenueShare; - final double marketingFee; - final double minimumDiscount; - final double level1; - final double level2; - final double level3; - final double level4; - final double level5; - final double level6; - final double level7; - final bool isActive; - final bool isDeleted; - final bool isOnline; - final bool isPhysical; - final bool isVariablePurchase; - final double minimumCardPurchase; - final double maximumCardPurchase; - final bool acceptsTips; - final String createdDateFormatted; - final int createdBy; - final bool isRegional; - final String modifiedDateFormatted; - final int modifiedBy; - final String usageInstructions; - final String usageInstructionsBak; - final int paymentGatewayId; - final int giftCardGatewayId; - final bool isHtmlDescription; - final String purchaseInstructions; - final String balanceInstructions; - final double amountPerCard; - final String processingMessage; - final bool hasBarcode; - final bool hasInventory; - final bool isVoidable; - final String receiptMessage; - final String cssBorderCode; - final String paymentInstructions; - final String alderSku; - final String ngcSku; - final String acceptedCurrency; - final String deepLink; - final bool isPayLater; + final int id; + final String legalName; + final String systemName; + final String description; + final String website; + final String termsAndConditions; + final String logoUrl; + final String cardImageUrl; + final String cardholderAgreement; + final double purchaseFee; + final double revenueShare; + final double marketingFee; + final double minimumDiscount; + final double level1; + final double level2; + final double level3; + final double level4; + final double level5; + final double level6; + final double level7; + final bool isActive; + final bool isDeleted; + final bool isOnline; + final bool isPhysical; + final bool isVariablePurchase; + final double minimumCardPurchase; + final double maximumCardPurchase; + final bool acceptsTips; + final String createdDateFormatted; + final int createdBy; + final bool isRegional; + final String modifiedDateFormatted; + final int modifiedBy; + final String usageInstructions; + final String usageInstructionsBak; + final int paymentGatewayId; + final int giftCardGatewayId; + final bool isHtmlDescription; + final String purchaseInstructions; + final String balanceInstructions; + final double amountPerCard; + final String processingMessage; + final bool hasBarcode; + final bool hasInventory; + final bool isVoidable; + final String receiptMessage; + final String cssBorderCode; + final List instructions; + final String alderSku; + final String ngcSku; + final String acceptedCurrency; + final String deepLink; + final bool isPayLater; } diff --git a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart index ddc1f0f3d..e5a085eb1 100644 --- a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart @@ -258,15 +258,29 @@ class IoniaBuyGiftCardDetailPage extends BasePage { builder: (BuildContext context) { return IoniaAlertModal( title: S.of(context).how_to_use_card, - content: Align( - alignment: Alignment.bottomLeft, - child: Text( - merchant.usageInstructionsBak, - style: textMedium( - color: Theme.of(context).textTheme.display2.color, - ), - ), - ), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: merchant.instructions + .map((instruction) { + return [ + Padding( + padding: EdgeInsets.all(10), + child: Text( + instruction.header, + style: textLargeSemiBold( + color: Theme.of(context).textTheme.display2.color, + ), + )), + Text( + instruction.body, + style: textMedium( + color: Theme.of(context).textTheme.display2.color, + ), + ) + ]; + }) + .expand((e) => e) + .toList()), actionTitle: S.current.send_got_it, ); }); diff --git a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart index 56b32aedb..c9efe7a99 100644 --- a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart @@ -159,7 +159,7 @@ class IoniaGiftCardDetailPage extends BasePage { title: S.of(context).how_to_use_card, content: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: viewModel.giftCard.usageInstructions + children: viewModel.giftCard.instructions .map((instruction) { return [ Padding( diff --git a/lib/src/screens/ionia/cards/ionia_payment_status_page.dart b/lib/src/screens/ionia/cards/ionia_payment_status_page.dart index 92bc62b91..d264842e6 100644 --- a/lib/src/screens/ionia/cards/ionia_payment_status_page.dart +++ b/lib/src/screens/ionia/cards/ionia_payment_status_page.dart @@ -1,12 +1,10 @@ import 'package:cake_wallet/ionia/ionia_gift_card.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/utils/show_bar.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/ionia/ionia_payment_status_view_model.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -44,7 +42,6 @@ class _IoniaPaymentStatusPageBody extends StatefulWidget { } class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPageBody> { - ReactionDisposer _onErrorReaction; ReactionDisposer _onGiftCardReaction; @override @@ -55,34 +52,6 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage .pushReplacementNamed(Routes.ioniaGiftCardDetailPage, arguments: [widget.viewModel.giftCard]); }); } - - if (widget.viewModel.error != null) { - WidgetsBinding.instance.addPostFrameCallback((_) { - showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: widget.viewModel.error, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - }); - } - - _onErrorReaction = reaction((_) => widget.viewModel.error, (String error) { - WidgetsBinding.instance.addPostFrameCallback((_) { - showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).error, - alertContent: error, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - }); - }); _onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard giftCard) { WidgetsBinding.instance.addPostFrameCallback((_) { @@ -96,7 +65,6 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage @override void dispose() { - _onErrorReaction?.reaction?.dispose(); _onGiftCardReaction?.reaction?.dispose(); widget.viewModel.timer.cancel(); super.dispose();