Example #1
0
        // Create new Sales Order
        //
        private SalesOrder BuildNewSalesOrder(ShopifyOrder shopifyOrderRecord, AcumaticaCustomer customer)
        {
            // Get the Shopify Order
            //
            var shopifyOrder = _shopifyJsonService.RetrieveOrder(shopifyOrderRecord.ShopifyOrderId);

            // Header
            //
            var salesOrder = BuildNewSalesOrderHeader(shopifyOrderRecord, shopifyOrder, customer);

            // Detail
            //
            salesOrder.Details = BuildSalesOrderDetail(shopifyOrder);

            // Billing Address & Contact
            //
            salesOrder.BillToContactOverride = true.ToValue();
            salesOrder.BillToContact         = BuildContact(shopifyOrder, shopifyOrder.billing_address);
            salesOrder.BillToAddressOverride = true.ToValue();
            salesOrder.BillToAddress         = BuildAddress(shopifyOrder.billing_address);

            // Shipping Address & Contact
            //
            salesOrder.ShipToContactOverride = true.ToValue();
            salesOrder.ShipToContact         = BuildContact(shopifyOrder, shopifyOrder.shipping_address);
            salesOrder.ShipToAddressOverride = true.ToValue();
            salesOrder.ShipToAddress         = BuildAddress(shopifyOrder.shipping_address);

            if (!shopifyOrder.MaybeShippingRateTitle.IsNullOrEmpty())
            {
                var carrierToShipVia
                    = _settingsRepository.RetrieveRateToShipVia(shopifyOrder.MaybeShippingRateTitle);

                if (carrierToShipVia != null)
                {
                    salesOrder.ShipVia = carrierToShipVia.AcumaticaShipViaId.ToValue();
                }
            }

            // Payment optimization *** FAIL - PENDING ACUMATICA SUPPORT ***
            //
            //var payment = _acumaticaOrderPaymentPut.BuildPaymentForCreate(shopifyOrderRecord.PaymentTransaction());
            //salesOrder.Payments = new List<object> { payment };

            salesOrder.PaymentRef = shopifyOrderRecord.PaymentTransaction().ShopifyTransactionId.ToString().ToValue();

            return(salesOrder);
        }
        private ValidationResult ReadyToCreateOrder(long shopifyOrderId)
        {
            var output      = new CreateOrderValidation();
            var orderRecord = _syncOrderRepository.RetrieveShopifyOrderWithNoTracking(shopifyOrderId);
            var order       = _shopifyJsonService.RetrieveOrder(shopifyOrderId);

            var settings = _settingsRepository.RetrieveSettings();

            // If the Starting Shopify Order weren't populated, we would not be here i.e.
            // ... the Shopify Order would not have been pulled from API
            //
            output.SettingsStartingOrderId = settings.ShopifyOrderId.Value;
            output.ShopifyOrderRecord      = orderRecord;
            output.ShopifyOrder            = order;

            BuildLineItemValidations(output, settings);

            output.ShopifyShippingRateName = order.MaybeShippingRateTitle;
            output.HasValidShippingRate    = _settingsRepository.RateMappingExists(order.MaybeShippingRateTitle);

            if (orderRecord.HasPayment())
            {
                output.ShopifyPaymentGatewayId = orderRecord.PaymentTransaction().ShopifyGateway;
                output.HasValidGateway
                    = _settingsRepository.GatewayExistsInConfig(output.ShopifyPaymentGatewayId);
            }

            return(output.Result());
        }
Example #3
0
        public ActionResult OrderAnalysis(long shopifyOrderId)
        {
            var financialSummary = _analysisDataService.GetOrderFinancialSummary(shopifyOrderId);
            var rootAction       = _pendingActionService.Create(shopifyOrderId);

            var record      = _shopifyOrderRepository.RetrieveOrder(shopifyOrderId);
            var order       = _shopifyJsonService.RetrieveOrder(record.ShopifyOrderId);
            var finAnalyzer = record.ToFinAnalyzer(order);

            var shopifyDetail = new
            {
                ShopifyOrderId      = shopifyOrderId,
                ShopifyOrderNbr     = record.ShopifyOrderNumber,
                ShopifyOrderHref    = _shopifyUrlService.ShopifyOrderUrl(shopifyOrderId),
                ShopifyCustomerId   = record.ShopifyCustomer.ShopifyCustomerId,
                ShopifyCustomerHref = _shopifyUrlService.ShopifyCustomerUrl(record.ShopifyCustomer.ShopifyCustomerId),

                ShopifyFinancialStatus     = record.ShopifyFinancialStatus,
                ShopifyFulfillmentStatus   = record.ShopifyFulfillmentStatus,
                ShopifyIsCancelled         = record.ShopifyIsCancelled,
                ShopifyAreAllItemsRefunded = record.IsCancelledOrAllRefunded(),

                Transfer = finAnalyzer,
            };

            return(new JsonNetResult(new
            {
                FinancialSummary = financialSummary,
                ShopifyDetail = shopifyDetail,
                RootAction = rootAction,
            }));
        }
