Ejemplo n.º 1
0
def get_config():
    config = get_config_dict()

    resp = jsonify(config)
    resp.status_code = 200

    return resp
Ejemplo n.º 2
0
def test_save_path():
    data = json.loads(request.form['data'])

    config = get_config_dict()

    if data["savePathType"] == "archive":
        save_path = config['pdf_processing_parameters']['save_file_path_archive']
    elif data["savePathType"] == "reminder":
        save_path = config['pdf_processing_parameters']['save_file_path_reminder']
    elif data["savePathType"] == "backups":
        save_path = config['other_parameters']['save_file_path_backups']
    else:
        return {
                   'code': 0,
                   'message': "Save path type not recognized. The save path type must be archive, reminder or backups."
               }, 400

    if os.path.isdir(save_path):
        response = {'success': True}

        resp = jsonify(response)
        resp.status_code = 200

        return resp

    else:
        return {
                   'code': 1,
                   'message': "The save path is incorrect"
               }, 400
Ejemplo n.º 3
0
def init_schedule():
    config = get_config_dict()
    is_quote_reminder_working = config['other_parameters'][
        'is_quote_reminder_working']
    is_quote_cancellation_working = config['other_parameters'][
        'is_quote_cancellation_working']

    cron_trigger_cancellation = CronTrigger(hour=7, minute=30, second=0)
    cron_trigger_reminder = CronTrigger(hour=8, minute=00, second=0)
    cron_trigger_backup = CronTrigger(day=1, hour=8, minute=15, second=0)

    quote_cancellation_scheduler.add_job(func=quote_cancellation,
                                         trigger=cron_trigger_cancellation)
    quote_reminder_scheduler.add_job(func=quote_reminder,
                                     trigger=cron_trigger_reminder)
    backup_scheduler.add_job(func=backup_data, trigger=cron_trigger_backup)

    quote_cancellation_scheduler.start()
    quote_reminder_scheduler.start()
    backup_scheduler.start()

    if not is_quote_reminder_working:
        quote_reminder_scheduler.pause()

    if not is_quote_cancellation_working:
        quote_cancellation_scheduler.pause()

    atexit.register(lambda: quote_reminder_scheduler.shutdown())
    atexit.register(lambda: quote_cancellation_scheduler.shutdown())
    atexit.register(lambda: backup_scheduler.shutdown())
Ejemplo n.º 4
0
def quote_cancellation():
    """ Function used in a scheduler to run everyday.
    Take information from config.json for the number of days before a quote is expired.

    Loop through every quotes in waiting state and check how long it has been in this state.
    Change the state to cancelled of every quote exceeding the number of days before a quote is expired.

    If a quote has its state changed, it also deletes the quote pdf file in the 'reminder' folder.
    """
    with db.app.app_context():
        number_of_quote_cancelled = 0

        config = get_config_dict()
        days_before_quote_cancellation = config['other_parameters']['days_before_quote_cancellation']

        quotes_in_waiting_state = get_quote_by_state_only("waiting")
        today_date = datetime.datetime.today()

        for quote in quotes_in_waiting_state:
            days_elapsed_since_quote_sent = (today_date - quote.quoteDate).days

            if days_elapsed_since_quote_sent >= days_before_quote_cancellation:
                query_quote.update_quote_state(quote, 'cancelled')
                query_log.insert_log('Le devis ' + str(quote.quoteNumber) + ' est passé à l\'état Annulé suite à son ' +
                                     'expiration', 'quote_cancellation_scheduler')
                Quote.delete_quote_pdf_file_reminder(quote.quotePdfName, 'cancelled')
                number_of_quote_cancelled += 1

        # We wait 1 second to be sure that the last log of the scheduler is the summary
        time.sleep(1)
        query_log.insert_log("Le programme d'annulation automatique de devis expirés s'est exécuté - Nombre de devis "
                             + "expirés : " + str(number_of_quote_cancelled), 'quote_cancellation_scheduler')
Ejemplo n.º 5
0
def get_document_object_from_pdf_content(pdf_content):
    """ With the content of a pdf in string, it returns
    an instance of an object depending on the type of
    the document:
        - Quote
        - Order
        - Invoice

    Returns None if the document type hasn't been found
    """

    config = get_config_dict()

    regex_quote = config['pdf_processing_parameters']['regex_quote']
    regex_order = config['pdf_processing_parameters']['regex_order']
    regex_invoice = config['pdf_processing_parameters']['regex_invoice']

    regex_quote_without_whitespace = re.sub(" ", "", regex_quote)
    regex_order_without_whitespace = re.sub(" ", "", regex_order)
    regex_invoice_without_whitespace = re.sub(" ", "", regex_invoice)

    if re.search(regex_quote, pdf_content) or \
            re.search(regex_quote_without_whitespace, pdf_content):
        return quote.Quote(pdf_content=pdf_content)

    elif re.search(regex_order, pdf_content) or \
            re.search(regex_order_without_whitespace, pdf_content):
        return order.Order(pdf_content=pdf_content)

    elif re.search(regex_invoice, pdf_content) or \
            re.search(regex_invoice_without_whitespace, pdf_content):
        return invoice.Invoice(pdf_content=pdf_content)

    return None
