示例#1
0
def render_vrije_dagen_page(output_folder: Path):

    table = VBlock([
        Table(
            vrije_dagen_overzicht(),
            TableConfig(
                headers=[
                    'Naam', 'Vorig jaar', 'Dit jaar nieuw',
                    'Dit jaar beschikbaar', 'Totaal', 'Pool'
                ],
                aligns=['left', 'right', 'right', 'right', 'right', 'right'],
                formats=['', '.5', '.5', '.5', '.5', '.5'],
                totals=[0, 0, 0, 0, 0, 1],
            ),
        ),
    ])

    page = Page([
        TextBlock('Vrije dagen', HEADER_SIZE),
        table,
        TextBlock(
            f'Pool = Dagen van vorig jaar + Dagen dit jaar * deel van het jaar dat is geweest ({fraction_of_the_year_past()*100:.0f}%).'
        ),
    ])
    page.render(output_folder / 'freedays.html')
示例#2
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")
示例#3
0
def commerce_block():
    minimal_interesting_amount = 20000
    sales_waarde_value = sales_waarde()
    top_sales = top_x_sales(minimal_amount=minimal_interesting_amount)
    sales_waarde_color = dependent_color(sales_waarde_value, 250000, 350000)
    commerce = VBlock([
        TextBlock("Commerce", HEADER_SIZE),
        TextBlock("Saleswaarde", MID_SIZE, padding=10),
        TextBlock(
            "Verwachte omzet maal kans van alle actieve<br/>salestrajecten.",
            color=GRAY,
        ),
        TextBlock(
            sales_waarde_value,
            HEADER_SIZE,
            text_format="K",
            color=sales_waarde_color,
            tooltip="Som van openstaande trajecten<br/>maal hun kans.",
        ),
        TrendLines().chart("sales_waarde",
                           250,
                           150,
                           min_y_axis=0,
                           x_start=months_ago(6)),
        VBlock(
            [
                TextBlock(f"Top {len(top_sales)} sales kansen", MID_SIZE),
                TextBlock(
                    f"Met een verwachte waarde van minimaal € {minimal_interesting_amount}.",
                    color=GRAY,
                ),
                Table(
                    top_sales,
                    TableConfig(headers=[],
                                aligns=["left", "right"],
                                formats=["", "€"]),
                ),
            ],
            link="sales.html",
        ),
        # klanten_block()
        travelbase_block(),
    ])
    return commerce
示例#4
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
示例#5
0
def render_travelbase_page(output_folder):
    bookings = get_bookings_per_week(booking_type='bookings')
    if not isinstance(bookings, pd.DataFrame):
        return  # An error occurred, no use to proceed
    totals = [(brand, bookings[brand].sum()) for brand in BRANDS]
    totals_table = Table(
        totals,
        TableConfig(aligns=['left', 'right'], formats=['', '0'], totals=[0,
                                                                         1]))
    page = Page([
        TextBlock('Travelbase', HEADER_SIZE),
        TextBlock(
            'Aantal boekingen per week. Weken lopen van maandag t/m zondag.',
            color='gray'),
        bar_chart(bookings, 600, 400),
        totals_table,
    ])

    page.render(output_folder / 'travelbase.html')
示例#6
0
def klanten_block():
    klanten = VBlock(
        [
            TextBlock("Klanten", MID_SIZE),
            TextBlock("Top 3 klanten laatste 6 maanden",
                      DEF_SIZE,
                      padding=10,
                      color=GRAY),
            Table(
                top_x_klanten_laatste_zes_maanden(3),
                TableConfig(
                    headers=[],
                    aligns=["left", "right", "right"],
                    formats=["", "€", "%"],
                    totals=[0, 0, 1],
                ),
            ),
        ],
        link="clients.html",
    )
    return klanten