Example #4
0
        private OrderAction BuildOrderPendingAction(ShopifyOrder record)
        {
            var output = new OrderAction();
            var order  = _shopifyJsonService.RetrieveOrder(record.ShopifyOrderId);

            output.ShopifyOrderId   = record.ShopifyOrderId;
            output.ShopifyOrderHref = _shopifyUrlService.ShopifyOrderUrl(record.ShopifyOrderId);
            output.ShopifyOrderName = order.name;

            output.Validation = new ValidationResult();
            output.ActionCode = ActionCode.None;

            if (!record.ExistsInAcumatica())
            {
                output.ActionCode =
                    order.IsCancelled || order.AreAllLineItemsRefunded
                        ? ActionCode.CreateBlankSyncRecord
                        : ActionCode.CreateInAcumatica;
            }
            else // Exists in Acumatica
            {
                output.AcumaticaSalesOrderNbr = record.AcumaticaSalesOrder.AcumaticaOrderNbr;
                output.AcumaticaSalesOrderHref
                    = _acumaticaUrlService.AcumaticaSalesOrderUrl(
                          SalesOrderType.SO, record.AcumaticaSalesOrder.AcumaticaOrderNbr);

                if (record.NeedsOrderPut ||
                    record.ShopifyTotalQuantity != record.SyncedSalesOrder().AcumaticaQtyTotal)
                {
                    output.ActionCode = ActionCode.UpdateInAcumatica;
                }
            }

            return(output);
        }
Example #5
0
        private void PullTransactionsFromShopify(ShopifyOrder orderRecord)
        {
            var transactionsJson = _orderApi.RetrieveTransactions(orderRecord.ShopifyOrderId);
            var transactions     = transactionsJson.DeserializeFromJson <TransactionList>();
            var order            = _shopifyJsonService.RetrieveOrder(orderRecord.ShopifyOrderId);

            foreach (var transaction in transactions.transactions)
            {
                var transactionRecord = _orderRepository.RetrieveTransaction(transaction.id);
                if (transactionRecord != null)
                {
                    transactionRecord.LastUpdated = DateTime.UtcNow;
                    _orderRepository.SaveChanges();
                    continue;
                }

                using (var dbTransaction = _orderRepository.BeginTransaction())
                {
                    var record = new ShopifyTransaction();

                    if (transaction.kind == TransactionKind.Refund)
                    {
                        record.IsSyncableToPayment = true;

                        var refund = order.RefundByTransaction(transaction.id);
                        if (refund != null)
                        {
                            record.ShopifyRefundId = refund.id;
                            record.IsPureCancel    = refund.IsPureCancel;
                        }
                    }

                    if (transaction.kind == TransactionKind.Capture || transaction.kind == TransactionKind.Sale)
                    {
                        record.IsSyncableToPayment = true;
                    }

                    record.ShopifyOrderId        = transaction.order_id;
                    record.ShopifyTransactionId  = transaction.id;
                    record.ShopifyStatus         = transaction.status;
                    record.ShopifyKind           = transaction.kind;
                    record.ShopifyGateway        = transaction.gateway;
                    record.ShopifyAmount         = transaction.amount;
                    record.ShopifyOrderMonsterId = orderRecord.MonsterId;
                    record.DateCreated           = DateTime.UtcNow;
                    record.LastUpdated           = DateTime.UtcNow;

                    _logService.Log(LogBuilder.DetectedNewShopifyTransaction(record));
                    _orderRepository.InsertTransaction(record);

                    _shopifyJsonService.Upsert(
                        ShopifyJsonType.Transaction, transaction.id, transaction.SerializeToJson());
                    dbTransaction.Commit();
                }
            }

            orderRecord.NeedsTransactionGet = false;
            _orderRepository.SaveChanges();
        }