Ejemplo n.º 6
0
def insert_log(message, type_log, error=False):
    config = get_config_dict()
    max_number_of_logs = config['other_parameters']['max_number_of_logs']

    number_of_logs = get_log_count()

    while number_of_logs >= max_number_of_logs:
        delete_oldest_log()
        number_of_logs = number_of_logs - 1

    new_log = LogTable(message=message, typeLog=type_log, error=error)
    db.session.add(new_log)
    db.session.commit()
Ejemplo n.º 7
0
def save_pdf():
    pdf_file = request.files['pdf']
    data = json.loads(request.form['data'])
    config = get_config_dict()

    document = pdf.get_object_from_document_type(
        data['documentData']['documentType'], data)

    save_file_path_archive = config["pdf_processing_parameters"]["save_file_path_archive"] + "\\" \
                             + data["documentData"]["documentName"]
    save_file_path_reminder = config["pdf_processing_parameters"]["save_file_path_reminder"] + "\\" \
                              + data["documentData"]["documentName"]
    try:
        if config["other_parameters"]["add_girbau_logo_pdf"]:
            pdf_file_with_girbau_logo = pdf.merge_two_pdf(
                pdf_file, document.get_overlay_logo_girbau_pdf())
            with open(save_file_path_archive, 'wb') as new_pdf_archive:
                new_pdf_archive.write(pdf_file_with_girbau_logo.getbuffer())

            if data['documentData']['documentType'] == "quote":
                pdf_file_with_girbau_logo.seek(0)
                with open(save_file_path_reminder, 'wb') as new_pdf_reminder:
                    new_pdf_reminder.write(
                        pdf_file_with_girbau_logo.getbuffer())

            pdf_file_with_girbau_logo.close()

        else:
            pdf_file.save(save_file_path_archive)
            if data['documentData']['documentType'] == "quote":
                pdf_file.seek(0)
                pdf_file.save(save_file_path_reminder)

        pdf_file.close()
        query.insert_log(
            "Le document " + data["documentData"]["documentName"] +
            " a été sauvegardé sur le serveur", 'pdf-processing')

        response = {"success": True}
        return jsonify(response), 200

    except FileNotFoundError:
        query.insert_log(
            "Une erreur est survenue lors de la sauvegarde du document " +
            data["documentData"]["documentName"] + " sur le serveur",
            'pdf-processing',
            error=True)

        return "An error has occurred while saving the file. Problem with the save path", 400
Ejemplo n.º 8
0
def send_mail():
    pdf_file = request.files['pdf']
    data = json.loads(request.form['data'])
    config = get_config_dict()

    document = pdf.get_object_from_document_type(
        data['documentData']['documentType'], data)

    client_mail = data['clientData']['clientMail']
    email_subject = document.get_email_subject()
    email_body = document.get_email_body()

    try:
        if config["other_parameters"]["add_girbau_logo_pdf"]:
            pdf_file_with_girbau_logo = pdf.merge_two_pdf(
                pdf_file, document.get_overlay_logo_girbau_pdf())
            send_email_to_client(client_mail, email_subject, email_body,
                                 pdf_file_with_girbau_logo, pdf_file.filename)
            pdf_file_with_girbau_logo.close()

        else:
            send_email_to_client(client_mail, email_subject, email_body,
                                 pdf_file, pdf_file.filename)

        query.insert_log(
            "Un e-mail a été envoyé au client " +
            data['clientData']['clientName'] + " avec le document " +
            data["documentData"]["documentName"], 'pdf-processing')

        pdf_file.close()

        response = {"success": True}
        return jsonify(response), 200

    except smtplib.SMTPException:
        query.insert_log(
            "Une erreur est survenue lors de l'envoi de l'e-mail au client " +
            data["clientData"]["clientName"] + " avec le document " +
            data["documentData"]["documentName"],
            'pdf-processing',
            error=True)

        return "An error has occurred when sending the email", 400
Ejemplo n.º 9
0
    def delete_quote_pdf_file_reminder(quote_pdf_filename, quote_state):
        """ Try to delete the quote_pdf_filename in the 'reminder' folder if it exists.

        :param quote_pdf_filename: The PDF file to delete
        :param quote_state: The state's quote used to know which log to insert
        """
        if quote_pdf_filename is not None:
            config = get_config_dict()
            path_pdf_file = config['pdf_processing_parameters'][
                'save_file_path_reminder'] + "\\" + quote_pdf_filename

            try:
                os.remove(path_pdf_file)
                if quote_state == 'validated':
                    query_log.insert_log(
                        "Le devis " + quote_pdf_filename +
                        " a été supprimé du dossier de relance " +
                        "de devis suite à sa validation", 'unarchive')
                if quote_state == 'cancelled':
                    query_log.insert_log(
                        "Le devis " + quote_pdf_filename +
                        " a été supprimé du dossier de relance " +
                        "de devis suite à son annulation", 'unarchive')

            except FileNotFoundError:
                if quote_state == 'validated':
                    query_log.insert_log(
                        "Impossible de supprimer le devis " +
                        quote_pdf_filename + " du dossier de " +
                        "relance de devis suite à sa validation - Le document n'a pas été trouvé "
                        "dans le dossier",
                        'unarchive',
                        error=True)
                if quote_state == 'cancelled':
                    query_log.insert_log(
                        "Impossible de supprimer le devis " +
                        quote_pdf_filename + " du dossier de " +
                        "relance de devis suite à son annulation - Le document n'a pas été trouvé "
                        "dans le dossier",
                        'unarchive',
                        error=True)
