public async Task <SubscriptionsSummary> ProcessOrderForUnAuthenticatedCustomer(string customerId, string paymentId, string payerId) { var startTime = DateTime.Now; customerId.AssertNotEmpty(nameof(customerId)); paymentId.AssertNotEmpty(nameof(paymentId)); payerId.AssertNotEmpty(nameof(payerId)); PayPalGateway paymentGateway = new PayPalGateway(ApplicationDomain.Instance, "ProcessingOrder"); // use payment gateway to extract order information. OrderViewModel orderToProcess = await paymentGateway.GetOrderDetailsFromPaymentAsync(payerId, paymentId, string.Empty, string.Empty); CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, customerId, paymentGateway); await commerceOperation.PurchaseAsync(orderToProcess); SubscriptionsSummary summaryResult = await this.GetSubscriptionSummaryAsync(customerId); // Capture the request for the customer summary for analysis. var eventProperties = new Dictionary <string, string> { { "CustomerId", orderToProcess.CustomerId }, { "PayerId", payerId }, { "PaymentId", paymentId } }; // Track the event measurements for analysis. var eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("api/order/NewCustomerProcessOrder", eventProperties, eventMetrics); return(summaryResult); }
public async Task <TransactionResult> UpdateSubscription([FromBody] OrderViewModel orderUpdateInformation) { if (!ModelState.IsValid) { var errorList = (from item in ModelState.Values from error in item.Errors select error.ErrorMessage).ToList(); string errorMessage = JsonConvert.SerializeObject(errorList); throw new PartnerDomainException(ErrorCode.InvalidInput).AddDetail("ErrorMessage", errorMessage); } string clientCustomerId = this.Principal.PartnerCenterCustomerId; orderUpdateInformation.Subscriptions.AssertNotNull(nameof(orderUpdateInformation.Subscriptions)); List <OrderSubscriptionItemViewModel> orderSubscriptions = orderUpdateInformation.Subscriptions.ToList(); if (!(orderSubscriptions.Count == 1)) { throw new PartnerDomainException(ErrorCode.InvalidInput).AddDetail("ErrorMessage", Resources.MoreThanOneSubscriptionUpdateErrorMessage); } string subscriptionId = orderSubscriptions.First().SubscriptionId; int additionalSeats = orderSubscriptions.First().Quantity; subscriptionId.AssertNotEmpty(nameof(subscriptionId)); // required for commerce operation. additionalSeats.AssertPositive(nameof(additionalSeats)); // required & should be greater than 0. string operationDescription = string.Format("Customer Id:[{0}] - Added to subscription:{1}.", clientCustomerId, subscriptionId); PayPalGateway paymentGateway = new PayPalGateway(ApplicationDomain.Instance, orderUpdateInformation.CreditCard, operationDescription); CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, clientCustomerId, paymentGateway); return(await commerceOperation.PurchaseAdditionalSeatsAsync(subscriptionId, additionalSeats)); }
public async Task <TransactionResult> ProcessOrderForAuthenticatedCustomer(string paymentId, string payerId, string orderId) { DateTime startTime = DateTime.Now; // extract order information and create payment payload. string clientCustomerId = Principal.PartnerCenterCustomerId; paymentId.AssertNotEmpty(nameof(paymentId)); payerId.AssertNotEmpty(nameof(payerId)); orderId.AssertNotEmpty(nameof(orderId)); // Create the right payment gateway to use for customer oriented payment transactions. IPaymentGateway paymentGateway = await CreatePaymentGateway("ProcessingOrder", clientCustomerId).ConfigureAwait(false); // use payment gateway to extract order information. OrderViewModel orderToProcess = await paymentGateway.GetOrderDetailsFromPaymentAsync(payerId, paymentId, orderId, clientCustomerId).ConfigureAwait(false); orderToProcess.CustomerId = clientCustomerId; CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, clientCustomerId, paymentGateway); TransactionResult transactionResult = null; switch (orderToProcess.OperationType) { case CommerceOperationType.Renewal: transactionResult = await commerceOperation.RenewSubscriptionAsync(orderToProcess).ConfigureAwait(false); break; case CommerceOperationType.AdditionalSeatsPurchase: transactionResult = await commerceOperation.PurchaseAdditionalSeatsAsync(orderToProcess).ConfigureAwait(false); break; case CommerceOperationType.NewPurchase: transactionResult = await commerceOperation.PurchaseAsync(orderToProcess).ConfigureAwait(false); break; } // Capture the request for the customer summary for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", orderToProcess.CustomerId }, { "OperationType", orderToProcess.OperationType.ToString() }, { "PayerId", payerId }, { "PaymentId", paymentId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("api/order/process", eventProperties, eventMetrics); return(transactionResult); }
/// <summary> /// Adds a portal subscription for the Customer. /// </summary> /// <param name="clientCustomerId">The Customer Id.</param> /// <param name="orderSubscriptions">The Order information containing credit card and list of subscriptions to add.</param> /// <returns>Transaction Result from commerce operation.</returns> private async Task <TransactionResult> AddCustomerSubscription(string clientCustomerId, OrderViewModel orderSubscriptions) { string operationDescription = string.Format("Customer Id:[{0}] - Added Subscription(s).", clientCustomerId); PayPalGateway paymentGateway = new PayPalGateway(ApplicationDomain.Instance, orderSubscriptions.CreditCard, operationDescription); CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, clientCustomerId, paymentGateway); List <PurchaseLineItem> orderItems = new List <PurchaseLineItem>(); foreach (var orderItem in orderSubscriptions.Subscriptions) { string offerId = orderItem.OfferId; int quantity = orderItem.Quantity; offerId.AssertNotEmpty(nameof(offerId)); // required for commerce operation. quantity.AssertPositive(nameof(quantity)); // required & should be greater than 0. orderItems.Add(new PurchaseLineItem(offerId, quantity)); } return(await commerceOperation.PurchaseAsync(orderItems)); }
/// <summary> /// Gets the subscriptions managed by customers and partners /// </summary> /// <returns>returns managed subscriptions view model</returns> private async Task <ManagedSubscriptionsViewModel> GetManagedSubscriptions() { DateTime startTime = DateTime.Now; string clientCustomerId = Principal.PartnerCenterCustomerId; // responseCulture determines decimals, currency and such CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale); // localeSpecificApiClient allows pulling offer names localized to supported portal locales compatible with Offer API supported locales. IPartner localeSpecificPartnerCenterClient = ApplicationDomain.Instance.PartnerCenterClient.With(RequestContextFactory.Instance.Create(ApplicationDomain.Instance.PortalLocalization.OfferLocale)); // Get all subscriptions of customer from PC ResourceCollection <Subscription> customerAllSubscriptions = await localeSpecificPartnerCenterClient.Customers.ById(clientCustomerId).Subscriptions.GetAsync().ConfigureAwait(false); IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(clientCustomerId).ConfigureAwait(false); IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false); IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false); List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>(); // iterate through and build the list of customer's subscriptions. foreach (CustomerSubscriptionEntity subscription in customerSubscriptions) { PartnerOffer partnerOfferItem = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId); string subscriptionTitle = partnerOfferItem.Title; string portalOfferId = partnerOfferItem.Id; decimal portalOfferPrice = partnerOfferItem.Price; DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime(); int remainingDays = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days; bool isRenewable = remainingDays <= 30; // IsRenewable is true if subscription is going to expire in 30 days. bool isEditable = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; // IsEditable is true if today is lesser or equal to subscription expiry date. // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription. MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId); if (alignedMicrosoftOffer == null) { // The offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer. partnerOfferItem.IsInactive = true; isRenewable = false; isEditable = false; } BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); // Compute the pro rated price per seat for this subcription & return for client side processing during updates. decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice, portalBranding.BillingCycle), Resources.Culture.NumberFormat.CurrencyDecimalDigits); SubscriptionViewModel subscriptionItem = new SubscriptionViewModel() { SubscriptionId = subscription.SubscriptionId, FriendlyName = subscriptionTitle, PortalOfferId = portalOfferId, PortalOfferPrice = portalOfferPrice.ToString("C", responseCulture), IsRenewable = isRenewable, IsEditable = isEditable, SubscriptionExpiryDate = subscriptionExpiryDate.Date.ToString("d", responseCulture), SubscriptionProRatedPrice = proratedPerSeatPrice }; // add this subcription to the customer's subscription list. customerSubscriptionsView.Add(subscriptionItem); } List <CustomerSubscriptionModel> customerManagedSubscriptions = new List <CustomerSubscriptionModel>(); List <PartnerSubscriptionModel> partnerManagedSubscriptions = new List <PartnerSubscriptionModel>(); // Divide the subscriptions by customer and partner foreach (Subscription customerSubscriptionFromPC in customerAllSubscriptions.Items) { SubscriptionViewModel subscription = customerSubscriptionsView.FirstOrDefault(sub => sub.SubscriptionId == customerSubscriptionFromPC.Id); // Customer managed subscription found if (subscription != null) { CustomerSubscriptionModel customerSubscription = new CustomerSubscriptionModel() { SubscriptionId = customerSubscriptionFromPC.Id, LicensesTotal = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture), Status = GetStatusType(customerSubscriptionFromPC.Status), CreationDate = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture), FriendlyName = subscription.FriendlyName, IsRenewable = subscription.IsRenewable, IsEditable = subscription.IsEditable, PortalOfferId = subscription.PortalOfferId, SubscriptionProRatedPrice = subscription.SubscriptionProRatedPrice }; customerManagedSubscriptions.Add(customerSubscription); } else { PartnerSubscriptionModel partnerSubscription = new PartnerSubscriptionModel() { Id = customerSubscriptionFromPC.Id, OfferName = customerSubscriptionFromPC.OfferName, Quantity = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture), Status = GetStatusType(customerSubscriptionFromPC.Status), CreationDate = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture), }; partnerManagedSubscriptions.Add(partnerSubscription); } } ManagedSubscriptionsViewModel managedSubscriptions = new ManagedSubscriptionsViewModel() { CustomerManagedSubscriptions = customerManagedSubscriptions.OrderByDescending(customerManagedSubscription => customerManagedSubscription.CreationDate), PartnerManagedSubscriptions = partnerManagedSubscriptions.OrderByDescending(partnerManagedSubscription => partnerManagedSubscription.CreationDate) }; // Capture the request for customer managed subscriptions and partner managed subscriptions for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", clientCustomerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "CustomerManagedSubscriptions", customerManagedSubscriptions.Count }, { "PartnerManagedSubscriptions", partnerManagedSubscriptions.Count } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetManagedSubscriptions", eventProperties, eventMetrics); return(managedSubscriptions); }
/// <summary> /// Gets the summary of subscriptions for a portal customer. /// </summary> /// <param name="customerId">The customer Id.</param> /// <returns>Subscription Summary.</returns> private async Task <SubscriptionsSummary> GetSubscriptionSummaryAsync(string customerId) { DateTime startTime = DateTime.Now; IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId).ConfigureAwait(false); IEnumerable <CustomerPurchaseEntity> customerSubscriptionsHistory = await ApplicationDomain.Instance.CustomerPurchasesRepository.RetrieveAsync(customerId).ConfigureAwait(false); IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false); IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false); // start building the summary. decimal summaryTotal = 0; // format all responses to client using portal locale. CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale); List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>(); // iterate through and build the list of customer's subscriptions. foreach (CustomerSubscriptionEntity subscription in customerSubscriptions) { decimal subscriptionTotal = 0; int licenseTotal = 0; List <SubscriptionHistory> historyItems = new List <SubscriptionHistory>(); // collect the list of history items for this subcription. IOrderedEnumerable <CustomerPurchaseEntity> subscriptionHistoryList = customerSubscriptionsHistory .Where(historyItem => historyItem.SubscriptionId == subscription.SubscriptionId) .OrderBy(historyItem => historyItem.TransactionDate); // iterate through and build the SubsriptionHistory for this subscription. foreach (CustomerPurchaseEntity historyItem in subscriptionHistoryList) { decimal orderTotal = Math.Round(historyItem.SeatPrice * historyItem.SeatsBought, responseCulture.NumberFormat.CurrencyDecimalDigits); historyItems.Add(new SubscriptionHistory() { OrderTotal = orderTotal.ToString("C", responseCulture), // Currency format. PricePerSeat = historyItem.SeatPrice.ToString("C", responseCulture), // Currency format. SeatsBought = historyItem.SeatsBought.ToString("G", responseCulture), // General format. OrderDate = historyItem.TransactionDate.ToLocalTime().ToString("d", responseCulture), // Short date format. OperationType = GetOperationType(historyItem.PurchaseType) // Localized Operation type string. }); // Increment the subscription total. licenseTotal += historyItem.SeatsBought; // Increment the subscription total. subscriptionTotal += orderTotal; } PartnerOffer partnerOfferItem = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId); string subscriptionTitle = partnerOfferItem.Title; string portalOfferId = partnerOfferItem.Id; decimal portalOfferPrice = partnerOfferItem.Price; DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime(); int remainingDays = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days; bool isRenewable = remainingDays <= 30; bool isEditable = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; // TODO :: Handle Microsoft offer being pulled back due to EOL. // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription. MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId); if (alignedMicrosoftOffer == null) { partnerOfferItem.IsInactive = true; } if (partnerOfferItem.IsInactive) { // in case the offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer. isRenewable = false; isEditable = false; } // Compute the pro rated price per seat for this subcription & return for client side processing during updates. decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice), responseCulture.NumberFormat.CurrencyDecimalDigits); SubscriptionViewModel subscriptionItem = new SubscriptionViewModel() { SubscriptionId = subscription.SubscriptionId, FriendlyName = subscriptionTitle, PortalOfferId = portalOfferId, PortalOfferPrice = portalOfferPrice.ToString("C", responseCulture), IsRenewable = isRenewable, // IsRenewable is true if subscription is going to expire in 30 days. IsEditable = isEditable, // IsEditable is true if today is lesser or equal to subscription expiry date. LicensesTotal = licenseTotal.ToString("G", responseCulture), // General format. SubscriptionTotal = subscriptionTotal.ToString("C", responseCulture), // Currency format. SubscriptionExpiryDate = subscriptionExpiryDate.Date.ToString("d", responseCulture), // Short date format. SubscriptionOrderHistory = historyItems, SubscriptionProRatedPrice = proratedPerSeatPrice }; // add this subcription to the customer's subscription list. customerSubscriptionsView.Add(subscriptionItem); // Increment the summary total. summaryTotal += subscriptionTotal; } // Capture the request for the customer summary for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", customerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "NumberOfSubscriptions", customerSubscriptionsView.Count } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetSubscriptionSummaryAsync", eventProperties, eventMetrics); // Sort List of subscriptions based on portal offer name. return(new SubscriptionsSummary() { Subscriptions = customerSubscriptionsView.OrderBy(subscriptionItem => subscriptionItem.FriendlyName), SummaryTotal = summaryTotal.ToString("C", responseCulture) // Currency format. }); }
public async Task <SubscriptionsSummary> ProcessOrderForUnAuthenticatedCustomer(string customerId, string paymentId, string payerId) { DateTime startTime = DateTime.Now; customerId.AssertNotEmpty(nameof(customerId)); paymentId.AssertNotEmpty(nameof(paymentId)); payerId.AssertNotEmpty(nameof(payerId)); BrandingConfiguration branding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); CustomerViewModel customerRegistrationInfoPersisted = await ApplicationDomain.Instance.CustomerRegistrationRepository.RetrieveAsync(customerId).ConfigureAwait(false); Customer newCustomer = new Customer() { CompanyProfile = new CustomerCompanyProfile() { Domain = customerRegistrationInfoPersisted.DomainName, }, BillingProfile = new CustomerBillingProfile() { Culture = customerRegistrationInfoPersisted.BillingCulture, Language = customerRegistrationInfoPersisted.BillingLanguage, Email = customerRegistrationInfoPersisted.Email, CompanyName = customerRegistrationInfoPersisted.CompanyName, DefaultAddress = new Address() { FirstName = customerRegistrationInfoPersisted.FirstName, LastName = customerRegistrationInfoPersisted.LastName, AddressLine1 = customerRegistrationInfoPersisted.AddressLine1, AddressLine2 = customerRegistrationInfoPersisted.AddressLine2, City = customerRegistrationInfoPersisted.City, State = customerRegistrationInfoPersisted.State, Country = customerRegistrationInfoPersisted.Country, PostalCode = customerRegistrationInfoPersisted.ZipCode, PhoneNumber = customerRegistrationInfoPersisted.Phone, } } }; // Register customer newCustomer = await ApplicationDomain.Instance.PartnerCenterClient.Customers.CreateAsync(newCustomer).ConfigureAwait(false); ResourceCollection <AgreementMetaData> agreements = await ApplicationDomain.Instance.PartnerCenterClient.AgreementDetails.GetAsync().ConfigureAwait(false); // Obtain reference to the Microsoft Cloud Agreement. AgreementMetaData microsoftCloudAgreement = agreements.Items.FirstOrDefault(agr => agr.AgreementType == AgreementType.MicrosoftCloudAgreement); // Attest that the customer has accepted the Microsoft Cloud Agreement (MCA). await ApplicationDomain.Instance.PartnerCenterClient.Customers[newCustomer.Id].Agreements.CreateAsync( new Agreement { DateAgreed = DateTime.UtcNow, PrimaryContact = new PartnerCenter.Models.Agreements.Contact { Email = customerRegistrationInfoPersisted.Email, FirstName = customerRegistrationInfoPersisted.FirstName, LastName = customerRegistrationInfoPersisted.LastName, PhoneNumber = customerRegistrationInfoPersisted.Phone }, TemplateId = microsoftCloudAgreement.TemplateId, Type = AgreementType.MicrosoftCloudAgreement, UserId = branding.AgreementUserId }); string newCustomerId = newCustomer.CompanyProfile.TenantId; CustomerViewModel customerViewModel = new CustomerViewModel() { AddressLine1 = newCustomer.BillingProfile.DefaultAddress.AddressLine1, AddressLine2 = newCustomer.BillingProfile.DefaultAddress.AddressLine2, City = newCustomer.BillingProfile.DefaultAddress.City, State = newCustomer.BillingProfile.DefaultAddress.State, ZipCode = newCustomer.BillingProfile.DefaultAddress.PostalCode, Country = newCustomer.BillingProfile.DefaultAddress.Country, Phone = newCustomer.BillingProfile.DefaultAddress.PhoneNumber, Language = newCustomer.BillingProfile.Language, FirstName = newCustomer.BillingProfile.DefaultAddress.FirstName, LastName = newCustomer.BillingProfile.DefaultAddress.LastName, Email = newCustomer.BillingProfile.Email, CompanyName = newCustomer.BillingProfile.CompanyName, MicrosoftId = newCustomer.CompanyProfile.TenantId, UserName = newCustomer.BillingProfile.Email, Password = newCustomer.UserCredentials.Password, AdminUserAccount = newCustomer.UserCredentials.UserName + "@" + newCustomer.CompanyProfile.Domain }; IPaymentGateway paymentGateway = PaymentGatewayConfig.GetPaymentGatewayInstance(ApplicationDomain.Instance, "ProcessingOrder"); OrderViewModel orderToProcess = await paymentGateway.GetOrderDetailsFromPaymentAsync(payerId, paymentId, string.Empty, string.Empty).ConfigureAwait(false); // Assign the actual customer Id orderToProcess.CustomerId = newCustomerId; CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, newCustomerId, paymentGateway); await commerceOperation.PurchaseAsync(orderToProcess).ConfigureAwait(false); SubscriptionsSummary summaryResult = await GetSubscriptionSummaryAsync(newCustomerId).ConfigureAwait(false); // Remove the persisted customer registration info. await ApplicationDomain.Instance.CustomerRegistrationRepository.DeleteAsync(customerId).ConfigureAwait(false); // Capture the request for the customer summary for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", orderToProcess.CustomerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("api/order/NewCustomerProcessOrder", eventProperties, eventMetrics); summaryResult.CustomerViewModel = customerViewModel; return(summaryResult); }
public async Task <SubscriptionsSummary> ProcessOrderForUnAuthenticatedCustomer(string customerId, string paymentId, string payerId) { var startTime = DateTime.Now; customerId.AssertNotEmpty(nameof(customerId)); paymentId.AssertNotEmpty(nameof(paymentId)); payerId.AssertNotEmpty(nameof(payerId)); // Retrieve customer registration details persisted CustomerRegistrationRepository customerRegistrationRepository = new CustomerRegistrationRepository(ApplicationDomain.Instance); CustomerViewModel customerRegistrationInfoPersisted = await ApplicationDomain.Instance.CustomerRegistrationRepository.RetrieveAsync(customerId); var newCustomer = new Customer() { CompanyProfile = new CustomerCompanyProfile() { Domain = customerRegistrationInfoPersisted.DomainName, }, BillingProfile = new CustomerBillingProfile() { Culture = customerRegistrationInfoPersisted.BillingCulture, Language = customerRegistrationInfoPersisted.BillingLanguage, Email = customerRegistrationInfoPersisted.Email, CompanyName = customerRegistrationInfoPersisted.CompanyName, DefaultAddress = new Address() { FirstName = customerRegistrationInfoPersisted.FirstName, LastName = customerRegistrationInfoPersisted.LastName, AddressLine1 = customerRegistrationInfoPersisted.AddressLine1, AddressLine2 = customerRegistrationInfoPersisted.AddressLine2, City = customerRegistrationInfoPersisted.City, State = customerRegistrationInfoPersisted.State, Country = customerRegistrationInfoPersisted.Country, PostalCode = customerRegistrationInfoPersisted.ZipCode, PhoneNumber = customerRegistrationInfoPersisted.Phone, } } }; // Register customer newCustomer = await ApplicationDomain.Instance.PartnerCenterClient.Customers.CreateAsync(newCustomer); var newCustomerId = newCustomer.CompanyProfile.TenantId; CustomerViewModel customerViewModel = new CustomerViewModel() { AddressLine1 = newCustomer.BillingProfile.DefaultAddress.AddressLine1, AddressLine2 = newCustomer.BillingProfile.DefaultAddress.AddressLine2, City = newCustomer.BillingProfile.DefaultAddress.City, State = newCustomer.BillingProfile.DefaultAddress.State, ZipCode = newCustomer.BillingProfile.DefaultAddress.PostalCode, Country = newCustomer.BillingProfile.DefaultAddress.Country, Phone = newCustomer.BillingProfile.DefaultAddress.PhoneNumber, Language = newCustomer.BillingProfile.Language, FirstName = newCustomer.BillingProfile.DefaultAddress.FirstName, LastName = newCustomer.BillingProfile.DefaultAddress.LastName, Email = newCustomer.BillingProfile.Email, CompanyName = newCustomer.BillingProfile.CompanyName, MicrosoftId = newCustomer.CompanyProfile.TenantId, UserName = newCustomer.BillingProfile.Email, Password = newCustomer.UserCredentials.Password, AdminUserAccount = newCustomer.UserCredentials.UserName + "@" + newCustomer.CompanyProfile.Domain }; IPaymentGateway paymentGateway = PaymentGatewayConfig.GetPaymentGatewayInstance(ApplicationDomain.Instance, "ProcessingOrder"); OrderViewModel orderToProcess = await paymentGateway.GetOrderDetailsFromPaymentAsync(payerId, paymentId, string.Empty, string.Empty); // Assign the actual customer Id orderToProcess.CustomerId = newCustomerId; CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, newCustomerId, paymentGateway); await commerceOperation.PurchaseAsync(orderToProcess); SubscriptionsSummary summaryResult = await this.GetSubscriptionSummaryAsync(newCustomerId); // Remove the persisted customer registration info. var deleteResult = ApplicationDomain.Instance.CustomerRegistrationRepository.DeleteAsync(customerId); // Capture the request for the customer summary for analysis. var eventProperties = new Dictionary <string, string> { { "CustomerId", orderToProcess.CustomerId } }; // Track the event measurements for analysis. var eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("api/order/NewCustomerProcessOrder", eventProperties, eventMetrics); summaryResult.CustomerViewModel = customerViewModel; return(summaryResult); }
/// <summary> /// Gets the summary of subscriptions for a portal customer. /// </summary> /// <param name="customerId">The customer Id.</param> /// <returns>Subscription Summary.</returns> private async Task <SubscriptionsSummary> GetSubscriptionSummary(string customerId) { var customerSubscriptionsTask = ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId); var customerSubscriptionsHistoryTask = ApplicationDomain.Instance.CustomerPurchasesRepository.RetrieveAsync(customerId); var allPartnerOffersTask = ApplicationDomain.Instance.OffersRepository.RetrieveAsync(); await Task.WhenAll(customerSubscriptionsTask, customerSubscriptionsHistoryTask, allPartnerOffersTask); var customerSubscriptionsHistory = customerSubscriptionsHistoryTask.Result; // retrieve all the partner offers to match against them IEnumerable <PartnerOffer> allPartnerOffers = allPartnerOffersTask.Result; // start building the summary. decimal summaryTotal = 0; // format all responses to client using portal locale. CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale); List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>(); // iterate through and build the list of customer's subscriptions. foreach (var subscription in customerSubscriptionsTask.Result) { decimal subscriptionTotal = 0; int licenseTotal = 0; List <SubscriptionHistory> historyItems = new List <SubscriptionHistory>(); // collect the list of history items for this subcription. var subscriptionHistoryList = customerSubscriptionsHistory .Where(historyItem => historyItem.SubscriptionId == subscription.SubscriptionId) .OrderBy(historyItem => historyItem.TransactionDate); // iterate through and build the SubsriptionHistory for this subscription. foreach (var historyItem in subscriptionHistoryList) { decimal orderTotal = Math.Round(historyItem.SeatPrice * historyItem.SeatsBought, 2); historyItems.Add(new SubscriptionHistory() { OrderTotal = orderTotal.ToString("C", responseCulture), PricePerSeat = historyItem.SeatPrice.ToString("C", responseCulture), // Currency format. SeatsBought = historyItem.SeatsBought.ToString("G", responseCulture), // General format. OrderDate = historyItem.TransactionDate.ToLocalTime().ToString("d", responseCulture), // Short date format. OperationType = this.GetOperationType(historyItem.PurchaseType) // Localized Operation type string. }); // Increment the subscription total. licenseTotal += historyItem.SeatsBought; // Increment the subscription total. subscriptionTotal += orderTotal; } var partnerOfferItem = allPartnerOffers.Where(offer => offer.Id == subscription.PartnerOfferId).FirstOrDefault(); string subscriptionTitle = partnerOfferItem.Title; string portalOfferId = partnerOfferItem.Id; decimal portalOfferPrice = partnerOfferItem.Price; DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime(); int remainingDays = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days; bool isRenewable = remainingDays <= 30; bool isEditable = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; if (partnerOfferItem.IsInactive) { // in case the offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer. isRenewable = false; isEditable = false; } // Compute the pro rated price per seat for this subcription & return for client side processing during updates. decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice), 2); SubscriptionViewModel subscriptionItem = new SubscriptionViewModel() { SubscriptionId = subscription.SubscriptionId, FriendlyName = subscriptionTitle, PortalOfferId = portalOfferId, PortalOfferPrice = portalOfferPrice.ToString("C", responseCulture), IsRenewable = isRenewable, // IsRenewable is true if subscription is going to expire in 30 days. IsEditable = isEditable, // IsEditable is true if today is lesser or equal to subscription expiry date. LicensesTotal = licenseTotal.ToString("G", responseCulture), // General format. SubscriptionTotal = subscriptionTotal.ToString("C", responseCulture), // Currency format. SubscriptionExpiryDate = subscriptionExpiryDate.Date.ToString("d", responseCulture), // Short date format. SubscriptionOrderHistory = historyItems, SubscriptionProRatedPrice = proratedPerSeatPrice }; // add this subcription to the customer's subscription list. customerSubscriptionsView.Add(subscriptionItem); // Increment the summary total. summaryTotal += subscriptionTotal; } // Sort List of subscriptions based on portal offer name. return(new SubscriptionsSummary() { Subscriptions = customerSubscriptionsView.OrderBy(subscriptionItem => subscriptionItem.FriendlyName), SummaryTotal = summaryTotal.ToString("C", responseCulture) // Currency format. }); }