Ejemplo n.º 1
0
def set_parking(bot, update):
    """callbackQuery handler. pattern: ^_next_btn$|^_previous_btn$|^_parkhouse-"""
    log.info(log_msg(update))
    update.callback_query.answer()
    user_id = update.effective_user.id
    user, created = Parking.get_or_create(user_id=user_id)

    if '_parkhouse-' in update.callback_query.data:
        parking_house = int(update.callback_query.data.split('-')[1])
        user.house = parking_house
        user.save()

    previous_btn = InlineKeyboardButton('⏪ Попередні', callback_data='_previous_btn')
    next_btn = InlineKeyboardButton('Наступні ⏩', callback_data='_next_btn')
    menu_btn = InlineKeyboardButton('Меню', callback_data='_menu')
    back_btn = InlineKeyboardButton('Назад', callback_data='parking')

    query = Parking.select().where(Parking.house == user.house)
    query = [i.parking for i in query]

    keyboard = []
    if '_parkhouse-' in update.callback_query.data or '_previous_btn' in update.callback_query.data:
        for i in range(0, 50, 5):
            row = []
            for j in range(1, 6):
                icon = f'🔑' if j + i in query else f''
                row.append(InlineKeyboardButton(str(j + i) + icon, callback_data=f'_park_place-{j + i}'))
            keyboard.append(row)
        keyboard.append([menu_btn, back_btn, next_btn])
    else:
        for i in range(50, 105, 5):
            row = []
            for j in range(1, 6):
                icon = f'🔑' if j + i in query else f''
                row.append(InlineKeyboardButton(str(j + i) + icon, callback_data=f'_park_place-{j + i}'))
            keyboard.append(row)
        keyboard.append([menu_btn, back_btn, previous_btn])

    reply_markup = InlineKeyboardMarkup(keyboard)
    bot.editMessageText(message_id=update.effective_message.message_id, text='Вкажіть Ваше паркомісце\n',
                        chat_id=user_id, reply_markup=reply_markup, parse_mode=ParseMode.HTML)
