예제 #1
0
        private Tariff GetMarketTariff(double latitude, double longitude)
        {
            var marketSettings = _networkServiceClient.GetCompanyMarketSettings(latitude, longitude);

            if (!marketSettings.Market.HasValueTrimmed() || !marketSettings.EnableAppFareEstimates)
            {
                return(null);
            }

            return(marketSettings.MarketTariff);
        }
예제 #2
0
        public object Get(FindMarketSettingsRequest request)
        {
            var marketSettings = _taxiHailNetworkServiceClient.GetCompanyMarketSettings(request.Latitude, request.Longitude);

            return(marketSettings != null
                ? new MarketSettings
            {
                HashedMarket = _cryptographyService.GetHashString(marketSettings.Market),
                EnableDriverBonus = marketSettings.EnableDriverBonus,
                OverrideEnableAppFareEstimates = marketSettings.EnableAppFareEstimates,
                EnableFutureBooking = marketSettings.EnableFutureBooking,
                MarketTariff = marketSettings.MarketTariff,
                DisableOutOfAppPayment = marketSettings.DisableOutOfAppPayment,
                ShowCallDriver = marketSettings.ShowCallDriver
            }
                : new MarketSettings());
        }
예제 #3
0
        protected CreateOrder BuildCreateOrderCommand(CreateOrderRequest request, AccountDetail account, CreateReportOrder createReportOrder)
        {
            _logger.LogMessage("Create order request : " + request);

            if (request.Settings.Country == null || !request.Settings.Country.Code.HasValueTrimmed())
            {
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable,
                                     string.Format(_resources.Get("PhoneNumberCountryNotProvided", request.ClientLanguageCode)));
            }

            var countryCode = CountryCode.GetCountryCodeByIndex(CountryCode.GetCountryCodeIndexByCountryISOCode(request.Settings.Country));

            if (PhoneHelper.IsPossibleNumber(countryCode, request.Settings.Phone))
            {
                request.Settings.Phone = PhoneHelper.GetDigitsFromPhoneNumber(request.Settings.Phone);
            }
            else
            {
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable,
                                     string.Format(_resources.Get("PhoneNumberFormat", request.ClientLanguageCode), countryCode.GetPhoneExample()));
            }

            // TODO MKTAXI-3576: Find a better way to do this...
            var isFromWebApp = request.FromWebApp;

            if (!isFromWebApp)
            {
                ValidateAppVersion(request.ClientLanguageCode, createReportOrder);
            }

            // Find market
            var marketSettings = _taxiHailNetworkServiceClient.GetCompanyMarketSettings(request.PickupAddress.Latitude, request.PickupAddress.Longitude);
            var market         = marketSettings.Market.HasValue() ? marketSettings.Market : null;

            createReportOrder.Market = market;

            var isFutureBooking = IsFutureBooking(request.PickupDate, marketSettings);

            if (!marketSettings.EnableFutureBooking && isFutureBooking)
            {
                // future booking not allowed
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, _resources.Get("CannotCreateOrder_FutureBookingNotAllowed", request.ClientLanguageCode));
            }

            BestAvailableCompany bestAvailableCompany;

            if (request.OrderCompanyKey.HasValue() || request.OrderFleetId.HasValue)
            {
                // For API user, it's possible to manually specify which company to dispatch to by using a fleet id
                bestAvailableCompany = _taxiHailNetworkHelper.FindSpecificCompany(market, createReportOrder, request.OrderCompanyKey, request.OrderFleetId, request.PickupAddress.Latitude, request.PickupAddress.Longitude);
            }
            else
            {
                bestAvailableCompany = _taxiHailNetworkHelper.FindBestAvailableCompany(marketSettings, request.PickupAddress.Latitude, request.PickupAddress.Longitude, isFutureBooking);
            }

            _logger.LogMessage("Best available company determined: {0}, in {1}",
                               bestAvailableCompany.CompanyKey.HasValue() ? bestAvailableCompany.CompanyKey : "local company",
                               market.HasValue() ? market : "local market");

            createReportOrder.CompanyKey  = bestAvailableCompany.CompanyKey;
            createReportOrder.CompanyName = bestAvailableCompany.CompanyName;

            if (market.HasValue())
            {
                if (!bestAvailableCompany.CompanyKey.HasValue())
                {
                    // No companies available that are desserving this region for the company
                    ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, _resources.Get("CannotCreateOrder_NoCompanies", request.ClientLanguageCode));
                }

                _taxiHailNetworkHelper.UpdateVehicleTypeFromMarketData(request.Settings, bestAvailableCompany.CompanyKey);
                var isConfiguredForCmtPayment = _taxiHailNetworkHelper.FetchCompanyPaymentSettings(bestAvailableCompany.CompanyKey);

                if (!isConfiguredForCmtPayment)
                {
                    // Only companies configured for CMT payment can support CoF orders outside of home market
                    request.Settings.ChargeTypeId = ChargeTypes.PaymentInCar.Id;
                }

                if (marketSettings.DisableOutOfAppPayment && request.Settings.ChargeTypeId == ChargeTypes.PaymentInCar.Id)
                {
                    // No payment method available since we can't pay in car
                    ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_NoChargeType, _resources.Get("CannotCreateOrder_NoChargeType", request.ClientLanguageCode));
                }
            }

            var isPaypal    = request.Settings.ChargeTypeId == ChargeTypes.PayPal.Id;
            var isBraintree = (request.Settings.ChargeTypeId == ChargeTypes.CardOnFile.Id) && (_serverSettings.GetPaymentSettings().PaymentMode == PaymentMethod.Braintree);

            var isPrepaid = isFromWebApp && (isPaypal || isBraintree);

            createReportOrder.IsPrepaid = isPrepaid;

            account.IBSAccountId = CreateIbsAccountIfNeeded(account, bestAvailableCompany.CompanyKey);

            var pickupDate = request.PickupDate ?? GetCurrentOffsetedTime(bestAvailableCompany.CompanyKey);

            createReportOrder.PickupDate = pickupDate;

            // User can still create future order, but we allow only one active Book now order.
            if (!isFutureBooking)
            {
                var pendingOrderId = GetPendingOrder();

                // We don't allow order creation if there's already an order scheduled
                if (!_serverSettings.ServerData.AllowSimultaneousAppOrders &&
                    pendingOrderId != null &&
                    !isFromWebApp)
                {
                    ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_PendingOrder, pendingOrderId.ToString());
                }
            }

            var rule = _ruleCalculator.GetActiveDisableFor(
                isFutureBooking,
                pickupDate,
                () =>
                _ibsServiceProvider.StaticData(bestAvailableCompany.CompanyKey)
                .GetZoneByCoordinate(
                    request.Settings.ProviderId,
                    request.PickupAddress.Latitude,
                    request.PickupAddress.Longitude),
                () => request.DropOffAddress != null
                    ? _ibsServiceProvider.StaticData(bestAvailableCompany.CompanyKey)
                .GetZoneByCoordinate(
                    request.Settings.ProviderId,
                    request.DropOffAddress.Latitude,
                    request.DropOffAddress.Longitude)
                        : null,
                market, new Position(request.PickupAddress.Latitude, request.PickupAddress.Longitude));

            if (rule != null)
            {
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, rule.Message);
            }

            // We need to validate the rules of the roaming market.
            if (market.HasValue())
            {
                // External market, query company site directly to validate their rules
                var orderServiceClient = new RoamingValidationServiceClient(bestAvailableCompany.CompanyKey, _serverSettings.ServerData.Target);

                _logger.LogMessage(string.Format("Validating rules for company in external market... Target: {0}, Server: {1}", _serverSettings.ServerData.Target, orderServiceClient.Url));

                var validationResult = orderServiceClient.ValidateOrder(request, true);
                if (validationResult.HasError)
                {
                    ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, validationResult.Message);
                }
            }

            if (Params.Get(request.Settings.Name, request.Settings.Phone).Any(p => p.IsNullOrEmpty()))
            {
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_SettingsRequired);
            }

            var referenceData = (ReferenceData)_referenceDataService.Get(new ReferenceDataRequest {
                CompanyKey = bestAvailableCompany.CompanyKey
            });

            request.PickupDate = pickupDate;

            request.Settings.Passengers = request.Settings.Passengers <= 0
                ? 1
                : request.Settings.Passengers;

            if (_serverSettings.ServerData.Direction.NeedAValidTarif &&
                (!request.Estimate.Price.HasValue || request.Estimate.Price == 0))
            {
                ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_NoFareEstimateAvailable,
                                     GetCreateOrderServiceErrorMessage(ErrorCode.CreateOrder_NoFareEstimateAvailable, request.ClientLanguageCode));
            }

            // IBS provider validation
            ValidateProvider(request, referenceData, market.HasValue(), createReportOrder);

            // Map the command to obtain a OrderId (web doesn't prepopulate it in the request)
            var orderCommand = Mapper.Map <Commands.CreateOrder>(request);

            _logger.LogMessage("MarketSettings for order {0}: {1}", orderCommand.OrderId, marketSettings.ToJson());

            var marketFees = _feesDao.GetMarketFees(market);

            orderCommand.BookingFees          = marketFees != null ? marketFees.Booking : 0;
            createReportOrder.BookingFees     = orderCommand.BookingFees;
            createReportOrder.AssignVehicleId = orderCommand.AssignVehicleId;

            // Promo code validation
            var promotionId = ValidatePromotion(bestAvailableCompany.CompanyKey, request.PromoCode, request.Settings.ChargeTypeId, account.Id, pickupDate, isFutureBooking, request.ClientLanguageCode, createReportOrder);

            // Charge account validation
            var accountValidationResult = ValidateChargeAccountIfNecessary(bestAvailableCompany.CompanyKey, request, orderCommand.OrderId, account, isFutureBooking, isFromWebApp, orderCommand.BookingFees, createReportOrder);

            createReportOrder.IsChargeAccountPaymentWithCardOnFile = accountValidationResult.IsChargeAccountPaymentWithCardOnFile;

            // if ChargeAccount uses payment with card on file, payment validation was already done
            if (!accountValidationResult.IsChargeAccountPaymentWithCardOnFile)
            {
                // Payment method validation
                ValidatePayment(bestAvailableCompany.CompanyKey, request, orderCommand.OrderId, account, isFutureBooking, request.Estimate.Price, orderCommand.BookingFees, isPrepaid, createReportOrder);
            }

            var chargeTypeIbs   = string.Empty;
            var chargeTypeEmail = string.Empty;
            var chargeTypeKey   = ChargeTypes.GetList()
                                  .Where(x => x.Id == request.Settings.ChargeTypeId)
                                  .Select(x => x.Display)
                                  .FirstOrDefault();

            chargeTypeKey = accountValidationResult.ChargeTypeKeyOverride ?? chargeTypeKey;

            if (chargeTypeKey != null)
            {
                // this must be localized with the priceformat to be localized in the language of the company
                // because it is sent to the driver
                chargeTypeIbs = _resources.Get(chargeTypeKey, _serverSettings.ServerData.PriceFormat);

                chargeTypeEmail = _resources.Get(chargeTypeKey, request.ClientLanguageCode);
            }

            // Get Vehicle Type from reference data
            var vehicleType = referenceData.VehiclesList
                              .Where(x => x.Id == request.Settings.VehicleTypeId)
                              .Select(x => x.Display)
                              .FirstOrDefault();

            // Use address alias if present.
            var addressAlias = request.PickupAddress.FriendlyName.HasValueTrimmed()
                ? request.PickupAddress.FriendlyName
                : request.PickupAddress.BuildingName;

            var ibsInformationNote = IbsHelper.BuildNote(
                _serverSettings.ServerData.IBS.NoteTemplate,
                chargeTypeIbs,
                request.Note,
                addressAlias,
                request.Settings.LargeBags,
                _serverSettings.ServerData.IBS.HideChargeTypeInUserNote);

            var fare = FareHelper.GetFareFromEstimate(request.Estimate);

            orderCommand.AccountId     = account.Id;
            orderCommand.UserAgent     = Request.UserAgent;
            orderCommand.ClientVersion = Request.Headers.Get("ClientVersion");
            orderCommand.IsChargeAccountPaymentWithCardOnFile = accountValidationResult.IsChargeAccountPaymentWithCardOnFile;
            orderCommand.CompanyKey               = bestAvailableCompany.CompanyKey;
            orderCommand.CompanyName              = bestAvailableCompany.CompanyName;
            orderCommand.CompanyFleetId           = bestAvailableCompany.FleetId;
            orderCommand.Market                   = market;
            orderCommand.IsPrepaid                = isPrepaid;
            orderCommand.Settings.ChargeType      = chargeTypeIbs;
            orderCommand.Settings.VehicleType     = vehicleType;
            orderCommand.IbsAccountId             = account.IBSAccountId.Value;
            orderCommand.ReferenceDataCompanyList = referenceData.CompaniesList.ToArray();
            orderCommand.IbsInformationNote       = ibsInformationNote;
            orderCommand.Fare                 = fare;
            orderCommand.Prompts              = accountValidationResult.Prompts;
            orderCommand.PromptsLength        = accountValidationResult.PromptsLength;
            orderCommand.PromotionId          = promotionId;
            orderCommand.ChargeTypeEmail      = chargeTypeEmail;
            orderCommand.OriginatingIpAddress = createReportOrder.OriginatingIpAddress = request.CustomerIpAddress;
            orderCommand.KountSessionId       = createReportOrder.OriginatingIpAddress = request.KountSessionId;
            orderCommand.IsFutureBooking      = createReportOrder.IsFutureBooking = isFutureBooking;
            orderCommand.AssignVehicleId      = createReportOrder.AssignVehicleId;

            Debug.Assert(request.PickupDate != null, "request.PickupDate != null");

            return(orderCommand);
        }
