Best Python code snippet using playwright-python
views.py
Source:views.py  
1from datetime import datetime, timedelta2import json3from django.http import HttpResponse4from django.shortcuts import render, redirect5from django.contrib.auth.models import User6from django.contrib.auth.decorators import login_required7from django.core.exceptions import ObjectDoesNotExist8from django.db.models import F9from django.views.decorators.csrf import csrf_exempt10from main.models import UserDetails11from leads.models import Timezone, RegalixTeams, Location, TimezoneMapping, Leads, WPPLeads12from representatives.models import (13    Availability,14    ScheduleLog,15    AvailabilityForTAT, AvailabilityForBoltTAT,16)17from reports.report_services import DownloadLeads18from lib.salesforce import SalesforceApi19from django.db.models import Q20from lib.helpers import send_mail21from django.template.loader import get_template22from django.template import Context23from django.db.models import Count24from collections import OrderedDict25# Create your views here.26@login_required27def users(request):28    """ List all Google representatives"""29    users = User.objects.all()30    roles = {31        1: 'Admin',32        2: 'Google Manager',33        3: 'Google Representative',34        4: 'Implementation Consultant'35    }36    return render(request, 'representatives/users.html', {'users': users, 'roles': roles})37@login_required38def add_edit_user(request, id=None):39    """ Manage Users information """40    try:41        user = User.objects.get(id=id)42    except ObjectDoesNotExist:43        user = None44    if request.method == 'POST':45        if not user:46            user = User()47        user.email = request.POST['username']48        user.first_name = request.POST['first_name']49        user.last_name = request.POST['last_name']50        user.save()51        try:52            user.profile.role = request.POST['ref_role_id']53            user.profile.user_supporting_region = request.POST['user_supporting_region']54            user.profile.user_manager_name = request.POST['user_manager_name']55            user.profile.user_manager_email = request.POST['user_manager_email']56            user.profile.save()57        except ObjectDoesNotExist:58            user_details = UserDetails()59            user_details.user = user60            user_details.role = request.POST['ref_role_id']61            user_details.user_supporting_region = request.POST['user_supporting_region']62            user_details.user_manager_name = request.POST['user_manager_name']63            user_details.user_manager_email = request.POST['user_manager_email']64            user_details.save()65        return redirect('representatives.views.users')66    return render(request, 'representatives/add_edit_user.html', {'rep_user': user})67@login_required68def plan_schedule(request, plan_month=0, plan_day=0, plan_year=0, process_type='TAG', team_id=0):69    """ Manage scheduling appointments"""70    time_zone = 'IST'71    if request.method == 'POST':72        changed_reords_in_slot = list()73        selected_tzone = Timezone.objects.get(zone_name=time_zone)74        slected_week_start_date = request.POST.get('schedule_week_start_date')75        slected_week_start_date = datetime.strptime(slected_week_start_date, '%m-%d-%Y')76        selected_team_id = request.POST.get('team')77        selected_team = RegalixTeams.objects.get(id=selected_team_id)78        for key, value in request.POST.items():79            if key.startswith('input'):80                # check each slot and add slots count if exists81                data_in_a_day = int(request.POST.get(key) or 0)82                keys = key.split('_')  # input_16_6_2014_0_0 / input_16_6_2014_0_3083                slot_day = int(keys[1])84                slot_month = int(keys[2])85                slot_year = int(keys[3])86                slot_hour = int(keys[4])87                slot_minutes = int(keys[5])88                slot_date = datetime(slot_year, slot_month, slot_day, slot_hour, slot_minutes)89                utc_date = SalesforceApi.get_utc_date(slot_date, selected_tzone.time_value)90                # if record already exist update availability count91                try:92                    availability = Availability.objects.get(date_in_utc=utc_date, team=selected_team)93                    if availability.availability_count != data_in_a_day:94                        updated_slot = get_created_or_updated_slot_details(selected_team, utc_date, selected_tzone,95                                                                           availability.availability_count,96                                                                           data_in_a_day)97                        changed_reords_in_slot.append(updated_slot)98                        desc = availability.availability_count99                        availability.availability_count = data_in_a_day100                        availability.save()101                        log = ScheduleLog()102                        log.user = request.user103                        log.availability = availability104                        log.availability_count = availability.availability_count105                        log.booked_count = availability.booked_count106                        log.description = str(desc) + " is Updated to " + str(availability.availability_count)107                        log.save()108                except ObjectDoesNotExist:109                    # create record if it doesn't exist and only if user added some slot information110                    if data_in_a_day:111                        availability = Availability()112                        availability.availability_count = data_in_a_day113                        availability.date_in_utc = utc_date114                        availability.team = selected_team115                        new_slot = get_created_or_updated_slot_details(selected_team, utc_date, selected_tzone, 0,116                                                                       data_in_a_day)117                        changed_reords_in_slot.append(new_slot)118                        availability.save()119                        log = ScheduleLog()120                        log.user = request.user121                        log.availability = availability122                        log.availability_count = availability.availability_count123                        log.booked_count = availability.booked_count124                        log.description = str(0) + " is Updated to " + str(data_in_a_day)125                        log.save()126        # trigger a mail with changes in slot127        if changed_reords_in_slot:128            changed_reords_in_slot = sorted(changed_reords_in_slot, key=lambda k: k['date_time'], reverse=True)129            mail_slot_changes(request, selected_team, changed_reords_in_slot)130        plan_month = slected_week_start_date.month131        plan_day = slected_week_start_date.day132        plan_year = slected_week_start_date.year133    exclude_types = ['MIGRATION']134    if request.user.groups.filter(name='OPERATIONS'):135        if not request.user.groups.filter(Q(name='WPP') | Q(name='TAG-AND-WPP')):136            exclude_types.append('WPP')137        teams = RegalixTeams.objects.filter(process_type=process_type, is_active=True).exclude(team_name='default team')138        process_types = RegalixTeams.objects.exclude(process_type__in=exclude_types).values_list('process_type',139                                                                                                 flat=True).distinct().order_by()140    else:141        process_types = RegalixTeams.objects.exclude(142            process_type='MIGRATION').filter(Q(team_lead__in=[request.user.id]) | Q(team_manager__in=[request.user.id]),143                                             is_active=True).values_list('process_type',144                                                                         flat=True).distinct().order_by()145        if process_type == 'TAG' and process_type not in process_types:146            if 'SHOPPING' in process_types:147                process_type = 'SHOPPING'148            else:149                process_type = 'WPP'150        teams = RegalixTeams.objects.filter(Q(team_lead__in=[request.user.id]) | Q(team_manager__in=[request.user.id]),151                                            process_type=process_type, is_active=True).exclude(152            team_name='default team').distinct().order_by()153    if not teams:154        # if team is not specified, select first team by default155        return render(156            request,157            'representatives/plan_schedule.html',158            {'error': True,159             'message': "No Teams"160             }161        )162    elif not int(team_id):163        # get first team for the selected process164        try:165            RegalixTeams.objects.get(process_type=process_type, id=team_id)166        except ObjectDoesNotExist:167            return redirect(168                'representatives.views.plan_schedule',169                plan_month=plan_month,170                plan_day=plan_day,171                plan_year=plan_year,172                process_type=process_type,173                team_id=teams[0].id174            )175    if not int(plan_month):176        # if month is not specified, select current month177        today = datetime.today()178        plan_month = today.month179        return redirect(180            'representatives.views.plan_schedule',181            plan_month=plan_month,182            plan_day=plan_day,183            plan_year=plan_year,184            process_type=process_type,185            team_id=team_id186        )187    if not int(plan_day):188        # if day is not specified, select today's day189        today = datetime.today()190        plan_day = today.day191        return redirect(192            'representatives.views.plan_schedule',193            plan_month=plan_month,194            plan_day=plan_day,195            plan_year=plan_year,196            process_type=process_type,197            team_id=team_id198        )199    if not int(plan_year):200        # if year is not specified, select current year201        today = datetime.today()202        plan_year = today.year203        return redirect(204            'representatives.views.plan_schedule',205            plan_month=plan_month,206            plan_day=plan_day,207            plan_year=plan_year,208            process_type=process_type,209            team_id=team_id210        )211    # create date from week start day212    plan_date = datetime(int(plan_year), int(plan_month), int(plan_day))213    plan_date += timedelta(hours=5, minutes=30)214    # if week start day is not monday, select appropriate start week day of given date215    if plan_date.weekday():216        plan_date -= timedelta(days=plan_date.weekday())217        return redirect(218            'representatives.views.plan_schedule',219            plan_month=plan_date.month,220            plan_day=plan_date.day,221            plan_year=plan_date.year,222            process_type=process_type,223            team_id=team_id224        )225    # prepare slot dates to display226    plan_dates = {227        'day1': plan_date,228        'day2': plan_date + timedelta(days=1),229        'day3': plan_date + timedelta(days=2),230        'day4': plan_date + timedelta(days=3),231        'day5': plan_date + timedelta(days=4),232        'day6': plan_date + timedelta(days=5)233    }234    # compute next week and previous week start dates235    prev_week = plan_date + timedelta(days=-7)236    next_week = plan_date + timedelta(days=7)237    tzone = Timezone.objects.get(zone_name=time_zone)238    utc_date = SalesforceApi.get_utc_date(plan_date, tzone.time_value)239    utc_start_date = utc_date240    utc_end_date = utc_start_date + timedelta(days=6)241    selected_team = RegalixTeams.objects.get(id=team_id)242    appointments_list = Availability.objects.filter(243        date_in_utc__range=(utc_start_date, utc_end_date),244        team=selected_team)245    #  for daylight savings notifications246    daylight_marquee_msg = ''247    today = datetime.today()248    locations = selected_team.location.all()249    for location in locations:250        if location.daylight_start and location.daylight_end:251            if today >= location.daylight_start and today <= location.daylight_end:252                date_difference = location.daylight_end.date() - today.date()253                if date_difference.days <= 15:254                    daylight_marquee_msg += 'Daylight Saving ends on %s for %s::' % (255                    location.daylight_end.strftime("%B %d, %Y"), location.location_name)256            if today < location.daylight_start:257                date_difference = location.daylight_start.date() - today.date()258                if date_difference.days <= 15:259                    daylight_marquee_msg += 'Daylight Saving starts on %s for %s::' % (260                    location.daylight_start.strftime("%B %d, %Y"), location.location_name)261    diff = divmod((utc_date - plan_date).total_seconds(), 60)262    diff_in_minutes = diff[0]263    total_booked = dict()264    total_available = dict()265    # prepare appointments slot keys266    appointments = dict()267    for key, _date in plan_dates.items():268        total_booked[datetime.strftime(_date, '%Y_%m_%d')] = []269        total_available[datetime.strftime(_date, '%Y_%m_%d')] = []270        for hour in range(24):271            # even hour slot272            minutes = 0273            even_key = 'input_'  # input_16_6_2014_0_00274            even_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)275            even_key += '_'276            even_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)277            even_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes)278            appointments[even_key] = dict()279            appointments[even_key]['value'] = 0280            appointments[even_key]['disabled'] = True if datetime(281                _date.year, _date.month, _date.day, hour, minutes) < datetime.utcnow() else False282            # odd hour slot283            minutes = 30284            odd_key = 'input_'  # input_16_6_2014_0_00285            odd_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)286            odd_key += '_'287            odd_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)288            odd_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes)289            appointments[odd_key] = dict()290            appointments[odd_key]['value'] = 0291            appointments[odd_key]['disabled'] = True if datetime(292                _date.year, _date.month, _date.day, hour, minutes) < datetime.utcnow() else False293    # calculate slots available vs booked for week294    for apptmnt in appointments_list:295        apptmnt.date_in_utc -= timedelta(minutes=diff_in_minutes)296        key = 'input_' + datetime.strftime(apptmnt.date_in_utc, '%d_%m_%Y') + \297              '_' + str(apptmnt.date_in_utc.hour) + '_' + str(apptmnt.date_in_utc.minute)298        appointments[key]['value'] = int(apptmnt.availability_count)299        appointments[key]['booked'] = int(apptmnt.booked_count)300        total_available[datetime.strftime(apptmnt.date_in_utc, '%Y_%m_%d')].append(int(apptmnt.availability_count))301        total_booked[datetime.strftime(apptmnt.date_in_utc, '%Y_%m_%d')].append(int(apptmnt.booked_count))302    total_slots = list()303    for key, value in sorted(total_available.iteritems()):304        total_slots.append({'available': sum(value), 'booked': sum(total_booked[key])})305    return render(306        request,307        'representatives/plan_schedule.html',308        {'schedule_date': plan_date,309         'time_zone': time_zone,310         'dates': plan_dates,311         'appointments': appointments,312         'prev_week': prev_week,313         'next_week': next_week,314         'teams': teams,315         'plan_month': plan_month,316         'plan_day': plan_day,317         'plan_year': plan_year,318         'process_type': process_type,319         'process_types': process_types,320         'selected_team': selected_team,321         'total_slots': total_slots,322         'daylight_marquee_msg': daylight_marquee_msg,323         }324    )325@login_required326def availability_list(request, avail_month=0, avail_day=0, avail_year=0, process_type='TAG', location_id=0,327                      time_zone='IST'):328    # if month is not specified, select current month329    if not int(avail_month):330        today = datetime.today()331        avail_month = today.month332        return redirect(333            'representatives.views.availability_list',334            avail_month=avail_month,335            avail_day=avail_day,336            avail_year=avail_year,337            process_type=process_type,338            location_id=location_id,339            time_zone=time_zone340        )341    # if day is not specified, select today's day342    if not int(avail_day):343        today = datetime.today()344        avail_day = today.day345        return redirect(346            'representatives.views.availability_list',347            avail_month=avail_month,348            avail_day=avail_day,349            avail_year=avail_year,350            process_type=process_type,351            location_id=location_id,352            time_zone=time_zone353        )354    # if year is not specified, select current year355    if not int(avail_year):356        today = datetime.today()357        avail_year = today.year358        return redirect(359            'representatives.views.availability_list',360            avail_month=avail_month,361            avail_day=avail_day,362            avail_year=avail_year,363            process_type=process_type,364            location_id=location_id,365            time_zone=time_zone366        )367    # create date from week start day368    avail_date = datetime(int(avail_year), int(avail_month), int(avail_day), 0, 0, 0)369    # if week start day is not monday, select appropriate start week day of given date370    if avail_date.weekday():371        avail_date -= timedelta(days=avail_date.weekday())372        return redirect(373            'representatives.views.availability_list',374            avail_month=avail_date.month,375            avail_day=avail_date.day,376            avail_year=avail_date.year,377            process_type=process_type,378            location_id=location_id,379            time_zone=time_zone380        )381    # compute next week and previous week start dates382    prev_week = avail_date + timedelta(days=-7)383    next_week = avail_date + timedelta(days=7)384    # prepare slot dates to display385    avail_dates = {386        'day1': avail_date,387        'day2': avail_date + timedelta(days=1),388        'day3': avail_date + timedelta(days=2),389        'day4': avail_date + timedelta(days=3),390        'day5': avail_date + timedelta(days=4)391    }392    # get UTC date for selected based on selected timezone393    tz = Timezone.objects.get(zone_name=time_zone)394    utc_date = SalesforceApi.get_utc_date(avail_date, tz.time_value)395    # filter and block past appointment slots396    today_date = datetime.utcnow() + timedelta(minutes=30)397    utc_start_date = utc_date if utc_date > today_date else today_date398    utc_end_date = utc_date + timedelta(days=5)399    # For Location Germay we have only one regalix team for both TAG ang Shopping form.400    # If Location Gernamy and process_type is SHOPPING refer avalability slots from team TAG - EMEA - German401    # if int(location_id) == 47 and process_type == 'SHOPPING':402    #     process_type = 'TAG'403    # get all appointments for future dates in the given week404    slots_data = Availability.objects.filter(405        date_in_utc__range=(utc_start_date, utc_end_date),406        team__location__id=location_id,407        team__process_type=process_type408    )409    diff = divmod((utc_date - avail_date).total_seconds(), 60)410    diff_in_minutes = diff[0]411    # set default value412    std_diff_in_minutes = diff_in_minutes413    ds_diff_in_minutes = diff_in_minutes414    is_daylight_now = False415    daylight_start = None416    daylight_end = None417    std_time_zone = None418    ds_time_zone = None419    # New Feature for future appointments in daylight saving mode420    try:421        location = Location.objects.get(id=location_id)422        if location.daylight_start and location.daylight_end:423            daylight_start = datetime(location.daylight_start.year, location.daylight_start.month,424                                      location.daylight_start.day, 0, 0, 0)425            daylight_end = datetime(location.daylight_end.year, location.daylight_end.month, location.daylight_end.day,426                                    0, 0, 0)427            daylight_start = SalesforceApi.get_utc_date(daylight_start, tz.time_value)428            daylight_end = SalesforceApi.get_utc_date(daylight_end, tz.time_value)429            std_time_zones_list = TimezoneMapping.objects.values_list('standard_timezone', flat=True).distinct()430            ds_time_zones_list = TimezoneMapping.objects.values_list('daylight_timezone', flat=True).distinct()431            if tz.id in ds_time_zones_list:432                timezone_mapping = TimezoneMapping.objects.get(daylight_timezone_id=tz.id)433            elif tz.id in std_time_zones_list:434                timezone_mapping = TimezoneMapping.objects.get(standard_timezone_id=tz.id)435            std_timezone = timezone_mapping.standard_timezone436            utc_ds_date = SalesforceApi.get_utc_date(avail_date, std_timezone.time_value)437            diff = divmod((utc_ds_date - avail_date).total_seconds(), 60)438            std_diff_in_minutes = diff[0]439            ds_time_zone = timezone_mapping.daylight_timezone440            utc_ds_date = SalesforceApi.get_utc_date(avail_date, ds_time_zone.time_value)441            diff = divmod((utc_ds_date - avail_date).total_seconds(), 60)442            ds_diff_in_minutes = diff[0]443            # # Check if appointment slot is between the daylight time444            # if utc_start_date >= daylight_start and utc_start_date <= daylight_end:445            #     is_daylight_now = True446            #     try:447            #         # Get standard timezone ussing TimezoneMapping table448            #         if tz.id in ds_time_zones_list:449            #             timezone_mapping = TimezoneMapping.objects.get(daylight_timezone_id=tz.id)450            #             new_time_zone = timezone_mapping.daylight_timezone451            #             utc_ds_date = SalesforceApi.get_utc_date(avail_date, new_time_zone.time_value)452            #             diff = divmod((utc_ds_date - avail_date).total_seconds(), 60)453            #             new_diff_in_minutes = diff[0]454            #             new_time_zone1 = timezone_mapping.standard_timezone455            #             utc_ds_date1 = SalesforceApi.get_utc_date(avail_date, new_time_zone1.time_value)456            #             diff1 = divmod((utc_ds_date1 - avail_date).total_seconds(), 60)457            #             new_diff_in_minutes1 = diff1[0]458            #         elif tz.id in std_time_zones_list:459            #             timezone_mapping = TimezoneMapping.objects.get(standard_timezone_id=tz.id)460            #             new_time_zone = timezone_mapping.daylight_timezone461            #             utc_std_date = SalesforceApi.get_utc_date(avail_date, new_time_zone.time_value)462            #             diff = divmod((utc_std_date - avail_date).total_seconds(), 60)463            #             new_diff_in_minutes = diff[0]464            #             new_time_zone1 = timezone_mapping.standard_timezone465            #             utc_ds_date1 = SalesforceApi.get_utc_date(avail_date, new_time_zone1.time_value)466            #             diff1 = divmod((utc_ds_date1 - avail_date).total_seconds(), 60)467            #             new_diff_in_minutes1 = diff1[0]468            #     except ObjectDoesNotExist:469            #         std_diff_in_minutes = diff_in_minutes470            # else:471            #     is_daylight_now = False472            #     try:473            #         ds_time_zone = TimezoneMapping.objects.get(standard_timezone_id=tz.id)474            #         ds_time_zone = ds_time_zone.daylight_timezone475            #         utc_ds_date = SalesforceApi.get_utc_date(avail_date, ds_time_zone.time_value)476            #         ds_diff = divmod((utc_ds_date - avail_date).total_seconds(), 60)477            #         ds_diff_in_minutes = ds_diff[0]478            #         timezone_mapping = TimezoneMapping.objects.get(standard_timezone_id=tz.id)479            #         new_time_zone1 = timezone_mapping.standard_timezone480            #         utc_ds_date1 = SalesforceApi.get_utc_date(avail_date, new_time_zone1.time_value)481            #         diff1 = divmod((utc_ds_date1 - avail_date).total_seconds(), 60)482            #         new_diff_in_minutes1 = diff1[0]483            #     except ObjectDoesNotExist:484            #         ds_diff_in_minutes = diff_in_minutes485            #     print ds_diff_in_minutes486    except ObjectDoesNotExist:487        location = None488    appointments = dict()489    timezone_for_appointments = dict()490    for key, _date in avail_dates.items():491        for hour in range(24):492            # Even Hour slot493            even_key = 'input_' + datetime.strftime(_date, '%d_%m_%Y') + '_' + str(hour)494            appointments[even_key] = 0495            # Odd Hour slot496            odd_key = 'input_' + datetime.strftime(_date, '%d_%m_%Y') + '_' + str(hour)497            appointments[odd_key] = 0498    slot_diff = 0499    for apptmnt in slots_data:500        # related_timezone = time_zone501        # print time_zone, apptmnt.date_in_utc502        # # If Daylight saving changes in between the slots/appointments503        # if location and daylight_start and daylight_end:504        #     if is_daylight_now:505        #         # If week starts with day light savings and ends with in the week then506        #         # Calculate appointments on standard timezones507        #         if apptmnt.date_in_utc >= daylight_start and apptmnt.date_in_utc <= daylight_end:508        #             apptmnt.date_in_utc -= timedelta(minutes=new_diff_in_minutes)509        #             related_timezone = new_time_zone.zone_name if new_time_zone else time_zone510        #         else:511        #             apptmnt.date_in_utc -= timedelta(minutes=new_diff_in_minutes1)512        #     else:513        #         print 'not day light each slot'514        #         # If week starts with standard timezones and ends with in the week then515        #         # Calculate appointments on daylight timezones516        #         print 'ds_diff_in_minutes', ds_diff_in_minutes, 'new_diff_in_minutes1', new_diff_in_minutes1517        #         if apptmnt.date_in_utc >= daylight_start and apptmnt.date_in_utc <= daylight_end:518        #             apptmnt.date_in_utc -= timedelta(minutes=ds_diff_in_minutes)519        #             related_timezone = ds_time_zone.zone_name if ds_time_zone else time_zone520        #         else:521        #             apptmnt.date_in_utc -= timedelta(minutes=new_diff_in_minutes1)522        # else:523        #     apptmnt.date_in_utc -= timedelta(minutes=diff_in_minutes)524        if location and daylight_start and daylight_end:525            if apptmnt.date_in_utc >= daylight_start and apptmnt.date_in_utc <= daylight_end:526                apptmnt.date_in_utc -= timedelta(minutes=ds_diff_in_minutes)527                related_timezone = ds_time_zone528            else:529                apptmnt.date_in_utc -= timedelta(minutes=std_diff_in_minutes)530                related_timezone = std_timezone531        else:532            apptmnt.date_in_utc = SalesforceApi.convert_utc_to_timezone(apptmnt.date_in_utc, tz.time_value)533            related_timezone = tz534        slot_diff = apptmnt.date_in_utc.minute535        key = 'input_' + datetime.strftime(apptmnt.date_in_utc, '%d_%m_%Y') + \536              '_' + str(apptmnt.date_in_utc.hour) + '_' + str(apptmnt.date_in_utc.minute)537        if apptmnt.availability_count > apptmnt.booked_count:538            appointments[key] = int(apptmnt.availability_count - apptmnt.booked_count)539        else:540            appointments[key] = 0541        timezone_for_appointments[key] = str(related_timezone)542    return render(543        request,544        'leads/availability_list.html',545        {'time_zone': time_zone,546         'location_id': location_id,547         'time_zone_desc': time_zone + ' (UTC' + tz.time_value + ')',548         'dates': avail_dates,549         'appointments': appointments,550         'timezone_for_appointments': timezone_for_appointments,551         'slot_diff': slot_diff,552         'process_type': process_type,553         'prev_week': prev_week,554         'next_week': next_week,555         }556    )557@login_required558@csrf_exempt559def check_and_add_appointment(request):560    response = dict()561    if request.method == 'POST':562        request_tzone = request.POST.get('time_zone')563        location_id = request.POST.get('location_id')564        requested_slots = json.loads(request.POST.get('slots'))565        # in case multiple slots needs to fill at once(TAG/SHOPPING)566        slots_filled = list()567        for selected_slot in requested_slots:568            requested_date = selected_slot['time']569            requested_date = datetime.strptime(requested_date, '%m/%d/%Y %I:%M %p')570            process_type = selected_slot['type']571            # For Location Germay we have only one regalix team for both TAG ang Shopping form.572            # If Location Gernamy and process_type is SHOPPING refer avalability slots from team TAG - EMEA - German573            # if int(location_id) == 47 and process_type == 'SHOPPING':574            #     process_type = 'TAG'575            response['status'] = 'FAILED'576            response['type'] = process_type577            # time zone conversion578            tz = Timezone.objects.get(zone_name=request_tzone)579            utc_date = SalesforceApi.get_utc_date(requested_date, tz.time_value)580            alotted_slots = Availability.objects.filter(581                date_in_utc=utc_date,582                team__location__id=location_id,583                team__process_type=process_type584            )585            for slot in alotted_slots:586                if datetime.utcnow() >= utc_date:587                    response['status'] = 'FAILED'588                elif slot.booked_count < slot.availability_count:589                    slot.booked_count += 1590                    slot.save()591                    response['status'] = 'SUCCESS'592                    slots_filled.append(slot.id)593                    break594            if response['status'] == 'FAILED':595                if slots_filled:596                    Availability.objects.filter(id__in=slots_filled).update(booked_count=F('booked_count') - 1)597                break598    return HttpResponse(json.dumps(response), content_type="application/json")599@login_required600def copy_appointment_to_next_week(request, plan_month=0, plan_day=0, plan_year=0, team_id=0):601    response = dict()602    appointment_list = list()603    week_end_date = datetime(int(plan_year), int(plan_month), int(plan_day))604    if week_end_date.weekday():605        week_end_date -= timedelta(days=week_end_date.weekday())606    # substract 330 minutes(5:30 hours) since the configuration is doing for indian team607    week_start_date = week_end_date - timedelta(days=7) - timedelta(seconds=(330 * 60))608    week_end_date = week_end_date - timedelta(seconds=(330 * 60)) - timedelta(seconds=1)609    availability_data = Availability.objects.filter(610        date_in_utc__range=(week_start_date, week_end_date),611        team_id=team_id612    )613    # get UTC date for selected based on selected timezone614    for avail_data in availability_data:615        appointment_dict = dict()616        # Get data for current week(to avoid template processing the logic)617        ist_date = avail_data.date_in_utc + timedelta(seconds=(330 * 60)) + timedelta(days=7)618        appointment_dict.update({619            'availability_count': avail_data.availability_count,620            'date_in_utc': datetime.strftime(ist_date, '%d_%m_%Y_%H_%M'),621        })622        appointment_list.append(appointment_dict)623    response['appointment'] = appointment_list624    return HttpResponse(json.dumps(response), content_type="application/json")625@login_required626def export_appointments(request):627    """ Export Appointments by Availability/Booked """628    default_process_type = ['TAG', 'SHOPPING', 'WPP']629    process_types = RegalixTeams.objects.exclude(process_type='MIGRATION').values_list('process_type',630                                                                                       flat=True).distinct().order_by()631    teams = RegalixTeams.objects.filter(process_type__in=process_types).exclude(team_name='default team')632    default_teams = RegalixTeams.objects.filter(process_type__in=default_process_type, is_active=True).exclude(633        team_name='default team')634    tag_by_team = dict()635    for team in teams:636        rec = {637            'name': str(team.team_name),638            'id': str(team.id)639        }640        if team.process_type not in tag_by_team:641            tag_by_team[str(team.process_type)] = [rec]642        else:643            tag_by_team[str(team.process_type)].append(rec)644    post_result_dict = {}645    if request.method == 'POST':646        from_date = request.POST.get('date_from')647        to_date = request.POST.get('date_to')648        process_type = request.POST.getlist('selectedProcessType')649        regalix_team = request.POST.getlist('selectedTeams')650        from_date = datetime.strptime(from_date, "%d/%m/%Y %H:%M")651        to_date = datetime.strptime(to_date, "%d/%m/%Y %H:%M")652        to_date = datetime(to_date.year, to_date.month, to_date.day, to_date.hour, to_date.minute, 59)653        time_zone = 'IST'654        selected_tzone = Timezone.objects.get(zone_name=time_zone)655        from_utc_date = SalesforceApi.get_utc_date(from_date, selected_tzone.time_value)656        to_utc_date = SalesforceApi.get_utc_date(to_date, selected_tzone.time_value)657        diff = divmod((from_utc_date - from_date).total_seconds(), 60)658        diff_in_minutes = diff[0]659        regalix_teams = RegalixTeams.objects.filter(id__in=regalix_team)660        post_result_dict = {process: [] for process in process_type}661        for team in regalix_teams:662            if team.process_type in post_result_dict:663                post_result_dict[team.process_type].append(int(team.id))664        collumn_attr = ['Hours', 'Team']665        s_date = from_date666        while True:667            if s_date <= to_date:668                collumn_attr.append(datetime.strftime(s_date, "%d/%m/%Y"))669                s_date = s_date + timedelta(days=1)670            else:671                break672        total_result = list()673        for rglx_team in regalix_teams:674            team_name = rglx_team.team_name675            if team_name[0] == 'S':676                process_type = 'SHOPPING'677            elif team_name[0] == 'T':678                process_type = 'TAG'679            else:680                process_type = 'WPP'681            # get all appointments for selected dates in given range682            slots_data = Availability.objects.filter(683                date_in_utc__range=(from_utc_date, to_utc_date),684                team__id=rglx_team.id,685                team__process_type=process_type686            ).order_by('team')687            result = list()688            team_name = rglx_team.team_name689            for i in range(0, 24):690                for j in ['00', '30']:691                    mydict = {}692                    if len(str(i)) == 1:693                        indx = '0%s' % (i)694                    else:695                        indx = str(i)696                    hour = "%s:%s" % (indx, j)697                    for ele in collumn_attr:698                        if ele == 'Team':699                            mydict[ele] = team_name700                        elif ele == 'Hours':701                            mydict[ele] = hour702                        else:703                            mydict[ele] = '-'704                    result.append(mydict)705            total_appointments = dict()706            for slot in slots_data:707                # time zone conversion708                requested_date = slot.date_in_utc709                requested_date -= timedelta(minutes=diff_in_minutes)710                _date = datetime.strftime(requested_date, "%d/%m/%Y")711                _time = datetime.strftime(requested_date, "%H:%M")712                availability_count = slot.availability_count713                booked_count = slot.booked_count714                if _date in total_appointments:715                    total_appointments[_date]['booked_count'] += booked_count716                    total_appointments[_date]['availability_count'] += availability_count717                else:718                    total_appointments[_date] = {'booked_count': booked_count, 'availability_count': availability_count}719                val = "%s|%s" % (booked_count, availability_count)720                for rec in result:721                    if str(_time) in rec.values():722                        rec[_date] = val723            total_dict = dict()724            for ele in collumn_attr:725                if ele == 'Team':726                    total_dict[ele] = ''727                elif ele == 'Hours':728                    total_dict[ele] = 'Total'729                else:730                    total_dict[ele] = '-'731            for _date_ele in total_appointments:732                if _date_ele in total_dict:733                    total_dict[_date_ele] = "%s|%s" % (str(total_appointments[_date_ele]['booked_count']),734                                                       str(total_appointments[_date_ele]['availability_count']))735            total_result.extend(result)736            total_result.append(total_dict)737        filename = "appointments-%s-to-%s" % (738        datetime.strftime(from_date, "%d-%m-%Y"), datetime.strftime(to_date, "%d-%m-%Y"))739        path = write_appointments_to_csv(total_result, collumn_attr, filename)740        response = DownloadLeads.get_downloaded_file_response(path)741        return response742    return render(request, 'representatives/export_appointments.html', {'teams': teams,743                                                                        'default_teams': default_teams,744                                                                        'process_types': process_types,745                                                                        'default_process_type': default_process_type,746                                                                        'post_result_dict': json.dumps(747                                                                            post_result_dict),748                                                                        'tag_by_team': tag_by_team})749@login_required750def export_appointments_with_schedule_appointments(request):751    """ Export Appointments by Availability/Booked """752    default_process_type = ['TAG', 'SHOPPING', 'WPP']753    process_types = RegalixTeams.objects.exclude(process_type='MIGRATION').values_list('process_type',754                                                                                       flat=True).distinct().order_by()755    teams = RegalixTeams.objects.filter(process_type__in=process_types).exclude(team_name='default team')756    default_teams = RegalixTeams.objects.filter(process_type__in=default_process_type, is_active=True).exclude(757        team_name='default team')758    tag_by_team = dict()759    for team in teams:760        rec = {761            'name': str(team.team_name),762            'id': str(team.id)763        }764        if team.process_type not in tag_by_team:765            tag_by_team[str(team.process_type)] = [rec]766        else:767            tag_by_team[str(team.process_type)].append(rec)768    post_result_dict = {}769    if request.method == 'POST':770        from_date = request.POST.get('date_from')771        to_date = request.POST.get('date_to')772        process_type = request.POST.getlist('selectedProcessType')773        regalix_team = request.POST.getlist('selectedTeams')774        from_date = datetime.strptime(from_date, "%Y/%m/%d %H:%M")775        to_date = datetime.strptime(to_date, "%Y/%m/%d %H:%M")776        to_date = datetime(to_date.year, to_date.month, to_date.day, to_date.hour, to_date.minute, 59)777        time_zone = 'IST'778        selected_tzone = Timezone.objects.get(zone_name=time_zone)779        from_utc_date = SalesforceApi.get_utc_date(from_date, selected_tzone.time_value)780        to_utc_date = SalesforceApi.get_utc_date(to_date, selected_tzone.time_value)781        diff = divmod((from_utc_date - from_date).total_seconds(), 60)782        diff_in_minutes = diff[0]783        regalix_teams = RegalixTeams.objects.filter(id__in=regalix_team)784        post_result_dict = {process: [] for process in process_type}785        for team in regalix_teams:786            if team.process_type in post_result_dict:787                post_result_dict[team.process_type].append(int(team.id))788        collumn_attr = ['Hours', 'Team']789        s_date = from_date790        while True:791            if s_date <= to_date:792                collumn_attr.append((datetime.strftime(s_date, "%d/%m/%Y")) + ' Booked|Opened')793                collumn_attr.append((datetime.strftime(s_date, "%d/%m/%Y")) + ' Rescheduled')794                s_date = s_date + timedelta(days=1)795            else:796                break797        total_result = list()798        for rglx_team in regalix_teams:799            team_name = rglx_team.team_name800            if team_name[0] == 'S':801                process_type = 'SHOPPING'802            elif team_name[0] == 'T':803                process_type = 'TAG'804            else:805                process_type = 'WPP'806            # get all appointments for selected dates in given range807            if process_type == 'SHOPPING':808                schedule_data = Leads.objects.exclude(rescheduled_appointment_in_ist=None).filter(809                    rescheduled_appointment_in_ist__range=(from_date, to_date),810                    country__in=rglx_team.location.values_list('location_name'),811                    type_1__in=['Google Shopping Setup', 'Existing Datafeed Optimization',812                                'Google Shopping Migration']).values('rescheduled_appointment_in_ist').annotate(813                    dcount=Count('rescheduled_appointment_in_ist'))814            elif process_type == 'TAG':815                schedule_data = Leads.objects.exclude(rescheduled_appointment_in_ist=None)816                schedule_data = schedule_data.exclude(817                    type_1__in=['Google Shopping Setup', 'Existing Datafeed Optimization',818                                'Google Shopping Migration']).filter(819                    rescheduled_appointment_in_ist__range=(from_date, to_date),820                    country__in=rglx_team.location.values_list('location_name')).values(821                    'rescheduled_appointment_in_ist').annotate(dcount=Count('rescheduled_appointment_in_ist'))822            else:823                schedule_data = WPPLeads.objects.exclude(rescheduled_appointment_in_ist=None).filter(824                    rescheduled_appointment_in_ist__range=(from_date, to_date),825                    country__in=rglx_team.location.values_list('location_name')).values(826                    'rescheduled_appointment_in_ist').annotate(dcount=Count('rescheduled_appointment_in_ist'))827            slots_data = Availability.objects.filter(828                date_in_utc__range=(from_utc_date, to_utc_date),829                team__id=rglx_team.id,830                team__process_type=process_type831            ).order_by('team')832            result = list()833            team_name = rglx_team.team_name834            for i in range(0, 24):835                for j in range(0, 60):836                    mydict = {}837                    if len(str(i)) == 1:838                        indx = '0%s' % (i)839                    else:840                        indx = str(i)841                    if len(str(j)) == 1:842                        j = '0%s' % (j)843                    else:844                        j = str(j)845                    hour = "%s:%s" % (indx, j)846                    for ele in collumn_attr:847                        if ele == 'Team':848                            mydict[ele] = team_name849                        elif ele == 'Hours':850                            mydict[ele] = hour851                        else:852                            mydict[ele] = '-'853                    result.append(mydict)854            total_appointments = dict()855            for data in schedule_data:856                requested_date = data.get('rescheduled_appointment_in_ist')857                _date = (datetime.strftime(requested_date, "%d/%m/%Y") + ' Rescheduled')858                _time = datetime.strftime(requested_date, "%H:%M")859                booked_count = data.get('dcount')860                if _date in total_appointments:861                    total_appointments[_date]['booked_count'] += booked_count862                else:863                    total_appointments[_date] = {'booked_count': booked_count}864                val = "%s" % (booked_count)865                for rec in result:866                    if str(_time) in rec.values():867                        rec[_date] = val868            total_schedule = dict()869            for slot in slots_data:870                # time zone conversion871                requested_date = slot.date_in_utc872                requested_date -= timedelta(minutes=diff_in_minutes)873                _date = (datetime.strftime(requested_date, "%d/%m/%Y") + ' Booked|Opened')874                _time = datetime.strftime(requested_date, "%H:%M")875                availability_count = slot.availability_count876                booked_count = slot.booked_count877                if _date in total_schedule:878                    total_schedule[_date]['booked_count'] += booked_count879                    total_schedule[_date]['availability_count'] += availability_count880                else:881                    total_schedule[_date] = {'booked_count': booked_count, 'availability_count': availability_count}882                val = "%s|%s" % (booked_count, availability_count)883                for rec in result:884                    if str(_time) in rec.values():885                        rec[_date] = val886            total_dict = dict()887            for ele in collumn_attr:888                if ele == 'Team':889                    total_dict[ele] = ''890                elif ele == 'Hours':891                    total_dict[ele] = 'Total'892                else:893                    total_dict[ele] = '-'894            for _date_ele in total_schedule:895                if _date_ele in total_dict:896                    total_dict[_date_ele] = "%s|%s" % (str(total_schedule[_date_ele]['booked_count']),897                                                       str(total_schedule[_date_ele]['availability_count']))898            for _date_ele in total_appointments:899                if _date_ele in total_dict:900                    total_dict[_date_ele] = "%s" % (str(total_appointments[_date_ele]['booked_count']))901            total_result.extend(result)902            total_result.append(total_dict)903        # remove empty records from total_result904        filter_result = list()905        for each_result in total_result:906            count = 0907            for key, value in each_result.iteritems():908                if each_result[key] == '-':909                    count += 1910                if count == (len(collumn_attr) - 2):911                    filter_result.append(each_result)912        for each_result in filter_result:913            if each_result in total_result:914                total_result.remove(each_result)915        filename = "appointments-%s-to-%s" % (916        datetime.strftime(from_date, "%d-%m-%Y"), datetime.strftime(to_date, "%d-%m-%Y"))917        path = write_appointments_to_csv(total_result, collumn_attr, filename)918        response = DownloadLeads.get_downloaded_file_response(path)919        return response920    return render(request, 'representatives/export_appointments_with_schedule_appointments.html', {'teams': teams,921                                                                                                   'default_teams': default_teams,922                                                                                                   'process_types': process_types,923                                                                                                   'default_process_type': default_process_type,924                                                                                                   'post_result_dict': json.dumps(925                                                                                                       post_result_dict),926                                                                                                   'tag_by_team': tag_by_team})927def write_appointments_to_csv(result, collumn_attr, filename):928    path = "/tmp/%s.csv" % (filename)929    DownloadLeads.conver_to_csv(path, result, collumn_attr)930    return path931def get_created_or_updated_slot_details(team, _date, selected_tzone, prev_available_cnt, updated_cnt):932    slot = {}933    ist_date = SalesforceApi.convert_utc_to_timezone(_date, selected_tzone.time_value)934    date_time = datetime.strftime(ist_date, '%b %d, %Y-%I:%M %p').split('-')935    _date, _time = date_time[0], date_time[1]936    slot['team'] = team937    slot['date'] = _date938    slot['time'] = _time939    slot['date_time'] = datetime.strftime(ist_date, '%Y-%m-%d %I:%M %p')940    slot['prev_available_cnt'] = int(prev_available_cnt)941    slot['updated_cnt'] = updated_cnt942    return slot943def mail_slot_changes(request, selected_team, changed_records):944    if request.POST.get('process_type') != 'WPP':945        signature = 'Tag Team'946    else:947        signature = 'WPP Team'948    mail_body = get_template('representatives/slot_changes_mail.html').render(949        Context({950            'records': changed_records,951            'team': selected_team,952            'signature': signature953        })954    )955    mail_subject = "Hey!!! %s, %s Booked %s Appointment Slot" % (956        request.user.first_name, request.user.last_name, selected_team.team_name)957    team_lead = [str(leader.email) for leader in selected_team.team_lead.all()]958    team_manager = [str(manager.email) for manager in selected_team.team_manager.all()]959    email_list = team_lead + team_manager960    mail_to = set(961        email_list962    )963    bcc = set([])964    mail_from = 'google@regalix-inc.com'965    attachments = list()966    send_mail(mail_subject, mail_body, mail_from, mail_to, list(bcc), attachments, template_added=True)967@login_required968def total_appointments(request, plan_month=0, plan_day=0, plan_year=0):969    """ Manage scheduling appointments"""970    default_process_type = ['TAG', 'SHOPPING', 'WPP']971    process_type = ['TAG', 'SHOPPING', 'WPP']972    exclude_types = ['MIGRATION']973    if request.user.groups.filter(name='OPERATIONS'):974        if not request.user.groups.filter(Q(name='WPP') | Q(name='TAG-AND-WPP')):975            exclude_types.append('WPP')976        teams = RegalixTeams.objects.filter(process_type__in=process_type, is_active=True).exclude(977            team_name='default team')978        process_types = RegalixTeams.objects.exclude(process_type__in=exclude_types).values_list('process_type',979                                                                                                 flat=True).distinct().order_by()980    else:981        process_types = RegalixTeams.objects.exclude(982            process_type='MIGRATION').filter(Q(team_lead__in=[request.user.id]) | Q(team_manager__in=[request.user.id]),983                                             is_active=True).values_list('process_type',984                                                                         flat=True).distinct().order_by()985        teams = RegalixTeams.objects.filter(Q(team_lead__in=[request.user.id]) | Q(team_manager__in=[request.user.id]),986                                            process_type__in=process_types, is_active=True).exclude(987            team_name='default team').distinct().order_by()988    if not teams:989        # if team is not specified, select first team by default990        return render(991            request,992            'representatives/total_appointments.html',993            {'error': True,994             'message': "No Teams"995             }996        )997    teams_dict = RegalixTeams.objects.filter(process_type__in=process_type, is_active=True).exclude(998        team_name='default team')999    name_id_dict = {team.id: team.team_name for team in teams_dict}1000    team_ids = RegalixTeams.objects.filter(process_type__in=process_type, is_active=True).exclude(1001        team_name='default team').values('id')1002    time_zone = 'IST'1003    post_result_dict = {}1004    if request.method == 'POST':1005        if 'prev_week_start_date' in request.POST:1006            team_ids = request.POST.get('prevselectedTeams')1007            process_type = request.POST.get('prevselectedProcessType')1008            team_ids = team_ids.split(',')1009            process_type = process_type.split(',')1010            week_start_date = datetime.strptime(str(request.POST.get('prev_week_start_date')), '%m-%d-%Y')1011            plan_year, plan_month, plan_day = week_start_date.year, week_start_date.month, week_start_date.day1012        elif 'next_week_start_date' in request.POST:1013            team_ids = request.POST.get('nextselectedTeams')1014            process_type = request.POST.get('nextselectedProcessType')1015            team_ids = team_ids.split(',')1016            process_type = process_type.split(',')1017            week_start_date = datetime.strptime(str(request.POST.get('next_week_start_date')), '%m-%d-%Y')1018            plan_year, plan_month, plan_day = week_start_date.year, week_start_date.month, week_start_date.day1019        else:1020            team_ids = request.POST.getlist('selectedTeams')1021            process_type = request.POST.getlist('selectedProcessType')1022            week_start_date = datetime.strptime(str(request.POST.get('schedule_week_start_date')), '%m-%d-%Y')1023            plan_year, plan_month, plan_day = week_start_date.year, week_start_date.month, week_start_date.day1024        selected_teams = RegalixTeams.objects.filter(id__in=team_ids)1025        post_result_dict = {process: [] for process in process_type}1026        for team in selected_teams:1027            if team.process_type in post_result_dict:1028                post_result_dict[team.process_type].append(int(team.id))1029    teams = RegalixTeams.objects.filter(process_type__in=process_type, is_active=True).exclude(team_name='default team')1030    default_teams = RegalixTeams.objects.filter(process_type__in=default_process_type, is_active=True).exclude(1031        team_name='default team')1032    process_types = RegalixTeams.objects.exclude(process_type__in=exclude_types).values_list('process_type',1033                                                                                             flat=True).distinct().order_by()1034    if not int(plan_month):1035        # if month is not specified, select current month1036        today = datetime.today()1037        plan_month = today.month1038        return redirect(1039            'representatives.views.total_appointments',1040            plan_month=plan_month,1041            plan_day=plan_day,1042            plan_year=plan_year,1043            # process_type=process_type,1044            # team_id=team_id1045        )1046    if not int(plan_day):1047        # if day is not specified, select today's day1048        today = datetime.today()1049        plan_day = today.day1050        return redirect(1051            'representatives.views.total_appointments',1052            plan_month=plan_month,1053            plan_day=plan_day,1054            plan_year=plan_year,1055            # process_type=process_type,1056            # team_id=team_id1057        )1058    if not int(plan_year):1059        # if year is not specified, select current year1060        today = datetime.today()1061        plan_year = today.year1062        return redirect(1063            'representatives.views.total_appointments',1064            plan_month=plan_month,1065            plan_day=plan_day,1066            plan_year=plan_year,1067            # process_type=process_type,1068            # team_id=team_id1069        )1070    # create date from week start day1071    plan_date = datetime(int(plan_year), int(plan_month), int(plan_day))1072    plan_date += timedelta(hours=5, minutes=30)1073    # if week start day is not monday, select appropriate start week day of given date1074    if plan_date.weekday():1075        plan_date -= timedelta(days=plan_date.weekday())1076        return redirect(1077            'representatives.views.total_appointments',1078            plan_month=plan_date.month,1079            plan_day=plan_date.day,1080            plan_year=plan_date.year,1081            # process_type=process_type,1082            # team_id=team_id1083        )1084    # prepare slot dates to display1085    plan_dates = {1086        'day1': plan_date,1087        'day2': plan_date + timedelta(days=1),1088        'day3': plan_date + timedelta(days=2),1089        'day4': plan_date + timedelta(days=3),1090        'day5': plan_date + timedelta(days=4),1091        'day6': plan_date + timedelta(days=5)1092    }1093    # compute next week and previous week start dates1094    prev_week = plan_date + timedelta(days=-7)1095    next_week = plan_date + timedelta(days=7)1096    tzone = Timezone.objects.get(zone_name=time_zone)1097    utc_date = SalesforceApi.get_utc_date(plan_date, tzone.time_value)1098    utc_start_date = utc_date1099    utc_end_date = utc_start_date + timedelta(days=6)1100    process = json.dumps(process_type)1101    selected_teams = RegalixTeams.objects.filter(id__in=team_ids)1102    result_dict = {process: [] for process in process_type}1103    for team in selected_teams:1104        if team.process_type in result_dict:1105            result_dict[team.process_type].append(int(team.id))1106    appointments_list = Availability.objects.filter(1107        date_in_utc__range=(utc_start_date, utc_end_date),1108        team__in=selected_teams)1109    diff = divmod((utc_date - plan_date).total_seconds(), 60)1110    diff_in_minutes = diff[0]1111    total_booked = dict()1112    total_available = dict()1113    team_names = dict()1114    # prepare appointments slot keys1115    appointments = dict()1116    for key, _date in plan_dates.items():1117        total_booked[datetime.strftime(_date, '%Y_%m_%d')] = []1118        total_available[datetime.strftime(_date, '%Y_%m_%d')] = []1119        for hour in range(24):1120            # even hour slot1121            minutes = 01122            even_key = 'input_'  # input_16_6_2014_0_001123            even_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1124            even_key += '_'1125            even_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1126            even_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes) + '_' + 'cur'1127            appointments[even_key] = dict()1128            appointments[even_key]['value'] = 01129            appointments[even_key]['booked'] = 01130            appointments[even_key]['team_count'] = dict()1131            appointments[even_key]['team_booked'] = dict()1132            # odd hour slot1133            minutes = 301134            odd_key = 'input_'  # input_16_6_2014_0_001135            odd_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1136            odd_key += '_'1137            odd_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1138            odd_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes) + '_' + 'cur'1139            appointments[odd_key] = dict()1140            appointments[odd_key]['value'] = 01141            appointments[odd_key]['booked'] = 01142            appointments[odd_key]['team_count'] = dict()1143            appointments[odd_key]['team_booked'] = dict()1144        # Here for North Americs am creating key_next day slots to show under sameday1145        for hour in range(0, 8):1146            minutes = 01147            even_key = 'input_'  # input_16_6_2014_0_001148            even_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1149            even_key += '_'1150            even_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1151            even_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes) + '_' + 'next'1152            appointments[even_key] = dict()1153            appointments[even_key]['value'] = 01154            appointments[even_key]['booked'] = 01155            appointments[even_key]['team_count'] = dict()1156            appointments[even_key]['team_booked'] = dict()1157            # odd hour slot1158            minutes = 301159            odd_key = 'input_'  # input_16_6_2014_0_001160            odd_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1161            odd_key += '_'1162            odd_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1163            odd_key += '_' + str(_date.year) + '_' + str(hour) + '_' + str(minutes) + '_' + 'next'1164            appointments[odd_key] = dict()1165            appointments[odd_key]['value'] = 01166            appointments[odd_key]['booked'] = 01167            appointments[odd_key]['team_count'] = dict()1168            appointments[odd_key]['team_booked'] = dict()1169    north_teams = ['TAG - SPLATAM - Spanish', 'TAG - SPLATAM - Portuguese', 'TAG - NA - Spanish', 'TAG - NA - English',1170                   'SHOPPING - SPLATAM - Spanish', 'SHOPPING - SPLATAM - Portuguese', 'SHOPPING - NA - English']1171    for apptmnt in appointments_list:1172        if name_id_dict[apptmnt.team_id] in north_teams and apptmnt.availability_count:1173            apptmnt.date_in_utc -= timedelta(minutes=diff_in_minutes)1174            if int(apptmnt.date_in_utc.hour) < 12:1175                apptmnt.date_in_utc -= timedelta(days=1)1176                key = 'input_' + datetime.strftime(apptmnt.date_in_utc, '%d_%m_%Y') + \1177                      '_' + str(apptmnt.date_in_utc.hour) + '_' + str(apptmnt.date_in_utc.minute) + '_' + 'next'1178            else:1179                key = 'input_' + datetime.strftime(apptmnt.date_in_utc, '%d_%m_%Y') + \1180                      '_' + str(apptmnt.date_in_utc.hour) + '_' + str(apptmnt.date_in_utc.minute) + '_' + 'cur'1181        else:1182            apptmnt.date_in_utc -= timedelta(minutes=diff_in_minutes)1183            key = 'input_' + datetime.strftime(apptmnt.date_in_utc, '%d_%m_%Y') + \1184                  '_' + str(apptmnt.date_in_utc.hour) + '_' + str(apptmnt.date_in_utc.minute) + '_' + 'cur'1185        if key in appointments:1186            team_name = str(apptmnt.team.team_name)1187            booked_count = int(apptmnt.booked_count)1188            available_count = int(apptmnt.availability_count)1189            appointments[key]['value'] += available_count1190            appointments[key]['booked'] += booked_count1191            appointments[key]['team_count'].update({team_name: '%s' % (available_count)})1192            if booked_count != 0L:1193                appointments[key]['team_booked'].update({team_name: '%s' % (booked_count)})1194                # Grouping all team with booked count1195                striped_time = datetime.strftime(apptmnt.date_in_utc, '%Y_%m_%d')1196                tn_dict = team_names.get(striped_time)1197                if tn_dict:1198                    tm_count = tn_dict.get(team_name, None)1199                    if tm_count:1200                        tn_dict[team_name] = tm_count + booked_count1201                    else:1202                        tn_dict[team_name] = booked_count1203                else:1204                    team_names[striped_time] = {team_name: booked_count}1205            total_available[datetime.strftime(apptmnt.date_in_utc, '%Y_%m_%d')].append(available_count)1206            total_booked[datetime.strftime(apptmnt.date_in_utc, '%Y_%m_%d')].append(booked_count)1207    total_slots = list()1208    for key, value in sorted(total_available.iteritems()):1209        if team_names.get(key) == None:1210            team_count = 01211        else:1212            team_count = team_names.get(key)1213        total_slots.append({'available': sum(value), 'booked': sum(total_booked[key]), 'team_counts': team_count})1214    # Without appointment total lead count, code start from here1215    plan_dates_without_appointment = {1216        'day1': plan_date,1217        'day2': plan_date + timedelta(days=1),1218        'day3': plan_date + timedelta(days=2),1219        'day4': plan_date + timedelta(days=3),1220        'day5': plan_date + timedelta(days=4),1221        'day6': plan_date + timedelta(days=5)1222    }1223    without_appointmnet_total_list = list()1224    rlsa_total_count = list()1225    for day_key, date_value in sorted(plan_dates_without_appointment.items()):1226        from_day = date_value.replace(hour=00, minute=00, second=00)1227        to_date = date_value.replace(hour=23, minute=59, second=59)1228        time_zone = 'IST'1229        selected_tzone = Timezone.objects.get(zone_name=time_zone)1230        from_day = SalesforceApi.get_utc_date(from_day, selected_tzone.time_value)1231        to_date = SalesforceApi.get_utc_date(to_date, selected_tzone.time_value)1232        all_active_teams = RegalixTeams.objects.filter(is_active=True)1233        all_active_team_country = all_active_teams.values_list('location__location_name')1234        all_without_appointment_active_country = ["%s" % data for data in all_active_team_country]1235        total_leads_without_appointmnet = Leads.objects.exclude(appointment_date__isnull=False) \1236            .filter(created_date__range=[from_day, to_date], country__in=all_without_appointment_active_country)1237        total_leads_without_appointmnet_count = total_leads_without_appointmnet.exclude(1238            type_1__in=['RLSA Bulk Implementation']).count()1239        try:1240            without_appointmnet_total_list.append({'total': total_leads_without_appointmnet_count})1241        except:1242            without_appointmnet_total_list.append({'total': 'error'})1243        # RLSA count without appointment1244        rlsa_total_leads = Leads.objects. \1245            filter(created_date__range=[from_day, to_date], country__in=all_without_appointment_active_country)1246        rlsa_total_leads_count = rlsa_total_leads.filter(type_1__in=['RLSA Bulk Implementation']).count()1247        try:1248            rlsa_total_count.append({'total_rlsa': rlsa_total_leads_count})1249        except:1250            rlsa_total_count.append({'total_rlsa': 'error'})1251    if request.method == 'POST':1252        if 'prev_week_start_date' in request.POST:1253            team_ids = request.POST.get('prevselectedTeams')1254            process_type = request.POST.get('prevselectedProcessType')1255            team_ids = team_ids.split(',')1256            process_type = process_type.split(',')1257        elif 'next_week_start_date' in request.POST:1258            team_ids = request.POST.get('nextselectedTeams')1259            process_type = request.POST.get('nextselectedProcessType')1260            team_ids = team_ids.split(',')1261            process_type = process_type.split(',')1262        else:1263            team_ids = request.POST.getlist('selectedTeams')1264            process_type = request.POST.getlist('selectedProcessType')1265        without_appointmnet_list = list()1266        shopping_leads_without_appointmnet_count = 01267        tag_leads_without_appointment_count = 01268        tag_total = list()1269        shopp_total = list()1270        wpp_total = list()1271        for process in process_type:1272            if process == "TAG":1273                for day_key, date_value in sorted(plan_dates_without_appointment.items()):1274                    from_day = date_value.replace(hour=00, minute=00, second=00)1275                    to_date = date_value.replace(hour=23, minute=59, second=59)1276                    time_zone = 'IST'1277                    selected_tzone = Timezone.objects.get(zone_name=time_zone)1278                    from_day = SalesforceApi.get_utc_date(from_day, selected_tzone.time_value)1279                    to_date = SalesforceApi.get_utc_date(to_date, selected_tzone.time_value)1280                    without_appointment_selected_teams = RegalixTeams.objects.filter(id__in=team_ids,1281                                                                                     process_type__in=process_type,1282                                                                                     is_active=True, )1283                    without_appointment_selected_country = without_appointment_selected_teams.values_list(1284                        'location__location_name')1285                    without_appointment_selected_country = ["%s" % data for data in1286                                                            without_appointment_selected_country]1287                    tag_leads_without_appointment = Leads.objects.filter(created_date__range=[from_day, to_date],1288                                                                         country__in=without_appointment_selected_country)1289                    tag_leads_without_appointment = tag_leads_without_appointment.exclude \1290                        (type_1__in=['Google Shopping Setup', 'Project Argos- Feed Performance Optimization',1291                                     'Existing Datafeed Optimization', 'Google Shopping Migration',1292                                     'RLSA Bulk Implementation'])1293                    tag_leads_without_appointment = tag_leads_without_appointment.exclude(1294                        appointment_date__isnull=False)1295                    tag_leads_without_appointment_count = tag_leads_without_appointment.count()1296                    tag_total.append(tag_leads_without_appointment_count)1297            elif process == "SHOPPING":1298                for day_key, date_value in sorted(plan_dates_without_appointment.items()):1299                    from_day = date_value.replace(hour=00, minute=00, second=00)1300                    to_date = date_value.replace(hour=23, minute=59, second=59)1301                    time_zone = 'IST'1302                    selected_tzone = Timezone.objects.get(zone_name=time_zone)1303                    from_day = SalesforceApi.get_utc_date(from_day, selected_tzone.time_value)1304                    to_date = SalesforceApi.get_utc_date(to_date, selected_tzone.time_value)1305                    without_appointment_selected_teams = RegalixTeams.objects.filter(id__in=team_ids,1306                                                                                     process_type__in=process_type,1307                                                                                     is_active=True, )1308                    without_appointment_selected_country = without_appointment_selected_teams.values_list(1309                        'location__location_name')1310                    without_appointment_selected_country = ["%s" % data for data in1311                                                            without_appointment_selected_country]1312                    shopping_leads_without_appointmnet = Leads.objects.filter(created_date__range=[from_day, to_date], \1313                                                                              type_1__in=['Google Shopping Setup',1314                                                                                          'Project Argos- Feed Performance Optimization',1315                                                                                          'Existing Datafeed Optimization', ],1316                                                                              country__in=without_appointment_selected_country)1317                    shopping_leads_without_appointmnet_count = shopping_leads_without_appointmnet.exclude(1318                        appointment_date__isnull=False).count()1319                    shopp_total.append(shopping_leads_without_appointmnet_count)1320            elif process == "WPP":1321                for day_key, date_value in sorted(plan_dates_without_appointment.items()):1322                    wpp_total.append(0)1323        without_appointmnet_total_list = list()1324        if (len(tag_total) > 0) and (len(shopp_total) > 0):1325            for i in range(0, 6):1326                resulted_sum = tag_total[i] + shopp_total[i]1327                without_appointmnet_total_list.append({'total': resulted_sum})1328        elif (len(tag_total) > 0) and len(shopp_total) == 0:1329            for each in tag_total:1330                without_appointmnet_total_list.append({'total': each})1331        elif (len(shopp_total) > 0) and (len(tag_total) == 0):1332            for each in shopp_total:1333                without_appointmnet_total_list.append({'total': each})1334        elif (len(wpp_total) > 0) and (len(tag_total) == 0) and (len(shopp_total) == 0):1335            for each in wpp_total:1336                without_appointmnet_total_list.append({'total': 'NA'})1337        else:1338            without_appointmnet_total_list.append({'total': 'error'})1339    return render(1340        request,1341        'representatives/total_appointments.html',1342        {'schedule_date': plan_date,1343         'time_zone': time_zone,1344         'dates': plan_dates,1345         'appointments': appointments,1346         'prev_week': prev_week,1347         'next_week': next_week,1348         'default_teams': default_teams,1349         'teams': teams,1350         'plan_month': plan_month,1351         'plan_day': plan_day,1352         'plan_year': plan_year,1353         'process_type': process_type,1354         'process_types': process_types,1355         'total_slots': total_slots,1356         'without_appointmnet_list': without_appointmnet_total_list,1357         'rlsa_total_count': rlsa_total_count,1358         'result_dict': json.dumps(result_dict),1359         'process': process,1360         'default_process_type': default_process_type,1361         'post_result_dict': json.dumps(post_result_dict),1362         }1363    )1364@login_required1365def appointments_calendar(request):1366    from leads.models import Leads1367    from django.db.models import Count1368    total_events = list()1369    leads_dict = Leads.objects.exclude(rescheduled_appointment_in_ist=None).values('rescheduled_appointment_in_ist',1370                                                                                   'customer_id').annotate(1371        count=Count('pk'))1372    for res_time in leads_dict:1373        if res_time['rescheduled_appointment_in_ist']:1374            res_dict = dict()1375            res_dict['title'] = ' CID - %s, Total Resch - %s' % (str(res_time['customer_id']), res_time['count'])1376            res_dict['start'] = datetime.strftime(res_time['rescheduled_appointment_in_ist'], "%Y-%m-%dT%H:%M:%S")1377            res_dict['end'] = datetime.strftime(res_time['rescheduled_appointment_in_ist'] + timedelta(minutes=20),1378                                                "%Y-%m-%dT%H:%M:%S")1379            total_events.append(res_dict)1380    return render(request, 'representatives/appointments_calendar.html', {'events': total_events})1381# Picasso TAT details1382@login_required1383def tat_details(request, plan_month=0, plan_day=0, plan_year=0):1384    """ Manage scheduling appointments"""1385    if not int(plan_month):1386        # if month is not specified, select current month1387        today = datetime.today()1388        plan_month = today.month1389        return redirect(1390            'representatives.views.tat_details',1391            plan_month=plan_month,1392            plan_day=plan_day,1393            plan_year=plan_year,1394        )1395    if not int(plan_day):1396        # if day is not specified, select today's day1397        today = datetime.today()1398        plan_day = today.day1399        return redirect(1400            'representatives.views.tat_details',1401            plan_month=plan_month,1402            plan_day=plan_day,1403            plan_year=plan_year,1404        )1405    if not int(plan_year):1406        # if year is not specified, select current year1407        today = datetime.today()1408        plan_year = today.year1409        return redirect(1410            'representatives.views.tat_details',1411            plan_month=plan_month,1412            plan_day=plan_day,1413            plan_year=plan_year,1414        )1415    # create date from week start day1416    plan_date = datetime(int(plan_year), int(plan_month), int(plan_day))1417    plan_date += timedelta(hours=5, minutes=30)1418    # if week start day is not monday, select appropriate start week day of given date1419    if plan_date.weekday():1420        plan_date -= timedelta(days=plan_date.weekday())1421        return redirect(1422            'representatives.views.tat_details',1423            plan_month=plan_date.month,1424            plan_day=plan_date.day,1425            plan_year=plan_date.year,1426        )1427    if request.method == 'POST':1428        # time_zone = 'IST'1429        # selected_tzone = Timezone.objects.get(zone_name=time_zone)1430        for key, value in request.POST.items():1431            if key.startswith('input'):1432                data_in_a_day = int(request.POST.get(key) or 0)1433                keys = key.split('_')  # input_16_6_2014_0_0 / input_16_6_2014_0_301434                slot_day = int(keys[1])1435                slot_month = int(keys[2])1436                slot_year = int(keys[3])1437                slot_type = keys[4]1438                slot_date = datetime(slot_year, slot_month, slot_day)1439                # utc_date = SalesforceApi.get_utc_date(slot_date, selected_tzone.time_value)1440                if slot_type == 'count':1441                    emp_count = int(data_in_a_day)1442                    try:1443                        tat_record = AvailabilityForTAT.objects.get(date_in_ist=slot_date)1444                        tat_record.availability_count = emp_count1445                        tat_record.save()1446                    except ObjectDoesNotExist:1447                        tat_record = AvailabilityForTAT(date_in_ist=slot_date, availability_count=emp_count)1448                        tat_record.save()1449                else:1450                    audits_per_day = int(data_in_a_day)1451                    try:1452                        tat_record = AvailabilityForTAT.objects.get(date_in_ist=slot_date)1453                        tat_record.audits_per_date = audits_per_day1454                        tat_record.save()1455                    except ObjectDoesNotExist:1456                        tat_record = AvailabilityForTAT(date_in_ist=slot_date, audits_per_date=audits_per_day)1457                        tat_record.save()1458    plan_dates = OrderedDict()1459    for i in range(1, 6):1460        plan_dates['day' + str(i)] = plan_date + timedelta(i - 1)1461    counts_list = list()1462    for key, _date in plan_dates.items():1463        mydict = dict()1464        count_key = 'input_'1465        count_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1466        count_key += '_'1467        count_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1468        count_key += '_' + str(_date.year)1469        mydict['input'] = count_key1470        mydict['count'] = 11471        mydict['audit'] = 31472        counts_list.append(mydict)1473    week_start = plan_date1474    week_end = plan_date + timedelta(4)1475    details = AvailabilityForTAT.objects.filter(date_in_ist__gte=week_start, date_in_ist__lte=week_end).order_by(1476        'date_in_ist')1477    for detail in details:1478        _date = detail.date_in_ist1479        count_key = 'input_'1480        count_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1481        count_key += '_'1482        count_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1483        count_key += '_' + str(_date.year)1484        for each_dict in counts_list:1485            if each_dict['input'] == count_key:1486                each_dict['count'] = detail.availability_count1487                each_dict['audit'] = detail.audits_per_date1488    # compute next week and previous week start dates1489    prev_week = plan_date + timedelta(days=-6)1490    next_week = plan_date + timedelta(days=8)1491    return render(1492        request,1493        'representatives/tat_details.html',1494        {'schedule_date': plan_date,1495         'dates': plan_dates,1496         'prev_week': prev_week,1497         'next_week': next_week,1498         'plan_month': plan_month,1499         'plan_day': plan_day,1500         'plan_year': plan_year,1501         'counts_dict': counts_list,1502         'picasso': True,1503         }1504    )1505# BOLT TAT details view1506@login_required1507def bolt_tat_details(request, plan_month=0, plan_day=0, plan_year=0):1508    """ Manage scheduling appointments"""1509    if not int(plan_month):1510        # if month is not specified, select current month1511        today = datetime.today()1512        plan_month = today.month1513        return redirect(1514            'representatives.views.bolt_tat_details',1515            plan_month=plan_month,1516            plan_day=plan_day,1517            plan_year=plan_year,1518        )1519    if not int(plan_day):1520        # if day is not specified, select today's day1521        today = datetime.today()1522        plan_day = today.day1523        return redirect(1524            'representatives.views.bolt_tat_details',1525            plan_month=plan_month,1526            plan_day=plan_day,1527            plan_year=plan_year,1528        )1529    if not int(plan_year):1530        # if year is not specified, select current year1531        today = datetime.today()1532        plan_year = today.year1533        return redirect(1534            'representatives.views.bolt_tat_details',1535            plan_month=plan_month,1536            plan_day=plan_day,1537            plan_year=plan_year,1538        )1539    # create date from week start day1540    plan_date = datetime(int(plan_year), int(plan_month), int(plan_day))1541    plan_date += timedelta(hours=5, minutes=30)1542    # if week start day is not monday, select appropriate start week day of given date1543    if plan_date.weekday():1544        plan_date -= timedelta(days=plan_date.weekday())1545        return redirect(1546            'representatives.views.bolt_tat_details',1547            plan_month=plan_date.month,1548            plan_day=plan_date.day,1549            plan_year=plan_date.year,1550        )1551    if request.method == 'POST':1552        # time_zone = 'IST'1553        # selected_tzone = Timezone.objects.get(zone_name=time_zone)1554        for key, value in request.POST.items():1555            if key.startswith('input'):1556                data_in_a_day = int(request.POST.get(key) or 0)1557                keys = key.split('_')  # input_16_6_2014_0_0 / input_16_6_2014_0_301558                slot_day = int(keys[1])1559                slot_month = int(keys[2])1560                slot_year = int(keys[3])1561                slot_type = keys[4]1562                slot_date = datetime(slot_year, slot_month, slot_day)1563                # utc_date = SalesforceApi.get_utc_date(slot_date, selected_tzone.time_value)1564                if slot_type == 'count':1565                    emp_count = int(data_in_a_day)1566                    try:1567                        tat_record = AvailabilityForBoltTAT.objects.get(date_in_ist=slot_date)1568                        tat_record.availability_count = emp_count1569                        tat_record.save()1570                    except ObjectDoesNotExist:1571                        tat_record = AvailabilityForBoltTAT(date_in_ist=slot_date, availability_count=emp_count)1572                        tat_record.save()1573                else:1574                    audits_per_day = int(data_in_a_day)1575                    try:1576                        tat_record = AvailabilityForBoltTAT.objects.get(date_in_ist=slot_date)1577                        tat_record.audits_per_date = audits_per_day1578                        tat_record.save()1579                    except ObjectDoesNotExist:1580                        tat_record = AvailabilityForBoltTAT(date_in_ist=slot_date, audits_per_date=audits_per_day)1581                        tat_record.save()1582    plan_dates = OrderedDict()1583    for i in range(1, 6):1584        plan_dates['day' + str(i)] = plan_date + timedelta(i - 1)1585    counts_list = list()1586    for key, _date in plan_dates.items():1587        mydict = dict()1588        count_key = 'input_'1589        count_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1590        count_key += '_'1591        count_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1592        count_key += '_' + str(_date.year)1593        mydict['input'] = count_key1594        mydict['count'] = 41595        mydict['audit'] = 41596        counts_list.append(mydict)1597    week_start = plan_date1598    week_end = plan_date + timedelta(4)1599    details = AvailabilityForBoltTAT.objects.filter(date_in_ist__gte=week_start, date_in_ist__lte=week_end).order_by(1600        'date_in_ist')1601    for detail in details:1602        _date = detail.date_in_ist1603        count_key = 'input_'1604        count_key += '0' + str(_date.day) if len(str(_date.day)) == 1 else str(_date.day)1605        count_key += '_'1606        count_key += '0' + str(_date.month) if len(str(_date.month)) == 1 else str(_date.month)1607        count_key += '_' + str(_date.year)1608        for each_dict in counts_list:1609            if each_dict['input'] == count_key:1610                each_dict['count'] = detail.availability_count1611                each_dict['audit'] = detail.audits_per_date1612    # compute next week and previous week start dates1613    prev_week = plan_date + timedelta(days=-6)1614    next_week = plan_date + timedelta(days=8)1615    return render(1616        request,1617        'representatives/bolt_tat_details.html',1618        {'schedule_date': plan_date,1619         'dates': plan_dates,1620         'prev_week': prev_week,1621         'next_week': next_week,1622         'plan_month': plan_month,1623         'plan_day': plan_day,1624         'plan_year': plan_year,1625         'counts_dict': counts_list,1626         'picasso': True,1627         }...cyber_launch
Source:cyber_launch  
1#!/usr/bin/python2# ****************************************************************************3# Copyright 2018 The Apollo Authors. All Rights Reserved.4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6#  You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15# ****************************************************************************16import signal17import sys18import logging19import os20import os.path21import subprocess22import time23import atexit24import argparse25import threading26import traceback27import xml.etree.ElementTree as ET28g_binary_name = 'mainboard'29g_pwd = os.getcwd()30g_script_name = os.path.basename(sys.argv[0]).split(".")[0]31g_process_pid = os.getpid()32g_process_name = g_script_name + "_" + str(g_process_pid)33cyber_path = os.getenv('CYBER_PATH')34"""35colorful logging36"""37BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)38RESET_SEQ = "\033[0m"39COLOR_SEQ = "\033[1;%dm"40BOLD_SEQ = "\033[1m"41COLORS = {42    'INFO':     GREEN,43    'WARNING':  YELLOW,44    'DEBUG':    BLUE,45    'ERROR':    RED,46    'CRITICAL': YELLOW47}48class ColoredFormatter(logging.Formatter):49    def __init__(self, msg):50        logging.Formatter.__init__(self, msg)51    def format(self, record):52        levelname = record.levelname53        if levelname in COLORS:54            if levelname == 'DEBUG':55                record.levelname = COLOR_SEQ % (30 + COLORS[levelname]) + \56                    record.msg.split('#')[0] + RESET_SEQ57                record.msg = COLOR_SEQ % (30 + COLORS[levelname]) + \58                    record.msg.split('#')[-1] + RESET_SEQ59            else:60                record.levelname = COLOR_SEQ % (30 + COLORS[levelname]) + \61                    g_process_name + RESET_SEQ62                record.msg = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + \63                    " " + record.msg.split('#')[-1] + RESET_SEQ64        return logging.Formatter.format(self, record)65color_formatter = ColoredFormatter("[%(levelname)-18s] %(message)s")66console = logging.StreamHandler()67console.setFormatter(color_formatter)68logger = logging.Logger(__name__)69logger.addHandler(console)70def exit_handler():71    stop()72    os.chdir(g_pwd)73    logger.info('cyber_launch exit.')74atexit.register(exit_handler)75def singleton(cls):76    instances = {}77    def getinstance(*args, **kwargs):78        if cls not in instances:79            instances[cls] = cls(*args, **kwargs)80        return instances[cls]81    return getinstance82def module_monitor(mod):83    while True:84        line = mod.popen.stdout.readline()85        if line:86            logger.debug('%s# %s' % (mod.name, line.strip('\n')))87            continue88        time.sleep(0.01)89class ProcessWrapper(object):90    def __init__(self, binary_path, dag_num, dag_list, process_name,91                 process_type, sched_name, exception_handler=''):92        self.time_of_death = None93        self.started = False94        self.binary_path = binary_path95        self.dag_num = dag_num96        self.dag_list = dag_list97        self.name = process_name98        self.sched_name = sched_name99        self.process_type = process_type100        self.popen = None101        self.exit_code = None102        self.args = []103        self.pid = -1104        self.exception_handler = exception_handler105    def wait(self):106        if self.started:107            self.popen.wait()108    def start(self):109        """110        Start a manager in process name111        """112        if self.process_type == 'binary':113            args_list = self.name.split()114        else:115            args_list = [self.binary_path, '-d'] + self.dag_list116            if len(self.name) != 0:117                args_list.append('-p')118                args_list.append(self.name)119            if len(self.sched_name) != 0:120                args_list.append('-s')121                args_list.append(self.sched_name)122        self.args = args_list123        try:124            self.popen = subprocess.Popen(args_list, stdout=subprocess.PIPE,125                                          stderr=subprocess.STDOUT)126        except Exception as err:127            logger.error('Subprocess Popen exception: ' + str(err))128            return 2129        else:130            if self.popen.pid == 0 or self.popen.returncode is not None:131                logger.error('Start process [%s] failed.' % self.name)132                return 2133        th = threading.Thread(target=module_monitor, args=(self, ))134        th.setDaemon(True)135        th.start()136        self.started = True137        self.pid = self.popen.pid138        logger.info('Start process [%s] successfully. pid: %d' %139                    (self.name, self.popen.pid))140        logger.info('-' * 120)141        return 0142    def is_alive(self):143        """144        Check the process if is still running145        @return: True if process is still running146        @rtype: bool147        """148        if not self.started:149            return False150        if self.popen is None:151            if self.time_of_death is None:152                self.time_of_death = time.time()153            return False154        self.exit_code = self.popen.poll()155        if self.exit_code is not None:156            if self.time_of_death is None:157                self.time_of_death = time.time()158            return False159        return True160    def get_exit_state(self):161        """162        @return: description of exit state163        @rtype: str164        """165        if self.popen.returncode is None:166            pass167        elif self.popen.returncode != 0:168            output = 'Process [%s] has died [pid %s, exit code %s, cmd %s].' % \169                     (self.name, self.pid, self.exit_code, ' '.join(self.args))170            logger.error(output)171        else:172            output = 'Process [%s] has finished. [pid %s, cmd %s].' % \173                     (self.name, self.pid, ' '.join(self.args))174            logger.error(output)175@singleton176class ProcessMonitor(object):177    def __init__(self):178        self.procs = []179        self.dead_cnt = 0180        self.done = False181        self.is_shutdown = False182    def register(self, p):183        """184        Register process with L{ProcessMonitor}185        @param p: Process186        @type  p: L{Process}187        """188        if self.has_process(p.name):189            logger.error(190                'Cannot add process due to duplicate name "%s".' % p.name)191        elif self.is_shutdown:192            logger.error(193                'Cannot add process [%s] due to monitor has been stopped.' % p.name)194        else:195            self.procs.append(p)196    def has_process(self, name):197        """198        @return: True if process is still be monitored. If False, process199        has died or was never registered with process200        @rtype: bool201        """202        return len([p for p in self.procs if p.name == name]) > 0203    def check_cleanup(self):204        """205        Check processes are alived, cleanup processes206        """207        dead_cnt = 0208        for pw in self.procs:209            if self.is_shutdown:210                break211            if pw.process_type == 'binary':212                continue213            try:214                if not pw.is_alive():215                    if pw.exception_handler == "respawn":216                        logger.warn(217                            'child process [%s][%d] exit, respawn!' % (pw.name, pw.pid))218                        result = pw.start()219                        if result != 0:220                            logger.error(221                                'respawn process [%s] failed, stop all!' % (pw.name))222                            stop()223                    elif pw.exception_handler == "exit":224                        logger.warn(225                            'child process [%s][%d] exit, stop all' % (pw.name, pw.pid))226                        stop()227                    dead_cnt += 1228            except Exception:229                dead_cnt += 1230                traceback.print_exc()231        if dead_cnt > 0:232            self.dead_cnt = dead_cnt233            if self.dead_cnt == len(self.procs):234                self.is_shutdown = True235    def run(self):236        """237        Run processes monitor, until all processes are died.238        """239        while not self.is_shutdown:240            self.check_cleanup()241            time.sleep(0.2)242        for p in self.procs:243            p.get_exit_state()244        if self.dead_cnt == len(self.procs):245            logger.info("All processes has died.")246            return True247        return False248    def stop(self, signal):249        """250        Stop all processes in monitor251        """252        for p in self.procs:253            if p.is_alive():254                p.popen.send_signal(signal)255        for p in self.procs:256            if p.is_alive():257                logger.warn('Waiting for [%s][%s] exit.' % (p.name, p.pid))258                p.wait()259                logger.info(260                    'Process [%s] has been stopped. dag_file: %s' % (p.name, p.dag_list))261        # Reset members262        self.procs = []263        self.dead_cnt = 0264def start(launch_file=''):265    """266    Start all modules in xml config267    """268    pmon = ProcessMonitor()269    # Find launch file270    if launch_file[0] == '/':271        launch_file = launch_file272    elif launch_file == os.path.basename(launch_file):273        launch_file = os.path.join(cyber_path, 'launch', launch_file)274    else:275        if os.path.exists(os.path.join(g_pwd, launch_file)):276            launch_file = os.path.join(g_pwd, launch_file)277        else:278            logger.error('Cannot find launch file: %s ' % launch_file)279            sys.exit(1)280    logger.info('Launch file [%s]' % launch_file)281    logger.info('=' * 120)282    if not os.path.isfile(launch_file):283        logger.error('Launch xml file %s does not exist' % launch_file)284        sys.exit(1)285    try:286        tree = ET.parse(launch_file)287    except Exception:288        logger.error('Parse xml failed. illegal xml!')289        sys.exit(1)290    total_dag_num = 0291    dictionary = {}292    dag_dict = {}293    root1 = tree.getroot()294    for module in root1.findall('module'):295        dag_conf = module.find('dag_conf').text296        process_name = module.find('process_name').text297        process_type = module.find('type')298        if process_type is None:299            process_type = 'library'300        else:301            process_type = process_type.text302            if process_type is None:303                process_type = 'library'304            process_type = process_type.strip()305        if process_type != 'binary':306            if dag_conf is None or not dag_conf.strip():307                logger.error('Library dag conf is null')308                continue309            if process_name is None:310                process_name = 'mainboard_default_' + str(os.getpid())311            process_name = process_name.strip()312            if dictionary.has_key(str(process_name)):313                dictionary[str(process_name)] += 1314            else:315                dictionary[str(process_name)] = 1316            if not dag_dict.has_key(str(process_name)):317                dag_dict[str(process_name)] = [str(dag_conf)]318            else:319                dag_dict[str(process_name)].append(str(dag_conf))320            if dag_conf is not None:321                total_dag_num += 1322    process_list = []323    root = tree.getroot()324    for env in root.findall('environment'):325        for var in env.getchildren():326            os.environ[var.tag] = str(var.text)327    for module in root.findall('module'):328        module_name = module.find('name').text329        dag_conf = module.find('dag_conf').text330        process_name = module.find('process_name').text331        sched_name = module.find('sched_name')332        process_type = module.find('type')333        exception_handler = module.find('exception_handler')334        if process_type is None:335            process_type = 'library'336        else:337            process_type = process_type.text338            if process_type is None:339                process_type = 'library'340            process_type = process_type.strip()341        if sched_name is None:342            sched_name = "CYBER_DEFAULT"343        else:344            sched_name = sched_name.text345        if process_name is None:346            process_name = 'mainboard_default_' + str(os.getpid())347        if dag_conf is None:348            dag_conf = ''349        if module_name is None:350            module_name = ''351        if exception_handler is None:352            exception_handler = ''353        else:354            exception_handler = exception_handler.text355        module_name = module_name.strip()356        dag_conf = dag_conf.strip()357        process_name = process_name.strip()358        sched_name = sched_name.strip()359        exception_handler = exception_handler.strip()360        logger.info('Load module [%s] %s: [%s] [%s] conf: [%s] exception_handler: [%s]' %361                    (module_name, process_type, process_name, sched_name, dag_conf,362                     exception_handler))363        if process_name not in process_list:364            if process_type == 'binary':365                if len(process_name) == 0:366                    logger.error(367                        'Start binary failed. Binary process_name is null.')368                    continue369                pw = ProcessWrapper(370                    process_name.split()[0], 0, [371                        ""], process_name, process_type,372                    exception_handler)373            # Default is library374            else:375                pw = ProcessWrapper(376                    g_binary_name, 0, dag_dict[377                        str(process_name)], process_name,378                    process_type, sched_name, exception_handler)379            result = pw.start()380            if result != 0:381                logger.error(382                    'Start manager [%s] failed. Stop all!' % process_name)383                stop()384            pmon.register(pw)385            process_list.append(process_name)386    # No module in xml387    if not process_list:388        logger.error("No module was found in xml config.")389        return390    all_died = pmon.run()391    if not all_died:392        logger.info("Stop all processes...")393        stop()394    logger.info("Cyber exit.")395def stop(sig=signal.SIGINT):396    """397    stop all modules398    """399    pmon = ProcessMonitor()400    if len(pmon.procs) == 0:401        return402    pmon.stop(sig)403    logger.info('All processes have been stopped.')404    sys.exit(0)405def stop_launch(launch_file):406    """407    Stop the launch file408    """409    if not launch_file:410        cmd = 'pkill -INT cyber_launch'411    else:412        cmd = 'pkill -INT -f ' + launch_file413    os.system(cmd)414    time.sleep(3)415    logger.info('Stop cyber launch finished.')416    sys.exit(0)417def signal_handler(sig, frame):418    logger.info('Keyboard interrupt received. Stop all processes.')419    stop(sig)420def main():421    """422    Main function423    """424    if cyber_path is None:425        logger.error(426            'Error: environment variable CYBER_PATH not found, set environment first.')427        sys.exit(1)428    os.chdir(cyber_path)429    parser = argparse.ArgumentParser(description='cyber launcher')430    subparsers = parser.add_subparsers(help='sub-command help')431    start_parser = subparsers.add_parser(432        'start', help='launch/benchmark.launch')433    start_parser.add_argument('file', nargs='?', action='store',434                              help='launch file, default is cyber.launch')435    stop_parser = subparsers.add_parser(436        'stop', help='stop all the module in launch file')437    stop_parser.add_argument('file', nargs='?', action='store',438                             help='launch file, default stop all the launcher')439    # restart_parser = subparsers.add_parser('restart', help='restart the module')440    # restart_parser.add_argument('file', nargs='?', action='store', help='launch file,441    #                            default is cyber.launch')442    params = parser.parse_args(sys.argv[1:])443    command = sys.argv[1]444    if command == 'start':445        start(params.file)446    elif command == 'stop':447        stop_launch(params.file)448    # elif command == 'restart':449    #    restart(params.file)450    else:451        logger.error('Invalid command %s' % command)452        sys.exit(1)453if __name__ == '__main__':454    signal.signal(signal.SIGINT, signal_handler)455    signal.signal(signal.SIGTERM, signal_handler)456    signal.signal(signal.SIGCHLD, signal.SIG_IGN)...system_memory.py
Source:system_memory.py  
1# Copyright 2014 The Chromium Authors. All rights reserved.2# Use of this source code is governed by a BSD-style license that can be3# found in the LICENSE file.4from metrics import memory5from metrics import Metric6from telemetry.value import scalar7class SystemMemoryMetric(Metric):8  """SystemMemoryMetric gathers system memory statistic.9  This metric collects system memory stats per test.  It reports the difference10  (delta) in system memory starts from the start of the test to the end of it.11  """12  def __init__(self, browser):13    super(SystemMemoryMetric, self).__init__()14    self._browser = browser15    self._memory_stats_start = None16    self._memory_stats_end = None17  def Start(self, page, tab):18    """Start the per-page preparation for this metric.19    Records the system memory stats at this point.20    """21    self._memory_stats_start = self._browser.memory_stats22  def Stop(self, page, tab):23    """Prepare the results for this page.24    The results are the differences between the current system memory stats25    and the values when Start() was called.26    """27    assert self._memory_stats_start, 'Must call Start() first'28    self._memory_stats_end = self._browser.memory_stats29  # |trace_name| and |exclude_metrics| args are not in base class Metric.30  # pylint: disable=W022131  def AddResults(self, tab, results, trace_name=None, exclude_metrics=None):32    """Add results for this page to the results object.33    Reports the delta in memory stats between the start stats and the end stats34    (as *_delta metrics). It reports end memory stats in case no matching start35    memory stats exists.36    Args:37      trace_name: Trace name to identify the summary results for current page.38      exclude_metrics: List of memory metrics to exclude from results,39                       e.g. VM, VMPeak, etc. See AddResultsForProcesses().40    """41    assert self._memory_stats_end, 'Must call Stop() first'42    memory_stats = _SubtractMemoryStats(self._memory_stats_end,43                                        self._memory_stats_start)44    if not memory_stats['Browser']:45      return46    exclude_metrics = exclude_metrics or {}47    memory.AddResultsForProcesses(results, memory_stats,48        metric_trace_name=trace_name, chart_trace_name='delta',49        exclude_metrics=exclude_metrics)50    if 'SystemCommitCharge' not in exclude_metrics:51      results.AddValue(scalar.ScalarValue(52          results.current_page,53          'commit_charge_delta.%s' % (trace_name or 'commit_charge'), 'kb',54          memory_stats['SystemCommitCharge'], important=False))55    if 'ProcessCount' not in exclude_metrics:56      results.AddValue(scalar.ScalarValue(57          results.current_page,58          'processes_delta.%s' % (trace_name or 'processes'), 'count',59          memory_stats['ProcessCount'], important=False))60def _SubtractMemoryStats(end_memory_stats, start_memory_stats):61  """Computes the difference in memory usage stats.62  Each of the two stats arguments is a dict with the following format:63      {'Browser': {metric: value, ...},64       'Renderer': {metric: value, ...},65       'Gpu': {metric: value, ...},66       'ProcessCount': value,67       etc68      }69  The metrics can be VM, WorkingSetSize, ProportionalSetSize, etc depending on70  the platform/test.71  NOTE: The only metrics that are not subtracted from original are the *Peak*72  memory values.73  Returns:74    A dict of process type names (Browser, Renderer, etc.) to memory usage75    metrics between the end collected stats and the start collected stats.76  """77  memory_stats = {}78  end_memory_stats = end_memory_stats or {}79  start_memory_stats = start_memory_stats or {}80  for process_type in end_memory_stats:81    memory_stats[process_type] = {}82    end_process_memory = end_memory_stats[process_type]83    if not end_process_memory:84      continue85    # If a process has end stats without start stats then report the end stats.86    # For example, a GPU process that started just after media playback.87    if (process_type not in start_memory_stats or88        not start_memory_stats[process_type]):89      memory_stats[process_type] = end_process_memory90      continue91    if not isinstance(end_process_memory, dict):92      start_value = start_memory_stats[process_type] or 093      memory_stats[process_type] = end_process_memory - start_value94    else:95      for metric in end_process_memory:96        end_value = end_process_memory[metric]97        start_value = start_memory_stats[process_type][metric] or 098        if 'Peak' in metric:99          memory_stats[process_type][metric] = end_value100        else:101          memory_stats[process_type][metric] = end_value - start_value...cpu.py
Source:cpu.py  
1# Copyright 2013 The Chromium Authors. All rights reserved.2# Use of this source code is governed by a BSD-style license that can be3# found in the LICENSE file.4from metrics import Metric5from telemetry.value import scalar6class CpuMetric(Metric):7  """Calulates CPU load over a span of time."""8  def __init__(self, browser):9    super(CpuMetric, self).__init__()10    self._browser = browser11    self._start_cpu = None12    self._stop_cpu = None13  def DidStartBrowser(self, browser):14    # Save the browser object so that cpu_stats can be accessed later.15    self._browser = browser16  def Start(self, page, tab):17    self._start_cpu = self._browser.cpu_stats18  def Stop(self, page, tab):19    assert self._start_cpu, 'Must call Start() first'20    self._stop_cpu = self._browser.cpu_stats21  # Optional argument trace_name is not in base class Metric.22  # pylint: disable=W022123  def AddResults(self, tab, results, trace_name='cpu_utilization'):24    assert self._stop_cpu, 'Must call Stop() first'25    cpu_stats = _SubtractCpuStats(self._stop_cpu, self._start_cpu)26    # Add a result for each process type.27    for process_type in cpu_stats:28      trace_name_for_process = '%s_%s' % (trace_name, process_type.lower())29      cpu_percent = 100 * cpu_stats[process_type]30      results.AddValue(scalar.ScalarValue(31          results.current_page, 'cpu_utilization.%s' % trace_name_for_process,32          '%', cpu_percent, important=False))33def _SubtractCpuStats(cpu_stats, start_cpu_stats):34  """Computes average cpu usage over a time period for different process types.35  Each of the two cpu_stats arguments is a dict with the following format:36      {'Browser': {'CpuProcessTime': ..., 'TotalTime': ...},37       'Renderer': {'CpuProcessTime': ..., 'TotalTime': ...}38       'Gpu': {'CpuProcessTime': ..., 'TotalTime': ...}}39  The 'CpuProcessTime' fields represent the number of seconds of CPU time40  spent in each process, and total time is the number of real seconds41  that have passed (this may be a Unix timestamp).42  Returns:43    A dict of process type names (Browser, Renderer, etc.) to ratios of cpu44    time used to total time elapsed.45  """46  cpu_usage = {}47  for process_type in cpu_stats:48    assert process_type in start_cpu_stats, 'Mismatching process types'49    # Skip any process_types that are empty.50    if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]):51      continue52    cpu_process_time = (cpu_stats[process_type]['CpuProcessTime'] -53                        start_cpu_stats[process_type]['CpuProcessTime'])54    total_time = (cpu_stats[process_type]['TotalTime'] -55                  start_cpu_stats[process_type]['TotalTime'])56    # Fix overflow for 32-bit jiffie counter, 64-bit counter will not overflow.57    # Linux kernel starts with a value close to an overflow, so correction is58    # necessary.59    if total_time < 0:60      total_time += 2**3261    # Assert that the arguments were given in the correct order.62    assert total_time > 0 and total_time < 2**31, (63        'Expected total_time > 0, was: %d' % total_time)64    cpu_usage[process_type] = float(cpu_process_time) / total_time...LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
