From 3e8ac6744988baa90a2987693ebea7fe715dbe9c Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Thu, 20 Jul 2017 11:26:22 +0200
Subject: [PATCH] Add new API endpoints

---
 app/api/main.py | 97 +++++++++++++++++++++++++++++++++++++++----------
 app/models.py   |  6 +++
 2 files changed, 84 insertions(+), 19 deletions(-)

diff --git a/app/api/main.py b/app/api/main.py
index a53978e..51a5289 100644
--- a/app/api/main.py
+++ b/app/api/main.py
@@ -14,12 +14,39 @@ from flask import (current_app, Blueprint, jsonify, request)
 from flask_jwt_extended import create_access_token, jwt_required
 from flask_ldap3_login import AuthenticationResponseStatus
 from ..extensions import ldap_manager, db
-from ..models import User, Item
+from ..models import User, Item, Manufacturer, Model, Location, Status
 from .. import utils
 
 bp = Blueprint('api', __name__)
 
 
+def get_generic_model(model):
+    # TODO: add pagination
+    items = model.query.order_by(model.name)
+    data = [item.to_dict() for item in items]
+    return jsonify(data)
+
+
+def create_generic_model(model, mandatory_field='name'):
+    data = request.get_json()
+    if data is None:
+        raise utils.InventoryError('Body should be a JSON object')
+    if mandatory_field not in data:
+        raise utils.InventoryError(f"Missing mandatory field '{mandatory_field}'", status_code=422)
+    try:
+        instance = model(**data)
+    except TypeError as e:
+        message = str(e).replace('__init__() got an ', '')
+        raise utils.InventoryError(message)
+    db.session.add(instance)
+    try:
+        db.session.commit()
+    except sa.exc.IntegrityError as e:
+        db.session.rollback()
+        raise utils.InventoryError('IntegrityError', status_code=409)
+    return jsonify(instance.to_dict()), 201
+
+
 @bp.route('/login', methods=['POST'])
 def login():
     data = request.get_json()
@@ -50,26 +77,58 @@ def get_items():
     # TODO: add pagination
     items = Item.query.order_by(Item._created)
     data = [item.to_dict() for item in items]
-    return jsonify({'items': data})
+    return jsonify(data)
 
 
 @bp.route('/items', methods=['POST'])
 @jwt_required
 def create_item():
-    data = request.get_json()
-    if data is None:
-        raise utils.InventoryError('Body should be a JSON object')
-    if 'serial_number' not in data:
-        raise utils.InventoryError('Missing mandatory field serial_number', status_code=422)
-    try:
-        item = Item(**data)
-    except TypeError as e:
-        message = str(e).replace('__init__() got an ', '')
-        raise utils.InventoryError(message)
-    db.session.add(item)
-    try:
-        db.session.commit()
-    except sa.exc.IntegrityError as e:
-        db.session.rollback()
-        raise utils.InventoryError('IntegrityError', status_code=409)
-    return jsonify(item.to_dict()), 201
+    return create_generic_model(Item, mandatory_field='serial_number')
+
+
+@bp.route('/manufacturers')
+@jwt_required
+def get_manufacturers():
+    return get_generic_model(Manufacturer)
+
+
+@bp.route('/manufacturers', methods=['POST'])
+@jwt_required
+def create_manufacturer():
+    return create_generic_model(Manufacturer)
+
+
+@bp.route('/models')
+@jwt_required
+def get_models():
+    return get_generic_model(Model)
+
+
+@bp.route('/models', methods=['POST'])
+@jwt_required
+def create_model():
+    return create_generic_model(Model)
+
+
+@bp.route('/locations')
+@jwt_required
+def get_locations():
+    return get_generic_model(Location)
+
+
+@bp.route('/locations', methods=['POST'])
+@jwt_required
+def create_locations():
+    return create_generic_model(Location)
+
+
+@bp.route('/status')
+@jwt_required
+def get_status():
+    return get_generic_model(Status)
+
+
+@bp.route('/status', methods=['POST'])
+@jwt_required
+def create_status():
+    return create_generic_model(Status)
diff --git a/app/models.py b/app/models.py
index 055de44..12b14cb 100644
--- a/app/models.py
+++ b/app/models.py
@@ -135,6 +135,9 @@ class QRCodeMixin:
     def __str__(self):
         return self.name
 
+    def to_dict(self):
+        return {'id': self.id, 'name': self.name}
+
 
 class Action(QRCodeMixin, db.Model):
     code = 'AC'
@@ -150,6 +153,9 @@ class Model(QRCodeMixin, db.Model):
     description = db.Column(db.Text)
     items = db.relationship('Item', back_populates='model')
 
+    def to_dict(self):
+        return {'id': self.id, 'name': self.name, 'description': self.description}
+
 
 class Location(QRCodeMixin, db.Model):
     code = 'LO'
-- 
GitLab