Пример #1
0
def percentage_directe_werknemers():
    """DDA Cijfer. Is het percentage productiemedewerkers tov het geheel"""
    period = Period(Day().plus_months(-6))
    productie_users = tuple_of_productie_users()
    return (100 * beschikbare_uren_volgens_rooster(
        period, employees=productie_users)[0] /
            beschikbare_uren_volgens_rooster(period)[0])
Пример #2
0
def hours_block(year, month):
    month_names = []
    data = []
    for m in range(month):
        month_names += [TextBlock(MAANDEN[m])]
        fromday = Day(year, m + 1, 1)
        untilday = fromday.plus_months(1)
        period = Period(fromday, untilday)
        data += [HoursData(period)]
    headers = month_names + ['', 'YTD']
    curyear = datetime.datetime.today().strftime('%Y')
    total_period = Period(curyear + '-01-01')
    data += [None, HoursData(total_period)]
    grid = kpi_grid(headers, data)

    chart = None
    if month >= 3:  # Voor maart heeft een grafiekje niet veel zin
        chart = BarChart(
            [d.omzet
             for d in data[:-2]],  # -2 is lelijk maar haalt de total col eraf
            ChartConfig(
                width=60 * month,
                height=150,
                colors=['#ddeeff'],
                bottom_labels=[MAANDEN[m] for m in range(month)],
                y_axis_max_ticks=5,
            ),
        )

    return VBlock([
        TextBlock('Billable uren', MID_SIZE),
        TextBlock(
            '''Beschikbare uren zijn alle uren die we hebben na afrek van vrije dagen en verzuim.<br/>
                   Klant uren zijn alle uren besteed aan werk voor klanten. <br/>
                   Billable uren is wat er over is na correcties. <br/>
                   Omzet is de omzet gemaakt in die uren.''',
            color=GRAY,
        ),
        grid,
        VBlock([TextBlock('Omzet op uren per maand'), chart],
               css_class="no-print"),
    ])
Пример #3
0
def testqueries():
    df = hours_dataframe()

    def get_diff(row):
        return row['tariff'] and not (row['tariff'] > 0)

    # diff = df.apply( get_diff, axis=1 )
    users = None  # ['Jurriaan Ruitenberg'] #['Caspar Geerlings', 'Kevin Lobine']
    day = Day('2021-01-08')
    end_day = Day('2021-02-01')

    period = Period(day, end_day)
    oud = geboekt_oud(period, users=users, only_clients=1, only_billable=1)
    oudsum = int(oud['hours'].sum() + oud['corrections'].sum())
    oudhours = int(oud['hours'].sum())
    oudcorr = int(oud['corrections'].sum())
    nieuw = geboekt_nieuw(period, users=users, only_clients=1, only_billable=1)
    nieuwsum = int(nieuw['hours'].sum() + nieuw['corrections'].sum())
    nieuwhours = int(nieuw['hours'].sum())
    nieuwcorr = int(nieuw['corrections'].sum())
    if oudsum != nieuwsum:
        a = 1

    while day < end_day:
        print(day)
        next = day.next()
        period = Period(day, next)
        oud = geboekt_oud(period, users=users, only_clients=1, only_billable=1)
        oud_per_user = oud.groupby(['employee'])[['corrections']].sum()
        oudsum = int(oud['corrections'].sum())
        nieuw = geboekt_nieuw(period,
                              users=users,
                              only_clients=1,
                              only_billable=1)
        nieuw_per_user = nieuw.groupby(['employee'])[['corrections']].sum()
        nieuwsum = int(nieuw['corrections'].sum())
        if oudsum != nieuwsum:
            a = 1
        day = next
    pass
