Commit a1dce9bd authored by Anthony Jacob's avatar Anthony Jacob
Browse files

initial commit with script already done

parent 50eb25c2
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+3 −0
Original line number Diff line number Diff line
Facture*.docx
Facture*.pdf
venv/

Recettes.xlsx

0 → 100644
+40.1 KiB

File added.

No diff preview for this file type.

generer.bat

0 → 100644
+1 −0
Original line number Diff line number Diff line
cmd /k "cd /d C:\Users\antho\dev_workspace\script-facture\venv\Scripts & .\activate.bat & cd /d C:\Users\antho\dev_workspace\script-facture & python .\main.py"
 No newline at end of file

main.py

0 → 100644
+212 −0
Original line number Diff line number Diff line
import os
import comtypes.client
import locale
from docx import Document
from datetime import datetime
from openpyxl import load_workbook


HEADER_INDEX = {
        "date": 0,
        "invoice": 1,
        "surname": 2,
        "name": 3,
        "wire": 4,
        "banknote": 5,
        "checknote": 6,
        "street": 8,
        "postcode": 9,
        "city": 10,
    }


def main():
    locale.setlocale(locale.LC_ALL, 'fr_FR')
    print("------ génération des factures ------")

    print("------ ouverture du fichier Recettes.xlsx ------")
    excel = load_workbook(filename=os.path.abspath("Recettes.xlsx"))

    month_choice = ""
    print(excel.sheetnames)

    while (month_choice not in excel.sheetnames):
        month_choice = input("pour quelle feuille souhaitez vous generer les factures? ")
        if (month_choice not in excel.sheetnames):
            print("le choix n'est pas valide")

    month_choice_int = excel.sheetnames.index(month_choice)

    worksheet = excel.worksheets[month_choice_int]

    start_line = line_input("numéro de ligne de debut: ") - 1
    end_line = line_input("numéro de ligne de fin: ", worksheet.max_row)

    word = open_com_word()

    for row in range(start_line, end_line):

        invoice_data = process_data(worksheet, row)
        if (invoice_data is not None):
            generate_docx_invoice(invoice_data)
            generate_pdf_invoice(word, invoice_data)

    close_com_word(word)

    # with open('input.csv', newline='') as csvfile:
    #    client_reader = csv.DictReader(csvfile, delimiter=';', quotechar='|')
    #    word = open_com_word()
    #    for row in client_reader:
    #        print("\n\ngénération de la facture pour la ligne")
    #        print(row)
    #        invoice_date = datetime.strptime( row['date'], '%d/%m/%Y')

    #        filename = "Facture NF." + row['num_facture'] + row['prenom'][0] + row['nom']
    #        # filename = invoice_date.strftime('%Y%m%d') + " " + row['nom'] + " " + row['prenom']
    #        # filename = datetime.today().strftime('%Y%m%d') + " " + row['nom'] + " " + 'dest'

    #        generate_docx_invoice(row, filename)

    #        generate_pdf_invoice(word, filename)

    #    close_com_word(word)


def process_data(worksheet, row):
    invoice_data = dict()
    index = 0

    for column in worksheet.iter_cols(1, worksheet.max_column):
        if (index == HEADER_INDEX["date"]):
            try:
                if (type(column[row].value) == datetime):
                    invoice_data["date_long"] = column[row].value.strftime('%A %d %B %Y')
                    invoice_data["date_short"] = column[row].value.strftime('%d/%m/%Y')
                else:
                    invoice_data["date_long"] = datetime.strptime(column[row].value, '%d-%m-%Y').strftime('%A %d %B %Y')
                    invoice_data["date_short"] = datetime.strptime(column[row].value, '%d-%m-%Y').strftime('%d/%m/%Y')
            except (ValueError, TypeError):
                pass
        elif (index == HEADER_INDEX["invoice"]):
            # if None or empty, no need to generate the invoice
            if (column[row].value is None or column[row].value == ""):
                return None
            invoice_data["invoice_number"] = column[row].value
        elif (index == HEADER_INDEX["surname"]):
            invoice_data["surname"] = column[row].value
        elif (index == HEADER_INDEX["name"]):
            invoice_data["name"] = column[row].value
        elif (index == HEADER_INDEX["wire"] and column[row].value and column[row].value != ""):
            invoice_data["price"] = column[row].value
        elif (index == HEADER_INDEX["banknote"] and column[row].value and column[row].value != ""):
            invoice_data["price"] = column[row].value
        elif (index == HEADER_INDEX["checknote"] and column[row].value and column[row].value != ""):
            invoice_data["price"] = column[row].value
        elif (index == HEADER_INDEX["street"]):
            invoice_data["street"] = ""
            if (column[row].value is not None):
                invoice_data["street"] = column[row].value
        elif (index == HEADER_INDEX["postcode"]):
            invoice_data["postcode"] = ""
            if (column[row].value is not None):
                invoice_data["postcode"] = column[row].value
        elif (index == HEADER_INDEX["city"]):
            invoice_data["city"] = ""
            if (column[row].value is not None):
                invoice_data["city"] = column[row].value

        index += 1

    # name_split = invoice_data["surname"].split(" ")
    # if (len(name_split) > 1):
    #     invoice_data["filename"] = "Facture NF." + str(invoice_data["invoice_number"]) + invoice_data["surname"][0] + invoice_data["name"]
    # else:
    #     invoice_data["filename"] = "Facture NF." + str(invoice_data["invoice_number"]) + invoice_data["surname"] + invoice_data["name"]
    invoice_data["filename"] = "Facture NF." + str(invoice_data["invoice_number"]) + invoice_data["surname"][0] + invoice_data["name"]

    return invoice_data


