Merge pull request #49 from eReuse/feature/33-export-lot-description

Feature/33 export lot description
This commit is contained in:
Jordi Nadeu 2020-08-18 21:21:17 +02:00 committed by GitHub
commit c11844ed51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 0 deletions

View File

@ -2,6 +2,7 @@ import csv
import datetime import datetime
import enum import enum
import uuid import uuid
from collections import OrderedDict
from io import StringIO from io import StringIO
from typing import Callable, Iterable, Tuple from typing import Callable, Iterable, Tuple
@ -19,6 +20,9 @@ from ereuse_devicehub.resources.action import models as evs
from ereuse_devicehub.resources.device import models as devs from ereuse_devicehub.resources.device import models as devs
from ereuse_devicehub.resources.device.views import DeviceView from ereuse_devicehub.resources.device.views import DeviceView
from ereuse_devicehub.resources.documents.device_row import DeviceRow, StockRow from ereuse_devicehub.resources.documents.device_row import DeviceRow, StockRow
from ereuse_devicehub.resources.documents.device_row import DeviceRow
from ereuse_devicehub.resources.lot import LotView
from ereuse_devicehub.resources.lot.models import Lot
@ -127,6 +131,42 @@ class DevicesDocumentView(DeviceView):
return output return output
class LotsDocumentView(LotView):
def find(self, args: dict):
query = (x for x in self.query(args) if x.owner_id == g.user.id)
return self.generate_lots_csv(query)
def generate_lots_csv(self, query):
"""Get lot query and put information in csv format."""
data = StringIO()
cw = csv.writer(data)
first = True
for lot in query:
l = LotRow(lot)
if first:
cw.writerow(l.keys())
first = False
cw.writerow(l.values())
output = make_response(data.getvalue())
output.headers['Content-Disposition'] = 'attachment; filename=lots-info.csv'
output.headers['Content-type'] = 'text/csv'
return output
class LotRow(OrderedDict):
def __init__(self, lot: Lot) -> None:
super().__init__()
self.lot = lot
# General information about lot
self['Id'] = lot.id.hex
self['Name'] = lot.name
self['Registered in'] = format(lot.created, '%c')
try:
self['Description'] = lot.description
except:
self['Description'] = ''
class StockDocumentView(DeviceView): class StockDocumentView(DeviceView):
# @cache(datetime.timedelta(minutes=1)) # @cache(datetime.timedelta(minutes=1))
def find(self, args: dict): def find(self, args: dict):
@ -191,6 +231,10 @@ class DocumentDef(Resource):
self.add_url_rule('/devices/', defaults=d, view_func=devices_view, methods=get) self.add_url_rule('/devices/', defaults=d, view_func=devices_view, methods=get)
lots_view = LotsDocumentView.as_view('lotsDocumentView', definition=self)
lots_view = app.auth.requires_auth(lots_view)
self.add_url_rule('/lots/', defaults=d, view_func=lots_view, methods=get)
stock_view = StockDocumentView.as_view('stockDocumentView', definition=self, auth=app.auth) stock_view = StockDocumentView.as_view('stockDocumentView', definition=self, auth=app.auth)
stock_view = app.auth.requires_auth(stock_view) stock_view = app.auth.requires_auth(stock_view)
self.add_url_rule('/stock/', defaults=d, view_func=stock_view, methods=get) self.add_url_rule('/stock/', defaults=d, view_func=stock_view, methods=get)

View File

@ -103,6 +103,10 @@ class LotView(View):
Lot.owner_id == g.user.id)) Lot.owner_id == g.user.id))
return query return query
def query(self, args):
query = Lot.query.distinct()
return query
def delete(self, id): def delete(self, id):
lot = Lot.query.filter_by(id=id).one() lot = Lot.query.filter_by(id=id).one()
lot.delete() lot.delete()

View File

@ -50,6 +50,7 @@ def test_api_docs(client: Client):
'/diy-and-gardenings/{id}/merge/', '/diy-and-gardenings/{id}/merge/',
'/documents/devices/', '/documents/devices/',
'/documents/erasures/', '/documents/erasures/',
'/documents/lots/',
'/documents/static/{filename}', '/documents/static/{filename}',
'/documents/stock/', '/documents/stock/',
'/drills/{id}/merge/', '/drills/{id}/merge/',

View File

@ -10,6 +10,7 @@ from ereuse_utils.test import ANY
from ereuse_devicehub.client import Client, UserClient from ereuse_devicehub.client import Client, UserClient
from ereuse_devicehub.resources.action.models import Snapshot from ereuse_devicehub.resources.action.models import Snapshot
from ereuse_devicehub.resources.documents import documents from ereuse_devicehub.resources.documents import documents
from ereuse_devicehub.resources.lot.models import Lot
from tests.conftest import file from tests.conftest import file
@ -258,3 +259,39 @@ def test_report_devices_stock_control(user: UserClient, user2: UserClient):
assert fixture_csv[0] == export_csv[0], 'Headers are not equal' assert fixture_csv[0] == export_csv[0], 'Headers are not equal'
assert fixture_csv[1] == export_csv[1], 'Computer information are not equal' assert fixture_csv[1] == export_csv[1], 'Computer information are not equal'
assert fixture_csv == export_csv
@pytest.mark.mvp
def test_get_document_lots(user: UserClient, user2: UserClient):
"""Tests submitting and retreiving all lots."""
l, _ = user.post({'name': 'Lot1', 'description': 'comments,lot1,testcomment-lot1,'}, res=Lot)
l, _ = user.post({'name': 'Lot2', 'description': 'comments,lot2,testcomment-lot2,'}, res=Lot)
l, _ = user2.post({'name': 'Lot3-User2', 'description': 'comments,lot3,testcomment-lot3,'}, res=Lot)
csv_str, _ = user.get(res=documents.DocumentDef.t,
item='lots/',
accept='text/csv')
csv2_str, _ = user2.get(res=documents.DocumentDef.t,
item='lots/',
accept='text/csv')
f = StringIO(csv_str)
obj_csv = csv.reader(f, f)
export_csv = list(obj_csv)
f = StringIO(csv2_str)
obj2_csv = csv.reader(f, f)
export2_csv = list(obj2_csv)
assert len(export_csv) == 3
assert len(export2_csv) == 2
assert export_csv[0] == export2_csv[0] == ['Id', 'Name', 'Registered in', 'Description']
assert export_csv[1][1] == 'Lot1' or 'Lot2'
assert export_csv[1][3] == 'comments,lot1,testcomment-lot1,' or 'comments,lot2,testcomment-lot2,'
assert export2_csv[1][1] == 'Lot3-User2'
assert export2_csv[1][3] == 'comments,lot3,testcomment-lot3,'

View File

@ -381,3 +381,14 @@ def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient):
query=[('id', device_id)], query=[('id', device_id)],
status=200) status=200)
assert not len(lot['devices']) assert not len(lot['devices'])
@pytest.mark.mvp
def test_get_multiple_lots(user: UserClient):
"""Tests submitting and retreiving multiple lots."""
l, _ = user.post({'name': 'Lot1', 'description': 'comments1,lot1,testcomment,'}, res=Lot)
l, _ = user.post({'name': 'Lot2', 'description': 'comments2,lot2,testcomment,'}, res=Lot)
l, _ = user.post({'name': 'Lot3', 'description': 'comments3,lot3,testcomment,'}, res=Lot)
l, _ = user.get(res=Lot)
assert len(l) == 3