示例#1
0
        public void when_order_completed_then_order_dto_populated()
        {
            var orderCompleted = new OrderStatusChanged
            {
                SourceId    = _orderId,
                Fare        = 23,
                Toll        = 2,
                Tip         = 5,
                Tax         = 12,
                Surcharge   = 1,
                IsCompleted = true
            };

            Sut.Handle(orderCompleted);

            using (var context = new BookingDbContext(DbName))
            {
                var dto = context.Find <OrderDetail>(_orderId);
                Assert.NotNull(dto);
                Assert.NotNull(dto.Status == (int)OrderStatus.Completed);
                Assert.AreEqual(orderCompleted.Fare, dto.Fare);
                Assert.AreEqual(orderCompleted.Toll, dto.Toll);
                Assert.AreEqual(orderCompleted.Tip, dto.Tip);
                Assert.AreEqual(orderCompleted.Tax, dto.Tax);
                Assert.AreEqual(orderCompleted.Surcharge, dto.Surcharge);
            }
        }
        public void when_amount_spent_attained_then_promotion_unlocked()
        {
            var accountId = Guid.NewGuid();
            var orderId1  = Guid.NewGuid();
            var orderId2  = Guid.NewGuid();

            var newOrderStatus = new OrderStatusChanged
            {
                IsCompleted = true,
                Status      = new OrderStatusDetail {
                    AccountId = accountId, Status = OrderStatus.Completed
                }
            };

            var newPaymentInit = new CreditCardPaymentInitiated
            {
                Meter = (decimal)15.31
            };

            var newPayment = new CreditCardPaymentCaptured_V2
            {
                FeeType           = FeeTypes.None,
                Meter             = (decimal)15.31,
                AuthorizationCode = Guid.NewGuid().ToString(),
                AccountId         = accountId
            };

            _orderCreatedCommand.AccountId = accountId;

            _orderCreatedCommand.SourceId = orderId1;
            newOrderStatus.SourceId       = orderId1;
            newPaymentInit.SourceId       = orderId1;
            newPaymentInit.OrderId        = orderId1;
            newPayment.SourceId           = orderId1;
            newPayment.OrderId            = orderId1;

            OrderGenerator.Handle(_orderCreatedCommand);
            OrderGenerator.Handle(newOrderStatus);
            CreditCardGenerator.Handle(newPaymentInit);
            CreditCardGenerator.Handle(newPayment);
            TriggerSut.Handle(newPayment);

            _orderCreatedCommand.SourceId = orderId2;
            newOrderStatus.SourceId       = orderId2;
            newPaymentInit.SourceId       = orderId2;
            newPaymentInit.OrderId        = orderId2;
            newPayment.SourceId           = orderId2;
            newPayment.OrderId            = orderId2;

            OrderGenerator.Handle(_orderCreatedCommand);
            OrderGenerator.Handle(newOrderStatus);
            CreditCardGenerator.Handle(newPaymentInit);
            CreditCardGenerator.Handle(newPayment);
            TriggerSut.Handle(newPayment);

            var commands = Commands.OfType <AddUserToPromotionWhiteList>().Where(c => c.AccountIds.Contains(accountId)).ToArray();

            Assert.AreEqual(1, commands.Count());
            Assert.AreEqual(30.62, commands[0].LastTriggeredAmount);
        }
        public void Handle(OrderStatusChanged @event)
        {
            using (var context = _contextFactory.Invoke())
            {
                var orderReport = context.Find <OrderReportDetail>(@event.SourceId);
                orderReport.Payment.MdtFare = @event.Fare;
                orderReport.Payment.MdtTip  = @event.Tip;
                orderReport.Payment.MdtToll = @event.Toll;

                if (@event.Status != null)
                {
                    orderReport.Account.AccountId            = @event.Status.AccountId;
                    orderReport.VehicleInfos.DriverId        = @event.Status.DriverInfos.DriverId;
                    orderReport.VehicleInfos.DriverFirstName = @event.Status.DriverInfos.FirstName;
                    orderReport.VehicleInfos.DriverLastName  = @event.Status.DriverInfos.LastName;
                    orderReport.VehicleInfos.Number          = @event.Status.VehicleNumber;
                    orderReport.VehicleInfos.Color           = @event.Status.DriverInfos.VehicleColor;
                    orderReport.VehicleInfos.Make            = @event.Status.DriverInfos.VehicleMake;
                    orderReport.VehicleInfos.Model           = @event.Status.DriverInfos.VehicleModel;
                    orderReport.VehicleInfos.Registration    = @event.Status.DriverInfos.VehicleRegistration;
                    orderReport.VehicleInfos.Type            = @event.Status.DriverInfos.VehicleType;

                    orderReport.OrderStatus.Status        = @event.Status.Status;
                    orderReport.OrderStatus.OrderIsNoShow = @event.Status.IBSStatusId == VehicleStatuses.Common.NoShow;

                    orderReport.Order.PickupDateTime = @event.Status.PickupDate != DateTime.MinValue
                        ? (DateTime?)@event.Status.PickupDate
                        : null;
                    orderReport.Order.CompanyName = @event.Status.CompanyName;
                }

                orderReport.OrderStatus.OrderIsCompleted = @event.IsCompleted;
                context.Save(orderReport);
            }
        }
        public void when_ride_count_attained_then_promotion_unlocked()
        {
            var accountId = Guid.NewGuid();
            var orderId1  = Guid.NewGuid();
            var orderId2  = Guid.NewGuid();

            var newOrderStatus = new OrderStatusChanged
            {
                IsCompleted = true,
                Status      = new OrderStatusDetail {
                    AccountId = accountId, Status = OrderStatus.Completed
                }
            };

            _orderCreatedCommand.AccountId = accountId;
            _orderCreatedCommand.SourceId  = orderId1;
            newOrderStatus.SourceId        = orderId1;

            OrderGenerator.Handle(_orderCreatedCommand);
            OrderGenerator.Handle(newOrderStatus);
            TriggerSut.Handle(newOrderStatus);

            _orderCreatedCommand.SourceId = orderId2;
            newOrderStatus.SourceId       = orderId2;

            OrderGenerator.Handle(_orderCreatedCommand);
            OrderGenerator.Handle(newOrderStatus);
            TriggerSut.Handle(newOrderStatus);

            var commands = Commands.OfType <AddUserToPromotionWhiteList>().Where(c => c.AccountIds.Contains(accountId)).ToArray();

            Assert.AreEqual(1, commands.Count());
            Assert.AreEqual(2, commands[0].LastTriggeredAmount);
        }
