Beispiel #1
0
        protected virtual async Task <IEnumerable <T> > Load <T>(IEnumerable ids, ISessionCache sessionCache,
                                                                 ITrackingProvider tracking, IAction <IEnumerable <LoadContext> > loadTask) where T : class
        {
            //setup the pipeline
            var pipe = new Middleware <IEnumerable <LoadContext> >();

            pipe.Use(new TrackingAction <LoadContext>(tracking));
            pipe.Use(new SessionAction <LoadContext>(sessionCache));
            pipe.Use(loadTask);

            //setup the load context
            var type         = typeof(T);
            var loadContexts = ids.Cast <object>().Select(id =>
            {
                var idKey = _idManager.GetFromId(type, id);
                return(new LoadContext()
                {
                    Key = idKey,
                    Type = type
                });
            }).ToList();


            await pipe.Execute(loadContexts);

            return(loadContexts.Select(x => x.Entity).Where(x => x != null).Cast <T>());
        }
Beispiel #2
0
        public async Task <T> LoadOne <T>(object id, ISessionCache sessionCache, ITrackingProvider tracking)
            where T : class
        {
            var result = await Load <T>(new[] { id }, sessionCache, tracking, new LoadFromDatabaseAction(_couchDb));

            return(result.FirstOrDefault());
        }
Beispiel #3
0
        public virtual async Task Process(ISessionCache sessionCache, ITrackingProvider tracking)
        {
            //var taskCtx = new CreateTaskContext(_couchDb, _idManager, _revisionAccessor, sessionCache);

            //setup the pipeline
            var pipe = new Middleware <IEnumerable <CommitContext> >();

            pipe.Use(new TrackingAction(tracking));
            pipe.Use(new TransactionAction(_transactionCoordinator));
            pipe.Use(new SessionAction(sessionCache));
            pipe.Use(new CommitToDatabaseAction(_couchDb, _revisionAccessor));

            //setup the bulk update context
            var bulkContexts = sessionCache.Entries.Select(entry =>
            {
                var bulkCtx = new CommitContext()
                {
                    ActionType = entry.Action,
                    Entity     = entry.Instance,
                    Key        = entry.Key
                };
                return(bulkCtx);
            });

            await pipe.Execute(bulkContexts);
        }
        private IList <TrackingResult> ProcessFileRecords(ITrackingProvider trackingProvider, IList <string> trackings)
        {
            var trackingList = trackings.Select(tr => new TrackingNumberToCheckDto()
            {
                TrackingNumber = tr,
                ToCountry      = "US"
            }).ToList();

            var trackResults = trackingProvider.TrackShipments(trackingList);

            if (trackResults.Count == 0)
            {
                _log.Info("No results. Wait.");
                Thread.Sleep(60000);
            }

            var results = new List <TrackingResult>();

            foreach (var track in trackResults)
            {
                var records = track.Records.OrderBy(r => r.Date).ToList();
                results.Add(new TrackingResult()
                {
                    TrackingNumber = track.TrackingNumber,
                    FirstTrackDate = records.FirstOrDefault()?.Date,
                    FirstZipCode   = records.FirstOrDefault()?.Zip,
                    SecondZipCode  = records.Skip(1).FirstOrDefault()?.Zip,
                });
            }

            return(results);
        }
Beispiel #5
0
        public TrackingController(IActiveRepository activeRepo, ICollectionRepository colRepo, ITrackingProvider trackingProvider)
        {
            if (activeRepo != null)
            {
                this._activeRepo = activeRepo;
            }
            else
            {
                this._activeRepo = new ActiveRepository();
            }

            if (colRepo != null)
            {
                this._colRepo = colRepo;
            }
            else
            {
                this._colRepo = new CollectionRepository();
            }

            if (trackingProvider != null)
            {
                this._trackingProvider = trackingProvider;
            }
            else
            {
                this._trackingProvider = new TrackingProvider(this._activeRepo, this._colRepo);
            }
        }