def generate_docx_invoice(invoice_data):
    print("------ generation du fichier " + invoice_data["filename"] + ".docx ------")
    print(os.path.abspath(invoice_data["filename"] + ".docx"))
    template: Document = Document("template.docx")

    replace_string_document(template, "XXSURNAMEXX", str(invoice_data["surname"]))
    replace_string_document(template, "XXNAMEXX", str(invoice_data["name"]))
    replace_string_document(template, "XXSTREETXX", str(invoice_data["street"]))
    replace_string_document(template, "XXPOSTCODEXX", str(invoice_data["postcode"]))
    replace_string_document(template, "XXCITYXX", str(invoice_data["city"]))
    replace_string_document(template, "XXPRICEXX", "{0:.2f}".format(invoice_data["price"]).replace(".", ","))
    replace_string_document(template, "XXDATEXX", str(invoice_data["date_short"]))
    replace_string_document(template, "XXDATELONGXX", str(invoice_data["date_long"]))
    replace_string_document(template, "XXINVOICEXX", str(invoice_data["invoice_number"]))

    template.save(invoice_data["filename"] + ".docx")
    del template


def open_com_word():
    print("------ ouverture de word ------")
    word = comtypes.client.CreateObject('Word.Application')
    word.visible = False
    return word


def close_com_word(word):
    print("\n------ fermeture de word ------")
    word.Quit()


def generate_pdf_invoice(word, invoice_data):

    print("------ generation du fichier " + invoice_data["filename"] + ".pdf ------")
    wdFormatPDF = 17

    in_file = os.path.abspath(invoice_data["filename"] + ".docx")
    out_file = os.path.abspath(invoice_data["filename"] + ".pdf")

    print(out_file)

    doc = word.Documents.Open(in_file)
    doc.SaveAs(out_file, FileFormat=wdFormatPDF)
    doc.Close()


def replace_string_document(document: Document, old_text: str, new_text: str):
    for paragraph in document.paragraphs:
        replace_string_paragraph(paragraph, old_text, new_text)

    for table in document.tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    replace_string_paragraph(paragraph, old_text, new_text)


def replace_string_paragraph(paragraph, old_text: str, new_text: str):
    # print(f"try to replace {old_text} by {new_text}")
    if old_text in paragraph.text:
        # Loop added to work with runs (strings with same style)
        for inline in paragraph.runs:
            if old_text in inline.text:
                text = inline.text.replace(old_text, new_text)
                inline.text = text


def line_input(message, max_allowed=None):
    correct = False
    while (not correct):
        line = input(message)
        try:
            line = int(line)
            if (max_allowed is not None and line > max_allowed):
                raise ValueError
            correct = True
        except ValueError:
            print("le numéro de ligne n'est pas valide")
    return line


if __name__ == '__main__':
    main()

requirements.txt

0 → 100644
+7 −0
Original line number Diff line number Diff line
comtypes==1.1.14
docx==0.2.4
et-xmlfile==1.1.0
lxml==4.9.1
openpyxl==3.0.10
Pillow==9.3.0
python-docx==0.8.11
Loading