Merge pull request #284 from eReuse/bugfix/3385-bug-date-allocate
fixed bugs of allocate
This commit is contained in:
commit
776c27a082
|
@ -1,4 +1,5 @@
|
|||
import copy
|
||||
import datetime
|
||||
import json
|
||||
from json.decoder import JSONDecodeError
|
||||
|
||||
|
@ -667,6 +668,10 @@ class AllocateForm(ActionFormMix):
|
|||
self.start_time.errors = ['Not a valid date value.!']
|
||||
return False
|
||||
|
||||
if start_time > datetime.datetime.now().date():
|
||||
self.start_time.errors = ['Not a valid date value.!']
|
||||
return False
|
||||
|
||||
if start_time and end_time and end_time < start_time:
|
||||
error = ['The action cannot finish before it starts.']
|
||||
self.end_time.errors = error
|
||||
|
@ -679,23 +684,100 @@ class AllocateForm(ActionFormMix):
|
|||
|
||||
def check_devices(self):
|
||||
if self.type.data == 'Allocate':
|
||||
txt = "You need deallocate before allocate this device again"
|
||||
for device in self._devices:
|
||||
if device.allocated:
|
||||
self.devices.errors = [txt]
|
||||
return False
|
||||
|
||||
device.allocated = True
|
||||
|
||||
return self.check_allocate()
|
||||
if self.type.data == 'Deallocate':
|
||||
txt = "Sorry some of this devices are actually deallocate"
|
||||
for device in self._devices:
|
||||
if not device.allocated:
|
||||
return self.check_deallocate()
|
||||
return True
|
||||
|
||||
def check_allocate(self):
|
||||
txt = "You need deallocate before allocate this device again"
|
||||
for device in self._devices:
|
||||
# | Allo - Deallo | Allo - Deallo |
|
||||
|
||||
allocates = [
|
||||
ac for ac in device.actions if ac.type in ['Allocate', 'Deallocate']
|
||||
]
|
||||
allocates.sort(key=lambda x: x.start_time)
|
||||
allocates.reverse()
|
||||
last_deallocate = None
|
||||
last_allocate = None
|
||||
for ac in allocates:
|
||||
if (
|
||||
ac.type == 'Deallocate'
|
||||
and ac.start_time.date() < self.start_time.data
|
||||
):
|
||||
# allow to do the action
|
||||
break
|
||||
|
||||
# check if this action is between an old allocate - deallocate
|
||||
if ac.type == 'Deallocate':
|
||||
last_deallocate = ac
|
||||
continue
|
||||
|
||||
if (
|
||||
ac.type == 'Allocate'
|
||||
and ac.start_time.date() > self.start_time.data
|
||||
):
|
||||
last_deallocate = None
|
||||
last_allocate = None
|
||||
continue
|
||||
|
||||
if ac.type == 'Allocate':
|
||||
last_allocate = ac
|
||||
|
||||
if last_allocate or not last_deallocate:
|
||||
self.devices.errors = [txt]
|
||||
return False
|
||||
|
||||
device.allocated = False
|
||||
device.allocated = True
|
||||
return True
|
||||
|
||||
def check_deallocate(self):
|
||||
txt = "Sorry some of this devices are actually deallocate"
|
||||
for device in self._devices:
|
||||
allocates = [
|
||||
ac for ac in device.actions if ac.type in ['Allocate', 'Deallocate']
|
||||
]
|
||||
allocates.sort(key=lambda x: x.start_time)
|
||||
allocates.reverse()
|
||||
last_deallocate = None
|
||||
last_allocate = None
|
||||
|
||||
for ac in allocates:
|
||||
# check if this action is between an old allocate - deallocate
|
||||
# | Allo - Deallo | Allo - Deallo |
|
||||
# | Allo |
|
||||
if (
|
||||
ac.type == 'Allocate'
|
||||
and ac.start_time.date() > self.start_time.data
|
||||
):
|
||||
last_allocate = None
|
||||
last_deallocate = None
|
||||
continue
|
||||
|
||||
if ac.type == 'Allocate' and not last_deallocate:
|
||||
last_allocate = ac
|
||||
break
|
||||
|
||||
if (
|
||||
ac.type == 'Deallocate'
|
||||
and ac.start_time.date() > self.start_time.data
|
||||
):
|
||||
last_deallocate = ac
|
||||
continue
|
||||
|
||||
if ac.type == 'Deallocate':
|
||||
last_allocate = None
|
||||
|
||||
if last_deallocate or not last_allocate:
|
||||
self.devices.errors = [txt]
|
||||
return False
|
||||
|
||||
if not last_deallocate and not last_allocate:
|
||||
self.devices.errors = [txt]
|
||||
return False
|
||||
|
||||
device.allocated = False
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import copy
|
||||
import pathlib
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from fractions import Fraction
|
||||
from itertools import chain
|
||||
|
@ -358,7 +357,6 @@ class Device(Thing):
|
|||
from ereuse_devicehub.resources.device import states
|
||||
|
||||
with suppress(LookupError, ValueError):
|
||||
# import pdb; pdb.set_trace()
|
||||
return self.last_action_of(*states.Physical.actions())
|
||||
|
||||
@property
|
||||
|
@ -407,7 +405,7 @@ class Device(Thing):
|
|||
def tradings(self):
|
||||
return {str(x.id): self.trading(x.lot) for x in self.actions if x.t == 'Trade'}
|
||||
|
||||
def trading(self, lot, simple=None):
|
||||
def trading(self, lot, simple=None): # noqa: C901
|
||||
"""The trading state, or None if no Trade action has
|
||||
ever been performed to this device. This extract the posibilities for to do.
|
||||
This method is performed for show in the web.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import csv
|
||||
import datetime
|
||||
import json
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
|
@ -686,6 +687,34 @@ def test_action_allocate_error_dates(user3: UserClientFlask):
|
|||
assert dev.actions[-1].type != 'Allocate'
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_allocate_error_future_dates(user3: UserClientFlask):
|
||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||
dev = snap.device
|
||||
uri = '/inventory/device/'
|
||||
user3.get(uri)
|
||||
start_time = (datetime.datetime.now() + datetime.timedelta(1)).strftime('%Y-%m-%d')
|
||||
end_time = (datetime.datetime.now() + datetime.timedelta(10)).strftime('%Y-%m-%d')
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': start_time,
|
||||
'end_time': end_time,
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
uri = '/inventory/action/allocate/add/'
|
||||
body, status = user3.post(uri, data=data)
|
||||
assert status == '200 OK'
|
||||
assert 'Action Allocate error' in body
|
||||
assert 'Not a valid date value.!' in body
|
||||
assert dev.actions[-1].type != 'Allocate'
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_deallocate(user3: UserClientFlask):
|
||||
|
@ -707,7 +736,7 @@ def test_action_deallocate(user3: UserClientFlask):
|
|||
uri = '/inventory/action/allocate/add/'
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert dev.actions[-1].type == 'Allocate'
|
||||
assert dev.allocated_status.type == 'Allocate'
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
|
@ -720,11 +749,200 @@ def test_action_deallocate(user3: UserClientFlask):
|
|||
}
|
||||
body, status = user3.post(uri, data=data)
|
||||
assert status == '200 OK'
|
||||
assert dev.actions[-1].type == 'Deallocate'
|
||||
assert dev.allocated_status.type == 'Deallocate'
|
||||
assert 'Action "Deallocate" created successfully!' in body
|
||||
assert dev.devicehub_id in body
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_deallocate_error(user3: UserClientFlask):
|
||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||
dev = snap.device
|
||||
uri = '/inventory/device/'
|
||||
user3.get(uri)
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-05-01',
|
||||
'end_time': '2000-06-01',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
uri = '/inventory/action/allocate/add/'
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert dev.allocated_status.type == 'Allocate'
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-01',
|
||||
'end_time': '2000-02-01',
|
||||
'end_users': 2,
|
||||
}
|
||||
body, status = user3.post(uri, data=data)
|
||||
assert status == '200 OK'
|
||||
assert dev.allocated_status.type != 'Deallocate'
|
||||
assert 'Action Deallocate error!' in body
|
||||
assert 'Sorry some of this devices are actually deallocate' in body
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_allocate_deallocate_error(user3: UserClientFlask):
|
||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||
dev = snap.device
|
||||
uri = '/inventory/device/'
|
||||
user3.get(uri)
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-01',
|
||||
'end_time': '2000-01-01',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
uri = '/inventory/action/allocate/add/'
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert dev.allocated_status.type == 'Allocate'
|
||||
assert len(dev.actions) == 13
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-02-01',
|
||||
'end_time': '2000-02-01',
|
||||
'end_users': 2,
|
||||
}
|
||||
body, status = user3.post(uri, data=data)
|
||||
assert status == '200 OK'
|
||||
assert dev.allocated_status.type == 'Deallocate'
|
||||
assert len(dev.actions) == 14
|
||||
|
||||
# is not possible to do an allocate between an allocate and an deallocate
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-15',
|
||||
'end_time': '2000-01-15',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert dev.allocated_status.type == 'Deallocate'
|
||||
# assert 'Action Deallocate error!' in body
|
||||
# assert 'Sorry some of this devices are actually deallocate' in body
|
||||
#
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-15',
|
||||
'end_time': '2000-01-15',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 14
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_allocate_deallocate_error2(user3: UserClientFlask):
|
||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||
dev = snap.device
|
||||
uri = '/inventory/device/'
|
||||
user3.get(uri)
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-10',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
uri = '/inventory/action/allocate/add/'
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 13
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-20',
|
||||
'end_users': 2,
|
||||
}
|
||||
body, status = user3.post(uri, data=data)
|
||||
assert status == '200 OK'
|
||||
assert len(dev.actions) == 14
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-02-10',
|
||||
'end_users': 2,
|
||||
}
|
||||
|
||||
uri = '/inventory/action/allocate/add/'
|
||||
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 15
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-02-20',
|
||||
'end_users': 2,
|
||||
}
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 16
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Allocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-25',
|
||||
'end_users': 2,
|
||||
}
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 17
|
||||
|
||||
data = {
|
||||
'csrf_token': generate_csrf(),
|
||||
'type': "Deallocate",
|
||||
'severity': "Info",
|
||||
'devices': "{}".format(dev.id),
|
||||
'start_time': '2000-01-27',
|
||||
'end_users': 2,
|
||||
}
|
||||
user3.post(uri, data=data)
|
||||
assert len(dev.actions) == 18
|
||||
|
||||
|
||||
@pytest.mark.mvp
|
||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||
def test_action_toprepare(user3: UserClientFlask):
|
||||
|
|
Reference in a new issue