Пример #4
0
def render_billable_page(output_folder: Path):
    users = sorted(tuple_of_productie_users())
    fromday = Day().plus_months(-6)
    period = Period(fromday)
    cols = 3
    rows = len(users) // cols + 1
    grid = Grid(rows, cols)
    row = 0
    col = 0
    for user in users:
        labels, hours = billable_trend_person_week(user, period)  # {weekno: hours} dict
        hours_data = HoursData(period, [user])
        chart = BarChart(
            hours,
            ChartConfig(
                width=400,
                height=220,
                colors=['#ddeeff'],
                bottom_labels=labels,
                max_y_axis=40,
                y_axis_max_ticks=5,
            ),
        )
        user_block = VBlock(
            [
                TextBlock(
                    f'{user} {hours_data.effectivity():.0f}%  / {hours_data.billable_perc():.0f}%', font_size=MID_SIZE
                ),
                chart,
            ]
        )
        grid.set_cell(row, col, user_block)
        col += 1
        if col == cols:
            col = 0
            row += 1

    page = Page(
        [
            TextBlock('Billable uren', HEADER_SIZE),
            TextBlock(
                'Billable uren per week het afgelopen halfjaar.<br/><br/>'
                + 'Grafiek toont uren gewerkt op billable projecten zonder rekening te houden met correcties.<br/>'
                + 'Percentages zijn effectiviteit en billable.',
                color="gray",
            ),
            grid,
        ]
    )
    page.render(output_folder / 'billable.html')
Пример #5
0
def operations_data(weeks, total_period=None, total_title=''):
    monday = Day().last_monday()
    hours_data = []
    headers = []
    for w in range(weeks):
        monday_earlier = monday.plus_days(-7)
        period = Period(monday_earlier, monday)
        hours_data = [HoursData(period)] + hours_data
        headers = [monday_earlier.strftime('wk %W')] + headers
        monday = monday_earlier
    if total_period:
        headers += ['', total_title]
        hours_data += [None, HoursData(total_period)]
    return headers, hours_data
Пример #6
0
def render_verzuim_page(output_folder: Path):
    timesheet = Timesheet()
    months = 3
    period = Period(Day().plus_months(-months))
    table = VBlock([
        Table(
            verzuim_list(period),
            TableConfig(
                headers=["Naam", "Dag", "soort", "Dagen"],
                aligns=["left", "left", "left", "right"],
                formats=[
                    "",
                    "",
                    "",
                    ".5",
                ],
                totals=[0, 0, 0, 1],
            ),
        ),
    ])

    verzuim = verzuimpercentage(period)
    verzuim_color = dependent_color(verzuim, 3, 1.5)
    page = Page([
        TextBlock("Verzuim", HEADER_SIZE),
        TextBlock(f"De afgelopen {months} maanden", color=GRAY),
        HBlock([
            VBlock([
                TextBlock("Geboekte uren", DEF_SIZE, color="gray", padding=5),
                TextBlock("Verzuim uren", DEF_SIZE, color="gray"),
                TextBlock("Verzuimopercentage", DEF_SIZE, color="gray"),
            ]),
            VBlock([
                TextBlock(
                    timesheet.normal_hours(period),
                    DEF_SIZE,
                    text_format=".",
                    padding=5,
                ),
                TextBlock(timesheet.absence_hours(period),
                          DEF_SIZE,
                          text_format="."),
                TextBlock(verzuim, verzuim_color, text_format="%1"),
            ]),
        ]),
        table,
    ])
    page.render(output_folder / "absence.html")
Пример #7
0
def update_omzet_per_week():
    """Tabel van dag, omzet waarbij dag steeds de maandag is van de week waar het om gaat"""
    trends = TrendLines()
    trend_name = 'omzet_per_week'
    last_day = trends.second_last_registered_day(
        trend_name)  # Always recalculate the last since hours may have changed
    y, m, d = str(last_day).split('-')
    last_day = BeautifulDate(
        int(y), int(m),
        int(d)) - MO  # Last Monday on or before the last calculated day
    last_sunday = D.today() - SU
    for monday in drange(last_day, last_sunday, 7 * days):
        sunday = monday + 6 * days
        period = Period(monday, monday + 7 * days)
        week_turnover = get_turnover_from_simplicate(period)
        # if monday < BeautifulDate(2021, 1, 1):
        #    week_turnover += get_turnover_from_extranet(monday, sunday)
        trends.update(trend_name, week_turnover, monday)
