private List <RMALineItem> BuildLineItemRMA(string supplierID, LineItemStatusChanges lineItemStatusChanges, List <HSLineItem> lineItemsChanged, HSOrder order) { List <RMALineItem> rmaLineItems = new List <RMALineItem>(); foreach (HSLineItem lineItem in lineItemsChanged) { if (lineItem.SupplierID == supplierID) { RMALineItem rmaLineItem = new RMALineItem() { ID = lineItem.ID, QuantityRequested = (int)lineItemStatusChanges.Changes.FirstOrDefault(change => change.ID == lineItem.ID)?.Quantity, QuantityProcessed = 0, Status = RMALineItemStatus.Requested, Reason = lineItemStatusChanges.Changes.FirstOrDefault(change => change.ID == lineItem.ID)?.Reason, PercentToRefund = null, RefundableViaCreditCard = order.xp.PaymentMethod == "Credit Card", IsResolved = false, IsRefunded = false, LineTotalRefund = 0 }; rmaLineItems.Add(rmaLineItem); } } return(rmaLineItems); }
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); }
public virtual void ApplyPercentToDiscount(RMALineItem rmaLineItem) { if (rmaLineItem.PercentToRefund <= 0 || rmaLineItem.PercentToRefund > 100) { throw new Exception($"The refund percentage for {rmaLineItem.ID} must be greater than 0 and no higher than 100 percent."); } if (rmaLineItem.PercentToRefund != null) { // Math.Round() by default would round 13.745 to 13.74 based on banker's rounding (going to the nearest even number when the final digit is 5). // This errs on the side of rounding up (away from zero) when only a percentage of a refund is applied. rmaLineItem.LineTotalRefund = Math.Round((decimal)(rmaLineItem.LineTotalRefund / 100 * rmaLineItem.PercentToRefund), 2, MidpointRounding.AwayFromZero); } }
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); } }
private List <LineItemStatusChanges> BuildLineItemStatusChanges(IEnumerable <RMALineItem> rmaLineItemsToUpdate, HSOrderWorksheet worksheet, RMAType rmaType, bool isDenyingAll) { if (!rmaLineItemsToUpdate.Any()) { return(new List <LineItemStatusChanges>()); } IEnumerable <HSLineItem> orderWorksheetLineItems = worksheet.LineItems .Where(li => rmaLineItemsToUpdate .Any(itemToUpdate => itemToUpdate.ID == li.ID)); List <LineItemStatusChanges> lineItemStatusChangesList = new List <LineItemStatusChanges>(); LineItemStatus actionCompleteType = rmaType == RMAType.Cancellation ? LineItemStatus.Canceled : LineItemStatus.Returned; LineItemStatus actionDeniedType = rmaType == RMAType.Cancellation ? LineItemStatus.CancelDenied : LineItemStatus.ReturnDenied; foreach (HSLineItem lineItem in orderWorksheetLineItems) { RMALineItem correspondingRMALineItem = rmaLineItemsToUpdate.FirstOrDefault(li => li.ID == lineItem.ID); if (correspondingRMALineItem.QuantityProcessed == correspondingRMALineItem.QuantityRequested) { if (isDenyingAll) { LineItemStatusChanges statusChangeToAdjust = lineItemStatusChangesList.FirstOrDefault(change => change.Status == actionDeniedType); BuildStatusChangeToAdjust(statusChangeToAdjust, actionDeniedType, lineItemStatusChangesList, correspondingRMALineItem, isDenyingAll); } else { LineItemStatusChanges statusChangeToAdjust = lineItemStatusChangesList.FirstOrDefault(change => change.Status == actionCompleteType); BuildStatusChangeToAdjust(statusChangeToAdjust, actionCompleteType, lineItemStatusChangesList, correspondingRMALineItem, isDenyingAll); } } else { int quantityToComplete = correspondingRMALineItem.QuantityProcessed; int quantityToDeny = correspondingRMALineItem.QuantityRequested - correspondingRMALineItem.QuantityProcessed; LineItemStatusChanges statusChangeForComplete = lineItemStatusChangesList.FirstOrDefault(change => change.Status == actionCompleteType); LineItemStatusChanges statusChangeForDeny = lineItemStatusChangesList.FirstOrDefault(change => change.Status == actionDeniedType); BuildStatusChangeToAdjust(statusChangeForComplete, actionCompleteType, lineItemStatusChangesList, correspondingRMALineItem, isDenyingAll, quantityToComplete); BuildStatusChangeToAdjust(statusChangeForDeny, actionDeniedType, lineItemStatusChangesList, correspondingRMALineItem, isDenyingAll, quantityToDeny); } } return(lineItemStatusChangesList); }
private void BuildStatusChangeToAdjust(LineItemStatusChanges statusChangeToAdjust, LineItemStatus lineItemStatus, List <LineItemStatusChanges> lineItemStatusChangesList, RMALineItem correspondingRMALineItem, bool isDenyingAll, int?overriddenQuantity = null) { int?quantityToChange = overriddenQuantity != null ? overriddenQuantity : correspondingRMALineItem.QuantityProcessed; if ((int)quantityToChange == 0) { return; } if (statusChangeToAdjust == null) { LineItemStatusChanges newStatusChange = new LineItemStatusChanges() { Status = lineItemStatus, Changes = new List <LineItemStatusChange>() }; lineItemStatusChangesList.Add(newStatusChange); statusChangeToAdjust = lineItemStatusChangesList.FirstOrDefault(change => change.Status == lineItemStatus); } decimal?refundAmount = null; if (!isDenyingAll) { refundAmount = correspondingRMALineItem.LineTotalRefund; } statusChangeToAdjust.Changes.Add(new LineItemStatusChange() { ID = correspondingRMALineItem.ID, Quantity = (int)quantityToChange, Comment = correspondingRMALineItem.Comment, Refund = refundAmount, QuantityRequestedForRefund = correspondingRMALineItem.QuantityRequested, }); }