Ejemplo n.º 10
0
def backup_data():
    """ Function used in a scheduler to run every month.
    Take information from config.json for :
        - The current backup number
        - The total number of backups
        - The backups saving path

    Saves all data up to date from the database in the backups saving path.

    When the current backup number exceed the total number of backups, it
    cycles back to 0, overwriting the oldest backup saved.

    Data saved:
        - Clients
        - Quotes
        - Orders
        - Invoices
    """
    with db.app.app_context():
        config = get_config_dict()

        current_backup_number = config['current_backup_number']
        number_of_backups = config['other_parameters']['number_of_backups']
        backup_path = config['other_parameters']['save_file_path_backups']

        current_backup_path = backup_path + "\\" + str(current_backup_number)
        try:
            if not os.path.exists(current_backup_path):
                os.mkdir(current_backup_path)

            __delete_previous_backup(current_backup_path)
            __make_data_backup(current_backup_path)

            update_config_backup_number((current_backup_number + 1) % number_of_backups)

            query_log.insert_log('Une sauvegarde des données a été réalisée', 'database')

        except IOError:
            query_log.insert_log('Une erreur est survenue lors de l\'exécution de la sauvegarde des données - '
                                 'Veuillez vérifier le chemin de sauvegarde des backups', 'database', error=True)
Ejemplo n.º 11
0
def quote_reminder():
    """ Function used in a scheduler to run everyday.
    Take information from config.json for :
        - The path for the 'reminder' folder where the quote pdf files are
        - The number of days before the first reminder is sent
        - The number of days before the second reminder is sent

    Loop through every quotes in waiting state and check how long it has been in this state.
    Send an email with the quote in PDF format in attachment to the client of the quote if
    it exceeds the time before the first reminder or second reminder is sent.

    Uses the pdf file in the folder 'reminder' given by the path in the config.json
    """
    with db.app.app_context():
        number_of_mail_sent = 0

        config = get_config_dict()
        path_folder_reminder = config['pdf_processing_parameters'][
            'save_file_path_reminder']
        days_before_first_reminder = config['other_parameters'][
            'days_before_first_reminder']
        days_before_second_reminder = config['other_parameters'][
            'days_before_second_reminder']

        first_reminder_email_subject = Quote.get_first_reminder_email_subject()
        first_reminder_email_body = Quote.get_first_reminder_email_body()
        second_reminder_email_subject = Quote.get_second_reminder_email_subject(
        )
        second_reminder_email_body = Quote.get_second_reminder_email_body()

        quotes_in_waiting_state = get_quote_by_state_only("waiting")
        today_date = datetime.datetime.today()

        try:
            smtp_server = connect_to_smtp_server()

            for quote in quotes_in_waiting_state:
                if __has_got_all_reminders(quote):
                    continue

                days_elapsed_since_quote_sent = (today_date -
                                                 quote.quoteDate).days

                if __can_send_first_reminder(quote,
                                             days_elapsed_since_quote_sent,
                                             days_before_first_reminder):
                    if __try_sending_reminder(smtp_server,
                                              quote,
                                              first_reminder_email_subject,
                                              first_reminder_email_body,
                                              path_folder_reminder,
                                              quote.quotePdfName,
                                              is_first_reminder=True):
                        number_of_mail_sent += 1

                elif __can_send_second_reminder(quote,
                                                days_elapsed_since_quote_sent,
                                                days_before_second_reminder):
                    if __try_sending_reminder(smtp_server,
                                              quote,
                                              second_reminder_email_subject,
                                              second_reminder_email_body,
                                              path_folder_reminder,
                                              quote.quotePdfName,
                                              is_first_reminder=False):
                        number_of_mail_sent += 1

            smtp_server.quit()

            # We wait 1 second to be sure that the last log of the scheduler is the summary
            time.sleep(1)
            query_log.insert_log(
                "Le programme de relance automatique de devis s'est exécuté - Nombre d'e-mails "
                + "envoyés : " + str(number_of_mail_sent), 'scheduler')

        except Exception as e:
            print(e)
            query_log.insert_log(
                "Une erreur est survenue lors du programme de relance automatique des devis "
                +
                "- Impossible de se connecter au serveur SMTP, veuillez vérifier les paramètres "
                + "d'envoi d'e-mail dans l'onglet \"Paramètres\"",
                'scheduler',
                error=True)