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 object Post(SwitchOrderToNextDispatchCompanyRequest request) { _logger.LogMessage("Switching order to another IBS : " + request.ToJson()); var account = _accountDao.FindById(new Guid(this.GetSession().UserAuthId)); var order = _orderDao.FindById(request.OrderId); var orderStatusDetail = _orderDao.FindOrderStatusById(request.OrderId); if (orderStatusDetail.Status != OrderStatus.TimedOut) { // Only switch companies if order is timedout return(orderStatusDetail); } // We are in a network timeout situation. if (orderStatusDetail.CompanyKey == request.NextDispatchCompanyKey) { _ibsCreateOrderService.CancelIbsOrder(order.IBSOrderId, order.CompanyKey, order.Settings.Phone, account.Id); orderStatusDetail.IBSStatusId = VehicleStatuses.Common.Timeout; orderStatusDetail.IBSStatusDescription = _resources.Get("OrderStatus_" + VehicleStatuses.Common.Timeout); return(orderStatusDetail); } var market = _taxiHailNetworkServiceClient.GetCompanyMarket(order.PickupAddress.Latitude, order.PickupAddress.Longitude); var isConfiguredForCmtPayment = _taxiHailNetworkHelper.FetchCompanyPaymentSettings(request.NextDispatchCompanyKey); var chargeTypeId = order.Settings.ChargeTypeId; var chargeTypeDisplay = order.Settings.ChargeType; if (!isConfiguredForCmtPayment) { // Only companies configured for CMT payment can support CoF orders outside of home market chargeTypeId = ChargeTypes.PaymentInCar.Id; chargeTypeDisplay = ChargeTypes.PaymentInCar.Display; } var newOrderRequest = new CreateOrderRequest { PickupDate = GetCurrentOffsetedTime(request.NextDispatchCompanyKey), PickupAddress = order.PickupAddress, DropOffAddress = order.DropOffAddress, Settings = new BookingSettings { LargeBags = order.Settings.LargeBags, Name = order.Settings.Name, NumberOfTaxi = order.Settings.NumberOfTaxi, Passengers = order.Settings.Passengers, Phone = order.Settings.Phone, ProviderId = null, ChargeType = chargeTypeDisplay, ChargeTypeId = chargeTypeId, // Reset vehicle type VehicleType = null, VehicleTypeId = null }, Note = order.UserNote, ClientLanguageCode = account.Language }; var fare = FareHelper.GetFareFromEstimate(new RideEstimate { Price = order.EstimatedFare }); var newReferenceData = (ReferenceData)_referenceDataService.Get(new ReferenceDataRequest { CompanyKey = request.NextDispatchCompanyKey }); // This must be localized with the priceformat to be localized in the language of the company // because it is sent to the driver var chargeTypeIbs = _resources.Get(chargeTypeDisplay, _serverSettings.ServerData.PriceFormat); var ibsInformationNote = IbsHelper.BuildNote( _serverSettings.ServerData.IBS.NoteTemplate, chargeTypeIbs, order.UserNote, order.PickupAddress.BuildingName, newOrderRequest.Settings.LargeBags, _serverSettings.ServerData.IBS.HideChargeTypeInUserNote); var networkErrorMessage = string.Format(_resources.Get("Network_CannotCreateOrder", order.ClientLanguageCode), request.NextDispatchCompanyName); int ibsAccountId; try { // Recreate order on next dispatch company IBS ibsAccountId = CreateIbsAccountIfNeeded(account, request.NextDispatchCompanyKey); } catch (Exception ex) { _logger.LogMessage(networkErrorMessage); _logger.LogError(ex); throw new HttpError(HttpStatusCode.InternalServerError, networkErrorMessage); } ValidateProvider(newOrderRequest, newReferenceData, market.HasValue(), null); var newOrderCommand = Mapper.Map <CreateOrder>(newOrderRequest); newOrderCommand.OrderId = request.OrderId; newOrderCommand.ReferenceDataCompanyList = newReferenceData.CompaniesList.ToArray(); newOrderCommand.Market = market; newOrderCommand.CompanyKey = request.NextDispatchCompanyKey; newOrderCommand.CompanyName = request.NextDispatchCompanyName; newOrderCommand.Fare = fare; newOrderCommand.IbsInformationNote = ibsInformationNote; _commandBus.Send(new InitiateIbsOrderSwitch { NewIbsAccountId = ibsAccountId, NewOrderCommand = newOrderCommand }); return(new OrderStatusDetail { OrderId = request.OrderId, Status = OrderStatus.Created, CompanyKey = request.NextDispatchCompanyKey, CompanyName = request.NextDispatchCompanyName, NextDispatchCompanyKey = null, NextDispatchCompanyName = null, IBSStatusId = string.Empty, IBSStatusDescription = string.Format(_resources.Get("OrderStatus_wosWAITINGRoaming", order.ClientLanguageCode), request.NextDispatchCompanyName), }); }