示例#7
0
def render_sales_page(output_folder: Path):

    sales_trajecten = VBlock([
        TextBlock('Actieve&nbsp;salestrajecten', MID_SIZE),
        Table(
            sales_waarde_details(),
            TableConfig(
                headers=[
                    'klant', 'project', 'grootte', 'kans', 'fase', 'waarde',
                    'bron'
                ],
                aligns=[
                    'left', 'left', 'right', 'right', 'left', 'right', 'left'
                ],
                formats=['', '', '€', '%', '', '€', ''],
                totals=[0, 0, 1, 0, 0, 1, 0],
            ),
        ),
    ])

    pijplijn = VBlock([
        TextBlock('Werk&nbsp;in&nbsp;de&nbsp;pijplijn', MID_SIZE),
        TextBlock('Moet uit Simplicate komen'),
        # Table(
        #     werk_in_pijplijn_details(),
        #     TableConfig(
        #         headers=['klant', 'project', '% af', 'onderhanden', 'eigenaar'],
        #         aligns=['left', 'left', 'right', 'right', 'left'],
        #         formats=['', '', '%', '€', ''],
        #         totals=[0, 0, 0, 1, 0],
        #     ),
        # ),
    ])

    page = Page(
        [TextBlock('Sales', HEADER_SIZE),
         HBlock([sales_trajecten, pijplijn])])

    page.render(output_folder / 'sales.html')
示例#8
0
def render_debiteuren_page(output_folder: Path):
    debiteuren = debiteuren_leeftijd_analyse()
    if not isinstance(debiteuren, pd.DataFrame):
        return  # Error occurred, no use to proceed
    page = Page([
        TextBlock('Debiteuren', HEADER_SIZE),
        Table(
            debiteuren,
            TableConfig(
                headers=[
                    'klant', 'openstaand', '<30 dg', '30-60 dg', '60-90 dg',
                    '> 90 dg'
                ],
                aligns=['left', 'right', 'right', 'right', 'right', 'right'],
                formats=['', '.', '.', '.', '.', '.'],
                totals=[0, 1, 1, 1, 1, 1],
                row_linking=lambda line, value:
                'https://oberview.oberon.nl/facturen/openstaand',
            ),
        ),
    ])
    page.render(output_folder / 'debiteuren.html')
示例#9
0
def render_detailpage():
    data = [[key, saved_cache[key]] for key in sorted(saved_cache.keys())]
    page = Page([Table(data)])
    page.render('output/details.html')
示例#10
0
def render_productiviteit_page():
    tables = HBlock([
        Table(
            productiviteit_overzicht(),
            block_id='overzicht',
            headers=[
                'persoon',
                'omzet',
                'uren',
                'per uur',
                'geboekt',
                'productief',
                '% productief',
                'billable',
                '% billable',
            ],
            aligns=[
                'left', 'right', 'right', 'right', 'right', 'right', 'right',
                'right', 'right'
            ],
            formats=['', '€', '.', '€', '.', '.', '%', '.', '%'],
            totals=[0, 1, 1, 0, 1, 1, 0, 1, 0],
        )
    ])

    for user in tuple_of_productie_users():
        data = productiviteit_persoon(user)
        target = user_target(user)
        if target:
            total = sum([row[3] for row in data])
            perc = (total / user_target_now(user) - 1) * 100
            percstr = do_format(perc, '+%')
            targetstr = f'target: € {target:,.0f}'.replace(',', '.')
        else:
            targetstr = percstr = ''
        tables.add_block(
            Table(
                data,
                block_id='productiviteit_' + user,
                headers=[user, targetstr, percstr, 'omzet', 'uren', 'per uur'],
                aligns=['left', 'left', 'left', 'right', 'right', 'right'],
                formats=['', '', '', '€', '.', '€'],
                totals=[0, 0, 0, 1, 1, 0],
            ))

    page = Page([
        TextBlock('Productiviteit', HEADER_SIZE),
        VBlock([TextBlock('Under construction', color='red'), tables])
    ])
    page.add_onloadcode('make_users_clickable();')
    page.render('output/productiviteit.html')

    for user in tuple_of_productie_users():
        productiviteit_table = Table(
            productiviteit_persoon(user),
            headers=[user, '', '', 'omzet', 'uren', 'per uur'],
            aligns=['left', 'left', 'left', 'right', 'right', 'right'],
            formats=['', '', '', '€', '.', '€'],
            totals=[0, 0, 0, 1, 1, 0],
        )

        chartdata = [{
            'x': rec['datum'].strftime('%Y-%m-%d'),
            'y': rec['hours']
        } for rec in billable_trend_person(user)]
        chart = ScatterChart(400,
                             400,
                             values=chartdata,
                             color='#6666cc',
                             fill_color='#ddeeff',
                             y_start=0,
                             x_type='date')

        page = Page([
            TextBlock(f'Productiviteit {user}', HEADER_SIZE), chart,
            productiviteit_table
        ])
        page.render(f'output/productiviteit_{user}.html')
示例#11
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')