|
@@ -25,7 +25,7 @@ db = SQLAlchemy(app)
|
25
|
25
|
|
26
|
26
|
# ---------- Models ----------
|
27
|
27
|
class Person(db.Model):
|
28
|
|
- """ Represents a person to be shown on the lists. """
|
|
28
|
+ """Represents a person to be shown on the lists."""
|
29
|
29
|
|
30
|
30
|
__tablename__ = "people"
|
31
|
31
|
|
|
@@ -56,7 +56,7 @@ class Person(db.Model):
|
56
|
56
|
|
57
|
57
|
|
58
|
58
|
class Export(db.Model):
|
59
|
|
- """ Represents a set of exported Settlements. """
|
|
59
|
+ """Represents a set of exported Settlements."""
|
60
|
60
|
|
61
|
61
|
__tablename__ = "exports"
|
62
|
62
|
|
|
@@ -77,7 +77,7 @@ class Export(db.Model):
|
77
|
77
|
|
78
|
78
|
|
79
|
79
|
class Settlement(db.Model):
|
80
|
|
- """ Represents a settlement of the list. """
|
|
80
|
+ """Represents a settlement of the list."""
|
81
|
81
|
|
82
|
82
|
__tablename__ = "settlements"
|
83
|
83
|
|
|
@@ -159,7 +159,7 @@ class Settlement(db.Model):
|
159
|
159
|
|
160
|
160
|
|
161
|
161
|
class ConsumptionType(db.Model):
|
162
|
|
- """ Represents a type of consumption to be counted. """
|
|
162
|
+ """Represents a type of consumption to be counted."""
|
163
|
163
|
|
164
|
164
|
__tablename__ = "consumption_types"
|
165
|
165
|
|
|
@@ -183,7 +183,7 @@ class ConsumptionType(db.Model):
|
183
|
183
|
|
184
|
184
|
|
185
|
185
|
class Consumption(db.Model):
|
186
|
|
- """ Represent one consumption to be counted. """
|
|
186
|
+ """Represent one consumption to be counted."""
|
187
|
187
|
|
188
|
188
|
__tablename__ = "consumptions"
|
189
|
189
|
|
|
@@ -222,13 +222,13 @@ class Consumption(db.Model):
|
222
|
222
|
|
223
|
223
|
@app.route("/ping")
|
224
|
224
|
def ping() -> None:
|
225
|
|
- """ Return a status ping. """
|
|
225
|
+ """Return a status ping."""
|
226
|
226
|
return "Pong"
|
227
|
227
|
|
228
|
228
|
|
229
|
229
|
@app.route("/status")
|
230
|
230
|
def status() -> None:
|
231
|
|
- """ Return a status dict with info about the database. """
|
|
231
|
+ """Return a status dict with info about the database."""
|
232
|
232
|
unsettled_q = Consumption.query.filter_by(settlement=None).filter_by(reversed=False)
|
233
|
233
|
|
234
|
234
|
unsettled = unsettled_q.count()
|
|
@@ -253,7 +253,7 @@ def status() -> None:
|
253
|
253
|
# Person
|
254
|
254
|
@app.route("/people", methods=["GET"])
|
255
|
255
|
def get_people():
|
256
|
|
- """ Return a list of currently known people. """
|
|
256
|
+ """Return a list of currently known people."""
|
257
|
257
|
q = Person.query.order_by(Person.name)
|
258
|
258
|
if request.args.get("active"):
|
259
|
259
|
active_status = request.args.get("active", type=int)
|
|
@@ -261,7 +261,7 @@ def get_people():
|
261
|
261
|
people = q.all()
|
262
|
262
|
|
263
|
263
|
engine = db.get_engine()
|
264
|
|
- query = '''
|
|
264
|
+ query = """
|
265
|
265
|
SELECT
|
266
|
266
|
consumptions.person_id,
|
267
|
267
|
consumptions.consumption_type_id,
|
|
@@ -273,10 +273,10 @@ def get_people():
|
273
|
273
|
consumptions.settlement_id IS NULL
|
274
|
274
|
AND consumptions.reversed = 0
|
275
|
275
|
GROUP BY consumptions.person_id, consumptions.consumption_type_id;
|
276
|
|
- '''
|
|
276
|
+ """
|
277
|
277
|
raw_counts = engine.execute(query)
|
278
|
278
|
|
279
|
|
- counts: 'Dict[int, Dict[str, int]]' = defaultdict(dict)
|
|
279
|
+ counts: "Dict[int, Dict[str, int]]" = defaultdict(dict)
|
280
|
280
|
for person_id, consumption_type_id, count in raw_counts:
|
281
|
281
|
counts[person_id][str(consumption_type_id)] = count
|
282
|
282
|
|
|
@@ -285,7 +285,7 @@ def get_people():
|
285
|
285
|
"name": person.name,
|
286
|
286
|
"active": person.active,
|
287
|
287
|
"person_id": person.person_id,
|
288
|
|
- "consumptions": counts[person.person_id]
|
|
288
|
+ "consumptions": counts[person.person_id],
|
289
|
289
|
}
|
290
|
290
|
for person in people
|
291
|
291
|
]
|
|
@@ -381,7 +381,7 @@ def add_consumption2(person_id: int, ct_id: int):
|
381
|
381
|
|
382
|
382
|
@app.route("/consumptions/<int:consumption_id>", methods=["DELETE"])
|
383
|
383
|
def reverse_consumption(consumption_id: int):
|
384
|
|
- """ Reverse a consumption. """
|
|
384
|
+ """Reverse a consumption."""
|
385
|
385
|
consumption = Consumption.query.get_or_404(consumption_id)
|
386
|
386
|
|
387
|
387
|
if consumption.reversed:
|
|
@@ -409,7 +409,7 @@ def reverse_consumption(consumption_id: int):
|
409
|
409
|
# ConsumptionType
|
410
|
410
|
@app.route("/consumption_types", methods=["GET"])
|
411
|
411
|
def get_consumption_types():
|
412
|
|
- """ Return a list of currently active consumption types. """
|
|
412
|
+ """Return a list of currently active consumption types."""
|
413
|
413
|
ctypes = ConsumptionType.query.filter_by(active=True).all()
|
414
|
414
|
result = [ct.as_dict for ct in ctypes]
|
415
|
415
|
return jsonify(consumption_types=result)
|
|
@@ -424,7 +424,7 @@ def get_consumption_type(consumption_type_id: int):
|
424
|
424
|
|
425
|
425
|
@app.route("/consumption_types", methods=["POST"])
|
426
|
426
|
def add_consumption_type():
|
427
|
|
- """ Add a new ConsumptionType. """
|
|
427
|
+ """Add a new ConsumptionType."""
|
428
|
428
|
json = request.get_json()
|
429
|
429
|
|
430
|
430
|
if not json:
|
|
@@ -445,14 +445,14 @@ def add_consumption_type():
|
445
|
445
|
# Settlement
|
446
|
446
|
@app.route("/settlements", methods=["GET"])
|
447
|
447
|
def get_settlements():
|
448
|
|
- """ Return a list of the active Settlements. """
|
|
448
|
+ """Return a list of the active Settlements."""
|
449
|
449
|
result = Settlement.query.all()
|
450
|
450
|
return jsonify(settlements=[s.as_dict for s in result])
|
451
|
451
|
|
452
|
452
|
|
453
|
453
|
@app.route("/settlements/<int:settlement_id>", methods=["GET"])
|
454
|
454
|
def get_settlement(settlement_id: int):
|
455
|
|
- """ Show full details for a single Settlement. """
|
|
455
|
+ """Show full details for a single Settlement."""
|
456
|
456
|
s = Settlement.query.get_or_404(settlement_id)
|
457
|
457
|
|
458
|
458
|
per_person = s.per_person
|
|
@@ -462,7 +462,7 @@ def get_settlement(settlement_id: int):
|
462
|
462
|
|
463
|
463
|
@app.route("/settlements", methods=["POST"])
|
464
|
464
|
def add_settlement():
|
465
|
|
- """ Create a Settlement, and link all un-settled Consumptions to it. """
|
|
465
|
+ """Create a Settlement, and link all un-settled Consumptions to it."""
|
466
|
466
|
json = request.get_json()
|
467
|
467
|
|
468
|
468
|
if not json:
|
|
@@ -486,14 +486,14 @@ def add_settlement():
|
486
|
486
|
# Export
|
487
|
487
|
@app.route("/exports", methods=["GET"])
|
488
|
488
|
def get_exports():
|
489
|
|
- """ Return a list of the created Exports. """
|
|
489
|
+ """Return a list of the created Exports."""
|
490
|
490
|
result = Export.query.all()
|
491
|
491
|
return jsonify(exports=[e.as_dict for e in result])
|
492
|
492
|
|
493
|
493
|
|
494
|
494
|
@app.route("/exports/<int:export_id>", methods=["GET"])
|
495
|
495
|
def get_export(export_id: int):
|
496
|
|
- """ Return an overview for the given Export. """
|
|
496
|
+ """Return an overview for the given Export."""
|
497
|
497
|
e = Export.query.get_or_404(export_id)
|
498
|
498
|
|
499
|
499
|
ss = [s.as_dict for s in e.settlements]
|
|
@@ -503,7 +503,7 @@ def get_export(export_id: int):
|
503
|
503
|
|
504
|
504
|
@app.route("/exports", methods=["POST"])
|
505
|
505
|
def add_export():
|
506
|
|
- """ Create an Export, and link all un-exported Settlements to it. """
|
|
506
|
+ """Create an Export, and link all un-exported Settlements to it."""
|
507
|
507
|
# Assert that there are Settlements to be exported.
|
508
|
508
|
s_count = Settlement.query.filter_by(export=None).count()
|
509
|
509
|
if s_count == 0:
|