def notify_pickup_delay(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) delivery_status_queryset = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_status_queryset = delivery_status_queryset.filter( Q(order_status=constants.ORDER_STATUS_PLACED) | Q(order_status=constants.ORDER_STATUS_QUEUED) ) current_datetime = datetime.now() delivery_status_queryset = delivery_status_queryset.filter(order__pickup_datetime__lte=current_datetime) pickup_guys = delivery_status_queryset.values_list('pickup_guy', flat = True).exclude(pickup_guy=None).distinct() for pickup_guy_id in pickup_guys: try: pickup_guy = get_object_or_404(DeliveryGuy, id = pickup_guy_id) pickupguy_wise_delivery_ids = delivery_status_queryset.filter(pickup_guy= pickup_guy).values_list('id', flat = True) delivery_ids = delivery_ids_string(pickupguy_wise_delivery_ids) delivery_ids_msg_string = delivery_ids_message_string(pickupguy_wise_delivery_ids) ops_managers = ops_executive_for_dg(pickup_guy) if len(ops_managers) > 0: notification_type = notification_type_for_code(constants.NOTIFICATION_CODE_LATE_PICKUP) for ops_manager in ops_managers: if check_if_notification_already_exists(notification_type, ops_manager, delivery_ids) is False: notification_message = constants.NOTIFICATION_MESSAGE_PICKUP_DELAY%(ops_manager.user.first_name, pickup_guy.user.first_name, delivery_ids_msg_string, pickup_guy.user.first_name, pickup_guy.user.username) new_notification = Notification.objects.create(notification_type = notification_type, delivery_id = delivery_ids, message = notification_message) ops_manager.notifications.add(new_notification) ops_manager.save() else: create_notif_for_no_ops_exec_for_delivery_guy(pickup_guy) except Exception, e: pass
def notify_unassigned_deliveries(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) delivery_status_queryset = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_status_queryset = delivery_status_queryset.filter(Q(delivery_guy=None)) delivery_status_queryset = delivery_status_queryset.filter( Q(order_status=constants.ORDER_STATUS_PLACED) | Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT)) notif_datetime = datetime.now() + timedelta(hours=2, minutes=0) delivery_status_queryset = delivery_status_queryset.filter(order__delivery_datetime__lte=notif_datetime) pincodes = delivery_status_queryset.values_list('order__delivery_address__pin_code', flat = True).distinct() for pincode in pincodes: pincode_wise_delivery_ids = delivery_status_queryset.filter(order__delivery_address__pin_code= pincode).values_list('id', flat = True) delivery_ids = delivery_ids_string(pincode_wise_delivery_ids) delivery_ids_msg_string = delivery_ids_message_string(pincode_wise_delivery_ids) ops_managers = ops_executive_for_pincode(pincode) if len(ops_managers) > 0: notification_type = notification_type_for_code(constants.NOTIFICATION_CODE_UNASSIGNED_DELIVERY) for ops_manager in ops_managers: if check_if_notification_already_exists(notification_type, ops_manager, delivery_ids) is False: notification_message = constants.NOTIFICATION_MESSAGE_UNASSIGNED_DELIVERY%(ops_manager.user.first_name, delivery_ids_msg_string, pincode) new_notification = Notification.objects.create(notification_type = notification_type, delivery_id = delivery_ids, message = notification_message) ops_manager.notifications.add(new_notification) ops_manager.save() else: create_notif_for_no_ops_exec_for_pincode(pincode)
def excel_download(request): try: start_date_string = request.QUERY_PARAMS.get('start_date', None) end_date_string = request.QUERY_PARAMS.get('end_date', None) start_date = parse_datetime(start_date_string) start_date = ist_day_start(start_date) end_date = parse_datetime(end_date_string) end_date = ist_day_end(end_date) except Exception as e: params = ['start_date', 'end_date'] return response_incomplete_parameters(params) # VENDOR FILTERING ----------------------------------------------------------- vendor = None role = user_role(request.user) if role == constants.VENDOR: vendor_agent = get_object_or_404(VendorAgent, user=request.user) vendor = vendor_agent.vendor else: vendor_id = request.QUERY_PARAMS.get('vendor_id', None) if vendor_id is not None: vendor = get_object_or_404(Vendor, pk=vendor_id) else: pass if vendor is not None: delivery_status_queryset = OrderDeliveryStatus.objects.filter( order__vendor=vendor).select_related('delivery_guy__user') else: delivery_status_queryset = OrderDeliveryStatus.objects.all( ).select_related('delivery_guy__user') # DATE FILTERING --------------------------------------------------------------- delivery_status_queryset = delivery_status_queryset.filter( date__gte=start_date, date__lte=end_date).select_related('order') # ------------------------------------------------------------------------------ if len(delivery_status_queryset) > 5000: error_message = 'Too many records. Max of 5000 deliveries can be downloaded at a time.' return response_error_with_message(error_message) # CONSTRUCTING RESPONSE --------------------------------------------------------------- ist_timedelta = timedelta(hours=5, minutes=30) excel_order_details = [] for delivery_status in delivery_status_queryset: try: date = delivery_status.date + ist_timedelta order = delivery_status.order excel_order = { 'date': date.strftime('%d-%m-%Y'), 'order_id': delivery_status.id, 'customer_name': order.consumer.full_name, 'customer_phone_number': order.consumer.phone_number, 'cod_amount': order.cod_amount, 'cod_collected': delivery_status.cod_collected_amount, 'cod_reason': delivery_status.cod_remarks, 'status': delivery_status.order_status, 'vendor_notes': order.notes, 'vendor_order_id': order.vendor_order_id } if role == constants.OPERATIONS: excel_order['vendor_name'] = order.vendor.store_name if delivery_status.delivery_guy is not None: excel_order[ 'delivery_guy'] = delivery_status.delivery_guy.user.first_name else: excel_order['delivery_guy'] = None excel_order_details.append(excel_order) except Exception as e: pass return response_with_payload(excel_order_details, None)
def vendor_report(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) # TOTAL ORDERS ---------------------------------------------------------------------- # filter on today # filter on all orders statues # then group by vendor name to get sum_of_cod_collected and sum_of_cod_amount # iterate over this list and for each vendor check length of orders delivery_statuses_today = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_statuses_today = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_CANCELLED) ) delivery_statuses_cancelled_today = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_CANCELLED) # Executed orders are delivery attempted and delivered orders since we charge the vendors under both these cases delivery_statuses_executed_today = delivery_statuses_today.filter(Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED)) vendors_tracked = delivery_statuses_today.values('order__vendor__store_name'). \ annotate(sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount'), total_orders=Count('order')) # Adding COD exclusions for cancelled, pickup attempted and delivery attempted amount delivery_statuses_without_attempted = delivery_statuses_today.exclude(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) delivery_statuses_without_attempted = delivery_statuses_without_attempted.exclude(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) delivery_statuses_without_attempted = delivery_statuses_without_attempted.exclude(order_status=constants.ORDER_STATUS_CANCELLED) vendors_tracked_2 = delivery_statuses_without_attempted.values('order__vendor__store_name'). \ annotate(sum_of_cod_collected_without_attempted=Sum('cod_collected_amount'), sum_of_cod_amount_without_attempted=Sum('order__cod_amount'), total_orders=Count('order')) # This is for handling delivery and pickup attempted case in COD # In both these cases, COD is not considered, but the order is still considered to be executed order for vendor in vendors_tracked: vendor_store_name = vendor['order__vendor__store_name'] filtered_vendors = vendors_tracked_2.filter(order__vendor__store_name=vendor_store_name) if len(filtered_vendors) ==1: single = filtered_vendors[0] # for single in filtered_dgs: vendor['sum_of_cod_collected'] = single['sum_of_cod_collected_without_attempted'] vendor['sum_of_cod_amount'] = single['sum_of_cod_amount_without_attempted'] else: vendor['sum_of_cod_collected'] = 0 vendor['sum_of_cod_amount'] = 0 #================================================================= for item in vendors_tracked: vendor_name = item['order__vendor__store_name'] sum_of_cod_collected = item['sum_of_cod_collected'] sum_of_cod_amount = item['sum_of_cod_amount'] orders_total_count = item['total_orders'] vendors = Vendor.objects.get(store_name=vendor_name) vendor_mail_id = [vendors.email] # ----------------------------------------------------------------------------------- if orders_total_count == 0: today_string = datetime.now().strftime("%Y %b %d") email_subject = 'YourGuy Vendor Report for %s: %s' % (vendor_name, today_string) email_body = "Good Evening," email_body = email_body + "\n\n You have no orders today." email_body = email_body + "\n\n- YourGuy BOT" send_email(vendor_mail_id, email_subject, email_body) return Response(status=status.HTTP_200_OK) else: orders_for_this_vendor = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end, order__vendor=vendors) list_of_orders = [] for single_order in orders_for_this_vendor: order_ids = single_order.id list_of_orders.append(order_ids) cancelled_orders = delivery_statuses_cancelled_today.filter(order__vendor__store_name=vendor_name) count_cancelled_orders = len(cancelled_orders) executed_orders = delivery_statuses_executed_today.filter(order__vendor__store_name=vendor_name) count_executed_orders = len(executed_orders) today_string = datetime.now().strftime("%Y %b %d") email_subject = 'YourGuy Vendor Report for %s: %s' % (vendor_name, today_string) email_body = "Good Evening Guys, \n\nPlease find the report of the day." email_body = email_body + "\nTotal orders = %s" % (orders_total_count) email_body = email_body + "\nCanceled orders = %s" % (count_cancelled_orders) email_body = email_body + "\nExecuted orders = %s" % (count_executed_orders) email_body = email_body + "\nCOD supposed to be collected: %s" % (sum_of_cod_amount) email_body = email_body + "\nCOD collected: %s" % (sum_of_cod_collected) email_body = email_body + "\nAll order numbers: %s" % (list_of_orders) email_body = email_body + "\n-----------------------------------" email_body = email_body + "\n\n- YourGuy BOT" send_email(vendor_mail_id, email_subject, email_body) #return Response(status=status.HTTP_200_OK)
def dg_report(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) # Number of dgs working today ---------------------------------------------------------------------- dg_working_today_count = DGAttendance.objects.filter(login_time__gte=day_start, login_time__lte=day_end).count() # -------------------------------------------- delivery_statuses_today = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_statuses_today = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_DELIVERED) ) delivery_statuses_today = delivery_statuses_today.exclude(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) all_dgs = delivery_statuses_today.values('delivery_guy__user__username'). \ annotate(sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount')) delivery_statuses_without_attempted = delivery_statuses_today.exclude(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) all_dgs_2 = delivery_statuses_without_attempted.values('delivery_guy__user__username'). \ annotate(sum_of_cod_collected_without_attempted=Sum('cod_collected_amount'), sum_of_cod_amount_without_attempted=Sum('order__cod_amount')) # This is for handling delivery attempted and pickup attempted case in COD # In both these cases, COD is not considered, but the order is still considered to be executed order for dg in all_dgs: dg_phone_number = dg['delivery_guy__user__username'] filtered_dgs = all_dgs_2.filter(delivery_guy__user__username=dg_phone_number) if len(filtered_dgs) ==1: single = filtered_dgs[0] # for single in filtered_dgs: dg['sum_of_cod_collected'] = single['sum_of_cod_collected_without_attempted'] dg['sum_of_cod_amount'] = single['sum_of_cod_amount_without_attempted'] else: dg['sum_of_cod_collected'] = 0 dg['sum_of_cod_amount'] = 0 all_pgs = delivery_statuses_today.values('pickup_guy__user__username').annotate( sum_of_cod_amount=Sum('order__cod_amount')) all_ops_execs = Employee.objects.filter(department=constants.OPERATIONS) # ----------------------------------------------------------------------------------- if dg_working_today_count == 0: today_string = datetime.now().strftime("%Y %b %d") email_subject = 'DG Report : %s' % (today_string) email_body = "Good Evening Guys," email_body = email_body + "\n\n No DG working today." email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_DG_REPORT, email_subject, email_body) else: # DG details for today today_string = datetime.now().strftime("%Y %b %d") email_subject = 'DG Report : %s' % (today_string) email_body = "Good Evening Guys, \nPlease find the dg report of the day." email_body = email_body + "\nTotal dgs working today = %s" % (dg_working_today_count) orders_executed_dg = delivery_statuses_today.filter(Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED)) orders_executed_pg = delivery_statuses_today.filter(Q(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY)) for single_ops_exec in all_ops_execs: associated_guys = single_ops_exec.associate_delivery_guys.all() orders_count = 0 executed_orders_count = 0 assigned_orders_count = 0 ops_cod_to_be_collected = 0 ops_cod_collected = 0 pgs_data = [] dgs_data = [] for single_pg in all_pgs: pg_ph_number = single_pg['pickup_guy__user__username'] if pg_ph_number is not None: pickup_guy = DeliveryGuy.objects.get(user__username=pg_ph_number) if pickup_guy in associated_guys: pickup_guy_full_name = pickup_guy.user.first_name + pickup_guy.user.last_name no_of_assigned_orders = delivery_statuses_today.filter(pickup_guy__user__username=pg_ph_number).count() assigned_orders_count = assigned_orders_count + no_of_assigned_orders no_of_executed_orders = orders_executed_pg.filter(pickup_guy__user__username=pg_ph_number).count() executed_orders_count = executed_orders_count + no_of_executed_orders pgs_data.append("%s - Orders: %s/%s" % (pickup_guy_full_name, no_of_executed_orders, no_of_assigned_orders)) else: # Handle case when pg is not assigned to an order but dg is assigned to the same order pass for single_dg in all_dgs: dg_ph_number = single_dg['delivery_guy__user__username'] if dg_ph_number is not None: dg = DeliveryGuy.objects.get(user__username=dg_ph_number) if dg in associated_guys: cod_collected = single_dg['sum_of_cod_collected'] if cod_collected is None: cod_collected = 0 cod_to_be_collected = single_dg['sum_of_cod_amount'] if cod_to_be_collected is None: cod_to_be_collected = 0 dg_full_name = dg.user.first_name + dg.user.last_name no_of_assigned_orders = delivery_statuses_today.filter(delivery_guy__user__username=dg_ph_number).count() assigned_orders_count = assigned_orders_count + no_of_assigned_orders no_of_executed_orders = orders_executed_dg.filter(delivery_guy__user__username=dg_ph_number).count() executed_orders_count = executed_orders_count + no_of_executed_orders dgs_data.append("%s - Orders: %s/%s, COD: %s/%s" % (dg_full_name, no_of_executed_orders, no_of_assigned_orders, cod_collected, cod_to_be_collected)) ops_cod_to_be_collected = ops_cod_to_be_collected + cod_to_be_collected ops_cod_collected = ops_cod_collected + cod_collected orders_count = "%s/%s" %(executed_orders_count, assigned_orders_count) else: # Handle Case when dg is not assigned to an order but pg is assigned to same order pass email_body = email_body + "\n\nOPS EXECUTIVE %s - Orders: %s, COD: %s/%s"%(single_ops_exec.user.first_name, orders_count, ops_cod_collected, ops_cod_to_be_collected) email_body = email_body + "\nPickup boys:\n" for single in pgs_data: email_body = email_body + single +"\n" email_body = email_body + "Delivery Boys:\n" for single in dgs_data: email_body = email_body + single + "\n" # --------------------------------------------------- # For unassociated pgs and dgs all_associated_guys = [] all_unassociated_pgs = [] all_unassociated_dgs = [] orders_count = 0 assigned_orders_count = 0 executed_orders_count = 0 ops_cod_to_be_collected = 0 ops_cod_collected = 0 for single_ops_exec in all_ops_execs: all_associated_guys.extend(single_ops_exec.associate_delivery_guys.all()) for single_pg in all_pgs: pg_ph_number = single_pg['pickup_guy__user__username'] if pg_ph_number is not None: pickup_guy = DeliveryGuy.objects.get(user__username=pg_ph_number) if not (pickup_guy in all_associated_guys): pickup_guy_full_name = pickup_guy.user.first_name + pickup_guy.user.last_name no_of_assigned_orders = delivery_statuses_today.filter(pickup_guy__user__username=pg_ph_number).count() assigned_orders_count = assigned_orders_count + no_of_assigned_orders no_of_executed_orders = orders_executed_pg.filter(pickup_guy__user__username=pg_ph_number).count() executed_orders_count = executed_orders_count + no_of_executed_orders all_unassociated_pgs.append("%s - Orders: %s/%s" % (pickup_guy_full_name, no_of_executed_orders, no_of_assigned_orders)) for single_dg in all_dgs: dg_ph_number = single_dg['delivery_guy__user__username'] if dg_ph_number is not None: dg = DeliveryGuy.objects.get(user__username=dg_ph_number) if dg not in all_associated_guys: cod_collected = single_dg['sum_of_cod_collected'] if cod_collected is None: cod_collected = 0 cod_to_be_collected = single_dg['sum_of_cod_amount'] if cod_to_be_collected is None: cod_to_be_collected = 0 dg_full_name = dg.user.first_name + dg.user.last_name no_of_assigned_orders = delivery_statuses_today.filter(delivery_guy__user__username=dg_ph_number).count() assigned_orders_count = assigned_orders_count + no_of_assigned_orders no_of_executed_orders = orders_executed_dg.filter(delivery_guy__user__username=dg_ph_number).count() executed_orders_count = executed_orders_count + no_of_executed_orders all_unassociated_dgs.append("%s - Orders: %s/%s, COD: %s/%s" % (dg_full_name, no_of_executed_orders, no_of_assigned_orders, cod_collected, cod_to_be_collected)) ops_cod_to_be_collected = ops_cod_to_be_collected + cod_to_be_collected ops_cod_collected = ops_cod_collected + cod_collected orders_count = "%s/%s" %(executed_orders_count, assigned_orders_count) email_body = email_body + "\n\nUNASSOCIATED PICKP/DELIVERY BOYS - Orders: %s, COD: %s/%s"%(orders_count, ops_cod_collected, ops_cod_to_be_collected) email_body = email_body + "\nPickup Boys:\n" for single in all_unassociated_pgs: email_body = email_body + single +"\n" email_body = email_body + "Delivery Boys:\n" for single in all_unassociated_dgs: email_body = email_body + single + "\n" email_body = email_body + "\n" email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_DG_REPORT, email_subject, email_body)
def cod_report(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) # TOTAL ORDERS ---------------------------------------------------------------------- delivery_statuses_today = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end, order__cod_amount__gt=0) orders_total_count = len(delivery_statuses_today) # ----------------------------------------------------------------------------------- if orders_total_count == 0: today_string = datetime.now().strftime("%Y %b %d") email_subject = 'COD Report : %s' % (today_string) email_body = "Good Evening Guys," email_body = email_body + "\n\n No COD today on the app." email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_COD_REPORT, email_subject, email_body) return Response(status=status.HTTP_200_OK) else: # COD as per ORDER_STATUS -------------------------------------------------------- orders_pending_queryset = delivery_statuses_today.filter(Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_INTRANSIT)) orders_pending = orders_pending_queryset.aggregate(sum_of_cod_amount=Sum('order__cod_amount')) pending_cod_amount = orders_pending['sum_of_cod_amount'] if pending_cod_amount is None: pending_cod_amount = 0 orders_attempted_queryset = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED)) orders_attempted = orders_attempted_queryset.aggregate(sum_of_cod_amount=Sum('order__cod_amount')) attempted_cod_amount = orders_attempted['sum_of_cod_amount'] if attempted_cod_amount is None: attempted_cod_amount = 0 orders_cancelled_queryset = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_CANCELLED) orders_cancelled = orders_cancelled_queryset.aggregate(sum_of_cod_amount=Sum('order__cod_amount')) cancelled_cod_amount = orders_cancelled['sum_of_cod_amount'] if cancelled_cod_amount is None: cancelled_cod_amount = 0 orders_executed_queryset = delivery_statuses_today.filter(Q(order_status=constants.ORDER_STATUS_DELIVERED) & Q(cod_collected_amount__lt=F('order__cod_amount'))) orders_executed = orders_executed_queryset.aggregate(sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount')) delivered_cod_collected = orders_executed['sum_of_cod_collected'] if delivered_cod_collected is None: delivered_cod_collected = 0 delivered_cod_amount = orders_executed['sum_of_cod_amount'] if delivered_cod_amount is None: delivered_cod_amount = 0 pending_cod = delivered_cod_amount - delivered_cod_collected pending_cod_amount = pending_cod_amount + pending_cod if pending_cod_amount is None: pending_cod_amount = 0 delivery_statuses_tracked_queryset = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_DELIVERED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) ) collected = delivery_statuses_today.aggregate(Sum('cod_collected_amount')) total_cod_collected = collected['cod_collected_amount__sum'] total_cod = delivery_statuses_tracked_queryset.aggregate(total_cod=Sum('order__cod_amount')) total_cod_amount = total_cod['total_cod'] # ------------------------------------------------------------------------------- today_string = datetime.now().strftime("%Y %b %d") email_subject = "COD Report : %s" % (today_string) email_body = "Good Evening Guys, \nPlease find the COD report of the day." email_body = email_body + "\n-----------------------\n" email_body = email_body + "\nDELIVERY STATUS wise COD" email_body = email_body + "\n-----------------------" email_body = email_body + "\nPENDING Orders amount: %0.0f" % (pending_cod_amount) email_body = email_body + "\nATTEMPTED Orders amount: %0.0f" % (attempted_cod_amount) email_body = email_body + "\nCANCELLED Orders amount: %0.0f" % (cancelled_cod_amount) email_body = email_body + "\nTOTAL COD amount: %0.0f" % (total_cod_amount) email_body = email_body + "\nCOLLECTED COD amount: %0.0f" % (total_cod_collected) email_body = email_body + "\n-----------------------\n" # COD as per VENDOR -------------------------------------------------------- # all tracked orders delivery_statuses_tracked_queryset = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED)) delivery_statuses_tracked_queryset = delivery_statuses_tracked_queryset.filter(order__cod_amount__gt=0) vendors_tracked = delivery_statuses_tracked_queryset.values('order__vendor__store_name'). \ annotate(sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount')) cod_with_vendor = '' for item in vendors_tracked: vendor = item['order__vendor__store_name'] sum_of_cod_collected = item['sum_of_cod_collected'] if sum_of_cod_collected is None: sum_of_cod_collected = 0 sum_of_cod_amount = item['sum_of_cod_amount'] if sum_of_cod_amount is None: sum_of_cod_amount = 0 cod_with_vendor = cod_with_vendor + \ "\n%s - COD: %s/%s" % \ (vendor, sum_of_cod_collected, sum_of_cod_amount) # ----------------------------------------------------------------------------------- email_body = email_body + "\n-----------------------\n" email_body = email_body + "\nVENDOR wise COD: \n* COD of pending and attempted orders are not considered." email_body = email_body + "\n\n" + cod_with_vendor # COD as per DG # dict of all DGs for tracked orders email_body = email_body + "\n-----------------------" email_body = email_body + "\nDG wise COD: \n* COD of pending and attempted orders are not considered." dg_tracked = delivery_statuses_tracked_queryset.values('delivery_guy__user__username'). \ annotate(sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount')) cod_with_dg = '' # for each DG, display his total collection and amount supposed to be collected for single_dg in dg_tracked: dg_ph_number = single_dg['delivery_guy__user__username'] sum_of_cod_collected = single_dg['sum_of_cod_collected'] if sum_of_cod_collected is None: sum_of_cod_collected = 0 sum_of_cod_amount = single_dg['sum_of_cod_amount'] if sum_of_cod_amount is None: sum_of_cod_amount = 0 if dg_ph_number is not None: dg = DeliveryGuy.objects.get(user__username=dg_ph_number) dg_full_name = dg.user.first_name + dg.user.last_name else: dg_full_name = 'Unassigned' cod_with_dg = "%s - COD: %s/%s" % \ (dg_full_name, sum_of_cod_collected, sum_of_cod_amount) email_body = email_body + "\n\n" + cod_with_dg # =============================================================== # For the same DG, specify vendor wise collection bifurcation, # For doing this, vendor and dg is being associated using order & filter by dg name and then by vendor name orders_tracked = OrderDeliveryStatus.objects.filter( delivery_guy__user__username=single_dg['delivery_guy__user__username'], date__gte=day_start, date__lte=day_end) orders_tracked = orders_tracked.filter(Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_DELIVERED)) orders_tracked = orders_tracked.filter(order__cod_amount__gt=0) vendor_tracked_per_order = orders_tracked.values('order__vendor__store_name').annotate( sum_of_cod_collected=Sum('cod_collected_amount'), sum_of_cod_amount=Sum('order__cod_amount')) for item in vendor_tracked_per_order: vendor_name = item['order__vendor__store_name'] sum_of_cod_collected = item['sum_of_cod_collected'] if sum_of_cod_collected is None: sum_of_cod_collected = 0 sum_of_cod_amount = item['sum_of_cod_amount'] if sum_of_cod_amount is None: sum_of_cod_amount = 0 cod_with_vendor = '' cod_with_vendor = " %s- COD: %s/%s" % (vendor_name, sum_of_cod_collected, sum_of_cod_amount) email_body = email_body + "\n" + cod_with_vendor # --------------------------------------------------------------------------- email_body = email_body + "\n----------------------------" email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_COD_REPORT, email_subject, email_body)
def daily_report(): date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) # TOTAL ORDERS ---------------------------------------------------------------------- delivery_statuses_today = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) orders_total_count = len(delivery_statuses_today) # ----------------------------------------------------------------------------------- if orders_total_count == 0: today_string = datetime.now().strftime("%Y %b %d") email_subject = 'Daily Report : %s' % (today_string) email_body = "Good Evening Guys," email_body = email_body + "\n\n No orders on the app." email_body = email_body + "\n\n Chill out!" email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_IDS_EVERYBODY, email_subject, email_body) return Response(status=status.HTTP_200_OK) else: # TOTAL ORDERS ASSIGNED vs UNASSIGNED ORDERS ---------------------------------------- orders_unassigned_count = delivery_statuses_today.filter(delivery_guy=None).count() orders_assigned_count = orders_total_count - orders_unassigned_count orders_unassigned_percentage = "{0:.0f}%".format( float(orders_unassigned_count) / float(orders_total_count) * 100) orders_assigned_percentage = "{0:.0f}%".format(float(orders_assigned_count) / float(orders_total_count) * 100) # ----------------------------------------------------------------------------------- # ORDERS ACC TO ORDER_STATUS -------------------------------------------------------- orders_placed_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_PLACED).count() orders_queued_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_QUEUED).count() orders_queued_percentage = "{0:.0f}%".format(float(orders_queued_count) / float(orders_total_count) * 100) orders_intransit_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_INTRANSIT).count() orders_intransit_percentage = "{0:.0f}%".format(float(orders_intransit_count) / float(orders_total_count) * 100) orders_out_for_delivery_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_OUTFORDELIVERY).count() orders_out_for_delivery_percentage = "{0:.0f}%".format(float(orders_out_for_delivery_count) / float(orders_total_count) * 100) orders_delivered_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_DELIVERED).count() orders_delivered_percentage = "{0:.0f}%".format(float(orders_delivered_count) / float(orders_total_count) * 100) orders_pickup_attempted_count = delivery_statuses_today.filter( order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED).count() orders_pickup_attempted_percentage = "{0:.0f}%".format( float(orders_pickup_attempted_count) / float(orders_total_count) * 100) orders_delivery_attempted_count = delivery_statuses_today.filter( order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED).count() orders_delivery_attempted_percentage = "{0:.0f}%".format( float(orders_delivery_attempted_count) / float(orders_total_count) * 100) orders_rejected_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_REJECTED).count() orders_rejected_percentage = "{0:.0f}%".format(float(orders_rejected_count) / float(orders_total_count) * 100) orders_canceled_count = delivery_statuses_today.filter(order_status=constants.ORDER_STATUS_CANCELLED).count() orders_canceled_percentage = "{0:.0f}%".format(float(orders_canceled_count) / float(orders_total_count) * 100) pending_orders_count = orders_queued_count + orders_placed_count + orders_intransit_count + orders_out_for_delivery_count pending_orders_percentage = "{0:.0f}%".format(float(pending_orders_count) / float(orders_total_count) * 100) completed_orders_count = orders_delivered_count + orders_pickup_attempted_count + \ orders_delivery_attempted_count + orders_rejected_count + orders_canceled_count completed_orders_percentage = "{0:.0f}%".format(float(completed_orders_count) / float(orders_total_count) * 100) # ----------------------------------------------------------------------------------- # DG ATTENDANCE DETAILS ------------------------------------------------------------- total_dg_count = DeliveryGuy.objects.all().count() total_dg_checked_in_count = DGAttendance.objects.filter(date__year=date.year, date__month=date.month, date__day=date.day).count() dg_checkin_percentage = "{0:.0f}%".format(float(total_dg_checked_in_count) / float(total_dg_count) * 100) # ----------------------------------------------------------------------------------- # TOTAL COD COLLECTED Vs SUPPOSSED TO BE COLLECTED ---------------------------------- total_cod_collected = delivery_statuses_today.aggregate(Sum('cod_collected_amount')) total_cod_collected = total_cod_collected['cod_collected_amount__sum'] if total_cod_collected is None: total_cod_collected = 0 executable_deliveries = delivery_statuses_today.filter( Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT) | Q(order_status=constants.ORDER_STATUS_DELIVERED) | Q(order_status=constants.ORDER_STATUS_DELIVERY_ATTEMPTED) | Q(order_status=constants.ORDER_STATUS_OUTFORDELIVERY) | Q(order_status=constants.ORDER_STATUS_PICKUP_ATTEMPTED)) total_cod_dict = executable_deliveries.aggregate(total_cod=Sum('order__cod_amount')) total_cod_to_be_collected = total_cod_dict['total_cod'] if total_cod_to_be_collected is None: total_cod_to_be_collected = 0 if total_cod_to_be_collected > 0: cod_collected_percentage = "{0:.0f}%".format( float(total_cod_collected) / float(total_cod_to_be_collected) * 100) else: cod_collected_percentage = "100%" # ----------------------------------------------------------------------------------- # DELIVERY BOY WHO HAVE COD -------------------------------------------------------- cod_deliveries = delivery_statuses_today.filter(cod_collected_amount__gt=0) cod_with_delivery_boys = cod_deliveries.values('delivery_guy__user__first_name').annotate( total=Sum('cod_collected_amount')) cod_with_dg_string = '' for item in cod_with_delivery_boys: delivery_guy = item['delivery_guy__user__first_name'] total = item['total'] if total is None: total = 0 cod_with_dg_string = cod_with_dg_string + "\n%s = %s" % (delivery_guy, total) # ----------------------------------------------------------------------------------- today_string = datetime.now().strftime("%Y %b %d") email_subject = 'Daily Report : %s' % (today_string) email_body = "Good Evening Guys, \n\nPlease find the report of the day." email_body = email_body + "\n\nTotal orders = %s" % (orders_total_count) email_body = email_body + "\nPending orders = %s [%s percent]" % ( pending_orders_count, pending_orders_percentage) email_body = email_body + "\nExecuted orders = %s [%s percent]" % ( completed_orders_count, completed_orders_percentage) email_body = email_body + "\n\nSTATUS WISE BIFURGATION ------------" email_body = email_body + "\nOrders assigned = %s [%s percent]" % ( orders_assigned_count, orders_assigned_percentage) email_body = email_body + "\nOrders unassigned = %s [%s percent]" % ( orders_unassigned_count, orders_unassigned_percentage) email_body = email_body + "\nQueued = %s [%s percent]" % (orders_queued_count, orders_queued_percentage) email_body = email_body + "\nInTransit = %s [%s percent]" % ( orders_intransit_count, orders_intransit_percentage) email_body = email_body + "\nOutForDelivery = %s [%s percent]" % ( orders_out_for_delivery_count, orders_out_for_delivery_percentage) email_body = email_body + "\nDelivered = %s [%s percent]" % ( orders_delivered_count, orders_delivered_percentage) email_body = email_body + "\nPickup Attempted = %s [%s percent]" % ( orders_pickup_attempted_count, orders_pickup_attempted_percentage) email_body = email_body + "\nDelivery Attempted = %s [%s percent]" % ( orders_delivery_attempted_count, orders_delivery_attempted_percentage) email_body = email_body + "\nRejected = %s [%s percent]" % ( orders_rejected_count, orders_rejected_percentage) email_body = email_body + "\nCanceled = %s [%s percent]" % ( orders_canceled_count, orders_canceled_percentage) email_body = email_body + "\n------------------------------------" email_body = email_body + "\n\nDELIVERY BOY ATTENDANCE -------" email_body = email_body + "\nTotal DGs on app = %s" % total_dg_count email_body = email_body + "\nTotal DGs CheckIn = %s [%s percent]" % ( total_dg_checked_in_count, dg_checkin_percentage) email_body = email_body + "\n-----------------------------------" email_body = email_body + "\n\nCOD DETAILS ------------------" email_body = email_body + "\nTotal COD to be collected = %s" % total_cod_to_be_collected email_body = email_body + "\nTotal COD collected = %s [%s percent]" % ( total_cod_collected, cod_collected_percentage) email_body = email_body + "\n-----------------------------------" email_body = email_body + "\n\nCOD WITH EACH DG ------------------" email_body = email_body + cod_with_dg_string email_body = email_body + "\n-----------------------------------" email_body = email_body + "\n\n- YourGuy BOT" send_email(constants.EMAIL_DAILY_REPORT, email_subject, email_body)
def assign_dg(): # FETCH ALL TODAY ORDERS -------------------------------------------- date = datetime.today() day_start = ist_day_start(date) day_end = ist_day_end(date) # FILTER TO BE ASSIGNED ORDERS ------------------------------------------------------------------------- delivery_status_queryset = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_status_queryset = delivery_status_queryset.filter(Q(delivery_guy=None) | Q(pickup_guy=None)) delivery_status_queryset = delivery_status_queryset.filter( Q(order_status=constants.ORDER_STATUS_PLACED) | Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT)) # -------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------- for delivery_status in delivery_status_queryset.all(): try: order = delivery_status.order # CUSTOMER AND VENDOR FILTERING ----------------------------------------------------------------- vendor = order.vendor consumer = order.consumer previous_delivery_statuses = OrderDeliveryStatus.objects.filter( delivery_guy__isnull=False, order__consumer=consumer, order__vendor=vendor) # ------------------------------------------------------------------------------------------------ # FILTER LAST 1 MONTHS ORDERS -------------------------------------------------------------------- two_months_previous_date = day_start - dateutil.relativedelta.relativedelta(months=1) previous_delivery_statuses = previous_delivery_statuses.filter( date__gte=two_months_previous_date, date__lte=day_start) # ------------------------------------------------------------------------------------------------ # FILTERING BY PICKUP TIME RANGE ----------------------------------------------------------------- pickup_hour = int(order.pickup_datetime.hour) previous_delivery_statuses = previous_delivery_statuses.filter( Q(order__pickup_datetime__hour=pickup_hour - 1) | Q(order__pickup_datetime__hour=pickup_hour) | Q(order__pickup_datetime__hour=pickup_hour + 1)) # ------------------------------------------------------------------------------------------------ # PICK LATEST PICKUP ASSIGNED PREVIOUSLY AND ASSIGN FOR TODAY --------------------------------------- try: if delivery_status.pickup_guy is None: latest_assigned_pickup = previous_delivery_statuses.exclude(pickup_guy=None).latest('date') if latest_assigned_pickup is not None: delivery_status.pickup_guy = latest_assigned_pickup.pickup_guy delivery_status.save() except Exception as e: pass # ------------------------------------------------------------------------------------------------ # PICK LATEST DELIVERY ASSIGNED AND ASSIGN FOR TODAY ------------------------------------------------ try: if delivery_status.delivery_guy is None: latest_assigned_delivery = previous_delivery_statuses.exclude(delivery_guy=None).latest('date') if latest_assigned_delivery is not None: delivery_status.delivery_guy = latest_assigned_delivery.delivery_guy delivery_status.save() except Exception as e: pass # ------------------------------------------------------------------------------------------------ except Exception as e: pass delivery_status_queryset = OrderDeliveryStatus.objects.filter(date__gte=day_start, date__lte=day_end) delivery_status_queryset = delivery_status_queryset.filter( Q(order_status=constants.ORDER_STATUS_PLACED) | Q(order_status=constants.ORDER_STATUS_QUEUED) | Q(order_status=constants.ORDER_STATUS_INTRANSIT)) unassigned_pickups_queryset = delivery_status_queryset.filter(Q(pickup_guy=None)).values('order__vendor__store_name').annotate(the_count=Count('order__vendor__store_name')) unassigned_pickups_string = '' for unassigned_pickups in unassigned_pickups_queryset: unassigned_pickups_string = unassigned_pickups_string + '%s - %s\n'%(unassigned_pickups['order__vendor__store_name'],unassigned_pickups['the_count']) unassigned_deliveries_queryset = delivery_status_queryset.filter(Q(delivery_guy=None)).values('order__vendor__store_name').annotate(the_count=Count('order__vendor__store_name')) unassigned_deliveries_string = '' for unassigned_deliveries in unassigned_deliveries_queryset: unassigned_deliveries_string = unassigned_deliveries_string + '%s - %s\n'%(unassigned_deliveries['order__vendor__store_name'],unassigned_deliveries['the_count']) # SEND AN EMAIL SAYING CANT FIND APPROPRAITE DELIVERY GUY FOR THIS ORDER. PLEASE ASSIGN MANUALLY today_string = datetime.now().strftime("%Y %b %d") email_subject = 'Unassigned orders for %s' % (today_string) email_body = "Hello, \nPlease find the unassigned orders for the day. " \ "\nUnassigned pickups: \n%s \n\nUnassigned deliveries: \n%s \n\nPlease assign manually. \n\n- Team YourGuy" \ % (unassigned_pickups_string, unassigned_deliveries_string) send_email(constants.EMAIL_UNASSIGNED_ORDERS, email_subject, email_body)