{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5b66458e29113e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import polars as pl\n",
    "\n",
    "pl.Config(\n",
    "    fmt_str_lengths=120,\n",
    "    fmt_table_cell_list_len=50,\n",
    "    set_tbl_rows=100,\n",
    "    tbl_cols=-1,\n",
    ")\n",
    "\n",
    "for methode_dividendes in (\"flat\", \"progressif\"):\n",
    "    df: pl.DataFrame = pl.DataFrame()\n",
    "\n",
    "    for i in range(0, 11):\n",
    "        benefice_reel = 3000\n",
    "        ca = 50000\n",
    "        depenses_pro = 5000\n",
    "        remuneration_plus_is = ca - depenses_pro - benefice_reel\n",
    "        is_minimal = benefice_reel * 0.15\n",
    "\n",
    "        salaires_brut = (remuneration_plus_is - is_minimal) * i / 10\n",
    "\n",
    "        def taux_dividendes():\n",
    "            taux = {}\n",
    "            if methode_dividendes == \"flat\":\n",
    "                taux = {\"retenue_source\": 0.7, \"abattement\": 0}\n",
    "            elif methode_dividendes == \"progressif\":\n",
    "                taux = {\"retenue_source\": 0.828, \"abattement\": 0.6}\n",
    "            return taux\n",
    "\n",
    "        def calcul_cout_dividendes():\n",
    "            return remuneration_plus_is - salaires_brut - is_minimal\n",
    "\n",
    "        def calcul_dividendes_bruts():\n",
    "            return calcul_cout_dividendes() / 1.15\n",
    "\n",
    "        def calcul_cout_remuneration():\n",
    "            return calcul_dividendes_bruts() * 1.15 + salaires_brut\n",
    "\n",
    "        def calcul_dividendes_net():\n",
    "            dividendes_bruts = calcul_dividendes_bruts()\n",
    "            dividendes_net = dividendes_bruts * taux_dividendes()[\"retenue_source\"]\n",
    "            return dividendes_net\n",
    "\n",
    "        def calcul_salaires_net():\n",
    "            return salaires_brut * 0.563\n",
    "\n",
    "        def calcul_revenu_imposable():\n",
    "            return (calcul_salaires_net() * 0.9) + (\n",
    "                calcul_dividendes_net() * taux_dividendes()[\"abattement\"]\n",
    "            )\n",
    "\n",
    "        def calcul_revenu_net():\n",
    "            return calcul_salaires_net() + calcul_dividendes_net()\n",
    "\n",
    "        def calcul_benefice():\n",
    "            return ca - depenses_pro - salaires_brut\n",
    "\n",
    "        def calcul_is():\n",
    "            return (calcul_benefice() - is_minimal) * 0.15\n",
    "\n",
    "        def calcul_ir(revenu):\n",
    "            tranches_ir = [[11488, 0], [29315, 0.11], [83283, 0.3]]\n",
    "            revenu_restant = revenu\n",
    "            ir = 0\n",
    "            for tranche in tranches_ir:\n",
    "                if revenu_restant > 0:\n",
    "                    ir_tranche = min(revenu_restant, tranche[0]) * tranche[1]\n",
    "                    ir = +ir_tranche\n",
    "                    revenu_restant = revenu_restant - tranche[0]\n",
    "\n",
    "            return ir\n",
    "\n",
    "        def calcul_revenu_ae():\n",
    "            apres_cotisations = calcul_cout_remuneration() * 0.76 - depenses_pro\n",
    "            impots = calcul_ir(apres_cotisations * 0.66)\n",
    "            return apres_cotisations - impots\n",
    "\n",
    "        def fmt(value):\n",
    "            return str(int(value))\n",
    "\n",
    "        # print(salaires_brut)\n",
    "        # print(calcul_cout_dividendes())\n",
    "        # print(calcul_dividendes_bruts())\n",
    "        # print(calcul_is())\n",
    "        # print(\"\")\n",
    "        # print(\"\")\n",
    "        #\n",
    "        # print(salaires_brut + calcul_dividendes_bruts() + calcul_is(), \" == \", remuneration_plus_is)\n",
    "\n",
    "        # assert salaires_brut + calcul_dividendes_bruts() + calcul_is() == remuneration_plus_is\n",
    "\n",
    "        row: dict = {\n",
    "            \"Salaires bruts\": [fmt(salaires_brut / 12)],\n",
    "            \"Dividendes bruts\": [fmt(calcul_cout_dividendes() / 12)],\n",
    "            \"Benefice\": [fmt(calcul_benefice())],\n",
    "            \"Benefice réél\": [\n",
    "                fmt(calcul_benefice() - calcul_is() - calcul_dividendes_bruts())\n",
    "            ],\n",
    "            \"IS\": [fmt(calcul_is())],\n",
    "            \"IR\": [fmt(calcul_ir(calcul_revenu_imposable()) / 12)],\n",
    "            \"IS + IR\": [fmt(calcul_is() + calcul_ir(calcul_revenu_imposable()))],\n",
    "            \"Salaires net\": [fmt(calcul_salaires_net() / 12)],\n",
    "            \"Dividendes net\": [fmt(calcul_dividendes_net() / 12)],\n",
    "            \"Revenu net ap. impôts\": [\n",
    "                fmt((calcul_revenu_net() - calcul_ir(calcul_revenu_imposable())) / 12)\n",
    "            ],\n",
    "            \"Revenue AE ap. impôts\": [fmt(calcul_revenu_ae() / 12)],\n",
    "        }\n",
    "\n",
    "        df = pl.concat([df, pl.from_dict(row)])\n",
    "\n",
    "    print(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "initial_id",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from dash import ALL, Dash, Input, Output, Patch, State, callback, dcc, html\n",
    "\n",
    "app = Dash()\n",
    "\n",
    "app.layout = html.Div(\n",
    "    [\n",
    "        html.Button(\"Add Filter\", id=\"add-filter-btn\", n_clicks=0),\n",
    "        html.Div(id=\"dropdown-container-div\", children=[]),\n",
    "        html.Div(id=\"dropdown-container-output-div\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "\n",
    "@callback(\n",
    "    Output(\"dropdown-container-div\", \"children\"), Input(\"add-filter-btn\", \"n_clicks\")\n",
    ")\n",
    "def display_dropdowns(n_clicks):\n",
    "    patched_children = Patch()\n",
    "    new_dropdown = dcc.Dropdown(\n",
    "        [\"NYC\", \"MTL\", \"LA\", \"TOKYO\"],\n",
    "        id={\"type\": \"city-filter-dropdown\", \"index\": n_clicks},\n",
    "    )\n",
    "    patched_children.append(new_dropdown)\n",
    "    return patched_children\n",
    "\n",
    "\n",
    "@callback(\n",
    "    Output(\"dropdown-container-output-div\", \"children\"),\n",
    "    Input({\"type\": \"city-filter-dropdown\", \"index\": ALL}, \"value\"),\n",
    "    State({\"type\": \"city-dynamic-dropdown\", \"index\": ALL}, \"id\"),\n",
    ")\n",
    "def display_output(values, ids):\n",
    "    return html.Div(\n",
    "        [html.Div(f\"Dropdown {i + 1} = {value}\") for (i, value) in enumerate(values)]\n",
    "        + [html.P(ids)],\n",
    "    )\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    app.run(debug=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