Beispiel #6
0
        public void UpdateAllShippedOrderStatus(TrackingManager trackingService,
                                                ITime time,
                                                IUnitOfWork db,
                                                ITrackingProvider trackingProvider,
                                                CompanyDTO company)
        {
            var carrierNames = ShippingServiceUtils.GetRelatedCarrierNames(trackingProvider.Carrier);

            var shippings = db.Orders.GetUnDeliveredMailInfoes(time.GetUtcTime(), true, null)
                            .OrderBy(o => o.OrderDate) //NOTE: first reprocess old trackings
                            .Where(sh => carrierNames.Contains(sh.Carrier))
                            .Take(500)
                            .ToList();

            shippings.AddRange(db.Orders.GetUnDeliveredShippingInfoes(time.GetUtcTime(), true, null)
                               .OrderBy(o => o.OrderDate) //NOTE: first reprocess old trackings
                               .Where(sh => carrierNames.Contains(sh.Carrier))
                               .Take(500)
                               .ToList());

            trackingService.UpdateOrderTracking(db,
                                                company,
                                                shippings,
                                                trackingProvider);
        }
Beispiel #7
0
 public Session(
     LoadPipeline loadPipeline,
     QueryPipeline queryPipeline,
     CommitPipeline commitPipeline,
     QueryFactory queryFactory,
     IIdManager idManager,
     IIdAccessor idAccessor,
     ITrackingProvider tracking,
     ISessionCache sessionCache
     )
 {
     _sessionCache   = sessionCache;
     _loadPipeline   = loadPipeline;
     _queryPipeline  = queryPipeline;
     _commitPipeline = commitPipeline;
     _queryFactory   = queryFactory;
     _idManager      = idManager;
     _idAccessor     = idAccessor;
     _tracking       = tracking;
 }
Beispiel #8
0
 public TrackingAction(ITrackingProvider tracking)
 {
     _tracking = tracking;
 }
