File size: 2,944 Bytes
2c59485
 
 
 
 
7c75767
28b188b
7c75767
2c59485
7c75767
9f9b802
7c75767
9f9b802
2c59485
9f9b802
28b188b
 
 
a07d7fa
28b188b
2c59485
28b188b
9f9b802
2c59485
28b188b
 
2c59485
9f9b802
 
2c59485
 
28b188b
 
 
7c75767
 
 
 
 
28b188b
7c75767
28b188b
 
 
 
 
 
 
 
 
2c59485
 
 
28b188b
2c59485
28b188b
2c59485
 
7c75767
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f9b802
7c75767
 
2c59485
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt

def process_data(df):
    # Clean data and handle missing values
    df = df[['Project Category', 'Logged']].copy()
    df = df.dropna(subset=['Project Category'])  # Remove rows with missing categories
    
    # Convert to string and consolidate categories
    df['Category'] = df['Project Category'].apply(
        lambda x: 'Billable' if 'Billable' in str(x) else str(x).strip()
    )
    
    # Aggregate data
    summary = df.groupby('Category')['Logged'].sum().reset_index()
    total = summary['Logged'].sum()
    summary['Percentage'] = (summary['Logged'] / total * 100).round(1)
    
    return summary

def create_pie_chart(data):
    fig, ax = plt.subplots(figsize=(6, 6))
    wedges, texts, autotexts = ax.pie(
        data['Logged'],
        labels=data['Category'],
        autopct='%1.1f%%',
        colors=['#4CAF50', '#FFC107', '#9E9E9E'],
        startangle=90
    )
    plt.setp(autotexts, size=10, weight="bold", color='white')
    ax.set_title('Overall Utilization', pad=20)
    return fig

def create_bar_chart(df):
    # Filter and prepare non-billable data
    non_billable = df[df['Category'] == 'Non-Billable']
    non_billable = non_billable.groupby('Project Category')['Logged'].sum().reset_index()
    
    fig, ax = plt.subplots(figsize=(10, 4))
    non_billable.plot(
        kind='bar',
        x='Project Category',
        y='Logged',
        ax=ax,
        legend=False
    )
    ax.set_title('Non-Billable Details')
    ax.set_ylabel('Hours')
    plt.xticks(rotation=45)
    return fig

def main():
    st.title('QA Utilization Dashboard')
    
    uploaded_file = st.file_uploader("Upload Timesheet", type=['xls', 'xlsx'])
    
    if uploaded_file:
        try:
            df = pd.read_excel(uploaded_file, sheet_name='Report')
            processed_data = process_data(df)
            
            # Show main visualization
            st.header("Overall Utilization")
            col1, col2 = st.columns([2, 1])
            
            with col1:
                if not processed_data.empty:
                    st.pyplot(create_pie_chart(processed_data))
                else:
                    st.warning("No data available for visualization")
            
            with col2:
                st.dataframe(
                    processed_data[['Category', 'Logged', 'Percentage']],
                    hide_index=True,
                    column_config={
                        'Logged': 'Hours',
                        'Percentage': st.column_config.NumberColumn(format="%.1f%%")
                    }
                )
            
            # Show non-billable details
            st.header("Non-Billable Breakdown")
            st.pyplot(create_bar_chart(processed_data))
            
        except Exception as e:
            st.error(f"Error processing file: {str(e)}")

if __name__ == "__main__":
    main()