Merge branch 'testing' into feature/server-side-render-parser-3021
This commit is contained in:
commit
e34b591690
|
@ -564,30 +564,68 @@ class NewActionForm(ActionFormMix):
|
||||||
|
|
||||||
class AllocateForm(ActionFormMix):
|
class AllocateForm(ActionFormMix):
|
||||||
start_time = DateField('Start time')
|
start_time = DateField('Start time')
|
||||||
end_time = DateField('End time')
|
end_time = DateField('End time', [validators.Optional()])
|
||||||
final_user_code = StringField('Final user code', [validators.length(max=50)])
|
final_user_code = StringField(
|
||||||
transaction = StringField('Transaction', [validators.length(max=50)])
|
'Final user code', [validators.Optional(), validators.length(max=50)]
|
||||||
end_users = IntegerField('End users')
|
)
|
||||||
|
transaction = StringField(
|
||||||
|
'Transaction', [validators.Optional(), validators.length(max=50)]
|
||||||
|
)
|
||||||
|
end_users = IntegerField('End users', [validators.Optional()])
|
||||||
|
|
||||||
def validate(self, extra_validators=None):
|
def validate(self, extra_validators=None):
|
||||||
is_valid = super().validate(extra_validators)
|
if not super().validate(extra_validators):
|
||||||
|
return False
|
||||||
|
|
||||||
if self.type.data not in ['Allocate', 'Deallocate']:
|
if self.type.data not in ['Allocate', 'Deallocate']:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not self.validate_dates():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.check_devices():
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def validate_dates(self):
|
||||||
start_time = self.start_time.data
|
start_time = self.start_time.data
|
||||||
end_time = self.end_time.data
|
end_time = self.end_time.data
|
||||||
|
|
||||||
|
if not start_time:
|
||||||
|
self.start_time.errors = ['Not a valid date value.!']
|
||||||
|
return False
|
||||||
|
|
||||||
if start_time and end_time and end_time < start_time:
|
if start_time and end_time and end_time < start_time:
|
||||||
error = ['The action cannot finish before it starts.']
|
error = ['The action cannot finish before it starts.']
|
||||||
self.start_time.errors = error
|
|
||||||
self.end_time.errors = error
|
self.end_time.errors = error
|
||||||
is_valid = False
|
return False
|
||||||
|
|
||||||
if not self.end_users.data:
|
if not end_time:
|
||||||
self.end_users.errors = ["You need to specify a number of users"]
|
self.end_time.data = self.start_time.data
|
||||||
is_valid = False
|
|
||||||
|
|
||||||
return is_valid
|
return True
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if self.type.data == 'Deallocate':
|
||||||
|
txt = "Sorry some of this devices are actually deallocate"
|
||||||
|
for device in self._devices:
|
||||||
|
if not device.allocated:
|
||||||
|
self.devices.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
device.allocated = False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class DataWipeDocumentForm(Form):
|
class DataWipeDocumentForm(Form):
|
||||||
|
|
|
@ -10,7 +10,7 @@ from typing import Dict, List, Set
|
||||||
from boltons import urlutils
|
from boltons import urlutils
|
||||||
from citext import CIText
|
from citext import CIText
|
||||||
from ereuse_utils.naming import HID_CONVERSION_DOC, Naming
|
from ereuse_utils.naming import HID_CONVERSION_DOC, Naming
|
||||||
from flask import g
|
from flask import g, request
|
||||||
from flask_sqlalchemy import event
|
from flask_sqlalchemy import event
|
||||||
from more_itertools import unique_everseen
|
from more_itertools import unique_everseen
|
||||||
from sqlalchemy import BigInteger, Boolean, Column
|
from sqlalchemy import BigInteger, Boolean, Column
|
||||||
|
@ -297,6 +297,11 @@ class Device(Thing):
|
||||||
actions.reverse()
|
actions.reverse()
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
@property
|
||||||
|
def public_link(self) -> str:
|
||||||
|
host_url = request.host_url.strip('/')
|
||||||
|
return "{}{}".format(host_url, self.url.to_text())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self) -> urlutils.URL:
|
def url(self) -> urlutils.URL:
|
||||||
"""The URL where to GET this device."""
|
"""The URL where to GET this device."""
|
||||||
|
|
|
@ -26,6 +26,14 @@
|
||||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#type">Type</button>
|
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#type">Type</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ device.public_link }}" target="_blank">Web</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#lots">Lots</button>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#status">Status</button>
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#status">Status</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -69,6 +77,50 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade profile-overview" id="lots">
|
||||||
|
<h5 class="card-title">Incoming Lots</h5>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{% for lot in device.lots %}
|
||||||
|
{% if lot.is_incoming %}
|
||||||
|
<div class="col">
|
||||||
|
<a class="ms-3" href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
|
<span>{{ lot.name }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="card-title">Outgoing Lots</h5>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{% for lot in device.lots %}
|
||||||
|
{% if lot.is_outgoing %}
|
||||||
|
<div class="col">
|
||||||
|
<a class="ms-3" href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
|
<span>{{ lot.name }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="card-title">Temporary Lots</h5>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
{% for lot in device.lots %}
|
||||||
|
{% if lot.is_temporary %}
|
||||||
|
<div class="col">
|
||||||
|
<a class="ms-3" href="{{ url_for('inventory.lotdevicelist', lot_id=lot.id) }}">
|
||||||
|
<span>{{ lot.name }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="tab-pane fade profile-overview" id="status">
|
<div class="tab-pane fade profile-overview" id="status">
|
||||||
<h5 class="card-title">Status Details</h5>
|
<h5 class="card-title">Status Details</h5>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -668,7 +668,7 @@ def test_action_allocate_error_required(user3: UserClientFlask):
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert 'Action Allocate error' in body
|
assert 'Action Allocate error' in body
|
||||||
assert 'You need to specify a number of users!' in body
|
assert 'Not a valid date value.' in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
|
Reference in New Issue