|
|
|
|
|
|
|
|
| import pandas as pd
|
| import numpy as np
|
| import matplotlib.pyplot as plt
|
| import matplotlib.ticker as ticker
|
| import panel as pn
|
|
|
| from bokeh.models.widgets.tables import NumberFormatter, DateFormatter
|
| from IPython.display import display, Markdown
|
| from loguru import logger
|
|
|
| import ledger_husfinans_functions as lhf
|
|
|
| pn.extension('tabulator')
|
| plt.style.use("matplotlibstylehus.mplstyle")
|
|
|
| split_percentage = {"Valentin":1-0.6278, "Bjørg&Marius":0.6278}
|
|
|
|
|
| dfs = pd.read_pickle("husfinans_hovedtabell.pickle")
|
| dfs = dfs[
|
| (dfs["Account"] == "House")
|
| ]
|
| dfs = dfs[["ID", "Type", "Date", "Amount", "Comment", "Name", "Split", "BudgetItem"]]
|
|
|
|
|
|
|
| baf = pd.read_pickle("husfinans_baf.pickle")
|
|
|
|
|
|
|
|
|
| actors = ["Bjørg&Marius", "Valentin"]
|
|
|
| baf_formatters = {
|
| 'Budget': NumberFormatter(format='0,0', text_align="right"),
|
| 'Actual': NumberFormatter(format='0,0', text_align="right"),
|
| 'Forecast': NumberFormatter(format='0,0', text_align="right"),
|
| 'Estimate': NumberFormatter(format='0,0', text_align="right"),
|
| 'Actual+F+E': NumberFormatter(format='0,0', text_align="right"),
|
| 'Diff': NumberFormatter(format='0,0', text_align="right"),
|
| }
|
|
|
| def baf_prep(actors):
|
| cols = ["Budget", "Actual", "Forecast", "Estimate", "Actual+F+E", "Diff"]
|
| baf2 = baf[baf["Name"].isin(actors)]
|
| baf2 = baf2.pivot_table(index="BudgetItem", values=cols, aggfunc="sum", margins=True)
|
| baf2 = baf2[["Budget", "Actual", "Forecast", "Estimate", "Actual+F+E", "Diff"]]
|
| return baf2
|
|
|
| baf_widget = pn.widgets.Tabulator(baf_prep(actors), disabled=True, formatters=baf_formatters)
|
|
|
| dfs_formatters = {
|
| 'Date': DateFormatter(format="%Y-%m-%d", text_align="right"),
|
| 'Amount': NumberFormatter(format='0,0', text_align="right"),
|
| 'Split': NumberFormatter(format='0.0%', text_align="right"),
|
| }
|
|
|
| dfs_widget = pn.widgets.Tabulator(pd.DataFrame(data=None, columns=[c for c in dfs.columns if c != "BudgetItem"]), disabled=True, show_index=False, formatters=dfs_formatters)
|
|
|
|
|
| def click(event):
|
|
|
| dfs2 = dfs[
|
| (dfs["BudgetItem"] == baf_widget.value.index[event.row])
|
| & dfs["Name"].isin(checkbutton_group.value)
|
| ]
|
| del dfs2["BudgetItem"]
|
| dfs_widget.value = dfs2
|
|
|
| baf_widget.on_click(click)
|
|
|
|
|
| checkbutton_group = pn.widgets.CheckButtonGroup(name='Name', value=actors, options=actors, button_style="outline", button_type="primary")
|
|
|
| def buttonclick(target, event):
|
| target.value = baf_prep(event.new)
|
|
|
| checkbutton_group.link(baf_widget, callbacks={"value":buttonclick})
|
|
|
| ww = pn.Column(checkbutton_group, pn.Row(baf_widget, dfs_widget))
|
|
|
| title = "Bernhar Herres vei 3"
|
| pn.template.BootstrapTemplate(
|
| title=title,
|
| main=ww,
|
|
|
| header_background="#F08080",
|
| ).servable(title=title)
|
|
|
|
|
|
|