|
@@ -54,6 +54,27 @@ class Person(db.Model):
|
54
|
54
|
}
|
55
|
55
|
|
56
|
56
|
|
|
57
|
+class Export(db.Model):
|
|
58
|
+ """ Represents a set of exported Settlements. """
|
|
59
|
+
|
|
60
|
+ __tablename__ = "exports"
|
|
61
|
+
|
|
62
|
+ export_id = db.Column(db.Integer, primary_key=True)
|
|
63
|
+ created_at = db.Column(
|
|
64
|
+ db.DateTime, default=datetime.datetime.utcnow, nullable=False
|
|
65
|
+ )
|
|
66
|
+
|
|
67
|
+ settlements = db.relationship("Settlement", backref="export", lazy=True)
|
|
68
|
+
|
|
69
|
+ @property
|
|
70
|
+ def as_dict(self) -> dict:
|
|
71
|
+ return {
|
|
72
|
+ "export_id": self.export_id,
|
|
73
|
+ "created_at": self.created_at.isoformat(),
|
|
74
|
+ "settlements": [s.settlement_id for s in self.settlements],
|
|
75
|
+ }
|
|
76
|
+
|
|
77
|
+
|
57
|
78
|
class Settlement(db.Model):
|
58
|
79
|
""" Represents a settlement of the list. """
|
59
|
80
|
|
|
@@ -61,6 +82,7 @@ class Settlement(db.Model):
|
61
|
82
|
|
62
|
83
|
settlement_id = db.Column(db.Integer, primary_key=True)
|
63
|
84
|
name = db.Column(db.String, nullable=False)
|
|
85
|
+ export_id = db.Column(db.Integer, db.ForeignKey("exports.export_id"), nullable=True)
|
64
|
86
|
|
65
|
87
|
consumptions = db.relationship("Consumption", backref="settlement", lazy=True)
|
66
|
88
|
|
|
@@ -73,12 +95,24 @@ class Settlement(db.Model):
|
73
|
95
|
"settlement_id": self.settlement_id,
|
74
|
96
|
"name": self.name,
|
75
|
97
|
"consumption_summary": self.consumption_summary,
|
|
98
|
+ "unique_people": self.unique_people,
|
76
|
99
|
}
|
77
|
100
|
|
78
|
101
|
@property
|
|
102
|
+ def unique_people(self) -> int:
|
|
103
|
+ q = (
|
|
104
|
+ Consumption.query.filter_by(settlement=self)
|
|
105
|
+ .filter_by(reversed=False)
|
|
106
|
+ .group_by(Consumption.person_id)
|
|
107
|
+ .count()
|
|
108
|
+ )
|
|
109
|
+ return q
|
|
110
|
+
|
|
111
|
+ @property
|
79
|
112
|
def consumption_summary(self) -> dict:
|
80
|
113
|
q = (
|
81
|
114
|
Consumption.query.filter_by(settlement=self)
|
|
115
|
+ .filter_by(reversed=False)
|
82
|
116
|
.group_by(Consumption.consumption_type_id)
|
83
|
117
|
.outerjoin(ConsumptionType)
|
84
|
118
|
.with_entities(
|
|
@@ -374,3 +408,35 @@ def add_settlement():
|
374
|
408
|
db.session.commit()
|
375
|
409
|
|
376
|
410
|
return jsonify(settlement=s.as_dict)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+# Export
|
|
414
|
+@app.route("/exports", methods=["GET"])
|
|
415
|
+def get_exports():
|
|
416
|
+ """ Return a list of the created Exports. """
|
|
417
|
+ result = Export.query.all()
|
|
418
|
+ return jsonify(exports=[e.as_dict for e in result])
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+@app.route("/exports/<int:export_id>", methods=["GET"])
|
|
422
|
+def get_export(export_id: int):
|
|
423
|
+ """ Return an overview for the given Export. """
|
|
424
|
+ e = Export.query.get_or_404(export_id)
|
|
425
|
+
|
|
426
|
+ ss = [s.as_dict for s in e.settlements]
|
|
427
|
+
|
|
428
|
+ return jsonify(export=e.as_dict, settlements=ss)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+@app.route("/exports", methods=["POST"])
|
|
432
|
+def add_export():
|
|
433
|
+ """ Create an Export, and link all un-exported Settlements to it. """
|
|
434
|
+ e = Export()
|
|
435
|
+
|
|
436
|
+ db.session.add(e)
|
|
437
|
+ db.session.commit()
|
|
438
|
+
|
|
439
|
+ Settlement.query.filter_by(export=None).update({"export_id": e.export_id})
|
|
440
|
+ db.session.commit()
|
|
441
|
+
|
|
442
|
+ return jsonify(export=e.as_dict), 201
|