Example #6
0
        private void CorrectFulfillmentWithUnknownRef(string shipmentNbr)
        {
            var salesOrderShipment = _syncOrderRepository.RetrieveSoShipment(shipmentNbr);

            if (!salesOrderShipment.HasSyncWithUnknownNbr())
            {
                return;
            }

            var fulfillmentRecord = salesOrderShipment.ShopifyFulfillment;

            var shopifyOrder =
                _shopifyJsonService.RetrieveOrder(
                    salesOrderShipment.AcumaticaSalesOrder.ShopifyOrder.ShopifyOrderId);

            var matches =
                shopifyOrder
                .fulfillments
                .Where(x => x.tracking_number == salesOrderShipment.AcumaticaTrackingNbr)
                .ToList();

            if (!matches.Any())
            {
                var content = LogBuilder.ShopifyFulfillmentWithUnknownRefNoMatches(salesOrderShipment);
                _logService.Log(content);
                _syncOrderRepository.SetErrorCountToMaximum(shopifyOrder.id);
                return;
            }

            if (matches.Count() > 1)
            {
                var content = LogBuilder.ShopifyFulfillmentWithUnknownRefTooManyMatches(salesOrderShipment);
                _logService.Log(content);
                _syncOrderRepository.SetErrorCountToMaximum(shopifyOrder.id);
                return;
            }

            fulfillmentRecord.Ingest(matches.First());
            fulfillmentRecord.DateCreated = DateTime.UtcNow;
            fulfillmentRecord.LastUpdated = DateTime.UtcNow;

            _logService.Log(LogBuilder.FillingUnknownShopifyFulfillmentRef(salesOrderShipment, fulfillmentRecord));
            _shopifyOrderRepository.SaveChanges();
        }
        public PaymentWrite BuildPaymentForCreate(ShopifyTransaction transactionRecord)
        {
            var transaction = _shopifyJsonService.RetrieveTransaction(transactionRecord.ShopifyTransactionId);
            var gateway     = _settingsRepository.RetrievePaymentGatewayByShopifyId(transaction.gateway);

            // Locate the Acumatica Customer
            //
            var shopifyCustomerId = transactionRecord.CustomerId();
            var customer          = _syncOrderRepository.RetrieveCustomer(shopifyCustomerId);
            var acumaticaCustId   = customer.AcumaticaCustId();

            // Build the Payment Ref and Description
            //
            var orderRecord = _syncOrderRepository.RetrieveShopifyOrder(transactionRecord.OrderId());
            var order       = _shopifyJsonService.RetrieveOrder(orderRecord.ShopifyOrderId);

            // Create the payload for Acumatica
            //
            var payment = new PaymentWrite();

            payment.CustomerID = acumaticaCustId.ToValue();
            payment.Hold       = false.ToValue();
            payment.Type       = PaymentType.Payment.ToValue();
            payment.PaymentRef = $"{transaction.id}".ToValue();

            var createdAtUtc  = (transaction.created_at ?? order.created_at).UtcDateTime;
            var acumaticaDate = _acumaticaTimeZoneService.ToAcumaticaTimeZone(createdAtUtc);

            payment.ApplicationDate = acumaticaDate.Date.ToValue();

            // Amount computations
            //
            payment.PaymentAmount = ((double)transaction.amount).ToValue();
            var appliedToOrder = orderRecord.TheoreticalPaymentRemaining();


            // Applied to Documents
            //
            var acumaticaOrderRef = orderRecord.AcumaticaSalesOrderId();

            if (acumaticaOrderRef.HasValue() && orderRecord.IsNotCancelledOrAllRefunded())
            {
                payment.OrdersToApply =
                    PaymentOrdersRef.ForOrder(acumaticaOrderRef, SalesOrderType.SO, (double)appliedToOrder);
            }

            payment.PaymentMethod = gateway.AcumaticaPaymentMethod.ToValue();
            payment.CashAccount   = gateway.AcumaticaCashAccount.ToValue();
            payment.Description   = $"Payment for Shopify Order #{orderRecord.ShopifyOrderNumber}".ToValue();

            return(payment);
        }
        public OrderAnalysisTotals GetOrderFinancialSummary(long shopifyOrderId)
        {
            var shopifyOrderRecord =
                ShopifyOrderQueryable.FirstOrDefault(x => x.ShopifyOrderId == shopifyOrderId);

            var shopifyOrder = _shopifyJsonService.RetrieveOrder(shopifyOrderId);

            var output = new OrderAnalysisTotals();

            output.ShopifyOrderNbr  = shopifyOrderRecord.ShopifyOrderNumber;
            output.ShopifyOrderId   = shopifyOrderRecord.ShopifyOrderId;
            output.ShopifyOrderHref = _shopifyUrlService.ShopifyOrderUrl(shopifyOrderRecord.ShopifyOrderId);

            output.ShopifyCustomerId   = shopifyOrderRecord.ShopifyCustomer.ShopifyCustomerId;
            output.ShopifyCustomerHref =
                _shopifyUrlService
                .ShopifyCustomerUrl(shopifyOrderRecord.ShopifyCustomer.ShopifyCustomerId);

            output.ShopifyTotalLinePrice     = shopifyOrder.LineItemAmountAfterDiscountAndRefund;
            output.ShopifyShippingPriceTotal = shopifyOrder.NetShippingPrice;
            output.ShopifyTotalTax           = shopifyOrder.NetTax;
            output.ShopifyOrderTotal         = shopifyOrder.NetOrderTotal;

            output.ShopifyOrderPayment  = shopifyOrderRecord.ShopifyPaymentAmount();
            output.ShopifyRefundPayment = shopifyOrderRecord.RefundTransactions().Sum(x => x.ShopifyAmount);
            output.ShopifyNetPayment    = shopifyOrderRecord.ShopifyNetPayment();

            output.ShopifyRefundItemTotal     = shopifyOrder.RefundLineItemTotal;
            output.ShopifyRefundShippingTotal = shopifyOrder.RefundShippingTotal;
            output.ShopifyRefundTaxTotal      = shopifyOrder.RefundTotalTax;
            output.ShopifyCreditTotal         = shopifyOrder.RefundCreditTotal;
            output.ShopifyDebitTotal          = shopifyOrder.RefundDebitTotal;
            output.ShopifyRefundTotal         = shopifyOrder.RefundTotal;
            output.ShopifyRefundOverpayment   = shopifyOrder.RefundOverpayment;

            if (shopifyOrderRecord.ExistsInAcumatica() &&
                shopifyOrderRecord.AcumaticaSalesOrder.AcumaticaOrderNbr != AcumaticaSyncConstants.BlankRefNbr)
            {
                output.AcumaticaSalesOrderNbr
                    = shopifyOrderRecord.AcumaticaSalesOrder.AcumaticaOrderNbr ?? "BLANK";
                output.AcumaticaSalesOrderHref
                    = _acumaticaUrlService.AcumaticaSalesOrderUrl(
                          SalesOrderType.SO, shopifyOrderRecord.AcumaticaSalesOrder.AcumaticaOrderNbr);

                output.AcumaticaCustomerNbr = shopifyOrderRecord.AcumaticaSalesOrder.AcumaticaCustomer.AcumaticaCustomerId;
                output.AcumaticaCustomerHref
                    = _acumaticaUrlService.AcumaticaCustomerUrl(
                          shopifyOrderRecord.AcumaticaSalesOrder.AcumaticaCustomer.AcumaticaCustomerId);

                var acumaticaOrder = shopifyOrderRecord.AcumaticaSalesOrder;
                output.AcumaticaOrderLineTotal = acumaticaOrder.AcumaticaLineTotal;
                output.AcumaticaOrderFreight   = acumaticaOrder.AcumaticaFreight;
                output.AcumaticaTaxTotal       = acumaticaOrder.AcumaticaTaxTotal;
                output.AcumaticaOrderTotal     = acumaticaOrder.AcumaticaOrderTotal;
            }

            output.AcumaticaPaymentTotal       = shopifyOrderRecord.AcumaticaPaymentAmount();
            output.AcumaticaRefundPaymentTotal = shopifyOrderRecord.AcumaticaCustomerRefundTotal();
            output.AcumaticaNetPaymentTotal    = shopifyOrderRecord.AcumaticaNetPaymentAmount();

            output.AcumaticaRefundCreditTotal = shopifyOrderRecord.AcumaticaCreditMemosTotal();
            output.AcumaticaRefundDebitTotal  = shopifyOrderRecord.AcumaticaDebitMemosTotal();

            output.AcumaticaInvoiceTaxTotal = shopifyOrderRecord.AcumaticaInvoiceTaxTotal();
            output.AcumaticaInvoiceTotal    = shopifyOrderRecord.AcumaticaInvoiceTotal();

            return(output);
        }