public virtual async Task <CommerceCommand> Process(CommerceContext commerceContext, string customerId, string productId) { RemoveWishlistCommand removeWishlistCommand = this; try { var customerEntity = await _getCustomerCommand.Process(commerceContext, customerId); if (customerEntity != null) { if (customerEntity.HasComponent <WishlistComponent>()) { WishlistComponent wishlistComponent = customerEntity.GetComponent <WishlistComponent>(); if (wishlistComponent.WishlistCollection != null) { foreach (var item in wishlistComponent.WishlistCollection) { if (item.ProductId == productId) { wishlistComponent.WishlistCollection.Remove(item); if (wishlistComponent.WishlistCollection.Count == 0) { customerEntity.RemoveComponents(wishlistComponent); } else { customerEntity.SetComponent(wishlistComponent); } break; } } } else { commerceContext.Logger.LogInformation($"start process of RemoveWishlistCommand has no Wishlist Component"); } } else { commerceContext.Logger.LogDebug($"start process of RemoveWishlistCommand has no Wishlist Component"); } await this._persistEntityPipeline.Run(new PersistEntityArgument(customerEntity), commerceContext.PipelineContext); } else { commerceContext.Logger.LogDebug($"start process of RemoveProductIdCommand has no Customer with this Id"); } } catch (Exception ex) { commerceContext.Logger.LogError(ex.Message, ex); } return(removeWishlistCommand); }
public virtual async Task <Wishlists> Process(CommerceContext commerceContext, string customerId, int take = 10, int skip = 0) { var customerEntity = await _getCustomerCommand.Process(commerceContext, customerId); Wishlists wishlists = new Wishlists(); wishlists.Wishlist = new List <Entities.WishlistEntity>(); try { if (customerEntity != null) { if (customerEntity.HasComponent <WishlistComponent>()) { var component = customerEntity.GetComponent <WishlistComponent>(); if (component?.WishlistCollection != null && component.WishlistCollection.Any()) { wishlists.TotalCount = component.WishlistCollection.Count; var customerWishlist = (skip == 0 && take == 0) ? component?.WishlistCollection : component?.WishlistCollection.Skip(skip).Take(take); foreach (var item in customerWishlist) { Entities.WishlistEntity wishlistEntity = new Entities.WishlistEntity() { ProductId = item.ProductId, ProductPrice = item.ProductPrice, ProductTitle = item.ProductTitle }; wishlists.Wishlist.Add(wishlistEntity); } } } } } catch (Exception ex) { commerceContext.Logger.LogError(ex.StackTrace, ex.Message, ex); } return(wishlists); }
public virtual async Task <Sitecore.Commerce.Plugin.Customers.Customer> Process(CommerceContext commerceContext, string customerID, bool subscribeEmail, string company) { try { var customerEntity = await _getCustomerCommand.Process(commerceContext, customerID); if (customerEntity != null) { var customerEntityView = await _getEntityViewCommand.Process(commerceContext, customerEntity.Id, "Master", "", ""); var composerEditView = customerEntityView.ChildViews.Where(x => x.Name == "Details").FirstOrDefault() as EntityView; if (composerEditView != null) { commerceContext.Logger.LogDebug($"Edit customer detail view loaded: {DateTime.Now}"); var updatedCustomerEntity = await _findEntityCommand.Process(commerceContext, typeof(Sitecore.Commerce.Plugin.Customers.Customer), composerEditView.EntityId) as Sitecore.Commerce.Plugin.Customers.Customer; var customDetails = new CustomerExtended(); customDetails.ReceiveEmailUpdates = Convert.ToBoolean(subscribeEmail); customDetails.Company = company; updatedCustomerEntity.SetComponent(customDetails); await this._persistEntityPipeline.Run(new PersistEntityArgument(updatedCustomerEntity), commerceContext.PipelineContext); } else { commerceContext.Logger.LogInformation($"Edit customer entityview is empty: {DateTime.Now}"); } } else { commerceContext.Logger.LogInformation($"Customer entityview is null: {DateTime.Now}"); } return(customerEntity); } catch (Exception e) { commerceContext.Logger.LogInformation($"Exception occured in getting customer { e.StackTrace} and id is {e.Message}"); return(await Task.FromException <Sitecore.Commerce.Plugin.Customers.Customer>(e)); } }
public virtual async Task <CommerceCommand> Process(CommerceContext commerceContext, WishlistModel wishlistModel) { AddWishlistCommand addWishlistCommand = this; try { var customerEntity = await _getCustomerCommand.Process(commerceContext, wishlistModel.CustomerId); if (customerEntity != null) { if (customerEntity.HasComponent <WishlistComponent>()) { var component = customerEntity.GetComponent <WishlistComponent>(); // Checking if product is already added to list or not bool isProductAdded = false; if (component.WishlistCollection == null) { component.WishlistCollection = new List <WishlistEntity>(); } else { isProductAdded = component.WishlistCollection.Any(x => x.ProductId == wishlistModel.ProductId); } if (!isProductAdded) { WishlistEntity wishlistEntity = new WishlistEntity() { ProductId = wishlistModel.ProductId, ProductTitle = wishlistModel.ProductTitle, ProductPrice = wishlistModel.ProductPrice }; component.WishlistCollection.Add(wishlistEntity); customerEntity.SetComponent(component); commerceContext.Logger.LogInformation($"AddWishlistCommand for customer id: {wishlistModel.CustomerId} added product Id: {wishlistModel.ProductId}"); } else { commerceContext.Logger.LogInformation($"AddWishlistCommand for customer id: {wishlistModel.CustomerId} NOT ADDED product Id: {wishlistModel.ProductId} as it already exists"); } } else { WishlistComponent wishlistComponent = new WishlistComponent(); wishlistComponent.WishlistCollection = new List <WishlistEntity>(); WishlistEntity wishlistEntity = new WishlistEntity() { ProductId = wishlistModel.ProductId, ProductTitle = wishlistModel.ProductTitle, ProductPrice = wishlistModel.ProductPrice }; wishlistComponent.WishlistCollection.Add(wishlistEntity); customerEntity.SetComponent(wishlistComponent); } await this._persistEntityPipeline.Run(new PersistEntityArgument(customerEntity), commerceContext.PipelineContext); } } catch (Exception ex) { commerceContext.Logger.LogError($"Exception occured in getting customer { ex.StackTrace} and id is {ex.Message}"); } return(addWishlistCommand); }
public async override Task <Order> Run(Order order, CommercePipelineExecutionContext context) { Condition.Requires(context).IsNotNull($"{this.Name}: The argument can not be null"); Condition.Requires(order).IsNotNull($"{this.Name}: The argument can not be null"); // Getting the blockchain contract address and ensuring the customer is a blockchain customer and opted in for product publishing var contactComponent = order.GetComponent <ContactComponent>(); if (contactComponent == null || !contactComponent.IsRegistered) { return(order); } var getCustomerCommand = new GetCustomerCommand(_getCustomerPipeline, _serviceProvider); var customerId = (contactComponent.CustomerId.ToLower().StartsWith("entity") ? contactComponent.CustomerId : CommerceEntity.IdPrefix <Customer>() + contactComponent.CustomerId); if (string.IsNullOrWhiteSpace(customerId)) { return(order); } var customer = await getCustomerCommand.Process(context.CommerceContext, customerId); var customerDetails = customer.GetComponent <CustomerDetailsComponent>(); if (!(customerDetails.View.ChildViews.Where(v => v.Name.ToLower() == Constants.Pipelines.Views.BlockchainInformationViewName.ToLower()).FirstOrDefault() is EntityView blockchainView)) { return(order); } var contractIdProperty = blockchainView.Properties.FirstOrDefault(p => p.Name == Constants.Pipelines.Fields.IdentityContractAddressFieldName); var publishProductsProperty = blockchainView.Properties.FirstOrDefault(p => p.Name == Constants.Pipelines.Fields.PublishProductsFieldName); // Only submit products for orders where customer have blockchain accounts and have enabled product publishing if (contractIdProperty == null || string.IsNullOrWhiteSpace(contractIdProperty.RawValue?.ToString()) || publishProductsProperty == null || publishProductsProperty.RawValue.ToString() == "false") { return(order); } var ethPolicy = context.GetPolicy <EthereumClientPolicy>(); if (ethPolicy == null) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: missing policy configuration.", context); return(order); } var web3 = new Web3(ethPolicy.NodeUrl); await Blockchain.UnlockMerchantAccountAsync(web3, context); var idContract = web3.Eth.GetContract(ethPolicy.IdentityContractABI, contractIdProperty.RawValue?.ToString()); var producIds = order.Lines.Select(o => o.GetComponent <CartProductComponent>()?.Id).ToList(); var hasPurchasedFunction = idContract.GetFunction("contactHasPurchasedProduct"); var purchasedProductFunction = idContract.GetFunction("addPurchasedProduct"); foreach (var productId in producIds) { try { // Check if the customer has purchased thisproduct in the past var hasPurchasedProduct = await hasPurchasedFunction.CallAsync <bool>(productId); if (hasPurchasedProduct) { continue; } var hash = await purchasedProductFunction.SendTransactionAsync(new TransactionInput { Gas = new HexBigInteger(200000), From = ethPolicy.MerchantAccountAddress }, productId); } catch (Exception ex) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: unable to send call contactHasPurchasedProduct or transaction addPurchasedProduct." + ex.Message, context); return(order); } Logging.Log(context.GetPolicy <KnownResultCodes>().Information, $"Ethereum: added product {productId} to {contractIdProperty.RawValue?.ToString()} purchase ledger.", context); } return(order); }
public async Task <IActionResult> Put([FromBody] ODataActionParameters value) { if (!this.ModelState.IsValid || value == null) { return((IActionResult) new BadRequestObjectResult((object)value)); } string id = value["customerId"].ToString(); if (!this.ModelState.IsValid || string.IsNullOrEmpty(id)) { return((IActionResult)this.NotFound()); } GetCustomerCommand command0 = this.Command <GetCustomerCommand>(); Customer customer = await command0.Process(this.CurrentContext, id); var y = customer.GetComponent <AddressComponent>(); //refactor string randoms = Guid.NewGuid().ToString().Replace("-", string.Empty).Replace("+", string.Empty); string cartId = string.Format("{0}{1}", "CUSTOM", randoms); string str = value["itemId"].ToString(); Decimal result; string q = "1"; if (!Decimal.TryParse(q, out result)) { return((IActionResult) new BadRequestObjectResult((object)q)); } AddCartLineCommand command = this.Command <AddCartLineCommand>(); CartLineComponent line = new CartLineComponent() { ItemId = str, Quantity = result }; Cart cart = await command.Process(this.CurrentContext, cartId, line); //FulfillmentComponent FulfillmentComponent fulfillment = (PhysicalFulfillmentComponent) new PhysicalFulfillmentComponent() { ShippingParty = new Party() { Address1 = y.Party.Address1, City = y.Party.City, ZipPostalCode = y.Party.ZipPostalCode, State = y.Party.State, StateCode = y.Party.StateCode, CountryCode = y.Party.CountryCode, AddressName = y.Party.AddressName, Name = y.Party.Name }, FulfillmentMethod = new EntityReference() { Name = "Ground", EntityTarget = "B146622D-DC86-48A3-B72A-05EE8FFD187A" } }; SetCartFulfillmentCommand _CartFulfillmentCommand = this.Command <SetCartFulfillmentCommand>(); Cart cart1 = await _CartFulfillmentCommand.Process(CurrentContext, cartId, fulfillment); //FederatedPaymentComponent decimal gt; Decimal.TryParse(cart1.Totals.GrandTotal.Amount.ToString(), out gt); FederatedPaymentComponent paymentComponent = new FederatedPaymentComponent(new Money() { Amount = gt }); paymentComponent.PaymentMethod = new EntityReference() { EntityTarget = "0CFFAB11-2674-4A18-AB04-228B1F8A1DEC", Name = "Federated" }; paymentComponent.PaymentMethodNonce = "fake-valid-nonce"; paymentComponent.BillingParty = new Party() { Address1 = y.Party.Address1, City = y.Party.City, ZipPostalCode = y.Party.ZipPostalCode, State = y.Party.State, StateCode = y.Party.StateCode, CountryCode = y.Party.CountryCode, AddressName = y.Party.AddressName, }; AddPaymentsCommand _PaymentsCommand = this.Command <AddPaymentsCommand>(); Cart cart2 = await _PaymentsCommand.Process(this.CurrentContext, cartId, (IEnumerable <PaymentComponent>) new List <PaymentComponent>() { (PaymentComponent)paymentComponent }); //CreateOrderCommand string email = customer.Email; CreateOrderCommand _CreateOrderCommand = this.Command <CreateOrderCommand>(); Order order = await _CreateOrderCommand.Process(this.CurrentContext, cartId, email); return((IActionResult) new ObjectResult((object)_CreateOrderCommand)); }
public async override Task <Order> Run(Order order, CommercePipelineExecutionContext context) { Condition.Requires(context).IsNotNull($"{this.Name}: The argument can not be null"); Condition.Requires(order).IsNotNull($"{this.Name}: The argument can not be null"); // Getting the blockchain contract address var contactComponent = order.GetComponent <ContactComponent>(); if (contactComponent == null || !contactComponent.IsRegistered) { return(order); } var getCustomerCommand = new GetCustomerCommand(_getCustomerPipeline, _serviceProvider); var customerId = (contactComponent.CustomerId.ToLower().StartsWith("entity") ? contactComponent.CustomerId : CommerceEntity.IdPrefix <Customer>() + contactComponent.CustomerId); if (string.IsNullOrWhiteSpace(customerId)) { return(order); } var customer = await getCustomerCommand.Process(context.CommerceContext, customerId); var customerDetails = customer.GetComponent <CustomerDetailsComponent>(); if (!(customerDetails.View.ChildViews.Where(v => v.Name.ToLower() == Constants.Pipelines.Views.BlockchainInformationViewName.ToLower()).FirstOrDefault() is EntityView blockchainView)) { return(order); } var contractIdProperty = blockchainView.Properties.FirstOrDefault(p => p.Name == Constants.Pipelines.Fields.IdentityContractAddressFieldName); // Only submit products for orders where customer have blockchain accounts and have enabled product publishing if (contractIdProperty == null || string.IsNullOrWhiteSpace(contractIdProperty.RawValue?.ToString())) { return(order); } var orderSubtotal = order.Totals.SubTotal.Amount; var ethPolicy = context.GetPolicy <EthereumClientPolicy>(); if (ethPolicy == null) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: missing policy configuration.", context); return(order); } var web3 = new Web3(ethPolicy.NodeUrl); // Unlock merch account to be able to send state change transactions await Blockchain.UnlockMerchantAccountAsync(web3, context); var idContract = web3.Eth.GetContract(ethPolicy.LoaltyContractABI, ethPolicy.LoyaltyContractAddress); var addLoyaltyPointsFunction = idContract.GetFunction("addLoyaltyPoints"); try { // TODO: this implementation uses a separate loyalty contract balance, potntial discrepancies over time with bank depletion var usdPerEth = await UpdateEthBalanceOnEntityView.GetUsdAmountAsync(1, context); var subtotalInWei = UnitConversion.Convert.ToWei((orderSubtotal / usdPerEth), UnitConversion.EthUnit.Ether); var loyaltyEstimatedAmount = UnitConversion.Convert.ToWei(((orderSubtotal / usdPerEth) / 100), UnitConversion.EthUnit.Ether); // validating the royalty contract amount by passing precalculated value (1%) var gasEstimate = await addLoyaltyPointsFunction.EstimateGasAsync(ethPolicy.MerchantAccountAddress, new HexBigInteger(200000), new HexBigInteger(loyaltyEstimatedAmount), subtotalInWei, contractIdProperty.RawValue.ToString()); var hash = await addLoyaltyPointsFunction.SendTransactionAsync(new TransactionInput { Gas = new HexBigInteger(gasEstimate), From = ethPolicy.MerchantAccountAddress, Value = new HexBigInteger(loyaltyEstimatedAmount) }, subtotalInWei, contractIdProperty.RawValue.ToString()); } catch (Exception ex) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: unable to send transaction addLoyaltyPoints. " + ex.Message, context); return(order); } Logging.Log(context.GetPolicy <KnownResultCodes>().Information, $"Ethereum: added loyalty points for the purchasein the amount of ${orderSubtotal} to {contractIdProperty.RawValue} based on the police defined in {ethPolicy.LoyaltyContractAddress}.", context); return(order); }
public async override Task <Order> Run(Order order, CommercePipelineExecutionContext context) { Condition.Requires(context).IsNotNull($"{this.Name}: The argument can not be null"); Condition.Requires(order).IsNotNull($"{this.Name}: The argument can not be null"); var ethPolicy = context.GetPolicy <EthereumClientPolicy>(); if (ethPolicy == null) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: missing policy configuration.", context); return(order); } // Getting customer id contract var contactComponent = order.GetComponent <ContactComponent>(); if (contactComponent == null || !contactComponent.IsRegistered) { return(order); } var getCustomerCommand = new GetCustomerCommand(_getCustomerPipeline, _serviceProvider); var customerId = (contactComponent.CustomerId.ToLower().StartsWith("entity") ? contactComponent.CustomerId : CommerceEntity.IdPrefix <Customer>() + contactComponent.CustomerId); if (string.IsNullOrWhiteSpace(customerId)) { return(order); } var customer = await getCustomerCommand.Process(context.CommerceContext, customerId); var customerDetails = customer.GetComponent <CustomerDetailsComponent>(); if (!(customerDetails.View.ChildViews.Where(v => v.Name.ToLower() == Constants.Pipelines.Views.BlockchainInformationViewName.ToLower()).FirstOrDefault() is EntityView blockchainView)) { return(order); } var contractIdProperty = blockchainView.Properties.FirstOrDefault(p => p.Name == Constants.Pipelines.Fields.IdentityContractAddressFieldName); if (contractIdProperty == null || string.IsNullOrWhiteSpace(contractIdProperty.RawValue?.ToString())) { return(order); } var web3 = new Web3(ethPolicy.NodeUrl); await Blockchain.UnlockMerchantAccountAsync(web3, context); var royaltyContract = web3.Eth.GetContract(ethPolicy.RoyaltyContractABI, ethPolicy.RoyaltyContractAddress); var getAssetUrlFunction = royaltyContract.GetFunction("getAssetUrl"); var assetPurchaseEvent = royaltyContract.GetEvent("AssetPurchased"); var orderLines = order.Lines; foreach (var orderLine in orderLines) { try { var token = new CancellationTokenSource(); var value = new HexBigInteger(8568000000000000); // the amount equates about $2 var product = orderLine.GetComponent <CartProductComponent>(); if (product == null) { continue; } if (!product.Tags.Any(t => t.Name == "blockchainroyalty")) { continue; } var producId = orderLine.GetComponent <CartProductComponent>()?.Id; var gasEstimate = await getAssetUrlFunction.EstimateGasAsync(ethPolicy.MerchantAccountAddress, new HexBigInteger(200000), value, producId, contractIdProperty.RawValue.ToString()); var receipt = await getAssetUrlFunction.SendTransactionAndWaitForReceiptAsync(ethPolicy.MerchantAccountAddress, gasEstimate, value, token, producId, contractIdProperty.RawValue.ToString()); var filterPurchaser = assetPurchaseEvent.CreateFilterInput(new BlockParameter(receipt.BlockNumber), BlockParameter.CreateLatest()); if (((bool)receipt.HasErrors())) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, $"Ethereum: unable to get receipt for the digital asset token retrieval. Transaction failed with status {receipt.Status}.", context); return(order); } var logs = await assetPurchaseEvent.GetAllChanges <AssetPurchaseEvent>(filterPurchaser); orderLine.SetComponent(new DigitalDownloadBlockchainTokenComponent { BlockchainDownloadToken = logs.Last().Event.Token }); } catch (Exception ex) { Logging.Log(context.GetPolicy <KnownResultCodes>().Error, "Ethereum: unable to send transaction getAssetUrl. " + ex.Message, context); return(order); } Logging.Log(context.GetPolicy <KnownResultCodes>().Information, $"Ethereum: received asset URL token from {ethPolicy.RoyaltyContractAddress}", context); } return(order); }