public static DataTable Price(ActivePrice activePrice, IEnumerable <NamedOffer> offers) { var table = new DbfTable(); table.Columns( Column.Char("CODEPST", 12), Column.Char("NAME", 80), Column.Char("CNTR", 15), Column.Char("FIRM", 40), Column.Numeric("QNTPACK", 8), Column.Char("EAN13", 13), Column.Numeric("NDS", 9, 2), Column.Date("GDATE"), Column.Numeric("QNT", 9, 2), Column.Numeric("NSP", 9, 2), Column.Numeric("GNVLS", 1), Column.Numeric("PRICE1", 9, 2), Column.Numeric("NEWFLG", 1), Column.Numeric("PROTECID", 8), Column.Numeric("QNTPST", 8), Column.Numeric("XCODE", 20)); foreach (var offer in offers) { table.Row( Value.For("CODEPST", offer.Code), Value.For("NAME", offer.ProductSynonym), //Value.For("CNTR", offer.), Value.For("FIRM", offer.ProducerSynonym), Value.For("QNTPACK", offer.RequestRatio), Value.For("EAN13", offer.EAN13.Slice(12)), //Value.For("NDS", offer.), Value.For("GDATE", offer.NormalizedPeriod), // ! Value.For("QNT", offer.Quantity), //Value.For("NSP", offer.), Value.For("GNVLS", offer.VitallyImportant), Value.For("PRICE1", offer.Cost), //Value.For("NEWFLG", offer.) //Value.For("PROTECID", offer.) //Value.For("QNTPST", offer.) Value.For("XCODE", offer.CoreId) ); } return(table.ToDataTable()); }
public static void Price(XmlWriter writer, ActivePrice activePrice, IEnumerable <NamedOffer> offers) { var supplier = activePrice.Id.Price.Supplier; writer.WriteStartElement("PACKET"); writer.WriteAttributeString("NAME", "Прайс-лист"); writer.WriteAttributeString("FROM", supplier.Name); writer.WriteAttributeString("TYPE", "10"); writer.WriteStartElement("PRICELIST"); writer.WriteAttributeString("DATE", activePrice.PriceDate.ToString("dd.MM.yyyy HH:mm")); writer.WriteAttributeString("NAME", $"{supplier.Name} {activePrice.Id.Price.PriceName}"); foreach (var offer in offers) { ExportOffer(writer, offer); } writer.WriteEndElement(); writer.WriteEndElement(); }
private static List <OrderResult> SaveOrders(ISession session, RequestLog log, ClientOrder[] clientOrders, bool force) { var user = log.User; var rules = session.Load <OrderRules>(user.Client.Id); var errors = new List <OrderResult>(); if (clientOrders == null) { return(errors); } using (StorageProcedures.GetActivePrices((MySqlConnection)session.Connection, user.Id)) { var orderitemMap = new Dictionary <OrderItem, uint>(); var orders = new List <Order>(); foreach (var clientOrder in clientOrders) { var address = session.Load <Address>(clientOrder.AddressId); var price = session.Load <PriceList>(clientOrder.PriceId); var activePrice = session.Get <ActivePrice>(new PriceKey(price, clientOrder.RegionId)); //мы должны принимать заказы даже если прайс-лист больше не активен, например устарел //как мне кажется смысла в этом не но так было всегда if (activePrice == null) { activePrice = new ActivePrice { Id = new PriceKey(price, clientOrder.RegionId), PriceDate = clientOrder.PriceDate }; } try { var order = new Order(activePrice, user, address, rules) { ClientOrderId = clientOrder.ClientOrderId, PriceDate = clientOrder.PriceDate, ClientAddition = clientOrder.Comment, CalculateLeader = false, PriceName = clientOrder.PriceName, CostId = clientOrder.CostId, CostName = clientOrder.CostName, }; foreach (var sourceItem in clientOrder.Items) { var offer = new Offer { Id = new OfferKey(sourceItem.OfferId.OfferId, sourceItem.OfferId.RegionId), Cost = (float)sourceItem.Cost, PriceList = activePrice, PriceCode = price.PriceCode, CodeFirmCr = sourceItem.ProducerId, }; var properties = typeof(BaseOffer).GetProperties().Where(p => p.CanRead && p.CanWrite); foreach (var property in properties) { var value = property.GetValue(sourceItem, null); property.SetValue(offer, value, null); } //клиент в поле уценка передает уценку с учетом клиентских настроек //оригинальная уценка хранится в поле OriginalJunk offer.Junk = sourceItem.OriginalJunk; try { var item = order.AddOrderItem(offer, sourceItem.Count); item.CostWithDelayOfPayment = ((float?)sourceItem.ResultCost).GetValueOrDefault(item.CostWithDelayOfPayment); if (rules.SendRetailMarkup) { item.RetailCost = sourceItem.RetailCost; item.RetailMarkup = sourceItem.RetailMarkup; } if (sourceItem.MinCost != null) { item.LeaderInfo = new OrderItemLeadersInfo { OrderItem = item, MinCost = (float?)sourceItem.MinCost, PriceCode = sourceItem.MinPrice?.PriceId, LeaderMinCost = (float?)sourceItem.LeaderCost, LeaderPriceCode = sourceItem.LeaderPrice?.PriceId, }; } orderitemMap.Add(item, sourceItem.Id); } catch (OrderException e) { //если здесь произошла ошибка значит есть проблема в клиентском приложении и нужно узнать об этом Log.Error($"Не удалось сформировать заявку по позиции {offer.Id}", e); throw new OrderException($"Не удалось сформировать заявку по позиции {offer.Id}", e); } } if (order.OrderItems.Count > 0) { orders.Add(order); } } catch (OrderException e) { Log.Warn($"Не удалось принять заказ {clientOrder.ClientOrderId}", e); errors.Add(new OrderResult(clientOrder.ClientOrderId, "Отправка заказов запрещена")); } } errors.AddEach(Validate(session, user, orders, force, orderitemMap)); //удаление дублей должно производиться после всех проверок тк заказ будет отброшен полностью //и проверки для него не важны или пройдет часть позиций которые пользователь "донабил" //в этом случае проверки для них не должны применяться тк они идут в "догонку" errors.AddEach(RemoveDuplicate(session, orders, orderitemMap)); //мы не должны сохранять валидные заказы если корректировка заказов //включена if (!user.UseAdjustmentOrders || errors.Count == 0) { var addressIds = orders.Select(o => o.AddressId).Distinct().ToArray(); if (addressIds.Length > 0) { var addresses = session.Query <Address>() .Where(a => addressIds.Contains(a.Id) && a.OrderLimits.Count > 0) .ToArray(); foreach (var order in orders) { var limit = addresses.Where(a => a.Id == order.AddressId) .SelectMany(a => a.OrderLimits) .FirstOrDefault(l => l.Supplier.Id == order.PriceList.Supplier.Id); if (limit != null) { session.Save(new PendingLimitLog(log, limit, limit.ConsumeLimit((decimal)order.CalculateSum()))); } } } //отмечаем заказа как удаленный до подтверждения orders.Each(o => o.Deleted = true); session.SaveEach(orders); session.SaveEach(orders.Select(o => new AcceptedOrderLog(log, o))); } errors = errors.Concat(orders.Select(o => new OrderResult(o, orderitemMap))).ToList(); } //информацию по отказам сохраняем для техподдержки foreach (var result in errors.Where(x => x.Result == OrderResultStatus.Reject)) { if (!String.IsNullOrEmpty(log.Error)) { log.Error += Environment.NewLine; } var order = clientOrders.FirstOrDefault(x => x.ClientOrderId == result.ClientOrderId); if (order == null) { continue; } var price = session.Get <PriceList>(order.PriceId); var sum = order.Items.Sum(x => x.Count * x.Cost); log.Error += $"Заказ {result.ClientOrderId} на сумму {sum} на поставщика" + $" {price?.Supplier?.Name} был отклонен по причине: {result.Error}"; } //в результате удаления дублей для одного клиентского заказа может быть сформировано два результата //один на приемку части заявки второй на удаленные позиций-дублей //нужно объединить эти данные return(errors.GroupBy(x => Tuple.Create(x.ClientOrderId, x.Result)) .Select(x => { if (x.Count() == 1) { return x.First(); } var dst = x.First(); dst.ServerOrderId = x.Max(y => y.ServerOrderId); dst.Lines.AddRange(x.Skip(1).SelectMany(y => y.Lines)); return dst; }) .ToList()); }