Browse Source

- Saving Overtime in Excel, Fastbill Update

Danny 2 years ago
parent
commit
600d57d6c3

+ 1 - 0
fast_excel_to_bill/config_for_custom_bills.py

@@ -3,6 +3,7 @@ DOCX_INPUT_PATH = r'C:\Users\Danny\Desktop\EnD and Investment\Tools\fast_excel_t
 LIST_OF_KEYS = ['Arbeitszeit', 'Task']
 ROUND_TIME = 300
 
+SAVE_OVERTIME_IN_TABLE = r'C:\Users\Danny\Desktop\EnD and Investment\Tools\time_recoder\time_recorded_tables\overtime_danny.xlsx'
 
 docx_output_dir_path = r'C:\Users\Danny\Desktop\EnD and Investment\Tools\fast_excel_to_bill\test_folder'# Variable cuz search of dir of customer can be implemeted
 list_of_place_holders = ['?Netto?','?zzgl.?', '?gesamt?', 'insertdate'] # variable cuz search can be implemented

+ 2 - 1
fast_excel_to_bill/main.py

@@ -16,7 +16,8 @@ def get_excel_data():
     bill_data_dict = main_data_collection(config_for_custom_bills.employee_worktime_table_pathes, config_for_custom_bills.LIST_OF_KEYS)
 
     # transform data to fomat
-    bill_data_dict, over_time = round_worktime_for_week(bill_data_dict, config_for_custom_bills.ROUND_TIME)
+    bill_data_dict = round_worktime_for_week(bill_data_dict, config_for_custom_bills.SAVE_OVERTIME_IN_TABLE,
+                                                        config_for_custom_bills.ROUND_TIME)
     bill_data_dict = add_sum_to_dict(bill_data_dict, config_for_custom_bills.income_per_hour)
     bill_data_dict = get_task_out_of_tree(bill_data_dict)
     return bill_data_dict

+ 1 - 1
fast_excel_to_bill/transform_excel_data_to_bill_data/chris_format.py

@@ -1,6 +1,6 @@
 from tool_lib.read_table import Read_unordered_Table
 from fast_excel_to_bill.transform_excel_data_to_bill_data.table_config import TABLE_PATH, LIST_OF_KEYS
-
+#TODO Currently not Working
 
 def main():
     table_object = Read_unordered_Table(path=TABLE_PATH, type= 'xlsx').get_values_after_key_as_dict(list_of_keys=LIST_OF_KEYS)

+ 0 - 2
fast_excel_to_bill/transform_excel_data_to_bill_data/table_config.py

@@ -1,2 +0,0 @@
-TABLE_PATH = r'C:\Users\Danny\Desktop\EnD and Investment\Tools\time_recoder\time_recorded_tables\work_time_danny.xlsx'
-LIST_OF_KEYS = ['BESCHREIBUNG','MENGE', 'EINZELPREIS', 'BETRAG']

+ 31 - 6
fast_excel_to_bill/transform_excel_data_to_bill_data/time_recorder_format_main.py

@@ -1,17 +1,42 @@
 from tool_lib.read_table import Read_Table
-from fast_excel_to_bill.transform_excel_data_to_bill_data.table_config import TABLE_PATH
-
+from tool_lib.create_excel_tables import CreateTable
 
 def add_sum_to_dict(work_time_dict, income_per_hour):
     for key in work_time_dict.keys():
         work_time_dict[key]['Betrag'] = int(work_time_dict[key]['Arbeitszeit']*income_per_hour)
     return work_time_dict
 
-def round_worktime_for_week(work_time_dict, round_time = 300):
+
+def save_overtime_in_excel(overtime_dict, overtime_table_path):
+    # Try to read existing Table
+    try:
+        read_table_object = Read_Table(overtime_table_path)
+        table_object = read_table_object.table_to_dict()
+        overtime_dict['Überstunden'] += table_object['Überstunden']
+        overtime_dict['KW'] += table_object['KW']
+    except:
+        pass
+
+    table_tuple = []
+    xlsx = CreateTable(overtime_dict,
+                              path=overtime_table_path)
+    writer = xlsx.create_writer()
+    xlsx.export_to_excel(writer)
+
+    # Add to Table
+
+
+
+
+def round_worktime_for_week(work_time_dict,overtime_table_path, round_time = 300):
+    overtime_dict ={'Überstunden':[], 'KW': []}
     for key in work_time_dict.keys():
