Commit c867817698135e7b42af74449f9fa9567c822492
1 parent
aadf1790
Exists in
master
and in
4 other branches
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(): | ... | ... |