def sync_app_state(request): earliest_pickup_time = ceil_datetime(trim_seconds(default_tz_now()) + datetime.timedelta(minutes=asap_interval()), minutes=booking_interval()) latest_pickup_time = earliest_pickup_time + datetime.timedelta(hours=(24*14)) dt_options = list(datetimeIterator(earliest_pickup_time, latest_pickup_time, delta=datetime.timedelta(minutes=booking_interval()))) response = { "logged_in": request.user.is_authenticated(), "pickup_datetime_options": [to_js_date(opt) for opt in dt_options], "pickup_datetime_default_idx": 0, "asap_as_default": True, "booking_data": request.session.get(CURRENT_BOOKING_DATA_KEY) } passenger = Passenger.from_request(request) response["show_url"] = "" # change to cause child browser to open with passed url if passenger: response["authenticated"] = True response["passenger_picture_url"] = passenger.picture_url ongoing_order = get_ongoing_order(passenger) if ongoing_order: response["ongoing_order_id"] = ongoing_order.id future_orders = get_future_orders_for(passenger) response["future_orders_count"] = len(future_orders) trimed_response = response.copy() trimed_response['pickup_datetime_options'] = response['pickup_datetime_options'][:9] + ['...'] logging.info("get_initial_status: %s" % trimed_response) return JSONResponse(response)
def track_order(request, order_id): order = Order.by_id(order_id) use_mock = False ride = None expiration_date = default_tz_now() if order: try: ride = order.ride or order.pickmeapp_ride except (SharedRide.DoesNotExist, PickMeAppRide.DoesNotExist): pass else: error_message = _("This ride is invalid") if not ride: error_message = _("This ride is invalid") else: expiration_date = ride.arrive_time + timedelta(minutes=15) if expiration_date < default_tz_now(): error_message = _("This ride has expired") if ride.station: station_icon_url = ride.station.app_icon_url station_phone = ride.station.phone if request.GET.get("use_mock"): error_message = "" station_icon_url = "https://s3.amazonaws.com/stations_icons/ny_icon.png" use_mock = True expiration_date = default_tz_now() + timedelta(minutes=15) expiration_date = to_js_date(expiration_date) # prepare for JS consumption return custom_render_to_response('track_order.html', locals(), context_instance=RequestContext(request))
def track_order(request, order_id): order = Order.by_id(order_id) use_mock = False ride = None expiration_date = default_tz_now() if order: try: ride = order.ride or order.pickmeapp_ride except (SharedRide.DoesNotExist, PickMeAppRide.DoesNotExist): pass else: error_message = _("This ride is invalid") if not ride: error_message = _("This ride is invalid") else: expiration_date = ride.arrive_time + timedelta(minutes=15) if expiration_date < default_tz_now(): error_message = _("This ride has expired") if ride.station: station_icon_url = ride.station.app_icon_url station_phone = ride.station.phone if request.GET.get("use_mock"): error_message = "" station_icon_url = "https://s3.amazonaws.com/stations_icons/ny_icon.png" use_mock = True expiration_date = default_tz_now() + timedelta(minutes=15) expiration_date = to_js_date(expiration_date) # prepare for JS consumption return custom_render_to_response("track_order.html", locals(), context_instance=RequestContext(request))
def get_discounted_offers(request, order_settings, start_ride_algo_data): user = request.user if request.user.is_authenticated() else None discounted_offers = [] earliest_offer_dt = ceil_datetime(max(trim_seconds(default_tz_now()) + datetime.timedelta(minutes=asap_interval()), order_settings.pickup_dt - OFFERS_TIMEDELTA), minutes=booking_interval()) discounts_data = compute_discounts_data(order_settings, earliest_offer_dt, order_settings.pickup_dt + OFFERS_TIMEDELTA, datetime.timedelta(minutes=booking_interval()), user = user ) for discount_data in discounts_data: discount_rule = discount_data.discount_rule discount_dt = discount_data.pickup_dt tariff_for_discount_offer = RuleSet.get_active_set(discount_dt) base_price_for_discount_offer = start_ride_algo_data.order_price(NEW_ORDER_ID, tariff_for_discount_offer) if base_price_for_discount_offer: discount = discount_rule.get_discount(base_price_for_discount_offer) if discount == 0: logging.info(u"skipping %s: grants zero discount" % discount_rule.name) continue offer_key = "%s_%s" % (DISCOUNTED_OFFER_PREFIX, get_uuid()) memcache.set(offer_key, DiscountData.dump(discount_data), namespace=DISCOUNTED_OFFERS_NS) offer_text = _(u"The price includes a discount of %g NIS") % discount if discount_rule.offer_text: offer_text = discount_rule.offer_text if offer_text.find("%g") > -1: # render discount amount offer_text %= discount discount_offer_data = { "ride_id": offer_key, "pickup_time": to_js_date(discount_dt), "discount_picture_url": discount_rule.picture_url, "discount_name": discount_rule.display_name, "passengers": [], "seats_left": MAX_SEATS, "price": base_price_for_discount_offer - discount, "new_ride": True, "comment": offer_text } user_agent = request.META.get("HTTP_USER_AGENT", "") if RE_2_1_AGENT.match(user_agent) is None: # only for client < 1.2.1 discount_offer_data.update({ "seats_left": MAX_SEATS - 1, "passengers": [{'name': discount_rule.display_name, 'picture_url': discount_rule.picture_url}] }) discounted_offers.append(discount_offer_data) return discounted_offers
def serialize(self): d = {} for attr in [ "id", "status", "taxi_id", "station_id", "lat", "lon", "raw_status" ]: d[attr] = getattr(self, attr) d["timestamp"] = to_js_date(self.timestamp) return d
def get_previous_rides(request, passenger): data = [] orders = passenger.orders.filter(depart_time__lt=utc_now(), status__in=ORDER_SUCCESS_STATUS).order_by('-depart_time') orders = orders.filter(type__in=[OrderType.PRIVATE, OrderType.SHARED])[:PREVIOUS_RIDES_TO_DISPLAY] seen_rides = [] for order in orders: ride = order.ride if not ride: logging.error("order [%s] not valid for previous rides (order.ride is None" % order.id) continue if ride in seen_rides: continue # skip duplicates (in case ride has multiple orders by same passenger) seen_rides.append(ride) ride_orders = ride.orders.all() ride_mates_orders = filter(lambda o: o != order, ride_orders) ride_mates = [{'name': mate_order.passenger.name, 'picture_url': mate_order.passenger.picture_url} for mate_order in ride_mates_orders for seat in range(order.num_seats)] dispatching_event = first(lambda e: e.taxi_id, ride.events.all()) ride_data = { "order_id": order.id, "pickup_time": to_js_date(order.pickup_point.stop_time), "passengers": ride_mates, "seats_left": MAX_SEATS - sum([o.num_seats for o in ride_orders]), "your_seats": order.num_seats, "taxi_number": dispatching_event.taxi_id if dispatching_event else None, "station_name": ride.station.name if ride.station else WAYBETTER_STATION_NAME, "price": order.get_billing_amount(), "price_alone": order.price_alone, "billing_status": ugettext_lazy(order.get_status_display().title()), "pickup": order.from_raw, "dropoff": order.to_raw, "is_private": order.type == OrderType.PRIVATE, "comment": "" } data.append(ride_data) return JSONResponse(data)
def get_next_rides(request, passenger): data = [] future_orders = get_future_orders_for(passenger) seen_rides = [] for order in future_orders: ride = order.ride if not ride: logging.error("order [%s] not valid for previous rides (order.ride is None" % order.id) continue if ride in seen_rides: continue # skip duplicates (in case ride has multiple orders by same passenger) seen_rides.append(ride) ride_orders = ride.orders.all() ride_mates_orders = filter(lambda o: o != order, ride_orders) ride_mates = [{'name': o.passenger.name, 'picture_url': o.passenger.picture_url} for o in ride_mates_orders for seat in range(o.num_seats)] ride_data = { "order_id": order.id, "pickup_time": to_js_date(order.pickup_point.stop_time), "passengers": ride_mates, "seats_left": MAX_SEATS - sum([o.num_seats for o in ride_orders]), "your_seats": order.num_seats, "price": order.get_billing_amount(), "price_alone": order.price_alone, "is_private": order.type == OrderType.PRIVATE, "pickup": order.from_raw, "dropoff": order.to_raw, "billing_status": _("or less"), "comment": "" } data.append(ride_data) return JSONResponse(data)
else: return JSONResponse({'error': 'error'}) else: form = DatePickerForm() init_end_date = init_end_date or default_tz_now_max() init_start_date = init_start_date or default_tz_now_min() if async: assert wrapper_locals.get('channel_id') assert wrapper_locals.get('token') async_computation_submitted_signal.send(sender="base_datepicker_page", channel_id=wrapper_locals.get('channel_id')) deferred.defer(f_data, init_start_date, init_end_date, channel_id=wrapper_locals.get('channel_id'), token=wrapper_locals.get('token')) data = simplejson.dumps({'status': 'submitted', 'token': wrapper_locals.get('token')}) else: data = simplejson.dumps(f_data(init_start_date, init_end_date)) start_date, end_date = to_js_date(init_start_date), to_js_date(init_end_date) extended_locals = wrapper_locals.copy() extended_locals.update(locals()) return render_to_response(template_name, extended_locals, context_instance=RequestContext(request)) def has_caller(caller_name): """ Check if the stack contains a caller with caller_name returns: True if a caller with caller_name is in the stack, False otherwise. """ result = False try: result = caller_name in [frame[3] for frame in inspect.getouterframes(inspect.currentframe())]
def book_ride(request): return JSONResponse({ 'status': 'failed', 'error': SERVICE_NOT_AVAILABLE_MSG }) passenger = Passenger.from_request(request) request_data = simplejson.loads(request.POST.get('data')) logging.info(u"book ride: %s\n%s" % (passenger, unicode(simplejson.dumps(request_data), "unicode-escape"))) result = { 'status': '', 'order_id': None, 'redirect': '', 'error': '', 'pickup_dt': None } if passenger and passenger.user and hasattr(passenger, "billing_info"): # we have logged-in passenger with billing_info - let's proceed order_settings = OrderSettings.fromRequest(request) ride_id = request_data.get("ride_id") new_ride = (ride_id == NEW_ORDER_ID) discounted_ride = (ride_id and str(ride_id).startswith(DISCOUNTED_OFFER_PREFIX)) join_ride = not (new_ride or discounted_ride) ride_to_join = SharedRide.by_id(ride_id) if join_ride else None order = None if ride_to_join: # check it is indeed a valid candidate if is_valid_candidate(ride_to_join, order_settings): order = create_order(order_settings, passenger, ride=ride_to_join) else: logging.warning("tried booking an invalid ride candidate") result['error'] = _("Sorry, but this ride has been closed for booking") else: # new or discounted ride, check pickup time isn't before ASAP (minus a couple seconds to allow booking to exactly ASAP) if order_settings.pickup_dt <= default_tz_now() + datetime.timedelta(minutes=asap_interval()) - datetime.timedelta(seconds=10): logging.warning("tried booking to expired pickup time %s" % order_settings.pickup_dt) result['error'] = _("Please choose a later pickup time") else: if discounted_ride: cached_discount_data = memcache.get(ride_id, namespace=DISCOUNTED_OFFERS_NS) discount_data = DiscountData.load(cached_discount_data) logging.info("[book_ride] discount_data = %s" % discount_data) order = create_order(order_settings, passenger, discount_data=discount_data) else: order = create_order(order_settings, passenger) if order: result['status'] = 'success' result['order_id'] = order.id result['pickup_formatted'] = order.from_raw result['pickup_dt'] = to_js_date(order.depart_time) result["price"] = order.get_billing_amount() ride_orders = [order] + ( list(ride_to_join.orders.all()) if ride_to_join else [] ) result["passengers"] = [{'name': o.passenger.name, 'picture_url': o.passenger.picture_url, 'is_you': o==order} for o in ride_orders for seat in range(o.num_seats)] result["seats_left"] = MAX_SEATS - sum([o.num_seats for o in ride_orders]) deferred.defer(join_offer_and_order, order, request_data) else: result['status'] = 'failed' else: # not authorized for booking, save current booking state in session set_current_booking_data(request) if passenger and not hasattr(passenger, "billing_info"): result['status'] = 'billing_failed' result['redirect'] = get_token_url(request) # go to billing else: result['status'] = 'auth_failed' logging.info("book ride result: %s" % result) return JSONResponse(result)
def get_offers(request): return JSONResponse({ 'status': 'failed', 'error': SERVICE_NOT_AVAILABLE_MSG }) order_settings = OrderSettings.fromRequest(request) # TODO_WB: save the requested search params and associate with a push_token from request for later notifications of similar searches if not order_settings.private: candidate_rides = get_candidate_rides(order_settings) look_for_discounts = True else: candidate_rides = [] look_for_discounts = False matching_rides = get_matching_rides(candidate_rides, order_settings) if not matching_rides: return JSONResponse({'error': u'מצטערים, הכתובת המבוקשת אינה באיזורי הכיסוי עדיין'}) offers = [] start_ride_algo_data = None for ride_data in matching_rides: ride_id = ride_data.ride_id ride = SharedRide.by_id(ride_id) # get price for offer according to tariff tariff = RuleSet.get_active_set(order_settings.pickup_dt) price = ride_data.order_price(NEW_ORDER_ID, tariff) price_alone = ride_data.order_price(NEW_ORDER_ID, tariff, sharing=False) if not price > 0: logging.warning("get_offers missing price for %s" % order_settings.pickup_dt) continue if ride_id == NEW_ORDER_ID: # start a new ride start_ride_algo_data = ride_data offer = { "asap": order_settings.asap, "pickup_time": to_js_date(order_settings.pickup_dt), "price": price, "seats_left": MAX_SEATS, "new_ride": True, "comment": _(u"You will be updated when someone joins") # TODO_WB: sharing chances } else: # sharing offers time_sharing = ride_data.order_time(NEW_ORDER_ID) time_alone = ride_data.order_time(NEW_ORDER_ID, sharing=False) time_addition = int((time_sharing - time_alone) / 60) pickup_point = ride_data.order_pickup_point(NEW_ORDER_ID) ride_orders = ride.orders.all() pickup_time = compute_new_departure(ride, ride_data) + datetime.timedelta(seconds=pickup_point.offset) if pickup_time < default_tz_now() + datetime.timedelta(minutes=asap_interval()): logging.info("skipping offer because pickup_time is too soon: %s" % pickup_time) continue offer = { "ride_id": ride_id, "pickup_time": to_js_date(pickup_time), "passengers": [{'name': order.passenger.name, 'picture_url': order.passenger.picture_url} for order in ride_orders for seat in range(order.num_seats)], "seats_left": MAX_SEATS - sum([order.num_seats for order in ride_orders]), "price": price, "new_ride": False, "comment": _(u"Money saved: %(money_saved)s NIS or more – additional time: %(time_added)s min") % {'time_added': time_addition, 'money_saved': "%g" % (price_alone - price)} } # good enough offer found, no discounts if order_settings.pickup_dt - datetime.timedelta(minutes=30) < pickup_time < order_settings.pickup_dt + datetime.timedelta(minutes=30): look_for_discounts = False offers.append(offer) # add discounted offers if relevant ## override look_for_discounts = True ## override if look_for_discounts and start_ride_algo_data: offers += get_discounted_offers(request, order_settings, start_ride_algo_data) offers = sorted(offers, key=lambda o: o["pickup_time"], reverse=False) deferred.defer(save_search_req_and_offers, Passenger.from_request(request), order_settings, offers) return JSONResponse({'offers': offers})
def serialize(self): d = {} for attr in ["station_id", "taxi_id", "ride_uuid", "lat", "lon"]: d[attr] = getattr(self, attr) d["timestamp"] = to_js_date(self.timestamp) return d
async_computation_submitted_signal.send( sender="base_datepicker_page", channel_id=wrapper_locals.get('channel_id')) deferred.defer(f_data, init_start_date, init_end_date, channel_id=wrapper_locals.get('channel_id'), token=wrapper_locals.get('token')) data = simplejson.dumps({ 'status': 'submitted', 'token': wrapper_locals.get('token') }) else: data = simplejson.dumps(f_data(init_start_date, init_end_date)) start_date, end_date = to_js_date(init_start_date), to_js_date( init_end_date) extended_locals = wrapper_locals.copy() extended_locals.update(locals()) return render_to_response(template_name, extended_locals, context_instance=RequestContext(request)) def has_caller(caller_name): """ Check if the stack contains a caller with caller_name returns: True if a caller with caller_name is in the stack, False otherwise. """