Пример #8
0
def corrections_block():
    weeks_back = 4
    interesting_correction = 8
    period = Period(Day().plus_weeks(-weeks_back))

    def corrections_percentage_coloring(value):
        return dependent_color(value, red_treshold=5, green_treshold=3)

    def project_link(_, fullline):
        return f"https://oberon.simplicate.com/projects/{fullline[0]}/hours"

    result = VBlock(
        [
            TextBlock("Correcties", MID_SIZE),
            HBlock(
                [
                    TextBlock(
                        corrections_percentage(period),
                        MID_SIZE,
                        text_format="%",
                        color=corrections_percentage_coloring,
                    ),
                    TextBlock(
                        f"correcties op uren van<br/> week {period.fromday.week_number()} "
                        +
                        f"tot en met week {period.fromday.week_number() + weeks_back - 1}.",
                        color=GRAY,
                    ),
                ],
                padding=70,
            ),
            Table(
                largest_corrections(interesting_correction, period),
                TableConfig(
                    headers=[],
                    aligns=["left", "left", "right"],
                    hide_columns=[0],
                    row_linking=project_link,
                ),
            ),
        ],
        link="corrections.html",
    )
    return result
Пример #9
0
def render_operations_page(output_folder: Path, year: int = None):
    weeks = 20
    if year:
        # Use given year. Create page with year name in it
        html_page = f'operations {year}.html'
    else:
        # Use the current year (default)
        year = int(datetime.datetime.today().strftime('%Y'))
        html_page = 'operations.html'
    total_period = Period(f'{year}-01-01', f'{year + 1}-01-01')
    page = Page([
        TextBlock('Operations KPI'
                  's', HEADER_SIZE),
        TextBlock(
            f"Belangrijkste KPI's per week de afgelopen {weeks} weken",
            color="gray",
        ),
        kpi_block(weeks=weeks, total_period=total_period, total_title='YTD'),
    ])
    page.render(output_folder / html_page)
Пример #10
0
def verzuim_block():
    period = Period(Day().plus_months(-3))
    verzuim = verzuimpercentage(period)
    verzuim_color = dependent_color(verzuim, 3, 1.5)
    return VBlock(
        [
            TextBlock("Verzuim", MID_SIZE),
            TextBlock("Verzuimpercentage de laatste 3 maanden",
                      DEF_SIZE,
                      color=GRAY),
            TextBlock(
                verzuim,
                MID_SIZE,
                text_format="%1",
                color=verzuim_color,
                tooltip=
                "Gemiddeld bij DDA in 2019: 3.0%. Groen bij 1,5%, rood bij 3%",
            ),
        ],
        link="absence.html",
    )
Пример #11
0
        ) for i in range(1, 8)]
        untilday = period.untilday if period.untilday else Day()
        ending_day_of_roster = min(timetable.get("end_date", "9999"),
                                   untilday.str)
        while day.str < ending_day_of_roster:
            index = day.week_number() % 2
            tot += table[day.day_of_week()][index]
            day = day.next()

    # Vrij
    timesheet = Timesheet()
    leave = timesheet.leave_hours(period, employees)

    # Ziek
    absence = timesheet.absence_hours(period, employees)

    return float(tot), float(leave), float(absence)


if __name__ == "__main__":
    os.chdir("..")
    load_cache()

    h = hours_dataframe()
    period_ = Period("2021-06-01", "2021-10-01")
    # Get the list of current employees
    employees_ = set(hours_dataframe(period_).employee.unique())

    for e in employees_:
        r, v, z = beschikbare_uren_volgens_rooster(period_, [e])
Пример #12
0
    # 3. Get the balance for this year
    this_year_balance = this_year.groupby(['employee_name']).sum('hours')['hours'] / 8

    # 4. Get the days

    # 4. Put them all in one overview
    overview = pd.concat([year_start, this_year_new, this_year_balance], axis=1).fillna(0)
    overview.columns = ['year_start', 'this_year_new', 'this_year_balance']

    # 5. Plus extra calculated columns
    overview['available'] = overview.apply(lambda x: x['year_start'] + x['this_year_balance'], axis=1)

    # Pool = Last + Year * Frac - Done
    overview['pool'] = overview.apply(lambda x: x['year_start'] + x['this_year_new'] * frac, axis=1)
    overview.reset_index(level=0, inplace=True)

    return overview


