Example #1
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);
        }
Example #2
0
        public decimal?ChargeBookingFeesIfNecessary(OrderStatusDetail orderStatusDetail)
        {
            var paymentSettings = _serverSettings.GetPaymentSettings();

            if (orderStatusDetail.IsPrepaid ||
                orderStatusDetail.CompanyKey == null || // If booking is made on home company, booking fees will be included in same trip receipt
                (paymentSettings.PaymentMode != PaymentMethod.Cmt &&
                 paymentSettings.PaymentMode != PaymentMethod.RideLinqCmt))
            {
                return(null);
            }

            var feesForMarket = _feesDao.GetMarketFees(orderStatusDetail.Market);
            var bookingFees   = feesForMarket != null
                ? feesForMarket.Booking
                : 0;

            if (bookingFees <= 0)
            {
                return(null);
            }

            _logger.LogMessage("Booking fee of {0} will be charged for order {1}{2}.",
                               bookingFees,
                               orderStatusDetail.IBSOrderId,
                               string.Format(orderStatusDetail.Market.HasValue()
                        ? "in market {0}"
                        : string.Empty,
                                             orderStatusDetail.Market));

            var account = _accountDao.FindById(orderStatusDetail.AccountId);

            if (!account.HasValidPaymentInformation)
            {
                _logger.LogMessage("Booking fee cannot be charged for order {0} because the user has no payment method configured.", orderStatusDetail.IBSOrderId);
                return(null);
            }

            try
            {
                // PreAuthorization
                var preAuthResponse = PreauthorizePaymentIfNecessary(orderStatusDetail.OrderId, bookingFees, FeeTypes.Booking);
                if (preAuthResponse.IsSuccessful)
                {
                    // Commit
                    var paymentResult = CommitPayment(bookingFees, bookingFees, orderStatusDetail.OrderId, FeeTypes.Booking);
                    if (paymentResult.IsSuccessful)
                    {
                        _logger.LogMessage("No show fee of amount {0} was charged for order {1}.", bookingFees, orderStatusDetail.IBSOrderId);
                        return(bookingFees);
                    }

                    throw new Exception(paymentResult.Message);
                }

                throw new Exception(preAuthResponse.Message);
            }
            catch (Exception ex)
            {
                _logger.LogMessage("Could not process no show fee for order {0}: {1}.", orderStatusDetail.IBSOrderId, ex.Message);
                return(null);
            }
        }