import datetime as dt import os import numpy as np import pandas as pd import streamlit as st import yaml from yaml.loader import SafeLoader from data.cli_dropbox import dropbox_load_config_files from data.excels import load_fit, load_transform_data, filter_multiple_conditions_data from utils.times import calculate_night_time, calculate_work_time, date_to_week_number from utils.btn_behaviors import reset, validate_duplicate, validate_end from utils.indemnites import calculate_astreinte, calculate_indemnites_km, calculate_overtimes from const import root_path st.set_page_config(layout="wide") with open(os.path.join(root_path, 'config.yaml')) as file: config = yaml.load(file, Loader=SafeLoader) pd.set_option('display.max_columns', None) #TODO download dropbox config files if not 'dropbox_update' in st.session_state.keys(): dropbox_load_config_files('/SEC_IND_GTP2023_INPUT', os.path.join(root_path, 'data/input'), config['data']) st.session_state.dropbox_update = True df = load_transform_data(os.path.join(root_path, 'data/input'), config['data']) # print("session_state", st.session_state) def affaire_change(indexes, df_key): filters = {} new_values = [] for key, value in st.session_state.items(): if key in df[df_key].columns and key not in ['intervenant', 'prestataire']: if st.session_state[key] != '-': filters[key] = value new_values.insert(len(new_values), value) indexes[key] = 0 st.session_state.df[df_key] = filter_multiple_conditions_data(df[df_key], filters) new_row = pd.DataFrame([['-'] * (df[df_key].shape[1])], columns=df[df_key].columns) for key, value in filters.items(): indexes[key] = 1 if value != '-'else 0 st.session_state.df[df_key] = pd.concat([new_row, st.session_state.df[df_key]], ignore_index=True) def intervenant_change(): if "intervenant" in st.session_state and st.session_state.intervenant != '-': st.session_state.contract_hours = st.session_state.df['intervenants'][st.session_state.df['intervenants']['intervenant'] == st.session_state.intervenant]['contrat heures'].values[0] st.session_state.supp_contract_hours = st.session_state.df['intervenants'][st.session_state.df['intervenants']['intervenant'] == st.session_state.intervenant]['contrat heures'].values[0] load_fit(datapath=os.path.join(root_path, 'data/output'), intervenant=st.session_state.intervenant, year=st.session_state.date_input.year, month= st.session_state.date_input.month ,week=date_to_week_number(st.session_state.date_input)) if 'df' not in st.session_state: st.session_state.df = df st.session_state.indexes_all = {k: 0 for k in df['all'].columns} st.session_state.indexes_vehicules = {k: 0 for k in df['vehicules'].columns} st.session_state.indexes_affaire = {k: 0 for k in df['affaire'].columns} st.session_state.indexes_intervenants = {k: 0 for k in df['intervenants'].columns} st.title('SECMI - Gestion des temps passés') codes = st.columns(3) intervenant = codes[0].selectbox('Intervenant', np.sort(st.session_state.df['intervenants'].intervenant.unique()), key='intervenant', on_change=intervenant_change) client = codes[1].selectbox('Client', np.sort(st.session_state.df['affaire'].client.unique()), key='client', on_change=affaire_change, kwargs={'indexes': st.session_state.indexes_affaire, 'df_key': 'affaire'}, index=st.session_state.indexes_affaire['client']) location = codes[2].selectbox('Localisation', np.sort(['En Atelier', 'En Clientèle']), key='location') # prestataire = codes[3].selectbox('Prestataire', np.sort(st.session_state.df['all'].prestataire.unique()), key='prestataire', on_change=value_change, kwargs={'indexes': st.session_state.indexes_all, 'df_key': 'all'}, index=st.session_state.indexes_all['prestataire']) st.session_state.prestataire = st.session_state.df['affaire']['prestataire'][1] affaire = st.selectbox('Affaire', np.sort(st.session_state.df['affaire'].affaire.unique()), key='affaire', on_change=affaire_change, kwargs={'indexes': st.session_state.indexes_affaire, 'df_key': 'affaire'}, index=st.session_state.indexes_affaire['affaire']) vehicules = st.selectbox('vehicules', np.sort(st.session_state.df['vehicules'].vehicules.unique()), key='vehicules')#, on_change=value_change,kwargs={'indexes': st.session_state.indexes_vehicules, 'df_key': 'vehicules'}, index=st.session_state.indexes_vehicules['Description']) absences = st.session_state.df['absences']['Libellé GTP2023'].tolist() absences.remove('Absence Formation') st.session_state.disable_times = True if len([string for string in absences if affaire.find(string) != -1]) else False st.divider() activites = st.text_area('Description des activités effectuées', key="activities_text_area") st.divider() temps = st.columns(5) if 'date_input' not in st.session_state: st.session_state.date_input = dt.datetime.now() # print(df['arrets']) date = temps[0].date_input( label="Date de la mission", value=st.session_state.date_input, min_value=dt.datetime.now() - dt.timedelta(days=15), max_value=dt.datetime.now(), on_change=load_fit, kwargs={'datapath': os.path.join(root_path, 'data/output'), 'intervenant': st.session_state.intervenant, 'year': st.session_state.date_input.year, 'month': st.session_state.date_input.month, 'week': date_to_week_number(st.session_state.date_input)}, key='date_input') # if 'fit' in st.session_state.keys(): # print(st.session_state.fit) # print(date_to_week_number(date), date_to_week_day(date)) public_holyday = temps[0].checkbox('Jour Férié', key="public_holyday") start_time = temps[1].time_input('heure début', dt.time(8, 00), key='start_time_input', disabled=st.session_state.disable_times) end_time = temps[2].time_input('heure fin', dt.time(16, 00), key='end_time_input', disabled=st.session_state.disable_times) pause_time = temps[3].time_input('temps de pause', dt.time(1, 00), step=300, key='pause_time_input') st.session_state.total_hours = calculate_work_time(start_time, end_time, pause_time, date) st.session_state.night_hours = calculate_night_time(start_time, end_time, pause_time, date) if st.session_state.total_hours > 8: st.warning('Les heures de travail enregistrées sont supérieures à 8 heures !') # print(st.session_state.df['supplements'].columns) supplements = temps[4] supplement1 = supplements.selectbox('Supplement 1', st.session_state.df['supplements'].supplements, key = 'supplement1') supplement2 = supplements.selectbox('Supplement 2', st.session_state.df['supplements'].supplements, key = 'supplement2') supplement3 = supplements.selectbox('Supplement 3', st.session_state.df['supplements'].supplements, key = 'supplement3') st.session_state.meal_bonus = 9.15 if st.session_state.total_hours >= 6.15 else 0 st.session_state.personal_tools_bonus = 3.2 if ' Transp. Caisse ' in [supplement1, supplement2, supplement3 ] else 0 st.session_state.intervention_bonus = 1 * st.session_state.total_hours if 'Prime Interv°' in [supplement1, supplement2, supplement3 ] else 0 st.session_state.on_call_bonus = calculate_astreinte() if st.session_state.intervenant != '-' and 'Astreinte Sem' in [supplement1, supplement2, supplement3 ] else 0 st.session_state.team_leader_bonus = 10 if 'Prime Chef Equ' in [supplement1, supplement2, supplement3 ] else 0 # st.session_state.painting_bonus = 1 * st.session_state.total_hours if ' H Peinture ' in [supplement1, supplement2, supplement3 ] else 0 # st.session_state.electrical_bonus = 1 * st.session_state.total_hours if ' H Qualif. Électrique ' in [supplement1, supplement2, supplement3 ] else 0 # st.session_state.welding_bonus = 1 * st.session_state.total_hours if ' H Soudure ' in [supplement1, supplement2, supplement3 ] else 0 st.session_state.overtime25, st.session_state.overtime50, st.session_state.overtime100 = calculate_overtimes() st.session_state.mileage_allowances_bonus , st.session_state.drive_hours = calculate_indemnites_km() year = st.session_state.date_input.year month = st.session_state.date_input.month week = date_to_week_number(st.session_state.date_input) st.divider() infos = st.columns(3, gap="large") infos[0].header(f'Temps total: ') infos[0].write(f'Temps de travail: {st.session_state.total_hours } heure(s)') infos[0].write(f'Temps de pause: {pause_time.hour + (pause_time.minute / 60)} heure(s)') infos[0].write(f'Heure de nuit: {st.session_state.night_hours} heure(s)') infos[0].write(f'Jour Férié: {"oui" if public_holyday else "non"}') if 'fit' in st.session_state.keys() and st.session_state.intervenant in st.session_state['fit'].keys() and year in st.session_state.fit[st.session_state.intervenant].keys() and month in st.session_state.fit[st.session_state.intervenant][year].keys() and week in st.session_state.fit[st.session_state.intervenant][year][month].keys(): infos[0].write(f'Heures indiquées dans le contrat de travail: {st.session_state.contract_hours} heures') if st.session_state.contract_hours > 35: infos[0].write(f'Dont Heures supplémentaires inclues dans le contrat: {st.session_state.supp_contract_hours} heures') infos[0].write(f'Heures totales de travail pour la semaine {week} : {st.session_state.fit[st.session_state["intervenant"]][year][month][week]["totals"]["worked_hours"]} heures') infos[0].write(f'Heure supp 25%: {st.session_state.overtime25} heure(s)') infos[0].write(f'Heure supp 50%: {st.session_state.overtime50} heure(s)') infos[0].write(f'Heure supp 100%: {st.session_state.overtime100} heure(s)') infos[1].header('Informations:') if st.session_state.mileage_allowances_bonus > 0: infos[0].write(f'Heure route: {st.session_state.drive_hours} heure(s)') infos[1].write(f'Indemnités kilométriques: {st.session_state.mileage_allowances_bonus}€') infos[1].write(f'Panier: {st.session_state.meal_bonus}€') infos[1].write(f'Transport de caisse: {st.session_state.personal_tools_bonus}€') infos[1].write(f'Prime d\'intervention: {st.session_state.intervention_bonus}€') infos[1].write(f'Prime d\'astreinte: {st.session_state.on_call_bonus}€') infos[1].write(f'Prime chef d\'équipe: {st.session_state.team_leader_bonus}€') # infos[1].write(f'Autre (Peinture, Soudure, Electricité): {st.session_state.electrical_bonus + st.session_state.painting_bonus + st.session_state.welding_bonus}€') reset_btn = infos[2].button('Effacer', on_click=reset, kwargs={"df": df}) validate_duplicate_btn = infos[2].button('Valider et Dupliquer', on_click=validate_duplicate) validate_end_btn = infos[2].button('Valider et Terminer', on_click=validate_end)