Esempio n. 1
0
def choose_station(ride):
    tariff = RuleSet.get_active_set(ride.depart_time)

    pricing_model_names = ride.cost_data.model_names_for_tariff(tariff)
    logging.info(
        u"found pricing models: %s" %
        u",".join([unicode(model_name) for model_name in pricing_model_names]))

    stations = Station.objects.filter(
        pricing_model_name__in=pricing_model_names)
    logging.info(u"found stations: %s" %
                 u",".join([unicode(station.name) for station in stations]))

    # make sure debug and real orders don't mix
    stations = filter(lambda station: station.debug == ride.debug, stations)

    logging.info(u"stations list: %s" %
                 u",".join([unicode(station.name) for station in stations]))

    if stations:
        return stations[0]

    else:
        logging.error(u"No sharing stations found %s" % ride.get_log())
        return None
Esempio n. 2
0
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
Esempio n. 3
0
def choose_station(ride):
    tariff = RuleSet.get_active_set(ride.depart_time)

    pricing_model_names = ride.cost_data.model_names_for_tariff(tariff)
    logging.info(u"found pricing models: %s" % u",".join([unicode(model_name) for model_name in pricing_model_names]))

    stations = Station.objects.filter(pricing_model_name__in=pricing_model_names)
    logging.info(u"found stations: %s" % u",".join([unicode(station.name) for station in stations]))

    # make sure debug and real orders don't mix
    stations = filter(lambda station: station.debug == ride.debug, stations)

    logging.info(u"stations list: %s" % u",".join([unicode(station.name) for station in stations]))

    if stations:
        return stations[0]

    else:
        logging.error(u"No sharing stations found %s" % ride.get_log())
        return None
Esempio n. 4
0
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})
Esempio n. 5
0
def send_ride_voucher(ride_id):
    ride = SharedRide.by_id(ride_id)
    if not (ride and ride.station):
        logging.error("can't send voucher ride_id=%s" % ride_id)
        return

    current_lang = translation.get_language()
    station_lang_code = settings.LANGUAGES[ride.station.language][0]
    translation.activate(station_lang_code)

    pickups = []
    dropoffs = []
    for p in sorted(ride.points.all(), key=lambda point: point.stop_time):
        orders = p.pickup_orders.all(
        ) if p.type == StopType.PICKUP else p.dropoff_orders.all()
        stop = {
            "count": sum([order.num_seats for order in orders]),
            "address": p.address
        }
        phones = [
            "%s - %s" % (o.passenger.name, o.passenger.phone) for o in orders
        ]
        if len(phones) == 1:
            stop["phones"] = phones

        if p.type == StopType.PICKUP:
            pickups.append(stop)
        if p.type == StopType.DROPOFF:
            dropoffs.append(stop)

    tariff = RuleSet.get_active_set(ride.depart_time)
    srz_cost_details = CostDetails.serialize(ride.cost_details)
    template_args = {
        "ride":
        ride,
        "taxi":
        ride.taxi_number,
        "ride_date":
        ride.depart_time.strftime("%d/%m/%y"),
        "ride_time": (ride.first_pickup.stop_time -
                      STATION_PICKUP_OFFSET).strftime("%H:%M"),
        "pickups":
        pickups,
        "dropoffs":
        dropoffs,
        "charged_stops":
        max(0,
            len(pickups) - 1),
        "cost_details":
        srz_cost_details,
        "distance":
        "%.1f" % float(ride.distance / 1000.0) if ride.distance else "",
        "additional_km":
        "%.1f" % float(srz_cost_details["additional_meters"] / 1000.0) if
        (srz_cost_details and srz_cost_details["additional_meters"]) else "",
        "tariff":
        tariff.name if tariff else ""
    }
    subject = "WAYBetter Ride: %s" % ride.id
    t = get_template("voucher_email.html")
    html = t.render(Context(template_args))
    # logging.info(html)

    if ride.station.vouchers_emails:
        emails = filter(lambda i: bool(i),
                        COMMA_SPLITTER.split(ride.station.vouchers_emails))
        # let us know so we will contact the station
        resend_voucher_html = html.replace(
            "</body>",
            "<br><br><a href='http://www.waybetter.com%s'>Resend Voucher</a></body>"
            % reverse(resend_voucher, kwargs={"ride_id": ride_id}))
        notify_by_email(u"Ride [%s] Voucher sent to %s [%s]" %
                        (ride.id, ride.station.name, ",".join(emails)),
                        html=resend_voucher_html,
                        attachments=[("voucher.html", html.encode("utf-8"))])

        for email in emails:
            try:
                validate_email(email)
                send_mail_as_noreply(email, subject, html=html)
            except ValidationError:
                logging.warning(u"Strange email number: %s" % email)

    if ride.station.printer_id:  # send print job to printer
        print_voucher(ride.station.printer_id, html, subject, ride_id)

    elif ride.station.fax_number:  # send fax to station
        logging.warning("No printer_id defined. Sending Fax")
        fax_voucher(ride.station.fax_number, html, subject, ride_id)

    else:
        logging.info("no voucher sent for station [%s]" % ride.station)

    translation.activate(current_lang)

    logging.info("ride [%s] voucher sent" % ride.id)
