Merge pull request #284 from eReuse/bugfix/3385-bug-date-allocate

fixed bugs of allocate
This commit is contained in:
cayop 2022-05-26 18:11:37 +02:00 committed by GitHub
commit 776c27a082
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 315 additions and 17 deletions

View file

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

View file

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

View file

@ -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 &#34;Deallocate&#34; 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):