| 
				
			 | 
			
			
				@@ -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 
			 |