Beispiel #9
0
 public Task <IEnumerable <T> > LoadMany <T>(IEnumerable ids, ISessionCache sessionCache, ITrackingProvider tracking)
     where T : class
 {
     return(Load <T>(ids, sessionCache, tracking,
                     new LoadManyFromDatabaseAction(_couchDb, _idManager, _idAccessor)));
 }
        public IList <TrackingState> UpdateOrderTracking(
            IUnitOfWork db,
            CompanyDTO company,
            IList <OrderToTrackDTO> shippings,
            ITrackingProvider trackingProvider)
        {
            _log.Info("UpdateOrderTracking, shippings=" + shippings.Count);
            try
            {
                var ruleList = _ruleList;

                var trackingList = shippings
                                   .Where(o => !String.IsNullOrEmpty(o.TrackingNumber))
                                   .Select(o => new TrackingNumberToCheckDto()
                {
                    TrackingNumber = o.TrackingNumber,
                    ToCountry      = o.ShippingAddress != null ? o.ShippingAddress.FinalCountry : null,
                }).ToList();

                var stateList = trackingProvider.TrackShipments(trackingList);
                var today     = _time.GetAppNowTime();

                _log.Info("UpdateOrderTracking, track count get back=" + stateList.Count);
                var processedShipmentIds = new List <long>();
                var processedMailInfoIds = new List <long>();
                foreach (var state in stateList)
                {
                    //NOTE: Fedex has delivery records not as last record (ex.: 393418292108)
                    var deliveredRecord = state.Records != null?state.Records.FirstOrDefault(r => _deliveryEventList.Contains(r.Message ?? "") || (r.Message ?? "").ToLower().StartsWith("delivered")) : null;

                    var lastRecord = deliveredRecord != null ? deliveredRecord : (state.Records != null ? state.Records.FirstOrDefault() : null);
                    var isBack     = lastRecord != null?_addressService.IsMine(lastRecord.AsAddressDto()) : false;

                    var shippingDto = shippings.FirstOrDefault(sh => sh.TrackingNumber == state.TrackingNumber);
                    if (shippingDto != null)
                    {
                        var hasStateChanges = false;
                        if (lastRecord == null)
                        {
                            hasStateChanges = false;
                            shippingDto.TrackingRequestAttempts = shippingDto.TrackingRequestAttempts + 1;
                            shippingDto.LastTrackingRequestDate = _time.GetUtcTime();
                            _log.Warn("UpdateOrderTracking, empty Records!");
                        }
                        else
                        {
                            _log.Info("UpdateOrderTracking, o=" + shippingDto.OrderNumber + ", tr=" +
                                      shippingDto.TrackingNumber + ", at=" + shippingDto.OrderDate + ", new state=" +
                                      lastRecord.Message + " at=" + lastRecord.Date);

                            var newStateEvent = StringHelper.Substring(lastRecord.Message, 100);
                            hasStateChanges = shippingDto.TrackingStateDate != lastRecord.Date ||
                                              shippingDto.TrackingStateEvent != newStateEvent;

                            shippingDto.TrackingStateSource = (int)lastRecord.Source;
                            shippingDto.TrackingStateDate   = lastRecord.Date;
                            shippingDto.TrackingStateEvent  = newStateEvent;
                            shippingDto.TrackingLocation    = lastRecord.Country + ", " + lastRecord.State + ", " +
                                                              lastRecord.City + ", " + lastRecord.Zip;

                            if (_deliveryEventList.Contains(lastRecord.Message) ||
                                lastRecord.Message.ToLower().StartsWith("delivered") ||
                                (lastRecord.Message.ToLower().Contains("shipment picked up") &&
                                 (state.Records.Count > 5 && lastRecord.Date < today.AddDays(-2))))
                            //NOTE: temporary solution for "Shipment Picked Up", every shipment may have transit status with that name (not final)
                            {
                                shippingDto.DeliveredStatus = isBack
                                    ? (int)DeliveredStatusEnum.DeliveredToSender
                                    : (int)DeliveredStatusEnum.Delivered;

                                shippingDto.IsDelivered        = true;
                                shippingDto.ActualDeliveryDate = lastRecord.Date;
                            }
                            else
                            {
                                //May happend like with refused tracking number https://tools.usps.com/go/TrackConfirmAction!input.action?tRef=qt&tLc=1&tLabels=9400116901495496872649
                                //Order #1577164597317
                                shippingDto.DeliveredStatus    = (int)DeliveredStatusEnum.None;
                                shippingDto.IsDelivered        = false;
                                shippingDto.ActualDeliveryDate = null;
                            }

                            //For DHL
                            if (lastRecord.Message.ToLower().StartsWith("Returned to shipper"))
                            {
                                shippingDto.DeliveredStatus    = (int)DeliveredStatusEnum.DeliveredToSender;
                                shippingDto.IsDelivered        = true;
                                shippingDto.ActualDeliveryDate = lastRecord.Date;
                            }

                            shippingDto.LastTrackingRequestDate = _time.GetUtcTime();

                            if (!hasStateChanges)
                            {
                                shippingDto.TrackingRequestAttempts = shippingDto.TrackingRequestAttempts + 1;
                            }
                            else
                            {
                                shippingDto.TrackingRequestAttempts = 1;
                            }

                            //NOTE: If state no changes for a long time => no requests
                            if (lastRecord.Date < _time.GetAppNowTime().AddDays(-50) ||
                                (shippingDto.OrderDate < _time.GetAppNowTime().AddDays(-90) &&
                                 lastRecord.Message.StartsWith(TrackingHelper.UndefinedPrefix)))
                            {
                                shippingDto.TrackingRequestAttempts = 10000;
                                if (lastRecord.Message.StartsWith(TrackingHelper.UndefinedPrefix))
                                {
                                    _log.Info("Info Unavailable, message=" + lastRecord.Message);
                                    shippingDto.DeliveredStatus = (int)DeliveredStatusEnum.InfoUnavailable;
                                }
                                _log.Info("Last attempt (= 10000)");
                            }
                        }


                        if (shippingDto.ShipmentInfoId.HasValue)
                        {
                            if (processedShipmentIds.Any(sh => sh == shippingDto.ShipmentInfoId.Value))
                            {
                                _log.Info("Shipment with that Id already processed: " + shippingDto.ShipmentInfoId.Value);
                            }
                            else
                            {
                                processedShipmentIds.Add(shippingDto.ShipmentInfoId.Value);

                                var changeFields = new List <Expression <Func <OrderShippingInfo, object> > >()
                                {
                                    p => p.LastTrackingRequestDate,
                                    p => p.TrackingRequestAttempts
                                };
                                if (hasStateChanges)
                                {
                                    changeFields.Add(p => p.TrackingStateSource);
                                    changeFields.Add(p => p.TrackingStateDate);
                                    changeFields.Add(p => p.TrackingStateEvent);
                                    changeFields.Add(p => p.TrackingLocation);

                                    changeFields.Add(p => p.DeliveredStatus);
                                    changeFields.Add(p => p.IsDelivered);
                                    changeFields.Add(p => p.ActualDeliveryDate);
                                }
                                db.OrderShippingInfos.TrackItem(new OrderShippingInfo()
                                {
                                    Id = shippingDto.ShipmentInfoId.Value,
                                    TrackingStateSource     = shippingDto.TrackingStateSource,
                                    TrackingStateDate       = shippingDto.TrackingStateDate,
                                    TrackingStateEvent      = shippingDto.TrackingStateEvent,
                                    TrackingLocation        = shippingDto.TrackingLocation,
                                    DeliveredStatus         = shippingDto.DeliveredStatus,
                                    IsDelivered             = shippingDto.IsDelivered,
                                    ActualDeliveryDate      = shippingDto.ActualDeliveryDate,
                                    LastTrackingRequestDate = shippingDto.LastTrackingRequestDate,
                                    TrackingRequestAttempts = shippingDto.TrackingRequestAttempts ?? 1
                                },
                                                                changeFields);
                            }
                        }

                        if (shippingDto.MailInfoId.HasValue)
                        {
                            if (processedMailInfoIds.Any(sh => sh == shippingDto.MailInfoId.Value))
                            {
                                _log.Info("Shipment with that Id already processed: " + shippingDto.MailInfoId.Value);
                            }
                            else
                            {
                                processedMailInfoIds.Add(shippingDto.MailInfoId.Value);

                                var changeFields = new List <Expression <Func <MailLabelInfo, object> > >()
                                {
                                    p => p.LastTrackingRequestDate,
                                    p => p.TrackingRequestAttempts
                                };
                                if (hasStateChanges)
                                {
                                    changeFields.Add(p => p.TrackingStateSource);
                                    changeFields.Add(p => p.TrackingStateDate);
                                    changeFields.Add(p => p.TrackingStateEvent);
                                    changeFields.Add(p => p.TrackingLocation);

                                    changeFields.Add(p => p.DeliveredStatus);
                                    changeFields.Add(p => p.IsDelivered);
                                    changeFields.Add(p => p.ActualDeliveryDate);
                                }
                                db.MailLabelInfos.TrackItem(new MailLabelInfo()
                                {
                                    Id = shippingDto.MailInfoId.Value,
                                    TrackingStateSource     = shippingDto.TrackingStateSource,
                                    TrackingStateDate       = shippingDto.TrackingStateDate,
                                    TrackingStateEvent      = shippingDto.TrackingStateEvent,
                                    TrackingLocation        = shippingDto.TrackingLocation,
                                    DeliveredStatus         = shippingDto.DeliveredStatus,
                                    IsDelivered             = shippingDto.IsDelivered,
                                    ActualDeliveryDate      = shippingDto.ActualDeliveryDate,
                                    LastTrackingRequestDate = shippingDto.LastTrackingRequestDate,
                                    TrackingRequestAttempts = shippingDto.TrackingRequestAttempts ?? 1
                                },
                                                            changeFields);
                            }
                        }

                        //NOTE: if do checks only when state changed, the rules based on calculate business day were never activated
                        //if (hasStateChanges)
                        if (lastRecord != null)
                        {
                            CheckRules(db,
                                       shippingDto,
                                       lastRecord.Message,
                                       lastRecord.Date,
                                       state.Records,
                                       ruleList);
                        }
                    }
                }
                db.Commit();

                return(stateList);
            }
            catch (Exception ex)
            {
                _log.Error("UpdateOrderTracking", ex);
            }
            return(null);
        }
Beispiel #11
0
        public virtual async Task <IEnumerable <T> > Query <T>(MongoQuery query, ISessionCache sessionCache, ITrackingProvider tracking)
            where T : class
        {
            var pipe = new Middleware <QueryContext, IEnumerable <LoadContext> >();

            pipe.Use(new TrackingAction(tracking));
            pipe.Use(new UpdateCacheAction(sessionCache));
            pipe.Use(new OverrideUsingCacheAction <LoadContext>(sessionCache));
            pipe.Use(new MongoQueryFromDatabaseAction(_couchDb, _idManager, _idAccessor));

            //setup the load context
            var type = typeof(T);

            var ctx = new QueryContext()
            {
                Query = query,
                Type  = type
            };

            var results = await pipe.Execute(ctx);

            return(results.Select(x => x.Entity).Where(x => x != null).Cast <T>());
        }