import 'dart:async'; import 'dart:io'; import 'dart:math' as math; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/product.dart'; import 'package:aitrainer_app/model/product_test.dart'; import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/purchase_service.dart'; import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/purchases.dart'; import 'package:aitrainer_app/util/track.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:purchases_flutter/offering_wrapper.dart'; part 'sales_event.dart'; part 'sales_state.dart'; class SalesBloc extends Bloc with Logging { List? tests = []; List product2Display = []; int productSet = -1; SalesBloc() : super(SalesInitial()); @override Stream mapEventToState( SalesEvent event, ) async* { try { if (event is SalesLoad) { yield SalesLoading(); log("Load Sales"); Track().track(TrackingEvent.sales_page); await RevenueCatPurchases().getOfferings(); this.getProductSet(); yield SalesReady(); } else if (event is SalesPurchase) { if (Cache().hasPurchased) { throw Exception("You have already a successfull subscription"); } yield SalesLoading(); final int productId = event.productId; log("Requesting purchase for: " + productId.toString()); Track().track(TrackingEvent.purchase_request); final Product? selectedProduct = this.getSelectedProduct(productId); log("SelectedProduct for purchase $selectedProduct"); if (selectedProduct != null) { await RevenueCatPurchases().makePurchase(selectedProduct); if (Cache().hasPurchased) { Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId); purchase.dateAdd = DateTime.now(); purchase.purchaseSum = 0; purchase.currency = "EUR"; await PurchaseApi().savePurchase(purchase); Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString()); } yield SalesSuccessful(); } else { yield SalesError(message: "No selected product"); } } } on Exception catch (ex) { yield SalesError(message: ex.toString()); } } Product? getSelectedProduct(int productId) { Product? prod; for (var product in this.product2Display) { if (product.productId == productId) { prod = product; } } return prod; } String getLocalizedPrice(String productId) { String price = ""; Offering? offering = RevenueCatPurchases().offering; if (offering != null) { for (var package in offering.availablePackages) { log("PlatformProduct " + package.toString()); if (productId == package.product.identifier) { price = package.product.priceString; if (price.contains(r'HUF')) { price = price.replaceAll(RegExp(r'HUF'), 'Ft'); price = price.replaceAll(RegExp(r',00'), ""); } break; } } } else { log(" !!! No Offering"); } return price; } void getProductSet() { int productId = 0; this.tests = Cache().productTests; List? products = Cache().products; if (products == null) { return; } if (tests != null && tests!.isEmpty) { var rand = math.Random.secure(); productSet = rand.nextInt(5) + 1; } else { trace("Previous ProductTest: " + tests![0].toJson().toString()); productId = tests![0].productId; for (var elem in products) { final Product product = elem; if (product.productId == productId) { productSet = product.productSet; break; } } } ProductTest productTest = ProductTest(); productSet = 2; log("ProductSet: " + productSet.toString()); for (var elem in products) { Product product = elem; if (product.productSet == productSet) { productId = product.productId; final String platformProductId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!; product.localizedPrice = getLocalizedPrice(platformProductId); product2Display.add(product); } } product2Display.sort((a, b) { return a.sort < b.sort ? -1 : 1; }); productTest.productId = productId; productTest.customerId = Cache().userLoggedIn!.customerId!; productTest.dateView = DateTime.now(); //ProductTestApi().saveProductTest(productTest); //Cache().productTests.add(productTest); } }