예제 #4
0
        public object Post(CancelOrder request)
        {
            var order   = _orderDao.FindById(request.OrderId);
            var account = _accountDao.FindById(new Guid(this.GetSession().UserAuthId));

            if (order == null)
            {
                return(new HttpResult(HttpStatusCode.NotFound));
            }

            if (account.Id != order.AccountId)
            {
                throw new HttpError(HttpStatusCode.Unauthorized, "Can't cancel another account's order");
            }

            if (order.IBSOrderId.HasValue)
            {
                var currentIbsAccountId = _accountDao.GetIbsAccountId(account.Id, order.CompanyKey);
                var orderStatus         = _orderDao.FindOrderStatusById(order.Id);

                var marketSettings = _networkServiceClient.GetCompanyMarketSettings(order.PickupAddress.Latitude, order.PickupAddress.Longitude);

                var canCancelWhenPaired = orderStatus.IBSStatusId.SoftEqual(VehicleStatuses.Common.Loaded) &&
                                          marketSettings.DisableOutOfAppPayment;

                if (currentIbsAccountId.HasValue &&
                    (!orderStatus.IBSStatusId.HasValue() ||
                     orderStatus.IBSStatusId.SoftEqual(VehicleStatuses.Common.Waiting) ||
                     orderStatus.IBSStatusId.SoftEqual(VehicleStatuses.Common.Assigned) ||
                     orderStatus.IBSStatusId.SoftEqual(VehicleStatuses.Common.Arrived) ||
                     orderStatus.IBSStatusId.SoftEqual(VehicleStatuses.Common.Scheduled) ||
                     canCancelWhenPaired))
                {
                    _ibsCreateOrderService.CancelIbsOrder(order.IBSOrderId.Value, order.CompanyKey, order.Settings.Phone, account.Id);
                }
                else
                {
                    var errorReason = !currentIbsAccountId.HasValue
                    ? string.Format("no IbsAccountId found for accountid {0} and companykey {1}", account.Id, order.CompanyKey)
                    : string.Format("orderDetail.IBSStatusId is not in the correct state: {0}, state: {1}", orderStatus.IBSStatusId, orderStatus.IBSStatusId);
                    var errorMessage = string.Format("Could not cancel order because {0}", errorReason);

                    _logger.LogMessage(errorMessage);

                    throw new HttpError(HttpStatusCode.BadRequest, _resources.Get("CancelOrderError"), errorMessage);
                }
            }
            else
            {
                _logger.LogMessage("We don't have an ibs order id yet, send a CancelOrder command so that when we receive the ibs order info, we can cancel it");
            }

            var command = new Commands.CancelOrder {
                OrderId = request.OrderId
            };

            _commandBus.Send(command);

            UpdateStatusAsync(command.OrderId);

            return(new HttpResult(HttpStatusCode.OK));
        }
