private async Task ProcessProductAsync(Product product) { CosmosListPage <LineItemDetailData> lineItemData = await GetLineItemDataAsync(product.ID); List <ProductDetailData> productDataList = await CreateProductDetailDataAsync(product, lineItemData?.Items); //Get current products in Cosmos to update/replace var requestOptions = BuildQueryRequestOptions(); foreach (ProductDetailData productData in productDataList) { var queryable = _productDetailRepo.GetQueryable().Where(x => x.PartitionKey == "PartitionValue" && x.Data.SpecCombo == productData.Data.SpecCombo); var listOptions = BuildProductListOptions(productData.ProductID, productData.Data.SpecCombo); CosmosListPage <ProductDetailData> currentProductDetailListPage = await _productDetailRepo.GetItemsAsync(queryable, requestOptions, listOptions); var cosmosID = ""; if (currentProductDetailListPage.Items.Count == 1) { cosmosID = productData.id = currentProductDetailListPage.Items[0].id; } await _productDetailRepo.UpsertItemAsync(cosmosID, productData); } }
private async Task UpsertOrderAndShipments(string orderID) { var orderWorksheet = await _oc.IntegrationEvents.GetWorksheetAsync <HSOrderWorksheet>(OrderDirection.Incoming, orderID); var shipments = await _oc.Shipments.ListAllAsync(orderID); foreach (var shipment in shipments) { var shipmentItems = await _oc.Shipments.ListAllItemsAsync(shipment.ID); foreach (var shipmentItem in shipmentItems) { var cosmosOrderWithShipments = OrderWithShipmentsMapper.Map(orderWorksheet, shipment, shipmentItem); if (cosmosOrderWithShipments.QuantityShipped != 0) { var queryable = _ordersAndShipmentsDataRepo.GetQueryable().Where(orderWithShipments => orderWithShipments.PartitionKey == "PartitionValue"); var requestOptions = BuildQueryRequestOptions(); var listOptions = BuildOrderWithShipmentsListOptions(orderID, shipmentItem.LineItemID, shipment.ID); CosmosListPage <OrderWithShipments> currentOrderWithShipmentsListPage = await _ordersAndShipmentsDataRepo.GetItemsAsync(queryable, requestOptions, listOptions); var cosmosID = ""; if (currentOrderWithShipmentsListPage.Items.Count() == 1) { cosmosID = cosmosOrderWithShipments.id = currentOrderWithShipmentsListPage.Items[0].id; } await _ordersAndShipmentsDataRepo.UpsertItemAsync(cosmosID, cosmosOrderWithShipments); } } } }
public async Task <List <HSLineItemOrder> > BuyerLineItemDetail(ListArgs <HSOrder> args, BuyerReportViewContext viewContext, string userID, string locationID, DecodedToken decodedToken) { IList <ListFilter> filters = new List <ListFilter>(); filters.Add(ApplyBuyerLineContext(viewContext, userID, locationID, decodedToken)); foreach (var filter in args.Filters) { filters.Add(ApplyBuyerLineFilter(filter)); } CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "OrderID", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <LineItemDetailData> queryable = _lineItemDetail.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <LineItemDetailData> lineItemDataResponse = await _lineItemDetail.GetItemsAsync(queryable, requestOptions, listOptions); List <LineItemDetailData> lineItemData = lineItemDataResponse.Items; listOptions.ContinuationToken = lineItemDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <LineItemDetailData> responseWithToken = await _lineItemDetail.GetItemsAsync(queryable, requestOptions, listOptions); lineItemData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var lineItems = new List <HSLineItemOrder>(); foreach (LineItemDetailData detailData in lineItemData) { foreach (HSLineItem lineDetail in detailData.Data.LineItems) { lineItems.Add(new HSLineItemOrder { HSOrder = detailData.Data.Order, HSLineItem = lineDetail }); } } return(lineItems); }
public async Task <CosmosListPage <RMA> > ListBuyerRMAs(CosmosListOptions listOptions, string buyerID) { IQueryable <RMA> queryable = _rmaRepo.GetQueryable().Where(rma => rma.FromBuyerID == buyerID); CosmosListPage <RMA> rmas = await GenerateRMAList(queryable, listOptions); return(rmas); }
public async Task <CosmosListPage <RMA> > ListBuyerRMAs(CosmosListOptions listOptions, VerifiedUserContext verifiedUser) { IQueryable <RMA> queryable = _rmaRepo.GetQueryable().Where(rma => rma.FromBuyerID == verifiedUser.Buyer.ID); CosmosListPage <RMA> rmas = await GenerateRMAList(queryable, listOptions); return(rmas); }
private async Task <CosmosListPage <RMA> > GenerateRMAList(IQueryable <RMA> queryable, CosmosListOptions listOptions) { QueryRequestOptions requestOptions = new QueryRequestOptions(); requestOptions.MaxItemCount = listOptions.PageSize; CosmosListPage <RMA> rmas = await _rmaRepo.GetItemsAsync(queryable, requestOptions, listOptions); return(rmas); }
public async Task <List <OrderWithShipments> > ShipmentDetail(string templateID, ListArgs <ReportAdHocFilters> args, DecodedToken decodedToken) { IList <ListFilter> filters = await BuildFilters(templateID, args, decodedToken, "DateSubmitted", "SupplierID"); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "OrderID", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <OrderWithShipments> queryable = _ordersAndShipments.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <OrderWithShipments> ordersWithShipmentsDataResponse = await _ordersAndShipments.GetItemsAsync(queryable, requestOptions, listOptions); List <OrderWithShipments> orderWithShipmentsData = ordersWithShipmentsDataResponse.Items; listOptions.ContinuationToken = ordersWithShipmentsDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <OrderWithShipments> responseWithToken = await _ordersAndShipments.GetItemsAsync(queryable, requestOptions, listOptions); orderWithShipmentsData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var ordersWithShipments = new List <OrderWithShipments>(); var supplierFilter = args.Filters.FirstOrDefault(filter => filter.PropertyName == "SupplierID"); var me = await _oc.Me.GetAsync(decodedToken.AccessToken); foreach (OrderWithShipments detailData in orderWithShipmentsData) { if (supplierFilter == null || supplierFilter.FilterExpression == detailData.SupplierID) { if (decodedToken.CommerceRole == CommerceRole.Seller || me.Supplier.ID == detailData.SupplierID) { ordersWithShipments.Add(detailData); } } } return(ordersWithShipments); }
private async Task <RMA> GetRMA(string rmaNumber, DecodedToken decodedToken) { var currentRMAFilter = new ListFilter("RMANumber", rmaNumber); CosmosListOptions currentRMAListOptions = new CosmosListOptions() { PageSize = 1, ContinuationToken = null, Filters = { currentRMAFilter } }; CosmosListPage <RMA> currentRMAListPage = await ListRMAs(currentRMAListOptions, decodedToken); RMA currentRMA = currentRMAListPage.Items[0]; return(currentRMA); }
public async Task <RMAWithLineItemStatusByQuantity> ProcessRefund(string rmaNumber, DecodedToken decodedToken) { var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken); RMA rma = await GetRMA(rmaNumber, decodedToken); ValidateRMA(rma, me.Supplier.ID); decimal initialAmountRefunded = rma.TotalCredited; IEnumerable <RMALineItem> rmaLineItemsToUpdate = rma.LineItems .Where(li => !li.IsRefunded && (li.Status == RMALineItemStatus.Approved || li.Status == RMALineItemStatus.PartialQtyApproved)).ToList(); HSOrderWorksheet worksheet = await _oc.IntegrationEvents.GetWorksheetAsync <HSOrderWorksheet>(OrderDirection.Incoming, rma.SourceOrderID); CosmosListPage <RMA> allRMAsOnThisOrder = await ListRMAsByOrderID(worksheet.Order.ID, decodedToken.CommerceRole, me, true); CalculateAndUpdateLineTotalRefund(rmaLineItemsToUpdate, worksheet, allRMAsOnThisOrder, rma.SupplierID); // UPDATE RMA LINE ITEM STATUSES SetRMALineItemStatusesToComplete(rmaLineItemsToUpdate); // UPDATE RMA STATUS UpdateRMAStatus(rma); await HandleRefund(rma, allRMAsOnThisOrder, worksheet, decodedToken); MarkRMALineItemsAsRefunded(rmaLineItemsToUpdate); decimal totalRefundedForThisTransaction = rma.TotalCredited - initialAmountRefunded; RMALog log = new RMALog() { Status = rma.Status, Date = DateTime.Now, AmountRefunded = totalRefundedForThisTransaction, FromUserID = me.ID }; rma.Logs.Insert(0, log); List <LineItemStatusChanges> lineItemStatusChangesList = BuildLineItemStatusChanges(rmaLineItemsToUpdate, worksheet, rma.Type, false); // SAVE RMA ItemResponse <RMA> updatedRMA = await _rmaRepo.ReplaceItemAsync(rma.id, rma); RMAWithLineItemStatusByQuantity rmaWithStatusByQuantityChanges = new RMAWithLineItemStatusByQuantity() { SupplierOrderID = $"{rma.SourceOrderID}-{rma.SupplierID}", RMA = updatedRMA.Resource, LineItemStatusChangesList = lineItemStatusChangesList }; return(rmaWithStatusByQuantityChanges); }
public async Task <CosmosListPage <RMA> > ListRMAs(CosmosListOptions listOptions, DecodedToken decodedToken) { IQueryable <RMA> queryable = _rmaRepo.GetQueryable().Where(rma => rma.PartitionKey == "PartitionValue"); if (decodedToken.CommerceRole == CommerceRole.Supplier) { var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken); queryable = queryable.Where(rma => rma.SupplierID == me.Supplier.ID); } CosmosListPage <RMA> rmas = await GenerateRMAList(queryable, listOptions); return(rmas); }
private bool ShouldIssueFullLineItemRefund(RMALineItem rmaLineItem, CosmosListPage <RMA> allRMAsOnThisOrder, HSOrderWorksheet orderWorksheet, string supplierID) { TransactionLineModel orderWorksheetLineItem = orderWorksheet.OrderCalculateResponse.xp.TaxResponse.lines.FirstOrDefault(li => li.lineNumber == rmaLineItem.ID); var rmasFromThisSupplier = allRMAsOnThisOrder.Items.Where(r => r.SupplierID == supplierID); // If this is the only RMA for this line item and all requested RMA quantity are approved, and the quantity equals the original order quantity, issue a full refund (line item cost + tax). if (rmaLineItem.Status == RMALineItemStatus.Approved && rmaLineItem.QuantityProcessed == orderWorksheetLineItem.quantity && rmasFromThisSupplier.Count() == 1) { return(true); } else { return(false); } }
public async Task <List <OrderDetailData> > PurchaseOrderDetail(string templateID, ListArgs <ReportAdHocFilters> args, DecodedToken decodedToken) { IList <ListFilter> filters = await BuildFilters(templateID, args, decodedToken, "DateSubmitted", "xp.SupplierIDs", "ShippingAddressID"); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "OrderID", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <OrderDetailData> queryable = _purchaseOrderDetail.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <OrderDetailData> purchaseOrderDataResponse = await _purchaseOrderDetail.GetItemsAsync(queryable, requestOptions, listOptions); List <OrderDetailData> purchaseOrderData = purchaseOrderDataResponse.Items; listOptions.ContinuationToken = purchaseOrderDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <OrderDetailData> responseWithToken = await _purchaseOrderDetail.GetItemsAsync(queryable, requestOptions, listOptions); purchaseOrderData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var purchaseOrders = new List <OrderDetailData>(); foreach (OrderDetailData purchaseOrder in purchaseOrderData) { purchaseOrder.ShipFromAddressID = purchaseOrder.Data.xp.SelectedShipMethodsSupplierView != null ? purchaseOrder.Data.xp.SelectedShipMethodsSupplierView[0].ShipFromAddressID : null; purchaseOrder.ShipMethod = purchaseOrder.Data.xp.SelectedShipMethodsSupplierView != null ? purchaseOrder.Data.xp.SelectedShipMethodsSupplierView[0].Name : null; purchaseOrders.Add(purchaseOrder); } return(purchaseOrders); }
public async Task <List <OrderDetailData> > SalesOrderDetail(string templateID, ListArgs <ReportAdHocFilters> args, DecodedToken decodedToken) { IList <ListFilter> filters = await BuildFilters(templateID, args, decodedToken, "DateSubmitted", "xp.SupplierIDs", "FromCompanyID"); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "OrderID", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <OrderDetailData> queryable = _salesOrderDetail.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <OrderDetailData> salesOrderDataResponse = await _salesOrderDetail.GetItemsAsync(queryable, requestOptions, listOptions); List <OrderDetailData> salesOrderData = salesOrderDataResponse.Items; listOptions.ContinuationToken = salesOrderDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <OrderDetailData> responseWithToken = await _salesOrderDetail.GetItemsAsync(queryable, requestOptions, listOptions); salesOrderData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var salesOrders = new List <OrderDetailData>(); foreach (OrderDetailData salesOrder in salesOrderData) { salesOrders.Add(salesOrder); } return(salesOrders); }
public async Task <CosmosListPage <RMA> > ListRMAsForOrder(string orderID, DecodedToken decodedToken) { var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken); HSOrder order = await _oc.Orders.GetAsync <HSOrder>(OrderDirection.Incoming, orderID); await EnsureUserCanAccessOrder(order, decodedToken); var listFilter = new ListFilter("SourceOrderID", orderID); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = 100, ContinuationToken = null, Filters = { listFilter } }; CosmosListPage <RMA> rmasOnOrder = await _rmaCommand.ListBuyerRMAs(listOptions, me.Buyer.ID); return(rmasOnOrder); }
private async Task UpsertLineItemDetail(string orderID) { var orderWorksheet = await _oc.IntegrationEvents.GetWorksheetAsync <HSOrderWorksheet>(OrderDirection.Incoming, orderID); var lineItems = await _oc.LineItems.ListAllAsync <HSLineItem>(OrderDirection.Incoming, orderID); var buyer = await _oc.Buyers.GetAsync <HSBuyer>(orderWorksheet.Order.FromCompanyID); var lineItemsWithMiscFields = await BuildLineItemsMiscFields(lineItems, orderWorksheet, buyer.Name); var lineItemsWithPurchaseOrders = await BuildLineItemsWithPurchaseOrders(orderID); var orderLineItemData = new HSOrderLineItemData() { Order = orderWorksheet.Order, LineItems = lineItems, LineItemsWithMiscFields = lineItemsWithMiscFields, LineItemsWithPurchaseOrderFields = lineItemsWithPurchaseOrders }; var queryable = _lineItemDetailDataRepo.GetQueryable().Where(order => order.PartitionKey == "PartitionValue"); var requestOptions = BuildQueryRequestOptions(); var cosmosLineItemOrder = new LineItemDetailData() { PartitionKey = "PartitionValue", OrderID = orderID, Data = orderLineItemData }; var listOptions = BuildListOptions(orderID); CosmosListPage <LineItemDetailData> currentLineItemListPage = await _lineItemDetailDataRepo.GetItemsAsync(queryable, requestOptions, listOptions); var cosmosID = ""; if (currentLineItemListPage.Items.Count() == 1) { cosmosID = cosmosLineItemOrder.id = currentLineItemListPage.Items[0].id; } await _lineItemDetailDataRepo.UpsertItemAsync(cosmosID, cosmosLineItemOrder); }
private async Task <CosmosListPage <LineItemDetailData> > GetLineItemDataAsync(string productID) { var queryable = _lineItemDetailDataRepo .GetQueryable() .Where(order => order.Data.LineItems.Any(lineItem => lineItem.ProductID == productID) && order.Data.Order.DateCreated > DateTime.Now.AddMonths(-12)); var requestOptions = new QueryRequestOptions() { MaxItemCount = 1 }; CosmosListOptions listOptions = new CosmosListOptions() { PageSize = 100, ContinuationToken = null }; CosmosListPage <LineItemDetailData> currentLineItemListPage = await _lineItemDetailDataRepo.GetItemsAsync(queryable, requestOptions, listOptions); return(currentLineItemListPage); }
private async Task <string> BuildRMANumber(HSOrder order) { var args = new CosmosListOptions() { PageSize = 100, Filters = new List <ListFilter>() { new ListFilter("SourceOrderID", order.ID) } }; CosmosListPage <RMA> existingRMAsOnOrder = await ListBuyerRMAs(args, order.FromCompanyID); int lastRMANumber = existingRMAsOnOrder.Items .OrderBy(rma => rma.RMANumber) .Select(rma => int.Parse(rma.RMANumber.Substring(rma.RMANumber.LastIndexOf("-") + 1))) .LastOrDefault(); string rmaSuffix = $"{lastRMANumber + 1}".PadLeft(2, '0'); string rmaNumber = $"{order.ID}-RMA-{rmaSuffix}"; return(rmaNumber); }
private async Task UpsertSalesOrderDetail(string orderID) { var order = await _oc.Orders.GetAsync <HSOrder>(OrderDirection.Incoming, orderID); var brand = await _oc.Buyers.GetAsync <HSBuyer>(order.FromCompanyID); var promos = await _oc.Orders.ListPromotionsAsync(OrderDirection.Incoming, orderID); var cosmosSalesOrder = new OrderDetailData() { PartitionKey = "PartitionValue", OrderID = orderID, Data = order, BrandName = brand.Name }; if (promos.Items.Count > 0) { cosmosSalesOrder.Promos = ReportPromoBuilder.BuildPromoFields(promos, ReportTypeEnum.SalesOrderDetail); } var queryable = _salesOrderDetailDataRepo.GetQueryable().Where(order => order.PartitionKey == "PartitionValue"); var requestOptions = BuildQueryRequestOptions(); var listOptions = BuildListOptions(orderID); CosmosListPage <OrderDetailData> currentOrderListPage = await _salesOrderDetailDataRepo.GetItemsAsync(queryable, requestOptions, listOptions); var cosmosID = ""; if (currentOrderListPage.Items.Count() == 1) { cosmosID = cosmosSalesOrder.id = currentOrderListPage.Items[0].id; } await _salesOrderDetailDataRepo.UpsertItemAsync(cosmosID, cosmosSalesOrder); }
public virtual async Task <CosmosListPage <RMA> > ListRMAsByOrderID(string orderID, CommerceRole commerceRole, MeUser me, bool accessAllRMAsOnOrder = false) { string sourceOrderID = orderID.Split("-")[0]; CosmosListOptions listOptions = new CosmosListOptions() { PageSize = 100 }; IQueryable <RMA> queryable = _rmaRepo.GetQueryable() .Where(rma => rma.PartitionKey == "PartitionValue" && rma.SourceOrderID == sourceOrderID); if (commerceRole == CommerceRole.Supplier && !accessAllRMAsOnOrder) { queryable = QueryOnlySupplierRMAs(queryable, me.Supplier.ID); } CosmosListPage <RMA> rmas = await GenerateRMAList(queryable, listOptions); return(rmas); }
public async Task <RMA> Get(ListArgs <RMA> args, DecodedToken decodedToken) { CosmosListOptions listOptions = new CosmosListOptions() { PageSize = 100, Search = args.Search, SearchOn = "RMANumber" }; IQueryable <RMA> queryable = _rmaRepo.GetQueryable() .Where(rma => rma.PartitionKey == "PartitionValue"); if (decodedToken.CommerceRole == CommerceRole.Supplier) { var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken); queryable = queryable.Where(rma => rma.SupplierID == me.Supplier.ID); } CosmosListPage <RMA> rmas = await GenerateRMAList(queryable, listOptions); return(rmas.Items[0]); }
public async Task <List <HSLineItemOrder> > LineItemDetail(string templateID, ListArgs <ReportAdHocFilters> args, DecodedToken decodedToken) { IList <ListFilter> filters = await BuildFilters(templateID, args, decodedToken, "DateSubmitted", "xp.SupplierIDs", "FromCompanyID"); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "OrderID", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <LineItemDetailData> queryable = _lineItemDetail.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <LineItemDetailData> lineItemDataResponse = await _lineItemDetail.GetItemsAsync(queryable, requestOptions, listOptions); List <LineItemDetailData> lineItemData = lineItemDataResponse.Items; listOptions.ContinuationToken = lineItemDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <LineItemDetailData> responseWithToken = await _lineItemDetail.GetItemsAsync(queryable, requestOptions, listOptions); lineItemData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var lineItems = new List <HSLineItemOrder>(); var supplierFilter = args.Filters.FirstOrDefault(filter => filter.PropertyName == "SupplierID"); var me = await _oc.Me.GetAsync(decodedToken.AccessToken); foreach (LineItemDetailData detailData in lineItemData) { foreach (HSLineItem lineDetail in detailData.Data.LineItems) { if (supplierFilter == null || supplierFilter.FilterExpression == lineDetail.SupplierID) { if (decodedToken.CommerceRole == CommerceRole.Supplier) { //filter down to only current supplierID var lineWithPOOrderFields = detailData.Data.LineItemsWithPurchaseOrderFields != null?detailData.Data.LineItemsWithPurchaseOrderFields.FirstOrDefault(line => line.SupplierID == me.Supplier.ID && line.ID == lineDetail.ID) : null; if (lineWithPOOrderFields != null) { lineDetail.ID = lineWithPOOrderFields.ID; detailData.Data.Order.Subtotal = lineWithPOOrderFields.Subtotal; detailData.Data.Order.ID = lineWithPOOrderFields.OrderID; detailData.Data.Order.Total = lineWithPOOrderFields.Total; lineDetail.UnitPrice = lineWithPOOrderFields.UnitPrice; } } if (decodedToken.CommerceRole == CommerceRole.Seller || me.Supplier.ID == lineDetail.SupplierID) { var lineWithMiscFields = detailData.Data.LineItemsWithMiscFields != null?detailData.Data.LineItemsWithMiscFields.FirstOrDefault(line => line.ID == lineDetail.ID) : null; lineItems.Add(new HSLineItemOrder { HSOrder = detailData.Data.Order, HSLineItem = lineDetail }); } } } } return(lineItems); }
private async Task UpsertPurchaseOrderDetail(string orderID) { var orders = await _oc.Orders.ListAllAsync <HSOrder>(OrderDirection.Outgoing, filters : $"ID={orderID}-*"); var queryable = _purchaseOrderDetailDataRepo.GetQueryable().Where(order => order.PartitionKey == "PartitionValue"); var requestOptions = BuildQueryRequestOptions(); var salesOrderWorksheet = await _oc.IntegrationEvents.GetWorksheetAsync <HSOrderWorksheet>(OrderDirection.Incoming, orderID); var promos = await _oc.Orders.ListPromotionsAsync(OrderDirection.Incoming, salesOrderWorksheet.Order.ID); var discountedLineItems = new List <HSLineItem>(); if (promos.Items.Count() > 0) { var discountedLineFilter = new Dictionary <string, object> { ["PromotionDiscount"] = ">0" }; discountedLineItems = await _oc.LineItems.ListAllAsync <HSLineItem>(OrderDirection.Incoming, salesOrderWorksheet.Order.ID, filters : discountedLineFilter); } foreach (var order in orders) { order.FromUser = salesOrderWorksheet.Order.FromUser; order.BillingAddress = new HSAddressBuyer() { xp = new BuyerAddressXP() { LocationID = salesOrderWorksheet?.Order?.BillingAddress?.xp?.LocationID } }; var brand = await _oc.Buyers.GetAsync <HSBuyer>(salesOrderWorksheet.Order.FromCompanyID); var supplier = await _oc.Suppliers.GetAsync <HSSupplier>(order.ToCompanyID); order.ShippingCost = GetPurchaseOrderShippingCost(salesOrderWorksheet, order.ToCompanyID); if (salesOrderWorksheet.Order.PromotionDiscount > 0) { order.PromotionDiscount = GetPurchaseOrderPromotionDiscount(salesOrderWorksheet, order.ToCompanyID); } var cosmosPurchaseOrder = new OrderDetailData() { PartitionKey = "PartitionValue", OrderID = order.ID, Data = order, SupplierName = supplier.Name, BrandName = brand.Name, }; if (promos.Items.Count > 0) { cosmosPurchaseOrder.Promos = ReportPromoBuilder.BuildPromoFields(promos, ReportTypeEnum.PurchaseOrderDetail, order.ToCompanyID, discountedLineItems); } var listOptions = BuildListOptions(order.ID); CosmosListPage <OrderDetailData> currentOrderListPage = await _purchaseOrderDetailDataRepo.GetItemsAsync(queryable, requestOptions, listOptions); var cosmosID = ""; if (currentOrderListPage.Items.Count() == 1) { cosmosID = cosmosPurchaseOrder.id = currentOrderListPage.Items[0].id; } await _purchaseOrderDetailDataRepo.UpsertItemAsync(cosmosID, cosmosPurchaseOrder); } }
public async Task <List <RMAWithRMALineItem> > RMADetail(string templateID, ListArgs <ReportAdHocFilters> args, DecodedToken decodedToken) { IList <ListFilter> filters = await BuildFilters(templateID, args, decodedToken, "DateCreated", "SupplierID"); CosmosListOptions listOptions = new CosmosListOptions() { PageSize = -1, Sort = "RMANumber", SortDirection = SortDirection.ASC, Filters = filters, }; IQueryable <RMA> queryable = _rmaDetail.GetQueryable() .Where(order => order.PartitionKey == "PartitionValue"); QueryRequestOptions requestOptions = new QueryRequestOptions { MaxItemCount = listOptions.PageSize, MaxConcurrency = -1 }; CosmosListPage <RMA> rmaDataResponse = await _rmaDetail.GetItemsAsync(queryable, requestOptions, listOptions); List <RMA> rmaData = rmaDataResponse.Items; listOptions.ContinuationToken = rmaDataResponse.Meta.ContinuationToken; while (listOptions.ContinuationToken != null) { CosmosListPage <RMA> responseWithToken = await _rmaDetail.GetItemsAsync(queryable, requestOptions, listOptions); rmaData.AddRange(responseWithToken.Items); listOptions.ContinuationToken = responseWithToken.Meta.ContinuationToken; } var rmas = new List <RMAWithRMALineItem>(); var supplierFilter = args.Filters.FirstOrDefault(filter => filter.PropertyName == "SupplierID"); var me = await _oc.Me.GetAsync(decodedToken.AccessToken); foreach (RMA detailData in rmaData) { if (supplierFilter == null || supplierFilter.FilterExpression == detailData.SupplierID) { if (decodedToken.CommerceRole == CommerceRole.Seller || me.Supplier.ID == detailData.SupplierID) { foreach (RMALineItem rmaLineItem in detailData.LineItems) { rmas.Add(new RMAWithRMALineItem { RMA = detailData, RMALineItem = rmaLineItem }); } } } } return(rmas); }
public virtual decimal GetShippingRefundIfCancellingAll(HSOrderWorksheet worksheet, RMA rma, CosmosListPage <RMA> allRMAsOnThisOrder) { // What are all the line items on this order for this supplier and their quantities? IEnumerable <HSLineItem> allLineItemsShippedFromThisSupplier = worksheet.LineItems .Where(li => li.SupplierID == rma.SupplierID && worksheet.Order.xp.PaymentMethod == "Credit Card"); Dictionary <string, int> allLineItemsDictionary = new Dictionary <string, int>(); foreach (HSLineItem li in allLineItemsShippedFromThisSupplier) { allLineItemsDictionary.Add(li.ID, li.Quantity); } // Including this RMA and previous RMAs for this supplier, get everything that has been refunded or is about to be refunded. var rmasFromThisSupplier = allRMAsOnThisOrder.Items.Where(r => r.SupplierID == rma.SupplierID); Dictionary <string, int> allCompleteRMALineItemsDictionary = new Dictionary <string, int>(); foreach (RMA existingRMA in rmasFromThisSupplier) { RMA rmaToAnalyze = existingRMA.RMANumber == rma.RMANumber ? rma : existingRMA; foreach (RMALineItem rmaLineItem in rmaToAnalyze.LineItems) { if (rmaLineItem.Status == RMALineItemStatus.Complete && rmaLineItem.RefundableViaCreditCard) { if (!allCompleteRMALineItemsDictionary.ContainsKey(rmaLineItem.ID)) { allCompleteRMALineItemsDictionary.Add(rmaLineItem.ID, rmaLineItem.QuantityProcessed); } else { allCompleteRMALineItemsDictionary[rmaLineItem.ID] += rmaLineItem.QuantityProcessed; } } } } // If these are the same, the supplier hasn't shipped anything, and shipping should be credited back to the buyer. bool shouldShippingBeCanceled = allLineItemsDictionary.OrderBy(kvp => kvp.Key) .SequenceEqual(allCompleteRMALineItemsDictionary.OrderBy(kvp => kvp.Key)); // Figure out what the buyer paid for shipping for this supplier on this order. if (shouldShippingBeCanceled) { string selectedShipMethodID = worksheet.ShipEstimateResponse.ShipEstimates .FirstOrDefault(estimate => estimate.xp.SupplierID == rma.SupplierID)?.SelectedShipMethodID; TransactionLineModel shippingLine = worksheet.OrderCalculateResponse.xp.TaxResponse.lines.FirstOrDefault(line => line.lineNumber == selectedShipMethodID); decimal shippingCostToRefund = (decimal)(shippingLine.taxableAmount + shippingLine.tax + shippingLine.exemptAmount); rma.ShippingCredited += shippingCostToRefund; return(shippingCostToRefund); } return(0M); }
public virtual async Task HandleRefund(RMA rma, CosmosListPage <RMA> allRMAsOnThisOrder, HSOrderWorksheet worksheet, DecodedToken decodedToken) { // Get payment info from the order ListPage <HSPayment> paymentResponse = await _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, rma.SourceOrderID); HSPayment creditCardPayment = paymentResponse.Items.FirstOrDefault(payment => payment.Type == OrderCloud.SDK.PaymentType.CreditCard); if (creditCardPayment == null) { // Items were not paid for with a credit card. No refund to process via CardConnect. return; } HSPaymentTransaction creditCardPaymentTransaction = creditCardPayment.Transactions .OrderBy(x => x.DateExecuted) .LastOrDefault(x => x.Type == "CreditCard" && x.Succeeded); decimal purchaseOrderTotal = (decimal)paymentResponse.Items .Where(payment => payment.Type == OrderCloud.SDK.PaymentType.PurchaseOrder) .Select(payment => payment.Amount) .Sum(); // Refund via CardConnect CardConnectInquireResponse inquiry = await _cardConnect.Inquire(new CardConnectInquireRequest { merchid = creditCardPaymentTransaction.xp.CardConnectResponse.merchid, orderid = rma.SourceOrderID, set = "1", currency = worksheet.Order.xp.Currency.ToString(), retref = creditCardPaymentTransaction.xp.CardConnectResponse.retref }); decimal shippingRefund = rma.Type == RMAType.Cancellation ? GetShippingRefundIfCancellingAll(worksheet, rma, allRMAsOnThisOrder) : 0M; decimal lineTotalToRefund = rma.LineItems .Where(li => li.IsResolved && !li.IsRefunded && li.RefundableViaCreditCard && (li.Status == RMALineItemStatus.PartialQtyComplete || li.Status == RMALineItemStatus.Complete) ).Select(li => li.LineTotalRefund) .Sum(); decimal totalToRefund = lineTotalToRefund + shippingRefund; // Update Total Credited on RMA rma.TotalCredited += totalToRefund; // Transactions that are queued for capture can only be fully voided, and we are only allowing partial voids moving forward. if (inquiry.voidable == "Y" && inquiry.setlstat == QUEUED_FOR_CAPTURE) { throw new CatalystBaseException(new ApiError { ErrorCode = "Payment.FailedToVoidAuthorization", Message = "This customer's credit card transaction is currently queued for capture and cannot be refunded at this time. Please try again later." }); } // If voidable, but not refundable, void the refund amount off the original order total if (inquiry.voidable == "Y") { await HandleVoidTransaction(worksheet, creditCardPayment, creditCardPaymentTransaction, totalToRefund, rma); } // If refundable, but not voidable, do a refund if (inquiry.voidable == "N") { await HandleRefundTransaction(worksheet, creditCardPayment, creditCardPaymentTransaction, totalToRefund, rma); } }
public void CalculateAndUpdateLineTotalRefund(IEnumerable <RMALineItem> lineItemsToUpdate, HSOrderWorksheet orderWorksheet, CosmosListPage <RMA> allRMAsOnThisOrder, string supplierID) { IEnumerable <dynamic> orderWorksheetLines = orderWorksheet.OrderCalculateResponse.xp.TaxResponse.lines; foreach (RMALineItem rmaLineItem in lineItemsToUpdate) { if (!rmaLineItem.RefundableViaCreditCard) { HSLineItem lineItemFromOrder = orderWorksheet.LineItems.FirstOrDefault(li => li.ID == rmaLineItem.ID); rmaLineItem.LineTotalRefund = lineItemFromOrder.LineTotal / lineItemFromOrder.Quantity * rmaLineItem.QuantityProcessed; } else { int quantityToRefund = rmaLineItem.QuantityProcessed; dynamic orderWorksheetLineItem = orderWorksheetLines.FirstOrDefault(li => li.lineNumber == rmaLineItem.ID); // Exempt products will have an exempt amount instead of a taxable amount. decimal lineItemBaseCost = orderWorksheetLineItem.exemptAmount > 0 ? orderWorksheetLineItem.exemptAmount : orderWorksheetLineItem.taxableAmount; decimal totalRefundIfReturningAllLineItems = (decimal)(lineItemBaseCost + orderWorksheetLineItem.tax); double taxableAmountPerSingleLineItem = (double)(lineItemBaseCost / orderWorksheetLineItem.quantity); double taxPerSingleLineItem = (double)(orderWorksheetLineItem.tax / orderWorksheetLineItem.quantity); double singleQuantityLineItemRefund = Math.Round(taxableAmountPerSingleLineItem + taxPerSingleLineItem, 2); decimal expectedLineTotalRefund = (decimal)singleQuantityLineItemRefund * quantityToRefund; rmaLineItem.LineTotalRefund = ValidateExpectedLineTotalRefund(expectedLineTotalRefund, totalRefundIfReturningAllLineItems, allRMAsOnThisOrder, rmaLineItem, orderWorksheet, supplierID); } ApplyPercentToDiscount(rmaLineItem); rmaLineItem.Status = rmaLineItem.QuantityProcessed == rmaLineItem.QuantityRequested ? RMALineItemStatus.Complete : RMALineItemStatus.PartialQtyComplete; } }
private decimal ValidateExpectedLineTotalRefund(decimal expectedLineTotalRefund, decimal totalRefundIfReturningAllLineItems, CosmosListPage <RMA> allRMAsOnThisOrder, RMALineItem rmaLineItem, HSOrderWorksheet orderWorksheet, string supplierID) { // If minor rounding error occurs during singleQuantityLineItemRefund calculation, ensure we don't refund more than the full line item cost on the order // Would only occur for full quantity cancellations/returns if (expectedLineTotalRefund > totalRefundIfReturningAllLineItems || ShouldIssueFullLineItemRefund(rmaLineItem, allRMAsOnThisOrder, orderWorksheet, supplierID)) { return(totalRefundIfReturningAllLineItems); } // If previous RMAs on this order for the same line item if (allRMAsOnThisOrder.Items.Count > 1) { decimal previouslyRefundedAmountForThisLineItem = 0M; // Find previously refunded total for line items on this order... foreach (RMA previouslyRefundedRMA in allRMAsOnThisOrder.Items) { RMALineItem previouslyRefundedLineItem = previouslyRefundedRMA.LineItems.FirstOrDefault(li => li.ID == rmaLineItem.ID); if (previouslyRefundedLineItem != null) { if (previouslyRefundedLineItem.IsRefunded && previouslyRefundedLineItem.RefundableViaCreditCard) { previouslyRefundedAmountForThisLineItem += previouslyRefundedLineItem.LineTotalRefund; } } } // If previous total + new line total > totalRefundIfReturningAllLineItems, then totalRefundIfReturningAllLineItems - previousTotal = newLineTotal if (previouslyRefundedAmountForThisLineItem + expectedLineTotalRefund > totalRefundIfReturningAllLineItems) { decimal totalAfterPossibleRoundingErrors = totalRefundIfReturningAllLineItems - previouslyRefundedAmountForThisLineItem; return(totalAfterPossibleRoundingErrors); } } return(expectedLineTotalRefund); }