def vrije_dagen_pool():
    vrije_dagen_overschot = vrije_dagen_overzicht()['pool'].sum()
    FTEs = aantal_fte()
    return vrije_dagen_overschot / FTEs


if __name__ == '__main__':
    os.chdir('..')
    period = Period(Day().plus_days(-10))
    print(verzuim_list(period))
    print(verzuim_list2(period))
Пример #13
0
def flatten_json(y):
    out = {}

    def flatten(x, name=""):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + "_")
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + "_")
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out


if __name__ == "__main__":
    os.chdir("..")
    load_cache()
    day = Day("2022-01-01")
    sim = simplicate()
    invoiced = invoiced_per_customer(sim, Period("2021-01-01", "2022-01-01"))
    pass
    # ohw = ohw_list(date)
    # print(ohw)
    # print(ohw['ohw'].sum())
Пример #14
0
def render_winstgevendheid_page(output_folder: Path, period=None):
    if period:
        period_description = f'Van {period.fromday} tot {period.untilday}'
    if not period:
        period = Period(Day().plus_months(-12))  # Laatste 12 maanden
        period_description = 'De laatste 12 maanden.'
    client_data = winst_per_klant(period)
    per_client = VBlock([
        TextBlock('Per klant', MID_SIZE),
        Table(
            client_data,
            TableConfig(
                id="winst_per_klant",
                headers=list(client_data.columns),
                aligns=[
                    'left', 'right', 'right', 'right', 'right', 'right',
                    'right', 'right'
                ],
                formats=['', '.', '€', '€', '€', '€', '€', '€'],
                totals=[False, True, True, True, True, True, False, False],
            ),
        ),
    ])

    project_data = winst_per_project(period)
    per_project = VBlock([
        TextBlock('Per project', MID_SIZE),
        Table(
            project_data,
            TableConfig(
                id="winst_per_project",
                headers=list(project_data.columns),
                aligns=[
                    'left', 'left', 'right', 'right', 'right', 'right',
                    'right', 'right', 'right'
                ],
                formats=['', '', '.', '€', '€', '€', '€', '€', '€'],
                totals=[
                    False, False, True, True, True, True, True, False, False
                ],
            ),
        ),
    ])

    person_data = winst_per_persoon(period)
    per_person = VBlock([
        TextBlock('Per persoon (voorlopig)', MID_SIZE),
        Table(
            person_data,
            TableConfig(
                id="winst_per_persoon",
                headers=list(person_data.columns),
                aligns=['left', 'right', 'right', 'right'],
                formats=['', '.', '€', '€'],
                totals=[False, True, True, True],
            ),
        ),
    ])

    page = Page([
        TextBlock('Winstgevendheid', HEADER_SIZE),
        TextBlock(
            f'''{period_description} Uitgaande van een productiviteit van {PRODUCTIVITEIT * 100:.0f}% 
                               en €{OVERIGE_KOSTEN_PER_FTE_PER_MAAND} per persoon per maand bureaukosten.''',
            color=GRAY,
        ),
        HBlock([per_client, per_project, per_person]),
    ])
    page.render(output_folder / 'winstgevendheid.html')
Пример #15
0
    per_person = VBlock([
        TextBlock('Per persoon (voorlopig)', MID_SIZE),
        Table(
            person_data,
            TableConfig(
                id="winst_per_persoon",
                headers=list(person_data.columns),
                aligns=['left', 'right', 'right', 'right'],
                formats=['', '.', '€', '€'],
                totals=[False, True, True, True],
            ),
        ),
    ])

    page = Page([
        TextBlock('Winstgevendheid', HEADER_SIZE),
        TextBlock(
            f'''{period_description} Uitgaande van een productiviteit van {PRODUCTIVITEIT * 100:.0f}% 
                               en €{OVERIGE_KOSTEN_PER_FTE_PER_MAAND} per persoon per maand bureaukosten.''',
            color=GRAY,
        ),
        HBlock([per_client, per_project, per_person]),
    ])
    page.render(output_folder / 'winstgevendheid.html')


if __name__ == '__main__':
    os.chdir('..')
    period = Period('2021-01-01', '2022-01-01')
    render_winstgevendheid_page(get_output_folder(), period)