예제 #1
0
def check_if_has_run_today():
    output_folder = get_output_folder()
    updater_file = output_folder / 'last_updated.txt'
    if updater_file.is_file():
        with open(updater_file) as f:
            last_updated = Day(f.read())
            if last_updated == Day():
                print('Script has already run today: exiting')
                sys.exit()
    with open(updater_file, 'w') as f:
        f.write(str(Day()))
예제 #2
0
파일: main.py 프로젝트: hpharmsen/dashboard
def main():
    '''What it says: the main function'''
    cd_to_script_path()
    output_folder = get_output_folder()
    clear_the_cache = process_command_line_params()
    if clear_the_cache:
        clear_cache()
    load_cache()
    module_initialisations()
    copy_resources(output_folder)
    render_all_pages(output_folder)
예제 #3
0
            DEF_SIZE,
            width=260,
            color=RED,
        ) for err in errs
    ]
    return VBlock([TextBlock("Errors", MID_SIZE)] + error_lines)


# def project_type_chart():
#     # Omzet per type project pie chart
#     data = omzet_per_type_project()
#     project_types = data['project_type'].tolist()
#     project_turnovers = omzet_per_type_project()['turnover'].tolist()
#     return PieChart(
#         260, 520, 'omzet per type project', project_types, project_turnovers, ['#55C', '#C55', '#5C5', '#555', '#5CC']
#     )
#
#
# def product_type_chart():
#     # Omzet per product pie chart
#     product_types = omzet_per_type_product()['product_type'].tolist()
#     product_turnovers = omzet_per_type_product()['turnover'].tolist()
#     return PieChart(
#         240, 520, 'omzet per product', product_types, product_turnovers, ['#5c5', '#C55', '#55C', '#555', '#5CC']
#     )

if __name__ == "__main__":
    os.chdir("..")
    load_cache()
    render_dashboard(get_output_folder())
예제 #4
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')


if __name__ == '__main__':
    os.chdir('..')
    render_vrije_dagen_page(get_output_folder())
예제 #5
0
            ),
        ),
    ])

    winst = VBlock([
        TextBlock('Winst vergelijking', MID_SIZE),
        LineChart(
            [
                winst_per_maand(),
                winst_begroot_per_maand(),
                winst_vorig_jaar_per_maand()
            ],
            ChartConfig(
                width=900,
                height=600,
                labels=MAANDEN,
                colors=['#4285f4', '#f4b400', '#db4437'],
                bottom_labels=['Winst', 'Winst begroot', 'Winst vorig jaar'],
            ),
        ),
    ])

    page = Page([TextBlock('Resultaat', HEADER_SIZE), VBlock([omzet, winst])])

    page.render('output/resultaat_vergelijking.html')


if __name__ == '__main__':
    os.chdir('..')
    render_resultaat_vergelijking_page(get_output_folder())
예제 #6
0
    return grid


def render_onderhanden_werk_page(output_folder: Path):
    day = Day()
    page = Page([
        TextBlock(f'Onderhanden werk per {day.strftime("%d/%m")}',
                  HEADER_SIZE),
        onderhanden_werk_list(day)
    ])
    page.render(output_folder / 'onderhanden.html')


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

    days = [Day('2022-1-1'), Day()]
    for test_day in days:
        test_page = Page([
            TextBlock(f'Onderhanden werk per {test_day.strftime("%d/%m")}',
                      HEADER_SIZE),
            onderhanden_werk_list(test_day),
        ])
        if test_day == Day():
            test_page.render(get_output_folder() / 'onderhanden.html')
        else:
            test_page.render(get_output_folder() /
                             f'onderhanden{test_day}.html')
        print(test_day, ohw_sum(test_day, minimal_intesting_value=1000))
예제 #7
0
                    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')


if __name__ == '__main__':
    os.chdir('..')

    render_billable_page(get_output_folder())
예제 #8
0
    corrections_coloring = lambda value: dependent_color(
        value.correcties_perc(), CORRECTIONS_RED, CORRECTIONS_GREEN)
    return kpi_grid(
        week_numbers,
        hours_data,
        verbose=verbose,
        effectivity_coloring=effectivity_coloring,
        corrections_coloring=corrections_coloring,
    )


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


if __name__ == '__main__':
    os.chdir('..')
    render_operations_page(get_output_folder())
예제 #9
0
        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')


if __name__ == '__main__':
    os.chdir('..')
    render_productiviteit_page(get_output_folder())
예제 #10
0
def report(render_year, render_month):
    print(f'\nGenerating report for {MAANDEN[render_month - 1]} {render_year}')
    render_maandrapportage(get_monthly_folder(), render_year, render_month)
    render_maandrapportage_page(get_monthly_folder(), get_output_folder())
예제 #11
0
                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')


if __name__ == '__main__':
    os.chdir('..')
    render_sales_page(get_output_folder())
예제 #12
0
        max_y_axis=max_value,
        y_axis_max_ticks=5,
    )
    return MultiScatterChart(chartdata, chart_config)


def bar_chart(data, width, height):
    chartdata = []
    for brand in BRANDS:
        values = [int(row[brand]) for _, row in data.iterrows()]
        chartdata += [values]
    z = list(zip(*chartdata))
    max_value = max([sum(series) for series in zip(*chartdata)])
    max_value = 100 * math.ceil(max_value / 100)
    chart_config = ChartConfig(
        width=width,
        height=height,
        colors=BAR_COLORS,
        min_y_axis=0,
        max_y_axis=max_value,
        y_axis_max_ticks=5,
        labels=BRANDS,
        bottom_labels=data['week'].tolist(),
    )
    return StackedBarChart(chartdata, chart_config)


if __name__ == '__main__':
    os.chdir(os.path.dirname(os.path.dirname(__file__)))
    render_travelbase_page(get_output_folder())
예제 #13
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)
예제 #14
0
    yuki_winst = omzet_tm_laatste_maand - projectkosten_tm_laatste_maand - kosten_tm_laatste_maand
    werkelijk = winst_werkelijk()
    begroot = winst_begroot()
    log('Yuki winst', yuki_winst)
    log('Winst werkelijk', werkelijk)
    log('Winst begroot', begroot)
    add_row(
        grid,
        'Winst',
        yuki_winst,
        '',
        werkelijk,
        begroot,
        bold=True,
    )
    return VBlock([TextBlock('Winstberekening', MID_SIZE), grid],
                  block_id="Winstberekening")


def render_resultaat_berekening(output_folder: Path):

    page = Page([HBlock([winst_berekening_block()])])
    page.render(output_folder / 'resultaat_berekening.html')


if __name__ == '__main__':
    os.chdir('..')
    clear_cache()
    render_resultaat_berekening(get_output_folder())
예제 #15
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')


if __name__ == '__main__':
    os.chdir('..')

    render_debiteuren_page(get_output_folder())
예제 #16
0
    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")


if __name__ == "__main__":
    os.chdir("..")
    render_verzuim_page(get_output_folder())