Esempio n. 6
0
def send_ride_voucher(ride_id):
    ride = SharedRide.by_id(ride_id)
    if not (ride and ride.station):
        logging.error("can't send voucher ride_id=%s" % ride_id)
        return

    current_lang = translation.get_language()
    station_lang_code = settings.LANGUAGES[ride.station.language][0]
    translation.activate(station_lang_code)

    pickups = []
    dropoffs = []
    for p in sorted(ride.points.all(), key=lambda point: point.stop_time):
        orders = p.pickup_orders.all() if p.type == StopType.PICKUP else p.dropoff_orders.all()
        stop = {
            "count": sum([order.num_seats for order in orders]),
            "address": p.address
        }
        phones = ["%s - %s" % (o.passenger.name, o.passenger.phone) for o in orders]
        if len(phones) == 1:
            stop["phones"] = phones

        if p.type == StopType.PICKUP:
            pickups.append(stop)
        if p.type == StopType.DROPOFF:
            dropoffs.append(stop)

    tariff = RuleSet.get_active_set(ride.depart_time)
    srz_cost_details = CostDetails.serialize(ride.cost_details)
    template_args = {
        "ride": ride,
        "taxi": ride.taxi_number,
        "ride_date": ride.depart_time.strftime("%d/%m/%y"),
        "ride_time": (ride.first_pickup.stop_time - STATION_PICKUP_OFFSET).strftime("%H:%M"),
        "pickups": pickups,
        "dropoffs": dropoffs,
        "charged_stops": max(0, len(pickups) - 1),
        "cost_details": srz_cost_details,
        "distance": "%.1f" % float(ride.distance/1000.0) if ride.distance else "",
        "additional_km": "%.1f" % float(srz_cost_details["additional_meters"]/1000.0) if (srz_cost_details and srz_cost_details["additional_meters"]) else "",
        "tariff": tariff.name if tariff else ""
    }
    subject = "WAYBetter Ride: %s" % ride.id
    t = get_template("voucher_email.html")
    html = t.render(Context(template_args))
    # logging.info(html)

    if ride.station.vouchers_emails:
        emails = filter(lambda i: bool(i), COMMA_SPLITTER.split(ride.station.vouchers_emails))
        # let us know so we will contact the station
        resend_voucher_html = html.replace("</body>", "<br><br><a href='http://www.waybetter.com%s'>Resend Voucher</a></body>" % reverse(resend_voucher, kwargs={"ride_id": ride_id}))
        notify_by_email(u"Ride [%s] Voucher sent to %s [%s]" % (ride.id, ride.station.name, ",".join(emails)),
            html=resend_voucher_html,
            attachments=[("voucher.html", html.encode("utf-8"))])

        for email in emails:
            try:
                validate_email(email)
                send_mail_as_noreply(email, subject, html=html)
            except ValidationError:
                logging.warning(u"Strange email number: %s" % email)

    if ride.station.printer_id: # send print job to printer
        print_voucher(ride.station.printer_id, html, subject, ride_id)

    elif ride.station.fax_number: # send fax to station
        logging.warning("No printer_id defined. Sending Fax")
        fax_voucher(ride.station.fax_number, html, subject, ride_id)

    else:
        logging.info("no voucher sent for station [%s]" % ride.station)

    translation.activate(current_lang)

    logging.info("ride [%s] voucher sent" % ride.id)