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); }
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); } }