diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py index 260218fe..27069e56 100644 --- a/ereuse_devicehub/inventory/forms.py +++ b/ereuse_devicehub/inventory/forms.py @@ -1,26 +1,46 @@ import copy import json from json.decoder import JSONDecodeError + from boltons.urlutils import URL from flask import g, request from flask_wtf import FlaskForm +from sqlalchemy import or_ from sqlalchemy.util import OrderedSet from wtforms import ( - BooleanField, DateField, FileField, FloatField, Form, HiddenField, - IntegerField, MultipleFileField, SelectField, StringField, TextAreaField, - URLField, validators) + BooleanField, + DateField, + FileField, + FloatField, + Form, + HiddenField, + IntegerField, + MultipleFileField, + SelectField, + StringField, + TextAreaField, + URLField, + validators, +) from wtforms.fields import FormField from ereuse_devicehub.db import db -from ereuse_devicehub.resources.action.models import RateComputer, Snapshot +from ereuse_devicehub.resources.action.models import RateComputer, Snapshot, Trade from ereuse_devicehub.resources.action.rate.v1_0 import CannotRate -from ereuse_devicehub.resources.action.schemas import \ - Snapshot as SnapshotSchema -from ereuse_devicehub.resources.action.views.snapshot import ( - move_json, save_json) +from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema +from ereuse_devicehub.resources.action.views.snapshot import move_json, save_json from ereuse_devicehub.resources.device.models import ( - SAI, Cellphone, Computer, Device, Keyboard, MemoryCardReader, Monitor, - Mouse, Smartphone, Tablet) + SAI, + Cellphone, + Computer, + Device, + Keyboard, + MemoryCardReader, + Monitor, + Mouse, + Smartphone, + Tablet, +) from ereuse_devicehub.resources.device.sync import Sync from ereuse_devicehub.resources.documents.models import DataWipeDocument from ereuse_devicehub.resources.enums import Severity, SnapshotSoftware @@ -30,8 +50,6 @@ from ereuse_devicehub.resources.tag.model import Tag from ereuse_devicehub.resources.tradedocument.models import TradeDocument from ereuse_devicehub.resources.user.exceptions import InsufficientPermission from ereuse_devicehub.resources.user.models import User -from ereuse_devicehub.resources.action.models import Trade -from sqlalchemy import or_ class LotDeviceForm(FlaskForm): @@ -47,9 +65,14 @@ class LotDeviceForm(FlaskForm): self._lot = ( Lot.query.outerjoin(Trade) .filter(Lot.id == self.lot.data) - .filter(or_(Trade.user_from == g.user, - Trade.user_to == g.user, - Lot.owner_id == g.user.id)).one() + .filter( + or_( + Trade.user_from == g.user, + Trade.user_to == g.user, + Lot.owner_id == g.user.id, + ) + ) + .one() ) devices = set(self.devices.data.split(",")) @@ -163,7 +186,7 @@ class UploadSnapshotForm(FlaskForm): return True - def save(self): + def save(self, commit=True): if any([x == 'Error' for x in self.result.values()]): return # result = [] @@ -185,7 +208,8 @@ class UploadSnapshotForm(FlaskForm): move_json(self.tmp_snapshots, path_snapshot, g.user.email) - db.session.commit() + if commit: + db.session.commit() return response def build(self, snapshot_json): # noqa: C901 @@ -355,7 +379,7 @@ class NewDeviceForm(FlaskForm): return True - def save(self): + def save(self, commit=True): json_snapshot = { 'type': 'Snapshot', @@ -411,7 +435,8 @@ class NewDeviceForm(FlaskForm): snapshot.device.resolution = self.resolution.data snapshot.device.screen = self.screen.data - db.session.commit() + if commit: + db.session.commit() return snapshot @@ -466,11 +491,17 @@ class TagDeviceForm(FlaskForm): super().__init__(*args, **kwargs) if self.delete: - tags = Tag.query.filter(Tag.owner_id == g.user.id).filter_by( - device_id=self.device_id - ).order_by(Tag.id) + tags = ( + Tag.query.filter(Tag.owner_id == g.user.id) + .filter_by(device_id=self.device_id) + .order_by(Tag.id) + ) else: - tags = Tag.query.filter(Tag.owner_id == g.user.id).filter_by(device_id=None).order_by(Tag.id) + tags = ( + Tag.query.filter(Tag.owner_id == g.user.id) + .filter_by(device_id=None) + .order_by(Tag.id) + ) self.tag.choices = [(tag.id, tag.id) for tag in tags] @@ -729,9 +760,14 @@ class TradeForm(NewActionForm): self._lot = ( Lot.query.outerjoin(Trade) .filter(Lot.id == self.lot.data) - .filter(or_(Trade.user_from == g.user, - Trade.user_to == g.user, - Lot.owner_id == g.user.id)).one() + .filter( + or_( + Trade.user_from == g.user, + Trade.user_to == g.user, + Lot.owner_id == g.user.id, + ) + ) + .one() ) def validate(self, extra_validators=None): diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py index 25d06fa3..e3ce18a4 100644 --- a/ereuse_devicehub/inventory/views.py +++ b/ereuse_devicehub/inventory/views.py @@ -40,15 +40,9 @@ devices = Blueprint('inventory.devices', __name__, url_prefix='/inventory') logger = logging.getLogger(__name__) -class DeviceListMix(View): - decorators = [login_required] - template_name = 'inventory/device_list.html' - - def get_context(self, lot_id): - # TODO @cayop adding filter - # https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56 - filter_types = ['Desktop', 'Laptop', 'Server'] - lots = ( +class GenericMixView(View): + def get_lots(self): + return ( Lot.query.outerjoin(Trade) .filter( or_( @@ -59,6 +53,17 @@ class DeviceListMix(View): ) .distinct() ) + + +class DeviceListMix(GenericMixView): + decorators = [login_required] + template_name = 'inventory/device_list.html' + + def get_context(self, lot_id): + # TODO @cayop adding filter + # https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56 + filter_types = ['Desktop', 'Laptop', 'Server'] + lots = self.get_lots() lot = None tags = ( Tag.query.filter(Tag.owner_id == current_user.id) @@ -118,12 +123,12 @@ class DeviceListView(DeviceListMix): return flask.render_template(self.template_name, **self.context) -class DeviceDetailView(View): +class DeviceDetailView(GenericMixView): decorators = [login_required] template_name = 'inventory/device_detail.html' def dispatch_request(self, id): - lots = Lot.query.filter(Lot.owner_id == current_user.id) + lots = self.get_lots() device = ( Device.query.filter(Device.owner_id == current_user.id) .filter(Device.devicehub_id == id) @@ -178,7 +183,7 @@ class LotDeviceDeleteView(View): return flask.redirect(next_url) -class LotCreateView(View): +class LotCreateView(GenericMixView): methods = ['GET', 'POST'] decorators = [login_required] template_name = 'inventory/lot.html' @@ -191,7 +196,7 @@ class LotCreateView(View): next_url = url_for('inventory.devices.lotdevicelist', lot_id=form.id) return flask.redirect(next_url) - lots = Lot.query.filter(Lot.owner_id == current_user.id) + lots = self.get_lots() context = {'form': form, 'title': self.title, 'lots': lots} return flask.render_template(self.template_name, **context) @@ -232,33 +237,56 @@ class LotDeleteView(View): return flask.redirect(next_url) -class UploadSnapshotView(View): +class UploadSnapshotView(GenericMixView): methods = ['GET', 'POST'] decorators = [login_required] template_name = 'inventory/upload_snapshot.html' - def dispatch_request(self): - lots = Lot.query.filter(Lot.owner_id == current_user.id).all() + def dispatch_request(self, lot_id=None): + lots = self.get_lots() form = UploadSnapshotForm() - context = {'page_title': 'Upload Snapshot', 'lots': lots, 'form': form} + context = { + 'page_title': 'Upload Snapshot', + 'lots': lots, + 'form': form, + 'lot_id': lot_id, + } if form.validate_on_submit(): - form.save() + snapshot = form.save(commit=False) + if lot_id: + lot = lots.filter(Lot.id == lot_id).one() + lot.devices.add(snapshot.device) + db.session.add(lot) + db.session.commit() return flask.render_template(self.template_name, **context) -class DeviceCreateView(View): +class DeviceCreateView(GenericMixView): methods = ['GET', 'POST'] decorators = [login_required] template_name = 'inventory/device_create.html' - def dispatch_request(self): - lots = Lot.query.filter(Lot.owner_id == current_user.id).all() + def dispatch_request(self, lot_id=None): + lots = self.get_lots() form = NewDeviceForm() - context = {'page_title': 'New Device', 'lots': lots, 'form': form} + context = { + 'page_title': 'New Device', + 'lots': lots, + 'form': form, + 'lot_id': lot_id, + } if form.validate_on_submit(): - form.save() + snapshot = form.save(commit=False) next_url = url_for('inventory.devices.devicelist') + if lot_id: + next_url = url_for('inventory.devices.lotdevicelist', lot_id=lot_id) + lot = lots.filter(Lot.id == lot_id).one() + lot.devices.add(snapshot.device) + db.session.add(lot) + + db.session.commit() + messages.success('Device "{}" created successfully!'.format(form.type.data)) return flask.redirect(next_url) return flask.render_template(self.template_name, **context) @@ -646,7 +674,15 @@ devices.add_url_rule('/lot//', view_func=LotUpdateView.as_view('lot_e devices.add_url_rule( '/upload-snapshot/', view_func=UploadSnapshotView.as_view('upload_snapshot') ) +devices.add_url_rule( + '/lot//upload-snapshot/', + view_func=UploadSnapshotView.as_view('lot_upload_snapshot'), +) devices.add_url_rule('/device/add/', view_func=DeviceCreateView.as_view('device_add')) +devices.add_url_rule( + '/lot//device/add/', + view_func=DeviceCreateView.as_view('lot_device_add'), +) devices.add_url_rule('/tag/', view_func=TagListView.as_view('taglist')) devices.add_url_rule('/tag/add/', view_func=TagAddView.as_view('tag_add')) devices.add_url_rule( diff --git a/ereuse_devicehub/templates/inventory/device_create.html b/ereuse_devicehub/templates/inventory/device_create.html index 8bcb5fae..eaf75dc0 100644 --- a/ereuse_devicehub/templates/inventory/device_create.html +++ b/ereuse_devicehub/templates/inventory/device_create.html @@ -370,7 +370,11 @@
+ {% if lot_id %} + Cancel + {% else %} Cancel + {% endif %}
diff --git a/ereuse_devicehub/templates/inventory/device_list.html b/ereuse_devicehub/templates/inventory/device_list.html index 4335a5b5..8c0b25b2 100644 --- a/ereuse_devicehub/templates/inventory/device_list.html +++ b/ereuse_devicehub/templates/inventory/device_list.html @@ -245,13 +245,21 @@