private void WriteOrders(IEnumerable <OrderLine> orderLines, WebOrderProcessType processType, OrderLineStatus newStatus, string ilnClientNumber) { using (var engine = new MultiRecordEngine(typeof(DatColEnvelope), typeof(DatColHeader), typeof(DatColDate), typeof(DatColOrderLine), typeof(DatColCount))) { orderLines.GroupBy(c => c.OrderID).ToList().ForEach(orderLinesCollection => { using (Stream memoryStream = new MemoryStream()) using (var streamWriter = new StreamWriter(memoryStream)) { var saveOrder = true; _magentoOrderNumber = orderLinesCollection.First().Order.WebSiteOrderNumber; engine.BeginWriteStream(streamWriter); var magentoOrderNumber = orderLinesCollection.First().Order.WebSiteOrderNumber; var envelope = new DatColEnvelope { ILNClientNumber = ilnClientNumber, ILNSapphNumber = ILNSapphNumber, MagentoOrderNumber = magentoOrderNumber }; engine.WriteNext(envelope); var header = new DatColHeader { MagentoOrderNumber = magentoOrderNumber, ILNSapphNumber = ILNSapphNumber, ILNClientNumber = ilnClientNumber, ILNClientNumber2 = ilnClientNumber }; engine.WriteNext(header); var date = new DatColDate(); engine.WriteNext(date); var orderLineCounter = 0; foreach (var line in orderLinesCollection) { if (line.Product == null) { saveOrder = false; continue; } var barcode = line.Product.ProductBarcodes.Where(x => x.BarcodeType.HasValue && x.BarcodeType.Value == 0).Select(x => x).FirstOrDefault(); if (barcode == null) { saveOrder = false; continue; } decimal totalUnitPriceToProcess; var quantityToProcess = 0; switch (processType) { case WebOrderProcessType.WebOrder: if (!line.Price.HasValue) { throw new ArgumentNullException(); } var discount = line.LineDiscount.HasValue ? line.LineDiscount.Value : 0; if (line.ProductID == _shipmentCostProductID) { totalUnitPriceToProcess = (decimal)(line.Price); } else { totalUnitPriceToProcess = (decimal)(line.Price.Value - discount); } if (line.OrderLedgers.Any(c => c.Status == (int)OrderLineStatus.ProcessedKasmut)) { var ledg = line.OrderLedgers.FirstOrDefault(c => c.Status == (int)OrderLineStatus.ProcessedKasmut); if (ledg != null) { if (ledg.Quantity != null) { quantityToProcess = line.Quantity - ledg.Quantity.Value; } } } break; case WebOrderProcessType.CancellationWebOrder: if (line.ProductID == _returnCostProductID) { quantityToProcess = line.Quantity; totalUnitPriceToProcess = (decimal)(line.UnitPrice.HasValue ? line.UnitPrice.Value : 0); } else { var returnLedger = line.OrderLedgers.FirstOrDefault(x => x.Status == CancelledStatus); quantityToProcess = -((returnLedger != null && returnLedger.Quantity.HasValue) ? returnLedger.Quantity.Value : line.Quantity); totalUnitPriceToProcess = (decimal)(Math.Abs(quantityToProcess) * line.UnitPrice); } break; case WebOrderProcessType.ReturnedWebOrder: if (line.ProductID == _returnCostProductID) { quantityToProcess = line.Quantity; totalUnitPriceToProcess = (decimal)(line.BasePrice.HasValue ? line.BasePrice.Value : 0); } else { // if product not ReturnCost // Quantity = Returned Quantity (if this not exists) // Shipped Quantity // Price = Paid price per Product (with discount) * Quantity var returnLedger = line.OrderLedgers.FirstOrDefault(x => x.Status == ReturnStatus); quantityToProcess = -((returnLedger != null && returnLedger.Quantity.HasValue) ? returnLedger.Quantity.Value : line.Quantity); totalUnitPriceToProcess = (decimal)(Math.Abs(quantityToProcess) * (line.Price / line.Quantity)); } break; default: throw new NotImplementedException(); } var orderLine = new DatColOrderLine { OrderLineNumber = ++orderLineCounter, Barcode = barcode.Barcode, Quantity = quantityToProcess == 0 ? line.Quantity : quantityToProcess, TotalUnitPrice = totalUnitPriceToProcess }; engine.WriteNext(orderLine); } var count = new DatColCount { TotalOrderLine = orderLinesCollection.Count(), TotalQuantity = 0 }; engine.WriteNext(count); engine.Flush(); streamWriter.Flush(); string webOrderFile; switch (processType) { case WebOrderProcessType.WebOrder: webOrderFile = WebOrderFileName; break; case WebOrderProcessType.CancellationWebOrder: case WebOrderProcessType.ReturnedWebOrder: webOrderFile = ReturnWebOrderFileName; break; default: throw new NotImplementedException(); } if (saveOrder) { var listOfOrderLines = orderLinesCollection.ToDictionary <OrderLine, int, int?>(line => line.OrderLineID, line => null); if (!_orderRepo.UpgradeOrderLinesStatus(listOfOrderLines, newStatus, true)) { _log.Info(string.Format("The system can not upgrade the status of order line {0} to {1}", listOfOrderLines.Keys, newStatus)); } else { var ftpManager = new FtpManager(_ftpSetting.FtpUri, null, false, true); ftpManager.Upload(memoryStream.Reset(), webOrderFile); } } else { //todo: log corrupt lines } } }); } }