def ride_viewed(request, work_station, ride_id): ride = SharedRide.by_id(ride_id) if ride and ride.station == work_station.station: if ride.change_status(old_status=RideStatus.ASSIGNED, new_status=RideStatus.VIEWED): return HttpResponse("OK") return HttpResponseForbidden()
def ride_status_sentinel(ride_id): logging.info("ride_status_sentinel: %s" % ride_id) ride = SharedRide.by_id(ride_id) if ride.status != ACCEPTED: send_ride_in_risk_notification( u"Ride not accepted by station %d minutes before depart time" % (RIDE_SENTINEL_GRACE.seconds / 60), ride_id)
def billing_approved_book_order(callback_args, order): from sharing.station_controller import send_ride_in_risk_notification ride_id = callback_args.get("ride_id") ride_data = callback_args.get("ride_data") discount_data = callback_args.get("discount_data") discount_data = DiscountData.load(discount_data) if discount_data else None if not (ride_id is not None and ride_data): logging.error("no ride_id or ride_data for on_billing_trx_approved") return try: if ride_id == NEW_ORDER_ID: ride = create_shared_ride_for_order(ride_data, order) else: ride = SharedRide.by_id(ride_id) if ride and ride.lock(): # try joining existing ride try: update_ride_add_order(ride, ride_data, order) ride.unlock() except Exception, e: #TODO_WB: handle this error in some way - try again, create a new ride logging.error(traceback.format_exc()) ride.unlock() raise Exception(e.message) else:
def resend_to_fleet_manager(request, ride_id): resend_result = False ride = SharedRide.by_id(ride_id) cancel_result = fleet_manager.cancel_ride(ride) if cancel_result: resend_result = fleet_manager.create_ride(ride) return JSONResponse({'result': resend_result})
def reassign_ride(request, work_station, ride_id): ride = SharedRide.by_id(ride_id) if ride and ride.station == work_station.station: ride.update(taxi_number=None) if fleet_manager.cancel_ride(ride) and fleet_manager.create_ride(ride): return HttpResponse("OK") else: logging.error("could not reassign ride: %s" % ride_id) return HttpResponseForbidden()
def _add_shared_ride(ride_id): ride = SharedRide.by_id(ride_id) shared_rides[ride_id] = { "id" : ride.id, "type" : "sharing", "taxi" : ride.taxi_number, "stops" : [p.serialize_for_status_page() for p in sorted(ride.points.all(), key=lambda p: p.stop_time)], "events" : [] } return ride
def manual_assign_ride(request): from sharing.sharing_dispatcher import assign_ride ride_id = request.POST.get("ride_id") station_id = request.POST.get("station_id") ride = SharedRide.by_id(ride_id) station = Station.by_id(station_id) if station and ride.station != station: fleet_manager.cancel_ride(ride) assign_ride(ride, station) return JSONResponse({'ride': ride.serialize_for_eagle_eye()})
def print_voucher(printer_id, html, title, ride_id): print_backend = DEFAULT_BACKEND logging.info(u"print_voucher: printer_id: %s" % printer_id) job_id = _do_voucher_send(printer_id, html, title, ride_id, print_backend, check_print_job_status) if not job_id: ride = SharedRide.by_id(ride_id) if ride.station.fax_number: notify_by_email(u"WARNING: Voucher printing failed, will try to send fax for ride: %s" % ride_id) logging.warning("printing failed, will send fax") fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification(u"Ride voucher failed to print and station has no fax number defined.", ride_id)
def send_ride_in_risk_notification(msg, ride_id): msg_key = u"%s_%s" % (ride_id, msg) namespace = "ride_in_risk_notifications" msg_sent = memcache.get(msg_key, namespace=namespace) if msg_sent: logging.info(u"skipping sending: %s" % msg) return ride = SharedRide.by_id(ride_id) if ride and ride.debug: logging.info("skipping notification for debug ride %s" % ride_id) elif ride: t = get_template("ride_in_risk_email.html") orders = ride.orders.all() passengers = [o.passenger for o in orders.all()] station = ride.station try: sharing_ws = station.work_stations.filter( accept_shared_rides=True)[0] except Exception: sharing_ws = None html = t.render( Context({ "passengers": [u"%s (%s)" % (p.full_name, p.phone) for p in passengers], "station_phones": station.phones.all() if station else [], "station_name": station.name if station else "[NO STATION]", "online_status": sharing_ws.is_online if sharing_ws else None, "ride_id": ride_id, "depart_time": ride.depart_time.strftime("%H:%M"), "ride_status": RideStatus.get_name(ride.status), "msg": msg })) logging.info("sending risk mail: %s" % html) notify_by_email("IMPORTANT: Ride In Risk [%s]" % ride_id, html=html) memcache.set(msg_key, True, namespace=namespace) for num in CRITICAL_MESSAGES_CONTACT_LIST: send_sms(num, msg)
def check_print_job_status(job_id, title, ride_id, html, counter=1, backend=None): try: status = get_status(job_id, backend=backend) logging.info("check_print_job_status(%s): '%s'" % (job_id, FaxStatus.get_name(status))) if status != FaxStatus.DONE: if counter > PRINT_COMPLETE_TIMEOUT: logging.info("print failure: title=%s" % title) ride = SharedRide.by_id(ride_id) if ride.station.fax_number: email_devs( u"Ride voucher did not print after %d minutes: %s. (sending fax)" % (PRINT_COMPLETE_TIMEOUT, title)) fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification( u"Ride voucher did not print after %d minutes: %s.\nNo fax number defined!." % (PRINT_COMPLETE_TIMEOUT, title), ride_id) else: logging.info("print still not done: counter=%s, title=%s" % (counter, title)) deferred.defer(check_print_job_status, job_id, title, ride_id, html, counter=counter + 1, backend=backend, _countdown=60) except Exception, e: trace = traceback.format_exc() logging.error("check_print_job_status failed with exception: %s" % trace) deferred.defer(check_print_job_status, job_id, title, ride_id, html, counter=counter + 1, backend=backend, _countdown=60)
def _add_shared_ride(ride_id): ride = SharedRide.by_id(ride_id) shared_rides[ride_id] = { "id": ride.id, "type": "sharing", "taxi": ride.taxi_number, "stops": [ p.serialize_for_status_page() for p in sorted(ride.points.all(), key=lambda p: p.stop_time) ], "events": [] } return ride
def manual_dispatch(request, work_station, ride_id): ride = SharedRide.by_id(ride_id) taxi_number = request.POST.get("taxi_number") pickup_estimate = request.POST.get("pickup_estimate") if taxi_number and pickup_estimate and ride and ride.station == work_station.station: ride.taxi_number = taxi_number ride.pickup_estimate = int(pickup_estimate) fleet_manager.cancel_ride(ride) fleet_manager.create_ride(ride) ride.change_status(old_status=RideStatus.VIEWED, new_status=RideStatus.ACCEPTED) return HttpResponse("OK") return HttpResponseForbidden()
def print_voucher(printer_id, html, title, ride_id): print_backend = DEFAULT_BACKEND logging.info(u"print_voucher: printer_id: %s" % printer_id) job_id = _do_voucher_send(printer_id, html, title, ride_id, print_backend, check_print_job_status) if not job_id: ride = SharedRide.by_id(ride_id) if ride.station.fax_number: notify_by_email( u"WARNING: Voucher printing failed, will try to send fax for ride: %s" % ride_id) logging.warning("printing failed, will send fax") fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification( u"Ride voucher failed to print and station has no fax number defined.", ride_id)
def create_ny_isr_ride(request, ride_id): ride = SharedRide.by_id(ride_id) if not ride: msg = "no SharedRide found with id=%s" % ride_id logging.error(msg) return HttpResponseBadRequest(msg) if settings.LOCAL: isrproxy_id = 2738544 test_station_id = 1008 else: isrproxy_id = 3673085 test_station_id = 1713061 # amir_station_1 if ride.debug: target_station_id = test_station_id target_station_isr_id = 8 # test station isr id else: # real rides created from stable - send to New York taxi station target_station_id = 1529226 target_station_isr_id = 10 logging.info(u"create_ny_isr_ride: %s" % u", ".join([unicode(s) for s in [target_station_id, ride]])) if not (ride.station and ride.station.id == target_station_id): msg = "wrong station: ride.station=%s target_station=%s" % ( ride.station, target_station_id) logging.error(msg) response = HttpResponseBadRequest(msg) else: # fix the station data since stable.Station does not have fleet field if not ride.station.fleet_station_id: ride.station.fleet_station_id = target_station_isr_id ride.station.save() ride.dn_fleet_manager_id = isrproxy_id ride.save() result = fleet_manager.create_ride(ride) response = HttpResponse(str(result)) return response
def save_search_req_and_offers(passenger, order_settings, offers): sr = SearchRequest.fromOrderSettings(order_settings, passenger) sr.save() for offer in offers: pickup_dt = offer['pickup_time'] / 1000 pickup_dt = datetime.datetime.fromtimestamp(pickup_dt).replace(tzinfo=TZ_INFO["UTC"]).astimezone(TZ_INFO['Asia/Jerusalem']) ride_offer = RideOffer(search_req=sr, ride_key=offer.get('ride_id'), ride=SharedRide.by_id(offer.get('ride_id')), pickup_dt=pickup_dt, seats_left=offer['seats_left'], price=offer['price'], new_ride=offer['new_ride']) if str(offer.get('ride_id')).startswith(DISCOUNTED_OFFER_PREFIX): cached_discount_data = memcache.get(offer.get('ride_id'), namespace=DISCOUNTED_OFFERS_NS) if cached_discount_data: discount_data = DiscountData.load(cached_discount_data) ride_offer.discount_rule = discount_data.discount_rule ride_offer.promotion = discount_data.promotion ride_offer.promo_code = discount_data.promo_code ride_offer.new_ride = True # this is actually a new ride ride_offer.save()
def create_ny_isr_ride(request, ride_id): ride = SharedRide.by_id(ride_id) if not ride: msg = "no SharedRide found with id=%s" % ride_id logging.error(msg) return HttpResponseBadRequest(msg) if settings.LOCAL: isrproxy_id = 2738544 test_station_id = 1008 else: isrproxy_id = 3673085 test_station_id = 1713061 # amir_station_1 if ride.debug: target_station_id = test_station_id target_station_isr_id = 8 # test station isr id else: # real rides created from stable - send to New York taxi station target_station_id = 1529226 target_station_isr_id = 10 logging.info(u"create_ny_isr_ride: %s" % u", ".join([unicode(s) for s in [target_station_id, ride]])) if not (ride.station and ride.station.id == target_station_id): msg = "wrong station: ride.station=%s target_station=%s" % (ride.station, target_station_id) logging.error(msg) response = HttpResponseBadRequest(msg) else: # fix the station data since stable.Station does not have fleet field if not ride.station.fleet_station_id: ride.station.fleet_station_id = target_station_isr_id ride.station.save() ride.dn_fleet_manager_id = isrproxy_id ride.save() result = fleet_manager.create_ride(ride) response = HttpResponse(str(result)) return response
def eagle_eye(request): from dateutil.parser import parse stations = [] for station in Station.objects.all(): try: sharing_ws = station.work_stations.filter(accept_shared_rides=True)[0] except Exception: sharing_ws = None stations.append({"name": station.name, "id": station.id, "debug": station.debug, "online_status": sharing_ws.is_online if sharing_ws else False}) if request.is_ajax(): ride_id = request.GET.get("ride_id") if ride_id: # update specific ride's data return JSONResponse(SharedRide.by_id(ride_id).serialize_for_eagle_eye()) # get all rides data start_date = parse(request.GET.get("start_date")).astimezone(IsraelTimeZone()) end_date = parse(request.GET.get("end_date")).astimezone(IsraelTimeZone()) start_date = datetime.combine(start_date, dt_time.min) end_date = datetime.combine(end_date, dt_time.max) rides = SharedRide.objects.filter(depart_time__gte=start_date, depart_time__lte=end_date).order_by("-depart_time") incomplete_orders = Order.objects.filter(depart_time__gte=start_date, depart_time__lte=end_date) incomplete_orders = filter(lambda o: o.status in [IGNORED, REJECTED, FAILED, ERROR, TIMED_OUT, CANCELLED], incomplete_orders) result = { 'rides': [r.serialize_for_eagle_eye() for r in rides], 'incomplete_orders': [o.serialize_for_eagle_eye() for o in incomplete_orders], 'stations': stations } return JSONResponse(result) else: lib_ng = True stations = simplejson.dumps(stations) return render_to_response("eagle_eye.html", locals(), context_instance=RequestContext(request))
def send_ride_in_risk_notification(msg, ride_id): msg_key = u"%s_%s" % (ride_id, msg) namespace = "ride_in_risk_notifications" msg_sent = memcache.get(msg_key, namespace=namespace) if msg_sent: logging.info(u"skipping sending: %s" % msg) return ride = SharedRide.by_id(ride_id) if ride and ride.debug: logging.info("skipping notification for debug ride %s" % ride_id) elif ride: t = get_template("ride_in_risk_email.html") orders = ride.orders.all() passengers = [o.passenger for o in orders.all()] station = ride.station try: sharing_ws = station.work_stations.filter(accept_shared_rides=True)[0] except Exception: sharing_ws = None html = t.render(Context({ "passengers": [u"%s (%s)" % (p.full_name, p.phone) for p in passengers], "station_phones": station.phones.all() if station else [], "station_name": station.name if station else "[NO STATION]", "online_status": sharing_ws.is_online if sharing_ws else None, "ride_id": ride_id, "depart_time": ride.depart_time.strftime("%H:%M"), "ride_status": RideStatus.get_name(ride.status), "msg": msg })) logging.info("sending risk mail: %s" % html) notify_by_email("IMPORTANT: Ride In Risk [%s]" % ride_id, html=html) memcache.set(msg_key, True, namespace=namespace) for num in CRITICAL_MESSAGES_CONTACT_LIST: send_sms(num, msg)
def check_print_job_status(job_id, title, ride_id, html, counter=1, backend=None): try: status = get_status(job_id, backend=backend) logging.info("check_print_job_status(%s): '%s'" % (job_id, FaxStatus.get_name(status))) if status != FaxStatus.DONE: if counter > PRINT_COMPLETE_TIMEOUT: logging.info("print failure: title=%s" % title) ride = SharedRide.by_id(ride_id) if ride.station.fax_number: email_devs(u"Ride voucher did not print after %d minutes: %s. (sending fax)" % (PRINT_COMPLETE_TIMEOUT, title)) fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification(u"Ride voucher did not print after %d minutes: %s.\nNo fax number defined!." % (PRINT_COMPLETE_TIMEOUT, title), ride_id) else: logging.info("print still not done: counter=%s, title=%s" % (counter, title)) deferred.defer(check_print_job_status, job_id, title, ride_id, html, counter=counter + 1, backend=backend, _countdown=60) except Exception, e: trace = traceback.format_exc() logging.error("check_print_job_status failed with exception: %s" % trace) deferred.defer(check_print_job_status, job_id, title, ride_id, html, counter=counter + 1, backend=backend, _countdown=60)
def complete_ride(request, ride_id): ride = SharedRide.by_id(ride_id) ride.change_status(new_status=RideStatus.COMPLETED) return JSONResponse({'ride': ride.serialize_for_eagle_eye()})
def accept_ride(request, ride_id): ride = SharedRide.by_id(ride_id) ride.change_status(new_status=RideStatus.ACCEPTED) return JSONResponse({'ride': ride.serialize_for_eagle_eye()})
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 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)
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)
def eagle_eye(request): from dateutil.parser import parse stations = [] for station in Station.objects.all(): try: sharing_ws = station.work_stations.filter( accept_shared_rides=True)[0] except Exception: sharing_ws = None stations.append({ "name": station.name, "id": station.id, "debug": station.debug, "online_status": sharing_ws.is_online if sharing_ws else False }) if request.is_ajax(): ride_id = request.GET.get("ride_id") if ride_id: # update specific ride's data return JSONResponse( SharedRide.by_id(ride_id).serialize_for_eagle_eye()) # get all rides data start_date = parse(request.GET.get("start_date")).astimezone( IsraelTimeZone()) end_date = parse(request.GET.get("end_date")).astimezone( IsraelTimeZone()) start_date = datetime.combine(start_date, dt_time.min) end_date = datetime.combine(end_date, dt_time.max) rides = SharedRide.objects.filter( depart_time__gte=start_date, depart_time__lte=end_date).order_by("-depart_time") incomplete_orders = Order.objects.filter(depart_time__gte=start_date, depart_time__lte=end_date) incomplete_orders = filter( lambda o: o.status in [IGNORED, REJECTED, FAILED, ERROR, TIMED_OUT, CANCELLED], incomplete_orders) result = { 'rides': [r.serialize_for_eagle_eye() for r in rides], 'incomplete_orders': [o.serialize_for_eagle_eye() for o in incomplete_orders], 'stations': stations } return JSONResponse(result) else: lib_ng = True stations = simplejson.dumps(stations) return render_to_response("eagle_eye.html", locals(), context_instance=RequestContext(request))