Ejemplo n.º 2
0
def show_parking(bot, update):
    """callbackQuery handler. pattern: ^_parking_owners_btn$"""
    log.info(log_msg(update))
    update.callback_query.answer()

    keyboard = [[InlineKeyboardButton('Назад', callback_data='parking'),
                InlineKeyboardButton('Меню', callback_data='_menu')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    parkings = Parking.select(Parking.house).where(Parking.parking).distinct().order_by(Parking.house)
    query = Parking.select().where(Parking.parking).order_by(Parking.parking)

    neighbors = []
    for i in parkings:
        neighbors.append(f'\n{"<b>Паркінг будинку №".rjust(30, " ")} {i.house}</b>\n')
        for user in query.where(Parking.house == i.house):
            neighbors.append(f'{user.user} <b>{user.parking}</b>\n')

    show_list = ('<b>Власники паркомісць</b>:\n'
                 + '{}' * len(neighbors)).format(*neighbors)

    bot.editMessageText(text=show_list, parse_mode=ParseMode.HTML, reply_markup=reply_markup,
                        chat_id=update.effective_user.id, message_id=update.effective_message.message_id)
Ejemplo n.º 3
0
def save_parking(bot, update):
    """callbackQuery handler. pattern: ^_park_place-"""
    log.info(log_msg(update))
    update.callback_query.answer()
    user_id = update.effective_user.id
    park_place = int(update.callback_query.data.split('-')[1])

    keyboard = [[InlineKeyboardButton('Назад', callback_data='parking')],
                [InlineKeyboardButton('Меню', callback_data='_menu')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    user = Parking.get(user_id=user_id)
    user.parking = park_place
    user.save()
    bot.editMessageText(message_id=update.effective_message.message_id, text='<b>Дякую Ваші дані збережено!</b>',
                        chat_id=user_id, reply_markup=reply_markup, parse_mode=ParseMode.HTML)
Ejemplo n.º 4
0
def loadsectors():
    for i in range(1, 5):
        new_sector = Sector()
        db.session.add(new_sector)
    for i in range(1, 5):
        with open('Sector ' + str(i)) as sector:
            for line in sector.readlines():
                loclat, loclong = line.split(', ')
                new_parking = Parking()
                new_parking.sectorid = i
                new_parking.loclat = loclat
                new_parking.loclong = loclong
                new_parking.available = 2
                new_parking.disability = random.choice(range(0, 2))
                db.session.add(new_parking)
    db.session.commit()
    flash("successfully added parking spots")
    return redirect(url_for('login'))
Ejemplo n.º 5
0
def setup():
    floor_obj = Floor(1, 5)
    Parking.add_floor(floor_obj)

    floor_obj_2 = Floor(2, 5)
    Parking.add_floor(floor_obj_2)

    Parking.park_a_vehicle(100, 'black')
    Parking.park_a_vehicle(200, 'black')
    Parking.get_all_floors()

    Parking.unpark_a_vehicle(200)
    Parking.get_all_floors()

    Parking.fetch_slot(100)
    Parking.fetch_slot_by_colour('black')
Ejemplo n.º 6
0
    def get(self):
        def _simple_error(message, code=400):
            self.error(code)
            self.response.out.write(
                simplejson.dumps({
                    'status': 'error',
                    'error': {
                        'message': message
                    },
                    'results': []
                }))
            return None

        self.response.headers['Content-Type'] = 'application/json'

        try:
            center = geotypes.Point(float(self.request.get('lat')),
                                    float(self.request.get('lon')))
        except ValueError:
            return _simple_error(
                'lat and lon parameters must be valid latitude and longitude values.'
            )

        max_results = self.request.get('results')
        try:
            max_results = int(
                max_results) if max_results else __default_max_results__
        except ValueError:
            return _simple_error('results must be a valid integer value')

        radius = self.request.get('radius')
        try:
            radius = int(radius) if radius else __default_radius__
        except ValueError:
            return _simple_error('radius must be a valid integer in meters')
        base_query = Parking.all()
        logging.info('radius is %d' % radius)
        logging.info('max results is %d' % max_results)
        results = Parking.proximity_fetch(base_query,
                                          center,
                                          max_results=max_results,
                                          max_distance=radius)
        logging.info('queried %d parkings' % len(results))
        results_arr = [{
            'id': result.parking_id,
            'name': result.name,
            'street': result.street_name,
            'house': result.house_number,
            'location': {
                'latitude': result.latitude,
                'longitude': result.longitude
            },
            'state': result.current_state,
            'capacity': result.capacity
        } for result in results]

        self.response.out.write(
            simplejson.dumps({
                'status': 'success',
                'results': results_arr
            },
                             indent=4))
def employeeController(action=None,resourceId=None):

    #keep non-logged users outside

    if ('employee' not in session):
        return redirect(url_for('backoffice_auth'))
    
    if not session['employee']['superAdmin'] and not resourceId:
        return redirect(url_for('backoffice_auth'))
    #check resourceId validity
    employeeData = None

    if resourceId:
        if ObjectId.is_valid(str(resourceId)):
            employeeData = Employee.objects(id=ObjectId(str(resourceId))).first()
            if not session['employee']['superAdmin'] and not (action == 'edit' and resourceId == session['employee']['_id']['$oid']):
                return render_template('404.html',errorString="Cannot access this area")
            if not employeeData:
                return render_template('404.html',errorString="This Employee does not exist")
        else:
            return render_template('404.html',errorString="This EmployeeId is not valid")

    errorString = ''
    employeeList = []
    evaluatedEmployee = None
    parkingList = []
    validationErrors = []
    pageTitle = ""


    #switch action cases (add,edit,delete,list)

    if action == 'add' or action == 'edit':

        pageTitle = "Add Employee" if action == "add" else "Edit Employee"
        templatePath = 'employees/add.html'

        if request.method == 'POST' and ('submit' in request.form):
            #validate username


            if 'login' in request.form:
                if not request.form['login']:
                    validationErrors.append("Field username is empty")
                else:
                    if len(request.form['login']) < 5:
                        validationErrors.append("Username field should be min. 5 chars")
                    if action == 'add':
                        if len(Employee.objects(login=request.form['login'])) > 0:
                            validationErrors.append("The username you've choose already exists")
                    else:
                        if len(Employee.objects(login=request.form['login'],login__ne=employeeData.login)) > 0:
                            validationErrors.append("The username you've choose already exists")
            else:
                validationErrors.append("Missing field username in request")

            #validate name
            if 'name' in request.form:
                if not request.form['name']:
                    validationErrors.append("Field name is empty")
            else:
                validationErrors.append("Missing field name in request")


            #validate password

            if 'password' in request.form:
                if not request.form['password']:
                    if(action == 'edit'):
                        hash = employeeData.password #keep old password
                    else:
                        validationErrors.append("Field password is empty")
                else:
                    if len(request.form['password']) < 8:
                        validationErrors.append("Password field should be min. 8 chars") 
                    else:
                        hash = hashlib.sha256(request.form['password'].encode()).hexdigest().upper()#make new hash
            else:
                validationErrors.append("Missing field password in request")

            active = 0
            superAdmin = 0

            if 'active' in request.form:
                active = (True if int(request.form['active']) == 1 else False)
            if 'superAdmin' in request.form:
                superAdmin = (True if int(request.form['superAdmin']) == 1 else False)


            #validate parking
            if not (action == 'edit' and resourceId and not session['employee']['superAdmin'] and str(session['employee']['_id']['$oid']) == resourceId):
                if 'relatedParking' in request.form:
                
                    #request.form['relatedParking']
                    if request.form['relatedParking'] and ObjectId.is_valid(str(request.form['relatedParking'])): 
                        if not Parking.objects(id=ObjectId(str(request.form['relatedParking']))).first():
                            validationErrors.append("The parking you are referencing is not existing")
                        else:
                            relatedParking = str(request.form['relatedParking'])

                    else:
                        validationErrors.append("The parking you are referencing is not valid")
                else:
                    validationErrors.append("Missing parking reference in request")
            else:
                relatedParking = session['employee']['relatedParking']['$oid']
                active = session['employee']['active']
                superAdmin = session['employee']['superAdmin']
            #validate active
            

            if len(validationErrors) == 0:
                 #save

                if action == 'add':
                    result = Employee(name = request.form['name'],
                                  login = request.form['login'],
                                  password = hash,
                                  relatedParking = ObjectId(str(relatedParking)),
                                  active = active,
                                  superAdmin = superAdmin
                                  ).save()
                    if result:
                        lastEmployee = Employee.objects(login=request.form['login']).first()
                        return redirect(url_for('employees',action='edit',resourceId=lastEmployee.id))
                    else:
                        validationErrors.append("Unable to write this record")
                else:
                    result = Employee.objects(id=ObjectId(str(resourceId))).update(name = request.form['name'],
                                  login = request.form['login'],
                                  password = hash,
                                  relatedParking = ObjectId(str(relatedParking)),
                                  active = active,
                                  superAdmin = superAdmin
                                  )
                    return redirect(url_for('employees',action='edit',resourceId=resourceId))
                 
                


            else:
                errorString ='|'.join(validationErrors)






    elif action == 'delete':
        pageTitle = "Employees"
        templatePath = 'employees/list.html'
        Employee.objects(id=ObjectId(str(resourceId))).delete()
        employeeList = Employee.objects().order_by('name')

    else:
        pageTitle = "Employees"
        templatePath = 'employees/list.html'     
        employeeList = Employee.objects().order_by('name')


    

    
    parkingList = Parking.objects().order_by('name')


    return render_template(
        templatePath,
        pageTitle=pageTitle,
        employee=session['employee'],
        userType='employee',
        errorString=errorString,
        evaluatedEmployee=evaluatedEmployee,
        employeeList=employeeList,
        parkingList=parkingList,
        employeeData=employeeData,
        action=action,
        resourceId=resourceId
        )
Ejemplo n.º 8
0
def employeeParkingController(action=None,resourceId=None):

    #keep non-logged users outside

    if ('employee' not in session) or (session['employee']['superAdmin'] is not True):
        return redirect(url_for('backoffice_auth'))

    #check resourceId validity
    parkingData = None

    if resourceId is not None:
        if ObjectId.is_valid(str(resourceId)):
            parkingData = Parking.objects(id=ObjectId(str(resourceId))).first()
            if not parkingData:
                return render_template('404.html',errorString="This Parking does not exist")
            else:
                if (session['employee']['superAdmin'] is not True) and session['employee']['relatedParking'] != str(resourceId):
                    return render_template('404.html',errorString="You do not have access to this page")
        else:
            return render_template('404.html',errorString="This ParkingID is not valid")

    errorString = ''
    parkingList = []
    validationErrors = []
    pageTitle = ""


    #switch action cases (add,edit,delete,list)

    if action == 'add' or action == 'edit':

        pageTitle = "Add Parking" if action == "add" else "Edit Parking"
        templatePath = 'parkings/add.html'

        if request.method == 'POST' and ('submit' in request.form):
            #validate username




            if 'name' in request.form:
                if not request.form['name']:
                    validationErrors.append("Field name is empty")
                else:                    
                    if action == 'add':
                        if len(Parking.objects(name=request.form['name'])) > 0:
                            validationErrors.append("The name you've choose already exists")
                    else:
                        if len(Parking.objects(name=request.form['name'],name__ne=parkingData.name)) > 0:
                            validationErrors.append("The name you've choose already exists")
            else:
                validationErrors.append("Missing field name in request")

            #validate companyName
            if 'city' in request.form:
                if not request.form['city']:
                    validationErrors.append("Field city is empty")
            else:
                validationErrors.append("Missing field city in request")

            #validate phone
            if 'district' in request.form:
                if not request.form['district']:
                    validationErrors.append("Field district is empty")
            else:
                validationErrors.append("Missing field district in request")
            
            #validate phone
            if 'address' in request.form:
                if not request.form['address']:
                    validationErrors.append("Field address is empty")
            else:
                validationErrors.append("Missing field address in request")

            if 'phone' in request.form:
                if not request.form['phone']:
                    validationErrors.append("Field phone is empty")
            else:
                validationErrors.append("Missing field phone in request")


            if 'pricePerHour' in request.form:
                if not request.form['pricePerHour'] or float(request.form['pricePerHour']) <= 0:
                    validationErrors.append("Field pricePerHour is empty or invalid")
            else:
                validationErrors.append("Missing field pricePerHour in request")
    

            
            active = False
            maxPlaces = 1

            if 'maxPlaces' in request.form:
                maxPlaces = request.form['maxPlaces']
            if 'active' in request.form:
                active = (True if int(request.form['active']) == 1 else False)
            
           
            
                

            if len(validationErrors) == 0:
                 #save

                 


    
                if action == 'add':
                    result = Parking(name = str(request.form['name']),
                                  city = str(request.form['city']),
                                  district = str(request.form['district']),
                                  address = str(request.form['address']),
                                  phone = str(request.form['phone']),
                                  pricePerHour = float(request.form['pricePerHour']),
                                  maxPlaces = maxPlaces,
                                  active = active
                                  ).save()
                    if result:
                        lastParking = Parking.objects(name=str(request.form['name'])).first()
                        return redirect(url_for('parkings',action='edit',resourceId=lastParking.id))
                    else:
                        validationErrors.append("Unable to write this record")
                else:
                    result = Parking.objects(id=ObjectId(str(resourceId))).update(name = str(request.form['name']),
                                  city = str(request.form['city']),
                                  district = str(request.form['district']),
                                  address = str(request.form['address']),
                                  phone = str(request.form['phone']),
                                  pricePerHour = float(request.form['pricePerHour']),
                                  maxPlaces = maxPlaces,
                                  active = active)
                    return redirect(url_for('parkings',action='edit',resourceId=resourceId))
                 
                


            else:
                errorString ='|'.join(validationErrors)






    elif action == 'delete':
        pageTitle = "Parkings"
        templatePath = 'parkings/list.html'
        Parking.objects(id=ObjectId(str(resourceId))).delete()
        parkingList = Parking.objects().order_by('companyName')

    else:
        pageTitle = "Parkings"
        templatePath = 'parkings/list.html'     
        parkingList = Parking.objects().order_by('companyName')
        

    

    


    return render_template(
        templatePath,
        pageTitle=pageTitle,
        employee=session['employee'],
        userType='employee',
        errorString=errorString,
        parkingList=parkingList,
        parkingData=parkingData,
        action=action,
        resourceId=resourceId
        )
def agencyReservationController(action=None, resourceId=None, config={}):

    #keep non-logged users outside

    if ('agency' not in session):
        return redirect(url_for('agency_auth'))

    #check resourceId validity
    reservationData = None
    if resourceId:
        if ObjectId.is_valid(str(resourceId)):
            reservationData = Reservation.objects(
                id=ObjectId(str(resourceId)),
                agency=ObjectId(str(
                    session['agency']['_id']['$oid']))).first()
            if not reservationData:
                return render_template(
                    '404.html', errorString="This Reservation does not exist")
            else:
                if str(session['agency']['_id']['$oid']) != str(
                        reservationData.agency):
                    return render_template(
                        '404.html',
                        errorString="You do not have access to this page")
        else:
            return render_template('404.html',
                                   errorString="This ParkingID is not valid")

    errorString = ''
    parkingList = []
    validationErrors = []
    pageTitle = ""
    reservationList = []
    agencyList = []
    counters = {"reservations": 0, "earned": 0, "agencyProfit": 0}

    #switch action cases (add,edit,delete,list)

    if action == 'add' or action == 'edit':

        pageTitle = "Add Reservation" if action == "add" else "Edit Reservation"
        templatePath = 'reservations/add_agency.html'
        parkingList = Parking.objects().order_by('name')

        if request.method == 'POST' and ('submit' in request.form):
            #return render_template("404.html",errorString=datetime.strptime("2019-02-01 15:26", '%Y-%m-%d %H:%M').isoformat())
            #validation

            #validate name
            if 'name' in request.form:
                if not request.form['name']:
                    validationErrors.append("Field name is empty")
            else:
                validationErrors.append("Missing field name in request")

            #validate surname
            if 'surname' in request.form:
                if not request.form['surname']:
                    validationErrors.append("Field surname is empty")
            else:
                validationErrors.append("Missing field surname in request")

            #validate email
            if 'email' in request.form:
                if not request.form['email'] or not request.form['email'].find(
                        "@"):
                    validationErrors.append("Field email is empty or invalid")
            else:
                validationErrors.append("Missing field email in request")

            #validate parking

            relatedParking = None
            if 'parking' in request.form:

                #request.form['relatedParking']
                if request.form['parking'] and ObjectId.is_valid(
                        str(request.form['parking'])):
                    if not Parking.objects(
                            id=ObjectId(str(request.form['parking']))).first():
                        validationErrors.append(
                            "The parking you are referencing is not existing")
                    else:
                        relatedParking = ObjectId(str(request.form['parking']))
                else:
                    validationErrors.append(
                        "The parking you are referencing is not valid")
            else:
                validationErrors.append("Missing parking reference in request")

            #validate agency

            relatedAgency = ObjectId(session['agency']['_id']['$oid'])

            #validate dates
            fromDate = None
            toDate = None
            if 'fromDate' in request.form:
                if not request.form['fromDate']:
                    validationErrors.append("Field fromDate is empty")
                else:
                    try:
                        fromDate = datetime.strptime(request.form['fromDate'],
                                                     '%Y-%m-%d %H:%M')
                    except:
                        validationErrors.append("Field fromDate is empty")

            else:
                validationErrors.append("Missing field fromDate in request")

            if 'toDate' in request.form:
                if not request.form['toDate']:
                    validationErrors.append("Field toDate is empty")
                else:
                    try:
                        toDate = datetime.strptime(request.form['toDate'],
                                                   '%Y-%m-%d %H:%M')
                    except:
                        validationErrors.append("Field toDate is empty")

            else:
                validationErrors.append("Missing field fromDate in request")

            #non-mandatory fields
            model = ""
            plate = ""
            type = "car"
            paymentType = "online"
            amount = 0
            agencyProfit = 0

            if 'model' in request.form:
                model = request.form['model']
            if 'plate' in request.form:
                plate = request.form['plate']
            if 'type' in request.form:
                type = ("car"
                        if str(request.form['type']) == "car" else "moto")
            if 'paymentType' in request.form:
                paymentType = ("online" if str(request.form['paymentType'])
                               == "online" else "onsite")

            if fromDate and toDate:
                #check date difference
                dateDiff = toDate - fromDate
                reservationHours = dateDiff.total_seconds() / 3600
                if reservationHours <= 0:
                    validationErrors.append(
                        "Distance between starting and ending date should be 1 hour"
                    )

            if len(validationErrors) == 0:

                #proceed calculating amount and (if needed) agencyProfit

                selectedParking = Parking.objects(id=relatedParking).first()
                amount = decimal.Decimal(
                    reservationHours) * selectedParking['pricePerHour']

                if relatedAgency:
                    #calc profit
                    selectedAgency = Agency.objects(id=relatedAgency).first()
                    agencyProfit = selectedAgency['profitRate'] * amount / 100

                if action == 'add':
                    executionDate = datetime.now()
                    result = Reservation(
                        status="CONFIRMED",
                        user={
                            'name': request.form['name'],
                            'surname': request.form['surname'],
                            'email': request.form['email'],
                            'model': model,
                            'plate': plate,
                            'type': type
                        },
                        fromDate=fromDate.isoformat(),
                        toDate=toDate.isoformat(),
                        parking=relatedParking,
                        amount=amount,
                        paymentType=paymentType,
                        agencyProfit=agencyProfit,
                        agency=relatedAgency,
                        executionDate=executionDate.isoformat()).save()
                    if result:
                        try:
                            server = smtplib.SMTP(
                                config['SMTP_CONFIG']['HOST'],
                                config['SMTP_CONFIG']['PORT'])
                            server.starttls()
                            server.login(config['SMTP_CONFIG']['LOGIN'],
                                         config['SMTP_CONFIG']['PASSWORD'])
                            to = str(request.form['email'])
                            msg = MIMEMultipart()
                            msg['From'] = config['SMTP_CONFIG']['SEND_FROM']
                            msg['To'] = to
                            msg['Subject'] = "Well done! Parking reservation confirm"
                            body = "<p>Dear " + escape(
                                request.form['name'] + " " +
                                request.form['surname']
                            ) + ",<br>this is your booking:<ul>\
                            <li>Code : " + str(result.id) + "</li>\
                            <li>Execution : " + executionDate.strftime(
                                '%d/%m/%Y %H:%M') + "</li>\
                            <li>From : " + fromDate.strftime(
                                    '%d/%m/%Y %H:%M') + "</li>\
                            <li>To : " + toDate.strftime(
                                        '%d/%m/%Y %H:%M') + "</li>\
                            <li>Amount : &euro;" + str(amount) + "</li>\
                            <li>Parking : " + escape(str(
                                            selectedParking.name)) + "</li>\
                            <li>Parking Address : " + escape(
                                                str(selectedParking.address) +
                                                "," +
                                                str(selectedParking.city) +
                                                " " + str(selectedParking.
                                                          district)) + "</li>\
                            </ul><br><br>Best regards,<br><b>eparkingsystem</b></p>\
                            "

                            msg.attach(MIMEText(body, 'html'))
                            text = msg.as_string()
                            server.sendmail(config['SMTP_CONFIG']['SEND_FROM'],
                                            to, text)
                            server.quit()
                        except:
                            pass

                        return redirect(url_for('agency_reservations'))
                    else:
                        validationErrors.append("Unable to write this record")
                else:
                    result = Reservation.objects(
                        id=ObjectId(str(resourceId))).update(
                            status="CONFIRMED",
                            user={
                                'name': request.form['name'],
                                'surname': request.form['surname'],
                                'email': request.form['email'],
                                'model': model,
                                'plate': plate,
                                'type': type
                            },
                            fromDate=fromDate.isoformat(),
                            toDate=toDate.isoformat(),
                            parking=relatedParking,
                            amount=amount,
                            paymentType=paymentType,
                            agencyProfit=agencyProfit,
                            agency=relatedAgency,
                            executionDate=datetime.now().isoformat())

                    return redirect(
                        url_for('agency_reservations',
                                action='edit',
                                resourceId=resourceId))

            else:
                errorString = '|'.join(validationErrors)

    elif action == 'delete':
        Reservation.objects(
            id=ObjectId(str(resourceId)),
            agency=ObjectId(str(session['agency']['_id']['$oid']))).delete()
        return redirect(url_for('agency_reservations'))

    else:
        pageTitle = "Reservations"
        templatePath = 'reservations/list.html'
        objectList = Reservation.objects(agency=ObjectId(
            str(session['agency']['_id']['$oid']))).order_by("-executionDate")

        reservationList = objectList.aggregate(*[{
            "$lookup": {
                "from": "parkings",
                "localField": "parking",
                "foreignField": "_id",
                "as": "parkingData"
            }
        }, {
            "$lookup": {
                "from": "agencies",
                "localField": "agency",
                "foreignField": "_id",
                "as": "agencyData"
            }
        }, {
            "$unwind": "$parkingData"
        }, {
            "$unwind": "$agencyData"
        }, {
            "$project": {
                "_id": 1,
                "status": 1,
                "user": 1,
                "fromDate": 1,
                "toDate": 1,
                "parking": 1,
                "amount": 1,
                "paymentType": 1,
                "agencyProfit": 1,
                "agency": 1,
                "executionDate": 1,
                "parkingName": "$parkingData.name",
                "agencyCompanyName": "$agencyData.companyName",
            }
        }])
        #get counters value
        counters['reservations'] = objectList.count()
        counters['agencyProfit'] = 0
        counters['earned'] = objectList.sum("agencyProfit")

    return render_template(templatePath,
                           pageTitle=pageTitle,
                           agency=session['agency'],
                           userType='agency',
                           errorString=errorString,
                           parkingList=parkingList,
                           agencyList=agencyList,
                           reservationList=reservationList,
                           reservationData=reservationData,
                           action=action,
                           resourceId=resourceId,
                           counters=counters)
def customerController(action="step1", config={}):

    parkingList = Parking.objects().order_by('companyName')

    templatePath = "customer/index.html"

    errorString = ''
    validationErrors = []

    if action == 'step1':

        if request.method == 'POST' and ('submit' in request.form):
            #validate and show amount

            if 'name' in request.form:
                if not request.form['name']:
                    validationErrors.append("Field name is empty")
            else:
                validationErrors.append("Missing field name in request")

            #validate surname
            if 'surname' in request.form:
                if not request.form['surname']:
                    validationErrors.append("Field surname is empty")
            else:
                validationErrors.append("Missing field surname in request")

            #validate email
            if 'email' in request.form:
                if not request.form['email'] or not request.form['email'].find(
                        "@"):
                    validationErrors.append("Field email is empty or invalid")
            else:
                validationErrors.append("Missing field email in request")

            #validate parking

            relatedParking = None
            if 'parking' in request.form:

                #request.form['relatedParking']
                if request.form['parking'] and ObjectId.is_valid(
                        str(request.form['parking'])):
                    if not Parking.objects(
                            id=ObjectId(str(request.form['parking']))).first():
                        validationErrors.append(
                            "The parking you are referencing is not existing")
                    else:
                        relatedParking = ObjectId(str(request.form['parking']))
                else:
                    validationErrors.append(
                        "The parking you are referencing is not valid")
            else:
                validationErrors.append("Missing parking reference in request")

            #validate agency

            #validate dates
            fromDate = None
            toDate = None
            if 'fromDate' in request.form:
                if not request.form['fromDate']:
                    validationErrors.append("Field fromDate is empty")
                else:
                    try:
                        fromDate = datetime.strptime(request.form['fromDate'],
                                                     '%Y-%m-%d %H:%M')
                    except:
                        validationErrors.append("Field fromDate is empty")

            else:
                validationErrors.append("Missing field fromDate in request")

            if 'toDate' in request.form:
                if not request.form['toDate']:
                    validationErrors.append("Field toDate is empty")
                else:
                    try:
                        toDate = datetime.strptime(request.form['toDate'],
                                                   '%Y-%m-%d %H:%M')
                    except:
                        validationErrors.append("Field toDate is empty")

            else:
                validationErrors.append("Missing field fromDate in request")

            #non-mandatory fields
            model = ""
            plate = ""
            type = "car"
            paymentType = "online"
            amount = 0
            agencyProfit = 0

            if 'model' in request.form:
                model = request.form['model']
            if 'plate' in request.form:
                plate = request.form['plate']
            if 'type' in request.form:
                type = ("car"
                        if str(request.form['type']) == "car" else "moto")
            if 'paymentType' in request.form:
                paymentType = ("online" if str(request.form['paymentType'])
                               == "online" else "onsite")

            if fromDate and toDate:
                #check date difference
                dateDiff = toDate - fromDate
                reservationHours = dateDiff.total_seconds() / 3600
                if reservationHours <= 0:
                    validationErrors.append(
                        "Distance between starting and ending date should be 1 hour"
                    )

            if len(validationErrors) == 0:

                #proceed calculating amount and (if needed) agencyProfit

                selectedParking = Parking.objects(id=relatedParking).first()
                amount = decimal.Decimal(
                    reservationHours) * selectedParking['pricePerHour']

                session['reservation'] = {
                    'user': {
                        'name': request.form['name'],
                        'surname': request.form['surname'],
                        'email': request.form['email'],
                        'model': model,
                        'plate': plate,
                        'type': type
                    },
                    'fromDate': fromDate,
                    'toDate': toDate,
                    'parking': str(relatedParking),
                    'amount': float(amount),
                    'paymentType': paymentType,
                    'agencyProfit': float(agencyProfit),
                }
                return redirect(url_for('customer', action='step2'))

            else:

                errorString = '|'.join(validationErrors)

    elif action == 'step2':
        templatePath = "customer/amount.html"
    elif action == 'step3':
        action = "error"
        templatePath = "customer/done.html"
        if "reservation" in session:
            executionDate = datetime.now()
            result = Reservation(
                status="CONFIRMED",
                user={
                    'name': session['reservation']['user']['name'],
                    'surname': session['reservation']['user']['surname'],
                    'email': session['reservation']['user']['email'],
                    'model': session['reservation']['user']['model'],
                    'plate': session['reservation']['user']['plate'],
                    'type': session['reservation']['user']['type']
                },
                fromDate=session['reservation']['fromDate'],
                toDate=session['reservation']['toDate'],
                parking=ObjectId(str(session['reservation']['parking'])),
                amount=session['reservation']['amount'],
                paymentType="online",
                executionDate=executionDate.isoformat()).save()
            if result:
                action = "success"
                selectedParking = Parking.objects(id=ObjectId(
                    str(session['reservation']['parking']))).first()
                try:
                    server = smtplib.SMTP(config['SMTP_CONFIG']['HOST'],
                                          config['SMTP_CONFIG']['PORT'])
                    server.starttls()
                    server.login(config['SMTP_CONFIG']['LOGIN'],
                                 config['SMTP_CONFIG']['PASSWORD'])
                    to = str(session['reservation']['user']['email'])
                    msg = MIMEMultipart()
                    msg['From'] = config['SMTP_CONFIG']['SEND_FROM']
                    msg['To'] = to
                    msg['Subject'] = "Well done! Parking reservation confirm"
                    body = "<p>Dear " + escape(
                        session['reservation']['user']['name'] + " " +
                        session['reservation']['user']['surname']
                    ) + ",<br>this is your booking:<ul>\
                            <li>Code : " + str(result.id) + "</li>\
                            <li>Execution : " + executionDate.strftime(
                        '%d/%m/%Y %H:%M') + "</li>\
                            <li>From : " + session['reservation'][
                            'fromDate'].strftime('%d/%m/%Y %H:%M') + "</li>\
                            <li>To : " + session['reservation'][
                                'toDate'].strftime('%d/%m/%Y %H:%M') + "</li>\
                            <li>Amount : &euro;" + str(
                                    session['reservation']['amount']) + "</li>\
                            <li>Parking : " + escape(str(
                                        selectedParking.name)) + "</li>\
                            <li>Parking Address : " + escape(
                                            str(selectedParking.address) +
                                            "," + str(selectedParking.city) +
                                            " " + str(selectedParking.district)
                                        ) + "</li>\
                            </ul><br><br>Best regards,<br><b>eparkingsystem</b></p>\
                            "

                    msg.attach(MIMEText(body, 'html'))
                    text = msg.as_string()
                    server.sendmail(config['SMTP_CONFIG']['SEND_FROM'], to,
                                    text)
                    server.quit()
                except:
                    pass

                session.clear()

    return render_template(
        templatePath,
        parkingList=parkingList,
        errorString=errorString,
        action=action,
        reservation=session['reservation'] if "reservation" in session else {})