示例#5
0
 /// <summary>
 /// Event invocator for the OrderFilled event
 /// </summary>
 /// <param name="e">The OrderEvent</param>
 protected virtual void OnOrderEvent(OrderEvent e)
 {
     try
     {
         OrderStatusChanged?.Invoke(this, e);
     }
     catch (Exception err)
     {
         Log.Error(err);
     }
 }
        public void Handle(OrderStatusChanged @event)
        {
            if (@event.IsCompleted)
            {
                var order       = _orderDao.FindById(@event.SourceId);
                var orderStatus = _orderDao.FindOrderStatusById(@event.SourceId);
                var pairingInfo = _orderDao.FindOrderPairingById(@event.SourceId);
                var account     = _accountDao.FindById(order.AccountId);

                if (_serverSettings.GetPaymentSettings(order.CompanyKey).PaymentMode == PaymentMethod.RideLinqCmt)
                {
                    // Check if card declined
                    InitializeCmtServiceClient();

                    if (CmtErrorCodes.IsTerminalError(orderStatus.PairingError))
                    {
                        // Terminal error, no need to react to paymentFailure.
                        return;
                    }
                    var trip = _cmtTripInfoServiceHelper.CheckForTripEndErrors(pairingInfo.PairingToken);

                    if (trip != null && trip.ErrorCode == CmtErrorCodes.CardDeclined)
                    {
                        _commandBus.Send(new ReactToPaymentFailure
                        {
                            AccountId       = order.AccountId,
                            OrderId         = order.Id,
                            IBSOrderId      = order.IBSOrderId,
                            CreditCardId    = account.DefaultCreditCard.GetValueOrDefault(),
                            TransactionId   = orderStatus.OrderId.ToString().Split('-').FirstOrDefault(), // Use first part of GUID to display to user
                            OverdueAmount   = Convert.ToDecimal(@event.Fare + @event.Tax + @event.Tip + @event.Toll),
                            TransactionDate = @event.EventDate
                        });

                        return;
                    }

                    // Since RideLinqCmt payment is processed automatically by CMT, we have to charge booking fees separately
                    _feeService.ChargeBookingFeesIfNecessary(orderStatus);
                }

                // If the user has decided not to pair (paying the ride in car instead),
                // we have to void the amount that was preauthorized
                if (_serverSettings.GetPaymentSettings(order.CompanyKey).PaymentMode != PaymentMethod.RideLinqCmt &&
                    (order.Settings.ChargeTypeId == ChargeTypes.CardOnFile.Id || order.Settings.ChargeTypeId == ChargeTypes.PayPal.Id) &&
                    (pairingInfo == null || pairingInfo.WasUnpaired) &&
                    !orderStatus.IsPrepaid)    //prepaid order will never have a pairing info
                {
                    // void the preauthorization to prevent misuse fees
                    _paymentService.VoidPreAuthorization(order.CompanyKey, @event.SourceId);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Event invocator for the OrderFilled event
        /// </summary>
        /// <param name="e">The OrderEvent</param>
        protected virtual void OnOrderEvent(OrderEvent e)
        {
            try
            {
                Log.Debug("Brokerage.OnOrderEvent(): " + e);

                OrderStatusChanged?.Invoke(this, e);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }
        }
示例#8
0
        /// <summary>
        /// Event invocator for the OrderFilled event
        /// </summary>
        /// <param name="e">The OrderEvent</param>
        protected virtual void OnOrderEvent(OrderEvent e)
        {
            try
            {
                OrderStatusChanged?.Invoke(this, e);

                if (Log.DebuggingEnabled)
                {
                    // log after calling the OrderStatusChanged event, the BrokerageTransactionHandler will set the order quantity
                    Log.Debug("Brokerage.OnOrderEvent(): " + e);
                }
            }
            catch (Exception err)
            {
                Log.Error(err);
            }
        }
示例#9
0
        private void OnOrderStatusChanged(OrderStatusChanged @event)
        {
            // special case for migration
            if (@event.IsCompleted)
            {
                _status = OrderStatus.Completed;
            }

            if (@event.Status != null) //possible with migration
            {
                _ibsStatus = @event.Status.IBSStatusId;
                _status    = @event.Status.Status;
            }

            if (@event.Fare.HasValue && @event.Fare.Value > 0)
            {
                _fare = @event.Fare;
            }
        }
示例#10
0
        public void When(OrderStatusChanged @event)
        {
            this.SuppressEvent();
            switch (@event.CurrentStatus)
            {
            case OrderStatus.Processing:
                this.Process();
                break;

            case OrderStatus.Deliver:
                this.Deliver();
                break;

            case OrderStatus.Closed:
                this.Closed();
                break;

            case OrderStatus.Cancel:
                this.Cancel();
                break;
            }
            this.UnsuppressedEvent();
        }
        private async Task CancelFailedPaymentOrders(CancellationToken stoppingToken)
        {
            var shouldCancelFailedPaymentOrders = _orderRepository.Query().Where(x => x.OrderStatus == OrderStatus.PendingPayment && x.UpdatedOn < DateTimeOffset.Now.AddMinutes(-5));

            foreach (var order in shouldCancelFailedPaymentOrders)
            {
                order.OrderStatus = OrderStatus.Canceled;
                order.UpdatedOn   = DateTimeOffset.Now;
                // TODO Rollback product stock
                var orderStatusChanged = new OrderStatusChanged
                {
                    OrderId   = order.Id,
                    OldStatus = OrderStatus.PendingPayment,
                    NewStatus = OrderStatus.Canceled,
                    UserId    = 0,
                    Note      = "System cancel"
                };

                await _mediator.Publish(orderStatusChanged, stoppingToken);
            }

            await _orderRepository.SaveChangesAsync();
        }
        public async Task <IActionResult> ChangeStatus(long id, [FromBody] OrderStatusForm model)
        {
            var order = _orderRepository.Query().FirstOrDefault(x => x.Id == id);

            if (order == null)
            {
                return(NotFound());
            }

            var currentUser = await _workContext.GetCurrentUser();

            if (!User.IsInRole("admin") && order.VendorId != currentUser.VendorId)
            {
                return(BadRequest(new { error = "You don't have permission to manage this order" }));
            }

            if (Enum.IsDefined(typeof(OrderStatus), model.StatusId))
            {
                order.OrderStatus = (OrderStatus)model.StatusId;
                await _orderRepository.SaveChangesAsync();

                var orderStatusChanged = new OrderStatusChanged
                {
                    OrderId   = order.Id,
                    OldStatus = OrderStatus.PendingPayment,
                    NewStatus = OrderStatus.Canceled,
                    UserId    = 0,
                    Note      = "System cancel"
                };

                await _mediator.Publish(orderStatusChanged);

                return(Accepted());
            }

            return(BadRequest(new { Error = "unsupported order status" }));
        }
 public void UpdateOrderStatus(OrderStatus orderStatus)
 {
     OrderStatusChanged?.Invoke(this, orderStatus);
 }
示例#14
0
        public void Do(DateTime?after = null)
        {
            var       skip     = 0;
            var       hasMore  = true;
            const int pageSize = 100000;

            after = after ?? DateTime.MinValue;

            Console.WriteLine("Migrating event since {0}", after);

            while (hasMore)
            {
                using (var context = _contextFactory.Invoke())
                {
                    context.Database.CommandTimeout = 0;
                    // order by date then by version in case two events happened at the same time
                    var events = context.Set <Event>()
                                 .OrderBy(x => x.EventDate)
                                 .ThenBy(x => x.Version)
                                 .Where(x => x.EventDate > after)
                                 .Skip(skip)
                                 .Take(pageSize)
                                 .ToList();

                    hasMore = events.Count == pageSize;
                    Console.WriteLine("Number of events migrated: " + (hasMore ? skip : (skip + events.Count)));
                    skip += pageSize;

                    foreach (var message in events.Where(x => x.EventType == typeof(PaymentSettingUpdated).FullName).ToList())
                    {
                        // fix BraintreeClientSettings namespace problem
                        message.Payload =
                            message.Payload.Replace("apcurium.MK.Common.Configuration.BraintreeClientSettings", "apcurium.MK.Common.Configuration.Impl.BraintreeClientSettings");

                        // fix PaymentSettingsUpdated events containing old PayPalCredentials
                        message.Payload =
                            message.Payload.Replace("apcurium.MK.Common.Configuration.Impl.PayPalCredentials", "apcurium.MK.Common.Configuration.Impl.PayPalServerCredentials");
                    }
                    context.SaveChanges();

                    // rename Order Pairing events
                    foreach (var message in events.Where(x =>
                                                         x.EventType.Contains("OrderPairedForRideLinqCmtPayment") ||
                                                         x.EventType.Contains("OrderUnpairedForRideLinqCmtPayment")))
                    {
                        message.Payload   = message.Payload.Replace("OrderPairedForRideLinqCmtPayment", "OrderPairedForPayment");
                        message.Payload   = message.Payload.Replace("OrderUnpairedForRideLinqCmtPayment", "OrderUnpairedForPayment");
                        message.EventType = message.EventType.Replace("OrderPairedForRideLinqCmtPayment", "OrderPairedForPayment");
                        message.EventType = message.EventType.Replace("OrderUnpairedForRideLinqCmtPayment", "OrderUnpairedForPayment");
                    }
                    context.SaveChanges();

                    // rename OrderCancelledBecauseOfIbsError events
                    foreach (var message in events.Where(x => x.EventType.Equals("apcurium.MK.Booking.Events.OrderCancelledBecauseOfIbsError")))
                    {
                        message.Payload   = message.Payload.Replace("OrderCancelledBecauseOfIbsError", "OrderCancelledBecauseOfError");
                        message.EventType = message.EventType.Replace("OrderCancelledBecauseOfIbsError", "OrderCancelledBecauseOfError");
                    }
                    context.SaveChanges();

                    // rename CreditCardAdded or CreditCardUpdated to CreditCardAddedOrUpdated
                    foreach (var message in events.Where(x =>
                                                         x.EventType.Equals("apcurium.MK.Booking.Events.CreditCardAdded") ||
                                                         x.EventType.Equals("apcurium.MK.Booking.Events.CreditCardUpdated")))
                    {
                        message.Payload   = message.Payload.Replace("CreditCardAdded", "CreditCardAddedOrUpdated");
                        message.Payload   = message.Payload.Replace("CreditCardUpdated", "CreditCardAddedOrUpdated");
                        message.EventType = message.EventType.Replace("CreditCardAdded", "CreditCardAddedOrUpdated");
                        message.EventType = message.EventType.Replace("CreditCardUpdated", "CreditCardAddedOrUpdated");
                    }
                    context.SaveChanges();

                    // convert OrderCompleted to OrderStatusChanged
                    foreach (var message in events.Where(x => x.EventType.Contains("OrderCompleted")).ToList())
                    {
                        var @event   = Deserialize <OrderCompleted>(message.Payload);
                        var newEvent = new OrderStatusChanged
                        {
                            EventDate   = @event.EventDate,
                            SourceId    = @event.SourceId,
                            Version     = @event.Version,
                            Fare        = @event.Fare,
                            Tax         = @event.Tax,
                            Tip         = @event.Tip,
                            Toll        = @event.Toll,
                            IsCompleted = true
                        };
                        message.Payload   = Serialize(newEvent);
                        message.EventType = message.EventType.Replace("OrderCompleted", "OrderStatusChanged");
                    }
                    context.SaveChanges();

                    // convert CreditCardPaymentCaptured to CreditCardPaymentCaptured_V2
                    foreach (var message in events.Where(x => x.EventType.Equals("apcurium.MK.Booking.Events.CreditCardPaymentCaptured")))
                    {
                        var @event   = Deserialize <CreditCardPaymentCaptured>(message.Payload);
                        var newEvent = Convert(@event);
                        message.Payload   = Serialize(newEvent);
                        message.EventType = message.EventType.Replace("CreditCardPaymentCaptured", "CreditCardPaymentCaptured_V2");
                    }
                    context.SaveChanges();

                    // convert UserAddedToPromotionWhiteList to UserAddedToPromotionWhiteList_V2
                    foreach (var message in events.Where(x => x.EventType.Equals("apcurium.MK.Booking.Events.UserAddedToPromotionWhiteList")))
                    {
                        var @event   = Deserialize <UserAddedToPromotionWhiteList>(message.Payload);
                        var newEvent = Convert(@event);
                        message.Payload   = Serialize(newEvent);
                        message.EventType = message.EventType.Replace("UserAddedToPromotionWhiteList", "UserAddedToPromotionWhiteList_V2");
                    }

                    context.SaveChanges();

                    // convert OrderFareUpdated to OrderStatusChanged
                    foreach (var message in events.Where(x => x.EventType.Contains("OrderFareUpdated")).ToList())
                    {
                        var @event   = Deserialize <OrderFareUpdated>(message.Payload);
                        var newEvent = new OrderStatusChanged
                        {
                            EventDate   = @event.EventDate,
                            SourceId    = @event.SourceId,
                            Version     = @event.Version,
                            Fare        = @event.Fare,
                            Tax         = @event.Tax,
                            Tip         = @event.Tip,
                            Toll        = @event.Toll,
                            IsCompleted = false
                        };
                        message.Payload   = Serialize(newEvent);
                        message.EventType = message.EventType.Replace("OrderFareUpdated", "OrderStatusChanged");
                    }
                    context.SaveChanges();

                    // update OrderStatusChanged containing a Status with an invalid pickup date
                    foreach (var message in events.Where(x => x.EventType.Equals("apcurium.MK.Booking.Events.OrderStatusChanged") &&
                                                         !x.Payload.Contains("\"Status\":null"))
                             .ToList())
                    {
                        var @event = Deserialize <OrderStatusChanged>(message.Payload);

                        @event.Status.PickupDate = @event.Status.PickupDate < ((DateTime)SqlDateTime.MinValue)
                            ? (DateTime)SqlDateTime.MinValue
                            : @event.Status.PickupDate;

                        message.Payload = Serialize(@event);
                    }
                    context.SaveChanges();

                    // update AppSettings
                    foreach (var message in events.Where(x => x.EventType.Equals("apcurium.MK.Booking.Events.AppSettingsAddedOrUpdated")))
                    {
                        message.Payload = message.Payload.Replace("\"Client.", "\"");
                        message.Payload = message.Payload.Replace("\"DistanceFormat\": \"KM\"", "\"DistanceFormat\": \"Km\"");
                        message.Payload = message.Payload.Replace("\"DistanceFormat\":\"KM\"", "\"DistanceFormat\":\"Km\"");
                        message.Payload = message.Payload.Replace("\"AvailableVehiclesMarket\"", "\"HoneyBadger.AvailableVehiclesMarket\"");
                        message.Payload = message.Payload.Replace("\"AvailableVehiclesFleetId\"", "\"HoneyBadger.AvailableVehiclesFleetId\"");
                    }
                    context.SaveChanges();
                }
            }
        }
示例#15
0
        public void Handle(OrderStatusChanged @event)
        {
            using (var context = _contextFactory.Invoke())
            {
                var fareAvailable = GetFareAvailable(@event.Fare);

                var details = context.Find <OrderStatusDetail>(@event.SourceId);
                if (details == null)
                {
                    @event.Status.NetworkPairingTimeout = GetNetworkPairingTimeoutIfNecessary(@event.Status, @event.EventDate);

                    @event.Status.ChargeAmountsTimeOut = GetChargeAmountsTimeoutIfNecessary(@event.Status, @event.EventDate);

                    @event.Status.FareAvailable = fareAvailable;
                    context.Set <OrderStatusDetail>().Add(@event.Status);
                }
                else
                {
                    if (@event.Status != null)
                    {
                        details.NetworkPairingTimeout = GetNetworkPairingTimeoutIfNecessary(@event.Status, @event.EventDate);
                        details.ChargeAmountsTimeOut  = GetChargeAmountsTimeoutIfNecessary(@event.Status, @event.EventDate);

                        details.IBSStatusId          = @event.Status.IBSStatusId;
                        details.DriverInfos          = @event.Status.DriverInfos;
                        details.VehicleNumber        = @event.Status.VehicleNumber;
                        details.TerminalId           = @event.Status.TerminalId;
                        details.ReferenceNumber      = @event.Status.ReferenceNumber;
                        details.Eta                  = @event.Status.Eta;
                        details.Status               = @event.Status.Status;
                        details.IBSStatusDescription = @event.Status.IBSStatusDescription;
                        details.PairingTimeOut       = @event.Status.PairingTimeOut;
                        details.PairingError         = @event.Status.PairingError;
                        details.RideLinqPairingCode  = @event.Status.RideLinqPairingCode;
                        details.TaxiAssignedDate     = @event.Status.TaxiAssignedDate;
                    }
                    else
                    {
                        // it will enter here only with migration from OrderCompleted or OrderFareUpdated
                        if (@event.IsCompleted)
                        {
                            details.Status = OrderStatus.Completed;
                        }
                    }

                    details.FareAvailable = fareAvailable;
                    context.Save(details);
                }

                var order = context.Find <OrderDetail>(@event.SourceId);
                if (order != null)
                {
                    // possible only with migration from OrderCompleted or OrderFareUpdated
                    if (@event.Status == null)
                    {
                        if (@event.IsCompleted)
                        {
                            order.Status = (int)OrderStatus.Completed;
                        }
                    }
                    else
                    {
                        order.Status = (int)@event.Status.Status;
                    }

                    if (@event.IsCompleted)
                    {
                        RemoveTemporaryPaymentInfo(context, @event.SourceId);

                        order.DropOffDate = @event.EventDate;
                    }

                    order.Fare      = @event.Fare;
                    order.Tip       = @event.Tip;
                    order.Toll      = @event.Toll;
                    order.Tax       = @event.Tax;
                    order.Surcharge = @event.Surcharge;

                    context.Save(order);
                }
                else
                {
                    _logger.LogMessage("Order Status without existing Order : " + @event.SourceId);
                }

                context.SaveChanges();
            }
        }
示例#16
0
        public void Handle(OrderStatusChanged @event)
        {
            if (@event.IsCompleted)
            {
                if (@event.Status.IsPrepaid)
                {
                    // Send receipt for PrePaid
                    // No tolls and surcharge for prepaid orders
                    SendTripReceipt(@event.SourceId,
                                    Convert.ToDecimal(@event.Fare ?? 0),
                                    Convert.ToDecimal(@event.Tip ?? 0),
                                    Convert.ToDecimal(@event.Tax ?? 0));
                }
                else
                {
                    var order       = _orderDao.FindById(@event.SourceId);
                    var pairingInfo = _orderDao.FindOrderPairingById(@event.SourceId);

                    var orderStatus = _orderDao.FindOrderStatusById(@event.SourceId);
                    if (CmtErrorCodes.IsTerminalError(orderStatus.PairingError))
                    {
                        return;
                    }

                    if (order.Settings.ChargeTypeId == ChargeTypes.PaymentInCar.Id)
                    {
                        // Send receipt for Pay in Car
                        SendTripReceipt(@event.SourceId,
                                        Convert.ToDecimal(@event.Fare ?? 0),
                                        Convert.ToDecimal(@event.Tip ?? 0),
                                        Convert.ToDecimal(@event.Tax ?? 0),
                                        toll: Convert.ToDecimal(@event.Toll ?? 0),
                                        surcharge: Convert.ToDecimal(@event.Surcharge ?? 0));
                    }
                    else if (pairingInfo != null && pairingInfo.DriverId.HasValue() && pairingInfo.Medallion.HasValue() && pairingInfo.PairingToken.HasValue())
                    {
                        // Send receipt for CMTRideLinq
                        InitializeCmtServiceClient(order.CompanyKey);

                        var tripInfo = _cmtTripInfoServiceHelper.GetTripInfo(pairingInfo.PairingToken);
                        if (tripInfo != null && !tripInfo.ErrorCode.HasValue && tripInfo.EndTime.HasValue)
                        {
                            var tollHistory = tripInfo.TollHistory != null
                                                                ? tripInfo.TollHistory.Sum(p => p.TollAmount)
                                                                : 0;

                            var meterAmount         = Math.Round(((double)tripInfo.Fare / 100), 2);
                            var tollAmount          = Math.Round(((double)tollHistory / 100), 2);
                            var tipAmount           = Math.Round(((double)tripInfo.Tip / 100), 2);
                            var taxAmount           = Math.Round(((double)tripInfo.Tax / 100), 2);
                            var surchargeAmount     = Math.Round(((double)tripInfo.Surcharge / 100), 2);
                            var extraAmount         = Math.Round(((double)tripInfo.Extra / 100), 2);
                            var accessFee           = Math.Round(((double)tripInfo.AccessFee / 100), 2);
                            var fareAtAlternateRate = Math.Round(((double)tripInfo.FareAtAlternateRate / 100), 2);

                            var tolls = new List <TollDetail>();

                            if (tripInfo.TollHistory != null)
                            {
                                tolls.AddRange(tripInfo.TollHistory.Select(toll =>
                                                                           new TollDetail
                                {
                                    TollName   = toll.TollName,
                                    TollAmount = toll.TollAmount
                                }));
                            }

                            SendTripReceipt(@event.SourceId,
                                            Convert.ToDecimal(meterAmount),
                                            Convert.ToDecimal(tipAmount),
                                            Convert.ToDecimal(taxAmount),
                                            extra: Convert.ToDecimal(extraAmount),
                                            toll: Convert.ToDecimal(tollAmount),
                                            surcharge: Convert.ToDecimal(surchargeAmount),
                                            cmtRideLinqFields: new SendReceipt.CmtRideLinqReceiptFields
                            {
                                DriverId            = tripInfo.DriverId.ToString(),
                                PickUpDateTime      = tripInfo.StartTime,
                                DropOffDateTime     = tripInfo.EndTime,
                                TripId              = tripInfo.TripId,
                                Distance            = tripInfo.Distance,
                                LastFour            = tripInfo.LastFour,
                                AccessFee           = accessFee,
                                FareAtAlternateRate = fareAtAlternateRate,
                                RateAtTripEnd       = tripInfo.RateAtTripEnd,
                                RateAtTripStart     = tripInfo.RateAtTripStart,
                                Tolls        = tolls.ToArray(),
                                TipIncentive = order.TipIncentive ?? 0
                            });
                        }
                    }
                }
            }
        }