Commit c867817698135e7b42af74449f9fa9567c822492

Authored by hitier
1 parent aadf1790

New stacked table by_labels for a category

Showing 2 changed files with 71 additions and 1 deletions   Show diff stats
app/db_mgr.py
... ... @@ -205,7 +205,62 @@ def charges_by_project_stacked(project_id, category="service"):
205 205 return all_charges
206 206  
207 207  
  208 +def charges_by_labels_stacked(category_id):
  209 + """
  210 + Build the list of charges for all projects, one period at a time, for each label of a category.
  211 +
  212 + Will return a table like:
  213 +
  214 + period, label_0, label_1, ....., label_n,
  215 + period_0, tot_charge_00, tot_charge_01, ....., tot_charge_0n,
  216 + period_1, tot_charge_10, tot_charge_11, ....., tot_charge_1n,
  217 + .
  218 + .
  219 + period_n, tot_charge_n0, tot_charge_n1, ....., tot_charge_nn,
  220 +
  221 + :param category_id:
  222 + :return: the table
  223 + """
  224 + sql_req = """
  225 + select l.name, ifnull(sum(ps.tot_charge), 0) as label_charge
  226 + from label l
  227 + join category_label cl on l.id = cl.label_id
  228 + join project_label pl on l.id = pl.label_id
  229 + left join ( select c.project_id, sum(c.charge_rate) as tot_charge
  230 + from charge c where c.period_id = {} group by c.project_id) ps
  231 + on ps.project_id = pl.project_id
  232 + where cl.category_id = {}
  233 + group by l.id
  234 + order by l.id;
  235 + """
  236 + labels_req = f"""
  237 + select l.name from label l
  238 + join category_label cl on l.id = cl.label_id
  239 + where cl.category_id = {category_id};
  240 + """
  241 +
  242 + labels_names = [name for (name,) in db.session.execute(labels_req)]
  243 + headers = ['period'] + labels_names
  244 + all_charges = [headers]
  245 + for (period_id, period_name) in db.session.execute("select id, name from period order by id"):
  246 + project_charges = [period_name]
  247 + charges_for_projects_req = sql_req.format(period_id, category_id)
  248 + for (project_name, project_charge) in db.session.execute(charges_for_projects_req):
  249 + project_charge = str(round(project_charge / charge_unit, 2)) if project_charge else '0'
  250 + project_charges.append(project_charge)
  251 + all_charges.append(project_charges)
  252 + return all_charges
  253 +
  254 +
208 255 def charges_for_projects_stacked():
  256 + """
  257 + TODO: code is wrong !!!
  258 + TODO: List of project_names is not like what is returned by the sql_join:
  259 + TODO: there are more project_names.
  260 + TODO: Should be a left join on a sub-sql query
  261 +
  262 + :return:
  263 + """
209 264 sql_req = """
210 265 select p.name, sum(charge_rate) as tot_charg
211 266 from charge
... ...
app/main/routes.py
... ... @@ -58,7 +58,9 @@ def projects():
58 58 @role_required('project')
59 59 def projects_stats():
60 60 num_projects = len(Project.query.all())
61   - return render_template('projects_stats.html', subtitle="Statistiques des projets ({})".format(num_projects))
  61 + this_categories = Category.query.all()
  62 + return render_template('projects_stats.html', subtitle="Statistiques des projets ({})".format(num_projects),
  63 + categories=this_categories)
62 64  
63 65  
64 66 @bp.route('/agents')
... ... @@ -394,6 +396,19 @@ def charge_agent_csv(agent_id):
394 396 return resp
395 397  
396 398  
  399 +@bp.route('/charge/labels/<category_id>')
  400 +@role_required('project')
  401 +def labels_stats_csv(category_id):
  402 + csv_table = []
  403 + for line in db_mgr.charges_by_labels_stacked(category_id):
  404 + line = [cell.replace(",", "-") for cell in line]
  405 + line_string = ",".join(line)
  406 + csv_table.append(line_string)
  407 + resp = make_response("\n".join(csv_table))
  408 + resp.headers['Content-Type'] = 'text/plain;charset=utf8'
  409 + return resp
  410 +
  411 +
397 412 @bp.route('/charge/projects')
398 413 @role_required('project')
399 414 def projects_stats_csv():
... ...