-        over_time = work_time_dict[key]['Arbeitszeit'] % round_time # default round to 5 hours
-        work_time_dict[key]['Arbeitszeit'] = (work_time_dict[key]['Arbeitszeit']-over_time)/ 60
-    return work_time_dict, over_time
+        overtime = work_time_dict[key]['Arbeitszeit'] % round_time # default round to 5 hours
+        work_time_dict[key]['Arbeitszeit'] = (work_time_dict[key]['Arbeitszeit']-overtime)/ 60
+        overtime_dict['Überstunden'] += [overtime]
+        overtime_dict['KW'] += [key]
+    save_overtime_in_excel(overtime_dict,overtime_table_path)
+    return work_time_dict
 
 def get_task_out_of_tree(work_time_dict):
     for key in work_time_dict.keys():

+ 278 - 15
tool_lib/create_excel_tables.py

@@ -1,8 +1,12 @@
 import pandas as pd
 import numpy as np
-from pandas import DataFrame
-from styleframe import StyleFrame
+# from pandas import DataFrame
+# from styleframe import StyleFrame
 import xlsxwriter
+import openpyxl
+# import Jinja2
+from openpyxl.worksheet.datavalidation import DataValidation
+
 
 # Values have to be a list of list
 # Title_string have to be a list of list of strings
@@ -16,6 +20,7 @@ class CreateTable:
         self.ordered_by = ordered_by
         self.order = order
         self.column = []
+        self.currency_format = []
         for key, v in self.dict.items():
             self.column += [key]
         if self.order:
@@ -31,10 +36,21 @@ class CreateTable:
         self.dataframes = pd.DataFrame(dict([(k, pd.Series(v)) for k, v in self.dict.items()]), columns=self.column)
 
     def create_writer(self):
-        return pd.ExcelWriter(self.path, engine='xlsxwriter')  #openpyxl xlsxwriter
+        return pd.ExcelWriter(self.path, engine='xlsxwriter')  # openpyxl xlsxwriter
+
+    def create_openpyxl_writer(self):
+        return pd.ExcelWriter(self.path, engine='openpyxl')  # openpyxl xlsxwriter
+
+    def load_openpyxl_workbook(self, additional_path=''):
+        if additional_path:
+            return openpyxl.load_workbook("dropdown.xlsx")
+        return openpyxl.load_workbook("dropdown.xlsx")
 
     def create_workbook(self):
-         return xlsxwriter.Workbook(self.path)
+        return xlsxwriter.Workbook(self.path)
+
+    def create_openpyxl_workbook(self):
+        return openpyxl.Workbook(self.path)
 
     def get_dataframe(self):
         return self.dataframes
@@ -42,6 +58,15 @@ class CreateTable:
     def append_to_csv(self):
         self.dataframes.to_csv(path_or_buf=self.path, index=self.index, mode='a')
 
+    def add_style_(self, style_dict):
+        return self.dataframes.style.format(style_dict)
+
+    def set_style_properties(self, style_dict):
+        return self.dataframes.style.set_properties(**style_dict)
+
+    def create_format(self):
+        self.currency_format = self.create_workbook().add_format()
+
     def export_to_csv(self):
         if self.order:
             raise NotImplementedError
@@ -57,31 +82,269 @@ class CreateTable:
         else:
             self.dataframes = self.dataframes.sort_values(by=self.ordered_by, axis=self.axis)
 