예제 #5
0
        private async Task <ServiceStatus> GetServiceStatus()
        {
            // Setup tests variable
            var useGeo = _serverSettings.ServerData.LocalAvailableVehiclesMode == LocalAvailableVehiclesModes.Geo ||
                         _serverSettings.ServerData.ExternalAvailableVehiclesMode == ExternalAvailableVehiclesModes.Geo;

            var useHoneyBadger = _serverSettings.ServerData.LocalAvailableVehiclesMode == LocalAvailableVehiclesModes.HoneyBadger ||
                                 _serverSettings.ServerData.ExternalAvailableVehiclesMode == ExternalAvailableVehiclesModes.HoneyBadger;

            var paymentSettings = _serverSettings.GetPaymentSettings();

            var useCmtPapi = paymentSettings.PaymentMode == PaymentMethod.Cmt ||
                             paymentSettings.PaymentMode == PaymentMethod.RideLinqCmt;

            // Setup tests
            var ibsTest = RunTest(() => Task.Run(() => _ibsProvider.Booking().GetOrdersStatus(new[] { 0 })), "IBS");

            var geoTest = useGeo
                ? RunTest(() => Task.Run(() => RunGeoTest()), "GEO")
                : Task.FromResult(false); // We do nothing here.

            var honeyBadger = useHoneyBadger
                ? RunTest(() => Task.Run(() => RunHoneyBadgerTest()), "HoneyBadger")
                : Task.FromResult(false); // We do nothing here.

            var orderStatusUpdateDetailTest = Task.Run(() => _statusUpdaterDao.GetLastUpdate());

            var sqlTest = RunTest(async() => await orderStatusUpdateDetailTest, "SQL");

            var mapiTest = paymentSettings.PaymentMode == PaymentMethod.RideLinqCmt
                ? RunTest(async() => await RunMapiTest(), "CMT MAPI")
                : Task.FromResult(false);

            var papiTest = useCmtPapi
                ? RunTest(() => Task.Run(() => RunPapiTest(paymentSettings.CmtPaymentSettings)), "CMT PAPI")
                : Task.FromResult(false);

            var customerPortalTest = RunTest(() => Task.Run(() => _networkService.GetCompanyMarketSettings(_serverSettings.ServerData.GeoLoc.DefaultLatitude, _serverSettings.ServerData.GeoLoc.DefaultLongitude)), "Customer Portal");

            // We use ConfigureAwait false here to ensure we are not deadlocking ourselves.
            await Task.WhenAll(ibsTest, geoTest, honeyBadger, sqlTest, mapiTest, papiTest, customerPortalTest).ConfigureAwait(false);

            var orderStatusUpdateDetails = orderStatusUpdateDetailTest.Result;

            var now = DateTime.UtcNow;

            var isUpdaterDeadlocked = orderStatusUpdateDetails.CycleStartDate.HasValue &&
                                      orderStatusUpdateDetails.CycleStartDate + TimeSpan.FromMinutes(10) < now;

            return(new ServiceStatus
            {
                IsIbsAvailable = ibsTest.Result,
                IbsUrl = _serverSettings.ServerData.IBS.WebServicesUrl,
                IsGeoAvailable = useGeo ? geoTest.Result : (bool?)null,
                GeoUrl = useGeo ? _serverSettings.ServerData.CmtGeo.ServiceUrl : null,
                IsHoneyBadgerAvailable = useHoneyBadger ? honeyBadger.Result : (bool?)null,
                HoneyBadgerUrl = _serverSettings.ServerData.HoneyBadger.ServiceUrl,
                IsSqlAvailable = sqlTest.Result,
                IsMapiAvailable = paymentSettings.PaymentMode == PaymentMethod.RideLinqCmt ? mapiTest.Result : (bool?)null,
                MapiUrl = paymentSettings.PaymentMode == PaymentMethod.RideLinqCmt ? GetMapiUrl() : null,
                IsPapiAvailable = useCmtPapi ? papiTest.Result : (bool?)null,
                PapiUrl = useCmtPapi ? GetPapiUrl() :null,
                IsCustomerPortalAvailable = customerPortalTest.Result,
                LastOrderUpdateDate = orderStatusUpdateDetails.LastUpdateDate,
                CycleStartDate = orderStatusUpdateDetails.CycleStartDate,
                LastOrderUpdateId = orderStatusUpdateDetails.Id.ToString(),
                LastOrderUpdateServer = orderStatusUpdateDetails.UpdaterUniqueId,
                IsUpdaterDeadlocked = isUpdaterDeadlocked
            });
        }