From 575d0ccf0bdef88d1447c130269d7060c6cdb5f0 Mon Sep 17 00:00:00 2001 From: Andrey Shabarshov Date: Sun, 26 Dec 2021 12:28:53 +0000 Subject: [PATCH] Merchant to client to merchant round trip implemented (no security). --- QRBee.Core/Data/ClientToMerchantResponse.cs | 20 ++- QRBee.Core/Data/MerchantToClientRequest.cs | 26 +++- QRBee/QRBee/ViewModels/ClientPageViewModel.cs | 114 +++++++++++++++++- .../QRBee/ViewModels/MerchantPageViewModel.cs | 49 +++++++- QRBee/QRBee/Views/ClientPage.xaml | 29 ++++- QRBee/QRBee/Views/ClientPage.xaml.cs | 21 +--- QRBee/QRBee/Views/MerchantPage.xaml | 9 +- 7 files changed, 227 insertions(+), 41 deletions(-) diff --git a/QRBee.Core/Data/ClientToMerchantResponse.cs b/QRBee.Core/Data/ClientToMerchantResponse.cs index 94c7b1a..8e4701a 100644 --- a/QRBee.Core/Data/ClientToMerchantResponse.cs +++ b/QRBee.Core/Data/ClientToMerchantResponse.cs @@ -32,7 +32,25 @@ set; } - public string AsString() => $"{Request.AsString()}|{ClientId}|{TimeStampUTC:O}"; + public string AsString() => $"{ClientId}|{TimeStampUTC:O}|{Request.AsString()}"; + + public static ClientToMerchantResponse FromString(string input) + { + var s = input.Split('|'); + if (s.Length != 3) + { + throw new ApplicationException("Expected 3 elements"); + } + + var res = new ClientToMerchantResponse() + { + Request = MerchantToClientRequest.FromString(string.Join("|", s.Skip(2))), + ClientId = s[0], + TimeStampUTC = DateTime.ParseExact(s[1], "O", null) + }; + + return res; + } } } diff --git a/QRBee.Core/Data/MerchantToClientRequest.cs b/QRBee.Core/Data/MerchantToClientRequest.cs index 3b1a134..946dbb2 100644 --- a/QRBee.Core/Data/MerchantToClientRequest.cs +++ b/QRBee.Core/Data/MerchantToClientRequest.cs @@ -1,4 +1,6 @@ -namespace QRBee.Core.Data +using System.Globalization; + +namespace QRBee.Core.Data { public record MerchantToClientRequest { @@ -32,7 +34,27 @@ set; } - public string AsString() => $"{TransactionId}|{Name}|{Amount:0.00}|{TimeStampUTC:O}"; + public string AsString() => $"{TransactionId}|{Name}|{Amount.ToString("0.00", CultureInfo.InvariantCulture)}|{TimeStampUTC:O}"; + + public static MerchantToClientRequest FromString(string input) + { + var s = input.Split('|'); + if (s.Length != 4) + { + throw new ApplicationException("Expected 4 elements"); + } + + var res = new MerchantToClientRequest + { + TransactionId = s[0], + Name = s[1], + Amount = Convert.ToDecimal(s[2], CultureInfo.InvariantCulture), + TimeStampUTC = DateTime.ParseExact(s[3],"O",null) + }; + + + return res; + } } } diff --git a/QRBee/QRBee/ViewModels/ClientPageViewModel.cs b/QRBee/QRBee/ViewModels/ClientPageViewModel.cs index 57062f7..c0ae4ab 100644 --- a/QRBee/QRBee/ViewModels/ClientPageViewModel.cs +++ b/QRBee/QRBee/ViewModels/ClientPageViewModel.cs @@ -1,12 +1,116 @@ using System; -using System.Collections.Generic; -using System.Text; +using QRBee.Core.Data; +using QRBee.Services; +using QRBee.Views; +using Xamarin.Forms; namespace QRBee.ViewModels { - - - internal class ClientPageViewModel + internal class ClientPageViewModel: BaseViewModel { + public bool _isVisible; + public string _amount; + private string _qrCode; + private MerchantToClientRequest _merchantToClientRequest; + private readonly ClientPage _clientPage; + + public ClientPageViewModel(Views.ClientPage clientPage) + { + ScanCommand = new Command(OnScanButtonClicked); + GenerateQrCommand = new Command(OnGenerateQrClicked); + _clientPage = clientPage; + } + + public Command ScanCommand + { + get; + } + + public Command GenerateQrCommand + { + get; + } + + private async void OnScanButtonClicked(object sender) + { + try + { + var scanner = DependencyService.Get(); + var result = await scanner.ScanQR(); + if (result != null) + { + _merchantToClientRequest = MerchantToClientRequest.FromString(result); + Amount = $"{_merchantToClientRequest.Amount:N2}"; + IsVisible = true; + } + } + catch (Exception ex) + { + throw; + } + } + + public string Amount + { + get => _amount; + set + { + if (value == _amount) + { + return; + } + _amount = value; + OnPropertyChanged(nameof(Amount)); + } + } + + public bool IsVisible + { + get => _isVisible; + set + { + if (value == _isVisible) + { + return; + } + _isVisible = value; + OnPropertyChanged(nameof(IsVisible)); + } + } + + public string QrCode + { + get => _qrCode; + set + { + // _qrCode = $"{Amount}/{Name}"; + if (_qrCode == value) + return; + + _qrCode = value; + OnPropertyChanged(nameof(QrCode)); + } + } + + public async void OnGenerateQrClicked(object obj) + { + + bool answer = await _clientPage.DisplayAlert("Confirmation", "Would you like to accept the offer?", "Yes", "No"); + if (answer) + { + var response = new ClientToMerchantResponse + { + ClientId = Guid.NewGuid().ToString("D"), + TimeStampUTC = DateTime.UtcNow, + Request = _merchantToClientRequest + + }; + // TODO Create merchant signature. + QrCode = response.AsString(); + } + + + } + } } diff --git a/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs b/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs index dcac196..5446308 100644 --- a/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs +++ b/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs @@ -1,21 +1,43 @@ using System; +using QRBee.Core.Data; +using QRBee.Services; using Xamarin.Forms; namespace QRBee.ViewModels { internal class MerchantPageViewModel : BaseViewModel { + private bool _isVisible; private string _name; private decimal _amount; private string _qrCode; public Command GenerateQrCommand { get; } + public Command ScanCommand{ get; } public MerchantPageViewModel() { + ScanCommand = new Command(OnScanButtonClicked); GenerateQrCommand = new Command(OnGenerateQrClicked); } + private async void OnScanButtonClicked(object sender) + { + try + { + var scanner = DependencyService.Get(); + var result = await scanner.ScanQR(); + if (result != null) + { + + } + } + catch (Exception ex) + { + throw; + } + } + public string Name { get => _name; @@ -42,6 +64,20 @@ namespace QRBee.ViewModels } } + public bool IsVisible + { + get => _isVisible; + set + { + if (value == _isVisible) + { + return; + } + _isVisible = value; + OnPropertyChanged(nameof(IsVisible)); + } + } + public string QrCode { get => _qrCode; @@ -58,9 +94,16 @@ namespace QRBee.ViewModels public async void OnGenerateQrClicked(object obj) { - QrCode = $"{Name}.{Amount:0.00}.{DateTime.UtcNow:O}"; - // Prefixing with `//` switches to a different navigation stack instead of pushing to the active one - // await Shell.Current.GoToAsync($"//{nameof(AboutPage)}"); + var trans = new MerchantToClientRequest + { + TransactionId = Guid.NewGuid().ToString("D"), + Name = Name, + Amount = Amount, + TimeStampUTC = DateTime.UtcNow + }; + // TODO Create merchant signature. + QrCode = trans.AsString(); + IsVisible = true; } } diff --git a/QRBee/QRBee/Views/ClientPage.xaml b/QRBee/QRBee/Views/ClientPage.xaml index 18e1071..8704605 100644 --- a/QRBee/QRBee/Views/ClientPage.xaml +++ b/QRBee/QRBee/Views/ClientPage.xaml @@ -1,6 +1,10 @@  @@ -9,13 +13,28 @@ - - - -