-        #Format
-        currency_format = self.create_workbook().add_format()
-        currency_format.set_align('center')
-        currency_format.set_align('center')
-
+        # Format
+        if self.currency_format:
+            self.currency_format.set_align('center')
+        else:
+            self.create_format()
+            self.currency_format.set_align('center')
 
         # First Tab
         self.dataframes.to_excel(excel_writer=writer, sheet_name='Karte ' + str(1), index=False)
         for column in self.dataframes:
-            column_width = max(self.dataframes[column].astype(str).map(len).max(), len(column)+5)
+            column_width = max(self.dataframes[column].astype(str).map(len).max(), len(column) + 5)
             col_idx = self.dataframes.columns.get_loc(column)
 
-            writer.sheets['Karte ' + str(1)].set_column(col_idx, col_idx, column_width, cell_format=currency_format)
+            writer.sheets['Karte ' + str(1)].set_column(col_idx, col_idx, column_width, cell_format=self.currency_format)
 
         # All other Tabs
 
         for count, each_dataframe in enumerate(additional_dataframes):
-            each_dataframe.to_excel(writer, sheet_name='Karte ' + str(count + 2),index=False)
+            each_dataframe.to_excel(writer, sheet_name='Karte ' + str(count + 2), index=False)
             for column in each_dataframe:
-                column_width = max(each_dataframe[column].astype(str).map(len).max(), len(column)+5)
+                column_width = max(each_dataframe[column].astype(str).map(len).max(), len(column) + 5)
                 col_idx = each_dataframe.columns.get_loc(column)
-                writer.sheets['Karte ' + str(count + 2)].set_column(col_idx, col_idx, column_width, cell_format=currency_format)
+                writer.sheets['Karte ' + str(count + 2)].set_column(col_idx, col_idx, column_width, cell_format=self.currency_format)
         writer.save()
 
-    def append_df_to_xlsx(self, df): #TODO extract even more
+    def append_df_to_xlsx(self, df):  # TODO extract even more
         df_excel = pd.read_excel(self.path)
         self.dataframes = pd.concat([df_excel, df], ignore_index=True)
         self.export_to_excel(self.create_writer())
+
+    def create_custom_excel_economy_calendar(self, writer):
+        if self.ordered_by == []:
+            pass
+        else:
+            self.dataframes = self.dataframes.sort_values(by=self.ordered_by, axis=self.axis)
+
+        # Format
+        self.currency_format = self.create_workbook().add_format()
+        self.currency_format.set_align('center')
+        self.currency_format.set_align('center')
+
+        self.dataframes.to_excel(excel_writer=writer, sheet_name='Karte ' + str(1), index=False)
+        for column in self.dataframes:
+            column_width = max(self.dataframes[column].astype(str).map(len).max(), len(column) + 5)
+            col_idx = self.dataframes.columns.get_loc(column)
+
+            writer.sheets['Karte ' + str(1)].set_column(col_idx, col_idx, column_width, cell_format=self.currency_format)
+
+        writer.save()
+
+    def add_another_page_to_excel(self, additional_dataframes, writer):
+        # Format
+        currency_format = self.create_workbook().add_format()
+        currency_format.set_align('center')
+        currency_format.set_align('center')
+
+        for count, each_dataframe in enumerate(additional_dataframes):
+            each_dataframe.to_excel(writer, sheet_name='Karte ' + str(count + 2), index=False)
+            for column in each_dataframe:
+                column_width = max(each_dataframe[column].astype(str).map(len).max(), len(column) + 5)
+                col_idx = each_dataframe.columns.get_loc(column)
+                writer.sheets['Karte ' + str(count + 2)].set_column(col_idx, col_idx, column_width, cell_format=currency_format)
+        return writer
+
+    def create_hyperlink_from_string(self, name: str):
+        self.dataframes.style.format({name: make_clickable})
+
+
+def make_clickable(val):
+    # target _blank to open new window
+    return '<a target="_blank" href="{}">{}</a>'.format(val, val)
+
+
+class XlsxWriterClass:
+    def __init__(self, path, another_sheet=''):
+        '''
+        :param path: Absolute Path
+        :param list_of_sheets: in this version only two sheets can be created. A little bit sloppy..
+        '''
+        self.path = path
+        self.wb = xlsxwriter.Workbook(self.path)
+        self.ws = self.wb.add_worksheet('Karte 1')
+        self.last_column = 0
+        self.alphabet = ['A', 'B', 'C', 'D', 'E',
+                         'F', 'G', 'H', 'I', 'J',
+                         'K', 'L', 'M', 'N', 'O',
+                         'P', 'Q', 'R', 'S', 'T',
+                         'U', 'V', 'W', 'X', 'Y',
+                         'Z',
+                         'AA', 'AB', 'AC', 'AD', 'AE',
+                         'AF', 'AG', 'AH', 'AI', 'AJ',
+                         'AK', 'AL', 'AM', 'AN', 'AO',
+                         'AP', 'AQ', 'AR', 'AS', 'AT',
+                         'AU', 'AV', 'AW', 'AX', 'AY',
+                         'AZ', ]
+        if another_sheet:
+            self.another_sheet = self.wb.add_worksheet('Karte2')
+            self.last_column_sheet2 = 1
+
+    def create_format_for_data(self, added_style):
+        self.style_ = self.wb.add_format(added_style)
+
+    def del_current_format_for_data(self):
+        self.style_ = False
+
+    def set_column_prop(self, col, width):
+        self.ws.set_column(first_col=col, last_col=col, width=width)
+
+    def set_row(self, count_rows, height):
+        for row in range(1, count_rows):
+            self.ws.set_row(row, height=height)
+
+    def write_data_in_free_column_with_bold_header(self, data, column_range=1, format_=False, data_with_own_format={}):
+        '''
+        :param data: dict format [key: list_of_values] or list of lists
+        :param column_range: only for list of lists
+        :param data_with_own_format: tuple of data and format : (data, format)
+        :return:
+        '''
+
+        assert column_range + self.last_column <= len(self.alphabet), 'Alphabet len is to small add new Columns [self.alphabet]'
+        if data_with_own_format:
+            special_data = data_with_own_format[0]
+            special_data_format = data_with_own_format[1]
+
+        if isinstance(data, dict):
+            for col, key in enumerate(data.keys()):
+                offset=0
+                # Header
+                self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1), key, self.wb.add_format({'bold': True}))
+                if data_with_own_format:
+                    for row in range(1, 1 + len(special_data[key])):
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), special_data[key][row - 1],
+                                      self.wb.add_format(special_data_format))
+                        offset += 1
+                for row in range(1, 1 + len(data[key])):
+                    if format_:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row+offset), data[key][row - 1], self.style_)
+                    else:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row+offset), data[key][row - 1])
+            self.last_column += len(data.keys())
+        else:
+            for col in range(0, column_range):
+                offset=0
+                # Header
+                self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1), data[col][0], {'bold': True})
+                if data_with_own_format:
+                    for row in range(1, 1 + len(special_data[col])):
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), special_data[col][row],
+                                      self.wb.add_format(special_data_format))
+                        offset += 1
+                for row in range(1, 1 + len(data[col])):
+                    if format_:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row+offset), data[col][row], self.style_)
+                    else:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row+offset), data[col][row])
+            self.last_column += len(data)
+
+    def write_dict_of_dicts_in_free_column_with_color_for_each_cell(self, data, column_range=1):
+        '''
+        :param data: dict format [key: {Color: [...], Value : [...]}]
+        :param column_range: len of used columns for dict only in assertions
+        :return:
+        '''
+
+        assert column_range + self.last_column <= len(self.alphabet), 'Alphabet len is to small add new Columns [self.alphabet]'
+        for col, key in enumerate(data.keys()):
+            # Header
+            self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1), key, self.wb.add_format({'bold': True}))
+            for row in range(1, 1 + len(data[key])):
+                self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), data[key][row - 1]['Value'],
+                              self.wb.add_format({'font_color': data[key][row - 1]['Color']}))
+        self.last_column += len(data.keys())
+
+    def write_data_in_free_column_with_custom_style_and_dropdown(self, data, column_range=1, format_=False, source=[1]):
+        '''
+        :param data: dict format [key: list_of_values] or list of lists
+        :param column_range: only for list of lists
+        :param source : list of dropdown values
+        :return:
+        '''
+
+        assert column_range + self.last_column <= len(self.alphabet), 'Alphabet len is to small add new Columns [self.alphabet]'
+        if isinstance(data, dict):
+            for col, key in enumerate(data.keys()):
+                # Header
+                self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1), key, self.wb.add_format({'bold': True}))
+                for row in range(1, 1 + len(data[key])):
+                    if format_:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), data[key][row - 1], self.style_)
+                        self.ws.conditional_format('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'type': 'cell',
+                                                                                                                   'criteria': '>=',
+                                                                                                                   'value': 10,
+                                                                                                                   'format': self.wb.add_format(
+                                                                                                                       {
+                                                                                                                           'bg_color': '#90ee90',
+                                                                                                                           'font_color': 'black'})})
+                        self.ws.data_validation('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'validate': 'list',
+                                                                                                                'source': source
+                                                                                                                })
+                    else:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), data[key][row - 1])
+                        self.ws.conditional_format('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'type': 'cell',
+                                                                                                                   'criteria': '>=',
+                                                                                                                   'value': 10,
+                                                                                                                   'format': self.wb.add_format(
+                                                                                                                       {
+                                                                                                                           'bg_color': '#90ee90',
+                                                                                                                           'font_color': 'black'})})
+                        self.ws.data_validation('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'validate': 'list',
+                                                                                                                'source': source
+                                                                                                                })
+            self.last_column += len(data.keys())
+        else:
+            for col in range(0, column_range):
+                # Header
+                self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1), data[col][0], {'bold': True})
+                for row in range(1, 1 + len(data[col])):
+                    if format_:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), data[col][row], self.style_)
+                        self.ws.conditional_format('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'type': 'cell',
+                                                                                                                   'criteria': '>=',
+                                                                                                                   'value': 10,
+                                                                                                                   'format': self.wb.add_format(
+                                                                                                                       {
+                                                                                                                           'bg_color': '#90ee90',
+                                                                                                                           'font_color': 'black'})})
+                        self.ws.data_validation('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'validate': 'list',
+                                                                                                                'source': source
+                                                                                                                })
+                    else:
+                        self.ws.write('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), data[col][row])
+                        self.ws.conditional_format('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'type': 'cell',
+                                                                                                                   'criteria': '>=',
+                                                                                                                   'value': 10,
+                                                                                                                   'format': self.wb.add_format(
+                                                                                                                       {
+                                                                                                                           'bg_color': '#90ee90',
+                                                                                                                           'font_color': 'black'})})
+                        self.ws.data_validation('{}{}'.format(self.alphabet[col + self.last_column], 1 + row), {'validate': 'list',
+                                                                                                                'source': source
+                                                                                                                })
+            self.last_column += len(data)
+
+    def write_data_in_free_column_on_another_sheet(self, data, column_range=1, format_=False):
+        '''
+        TODO This function does not work properly, generalization is recommended
+        :param data: dict format or list of lists
+        :param column_range:
+        :return:
+        '''
+
+        assert column_range <= len(self.alphabet), 'Alphabet len is to small add new Columns [self.alphabet]'
+        if isinstance(data, dict):
+            pass
+        else:
+            for col in range(0, column_range):  # Generates 99 "ip" address in the Column A;
+                for row in range(self.last_column_sheet2, self.last_column_sheet2 + len(data[col])):
+                    if format_:
+                        self.another_sheet.write('{}{}'.format(self.alphabet[col], row), data[col][row - 1], self.style_)
+                    else:
+                        self.another_sheet.write('{}{}'.format(self.alphabet[col], row), data[col][row - 1])
+            self.last_column_sheet2 = len(data)
+
+    def save_and_close_excel(self):
+        self.wb.close()