Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
Cayo Puigdefabregas | 6dc033281d | |
Cayo Puigdefabregas | 5bcf3b2a63 | |
Cayo Puigdefabregas | fa55ac017d | |
cayop | e2c04e3e48 | |
Cayo Puigdefabregas | 6bf91d3362 | |
cayop | 4b7bf24d86 | |
Cayo Puigdefabregas | 3a1f135310 | |
Cayo Puigdefabregas | 1941f28ab3 | |
Cayo Puigdefabregas | 25fd9c3b6f | |
cayop | 07e506f999 | |
Cayo Puigdefabregas | 72e4481b5d | |
Cayo Puigdefabregas | 9209e3cfaa | |
Cayo Puigdefabregas | 3408af33a8 | |
Cayo Puigdefabregas | d5e93f3a52 | |
Cayo Puigdefabregas | b405f715e0 | |
Cayo Puigdefabregas | c79cfd05fa | |
Cayo Puigdefabregas | ae310ece6d |
|
@ -7,6 +7,12 @@ ml).
|
||||||
|
|
||||||
## testing
|
## testing
|
||||||
|
|
||||||
|
## [2.5.4] - 2023-08-7
|
||||||
|
- [added] #460 new device Solar Panel
|
||||||
|
- [fixed] #459 Deploy without Dummy
|
||||||
|
- [fixed] #461 Fix some behavior of orphans components (DataStorage)
|
||||||
|
- [fixed] #462 Remove constraints in weight in placeholder
|
||||||
|
|
||||||
## [2.5.3] - 2023-05-13
|
## [2.5.3] - 2023-05-13
|
||||||
- [added] #450 add new datawipe in csv.
|
- [added] #450 add new datawipe in csv.
|
||||||
- [changed] #447 Share a lot between 2 users, one is owner the other is read only.
|
- [changed] #447 Share a lot between 2 users, one is owner the other is read only.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "2.5.3"
|
__version__ = "2.5.4"
|
||||||
|
|
|
@ -41,7 +41,7 @@ from ereuse_devicehub.inventory.models import (
|
||||||
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
||||||
from ereuse_devicehub.parser.parser import ParseSnapshotLsHw
|
from ereuse_devicehub.parser.parser import ParseSnapshotLsHw
|
||||||
from ereuse_devicehub.parser.schemas import Snapshot_lite
|
from ereuse_devicehub.parser.schemas import Snapshot_lite
|
||||||
from ereuse_devicehub.resources.action.models import Snapshot, Trade
|
from ereuse_devicehub.resources.action.models import Snapshot, Trade, VisualTest
|
||||||
from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema
|
from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema
|
||||||
from ereuse_devicehub.resources.action.views.snapshot import (
|
from ereuse_devicehub.resources.action.views.snapshot import (
|
||||||
SnapshotMixin,
|
SnapshotMixin,
|
||||||
|
@ -68,6 +68,7 @@ from ereuse_devicehub.resources.device.models import (
|
||||||
Projector,
|
Projector,
|
||||||
Server,
|
Server,
|
||||||
Smartphone,
|
Smartphone,
|
||||||
|
SolarPanel,
|
||||||
SolidStateDrive,
|
SolidStateDrive,
|
||||||
Tablet,
|
Tablet,
|
||||||
TelevisionSet,
|
TelevisionSet,
|
||||||
|
@ -113,7 +114,7 @@ DEVICES = {
|
||||||
"SAI",
|
"SAI",
|
||||||
"Keyboard",
|
"Keyboard",
|
||||||
],
|
],
|
||||||
"Other Devices": ["Other"],
|
"Other Devices": ["SolarPanel", "Other"],
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPES_DOCUMENTS = [
|
TYPES_DOCUMENTS = [
|
||||||
|
@ -131,7 +132,7 @@ MONITORS = ["ComputerMonitor", "Monitor", "TelevisionSet", "Projector"]
|
||||||
MOBILE = ["Mobile", "Tablet", "Smartphone", "Cellphone"]
|
MOBILE = ["Mobile", "Tablet", "Smartphone", "Cellphone"]
|
||||||
STORAGE = ["HardDrive", "SolidStateDrive"]
|
STORAGE = ["HardDrive", "SolidStateDrive"]
|
||||||
ACCESSORIES = ["Mouse", "MemoryCardReader", "SAI", "Keyboard"]
|
ACCESSORIES = ["Mouse", "MemoryCardReader", "SAI", "Keyboard"]
|
||||||
OTHERS = ["Other"]
|
OTHERS = ["Other", "SolarPanel"]
|
||||||
DATASTORAGE = ['HardDrive', 'SolidStateDrive']
|
DATASTORAGE = ['HardDrive', 'SolidStateDrive']
|
||||||
|
|
||||||
|
|
||||||
|
@ -433,6 +434,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
"Keyboard": Keyboard,
|
"Keyboard": Keyboard,
|
||||||
"SAI": SAI,
|
"SAI": SAI,
|
||||||
"MemoryCardReader": MemoryCardReader,
|
"MemoryCardReader": MemoryCardReader,
|
||||||
|
"SolarPanel": SolarPanel,
|
||||||
"Other": Other,
|
"Other": Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,6 +482,10 @@ class NewDeviceForm(FlaskForm):
|
||||||
if self._obj.type in ['HardDrive', 'SolidStateDrive']:
|
if self._obj.type in ['HardDrive', 'SolidStateDrive']:
|
||||||
if self._obj.size:
|
if self._obj.size:
|
||||||
self.data_storage_size.data = self._obj.size / 1000
|
self.data_storage_size.data = self._obj.size / 1000
|
||||||
|
if self._obj.appearance():
|
||||||
|
self.appearance.data = self._obj.appearance().name
|
||||||
|
if self._obj.functionality():
|
||||||
|
self.functionality.data = self._obj.functionality().name
|
||||||
|
|
||||||
if self._obj.placeholder.is_abstract:
|
if self._obj.placeholder.is_abstract:
|
||||||
self.type.render_kw = disabled
|
self.type.render_kw = disabled
|
||||||
|
@ -515,23 +521,23 @@ class NewDeviceForm(FlaskForm):
|
||||||
error = ["Not a correct value"]
|
error = ["Not a correct value"]
|
||||||
is_valid = super().validate(extra_validators)
|
is_valid = super().validate(extra_validators)
|
||||||
|
|
||||||
if self.weight.data and not (0.1 <= self.weight.data <= 5):
|
if self.weight.data and not (0.1 <= self.weight.data) or self.weight.data == 0:
|
||||||
txt = ["Supported values between 0.1 and 5"]
|
txt = ["Supported values greater than 0.1"]
|
||||||
self.weight.errors = txt
|
self.weight.errors = txt
|
||||||
is_valid = False
|
is_valid = False
|
||||||
|
|
||||||
if self.height.data and not (0.1 <= self.height.data <= 5):
|
if self.height.data and not (0.1 <= self.height.data) or self.height.data == 0:
|
||||||
txt = ["Supported values between 0.1 and 5"]
|
txt = ["Supported values greater than 0.1"]
|
||||||
self.height.errors = txt
|
self.height.errors = txt
|
||||||
is_valid = False
|
is_valid = False
|
||||||
|
|
||||||
if self.width.data and not (0.1 <= self.width.data <= 5):
|
if self.width.data and not (0.1 <= self.width.data) or self.width.data == 0:
|
||||||
txt = ["Supported values between 0.1 and 5"]
|
txt = ["Supported values greater than 0.1"]
|
||||||
self.width.errors = txt
|
self.width.errors = txt
|
||||||
is_valid = False
|
is_valid = False
|
||||||
|
|
||||||
if self.depth.data and not (0.1 <= self.depth.data <= 5):
|
if self.depth.data and not (0.1 <= self.depth.data) or self.depth.data == 0:
|
||||||
txt = ["Supported values between 0.1 and 5"]
|
txt = ["Supported values greater than 0.1"]
|
||||||
self.depth.errors = txt
|
self.depth.errors = txt
|
||||||
is_valid = False
|
is_valid = False
|
||||||
|
|
||||||
|
@ -698,17 +704,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
if self.data_storage_size.data:
|
if self.data_storage_size.data:
|
||||||
self._obj.size = self.data_storage_size.data * 1000
|
self._obj.size = self.data_storage_size.data * 1000
|
||||||
|
|
||||||
if (
|
self.edit_visual_test(self._obj)
|
||||||
self.appearance.data
|
|
||||||
and self.appearance.data != self._obj.appearance().name
|
|
||||||
):
|
|
||||||
self._obj.set_appearance(self.appearance.data)
|
|
||||||
|
|
||||||
if (
|
|
||||||
self.functionality.data
|
|
||||||
and self.functionality.data != self._obj.functionality().name
|
|
||||||
):
|
|
||||||
self._obj.set_functionality(self.functionality.data)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self._obj.placeholder.id_device_supplier = (
|
self._obj.placeholder.id_device_supplier = (
|
||||||
|
@ -718,11 +714,33 @@ class NewDeviceForm(FlaskForm):
|
||||||
self.id_device_internal.data or None
|
self.id_device_internal.data or None
|
||||||
)
|
)
|
||||||
self._obj.placeholder.pallet = self.pallet.data or None
|
self._obj.placeholder.pallet = self.pallet.data or None
|
||||||
|
|
||||||
|
pl_dev = self._obj.placeholder.device
|
||||||
|
self.edit_visual_test(pl_dev)
|
||||||
|
|
||||||
placeholder_log = PlaceholdersLog(
|
placeholder_log = PlaceholdersLog(
|
||||||
type="Update", source='Web form', placeholder=self._obj.placeholder
|
type="Update", source='Web form', placeholder=self._obj.placeholder
|
||||||
)
|
)
|
||||||
db.session.add(placeholder_log)
|
db.session.add(placeholder_log)
|
||||||
|
|
||||||
|
def edit_visual_test(self, dev):
|
||||||
|
if not dev.appearance() or not dev.functionality():
|
||||||
|
visual_test = VisualTest(
|
||||||
|
appearance_range=self.appearance.data,
|
||||||
|
functionality_range=self.functionality.data,
|
||||||
|
device=dev,
|
||||||
|
)
|
||||||
|
db.session.add(visual_test)
|
||||||
|
else:
|
||||||
|
if self.appearance.data and self.appearance.data != dev.appearance().name:
|
||||||
|
dev.set_appearance(self.appearance.data)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.functionality.data
|
||||||
|
and self.functionality.data != dev.functionality().name
|
||||||
|
):
|
||||||
|
dev.set_functionality(self.functionality.data)
|
||||||
|
|
||||||
|
|
||||||
class TagDeviceForm(FlaskForm):
|
class TagDeviceForm(FlaskForm):
|
||||||
tag = SelectField(
|
tag = SelectField(
|
||||||
|
@ -1211,7 +1229,6 @@ class TradeForm(ActionFormMixin):
|
||||||
or email_to == email_from
|
or email_to == email_from
|
||||||
or g.user.email not in [email_from, email_to]
|
or g.user.email not in [email_from, email_to]
|
||||||
):
|
):
|
||||||
|
|
||||||
errors = ["If you want confirm, you need a correct email"]
|
errors = ["If you want confirm, you need a correct email"]
|
||||||
self.user_to.errors = errors
|
self.user_to.errors = errors
|
||||||
self.user_from.errors = errors
|
self.user_from.errors = errors
|
||||||
|
@ -1917,7 +1934,6 @@ class UploadPlaceholderForm(FlaskForm):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
|
|
||||||
for device, placeholder_log in self.placeholders:
|
for device, placeholder_log in self.placeholders:
|
||||||
db.session.add(device)
|
db.session.add(device)
|
||||||
db.session.add(placeholder_log)
|
db.session.add(placeholder_log)
|
||||||
|
@ -1946,7 +1962,6 @@ class EditPlaceholderForm(FlaskForm):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
|
|
||||||
for device in self.placeholders:
|
for device in self.placeholders:
|
||||||
db.session.add(device)
|
db.session.add(device)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Revises: ${down_revision | comma,n}
|
||||||
Create Date: ${create_date}
|
Create Date: ${create_date}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op, context
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
import sqlalchemy_utils
|
||||||
import citext
|
import citext
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
"""reset check_constraint of placeholders
|
||||||
|
|
||||||
|
Revision ID: 57e6201f280c
|
||||||
|
Revises: 8ccba3cb37c2
|
||||||
|
Create Date: 2023-08-02 15:56:12.484340
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import context, op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '57e6201f280c'
|
||||||
|
down_revision = '8ccba3cb37c2'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_inv():
|
||||||
|
INV = context.get_x_argument(as_dictionary=True).get('inventory')
|
||||||
|
if not INV:
|
||||||
|
raise ValueError("Inventory value is not specified")
|
||||||
|
return INV
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
sql = "select constraint_name from information_schema.table_constraints "
|
||||||
|
sql += "where table_name='device' and constraint_type='CHECK';"
|
||||||
|
con = op.get_bind()
|
||||||
|
constraints = []
|
||||||
|
for c in con.execute(sql):
|
||||||
|
constraints.append(c.constraint_name)
|
||||||
|
if 'device_depth_check' in constraints:
|
||||||
|
op.drop_constraint(
|
||||||
|
'device_depth_check', "device", type_="check", schema=f'{get_inv()}'
|
||||||
|
)
|
||||||
|
if 'device_height_check' in constraints:
|
||||||
|
op.drop_constraint(
|
||||||
|
'device_height_check', "device", type_="check", schema=f'{get_inv()}'
|
||||||
|
)
|
||||||
|
if 'device_width_check' in constraints:
|
||||||
|
op.drop_constraint(
|
||||||
|
'device_width_check', "device", type_="check", schema=f'{get_inv()}'
|
||||||
|
)
|
||||||
|
if 'device_weight_check' in constraints:
|
||||||
|
op.drop_constraint(
|
||||||
|
'device_weight_check', "device", type_="check", schema=f'{get_inv()}'
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_check_constraint(
|
||||||
|
"device_depth_check",
|
||||||
|
"device",
|
||||||
|
sa.Column("depth") >= (0.1),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.create_check_constraint(
|
||||||
|
"device_height_check",
|
||||||
|
"device",
|
||||||
|
sa.Column("depth") >= (0.1),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.create_check_constraint(
|
||||||
|
"device_width_check",
|
||||||
|
"device",
|
||||||
|
sa.Column("depth") >= (0.1),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.create_check_constraint(
|
||||||
|
"device_weight_check",
|
||||||
|
"device",
|
||||||
|
sa.Column("depth") >= (0.1),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
pass
|
|
@ -0,0 +1,41 @@
|
||||||
|
"""add solar panel
|
||||||
|
|
||||||
|
Revision ID: 8ccba3cb37c2
|
||||||
|
Revises: 5169765e2653
|
||||||
|
Create Date: 2023-07-26 09:23:21.326465
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import context, op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '8ccba3cb37c2'
|
||||||
|
down_revision = '5169765e2653'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_inv():
|
||||||
|
INV = context.get_x_argument(as_dictionary=True).get('inventory')
|
||||||
|
if not INV:
|
||||||
|
raise ValueError("Inventory value is not specified")
|
||||||
|
return INV
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# creating Solar panel device.
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'solar_panel',
|
||||||
|
sa.Column('id', sa.BigInteger(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
['id'],
|
||||||
|
[f'{get_inv()}.device.id'],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table('solar_panel', schema=f'{get_inv()}')
|
|
@ -726,3 +726,34 @@ class OtherDef(DeviceDef):
|
||||||
root_path,
|
root_path,
|
||||||
cli_commands,
|
cli_commands,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SolarPanelDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.SolarPanel
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
app,
|
||||||
|
import_name=__name__,
|
||||||
|
static_folder=None,
|
||||||
|
static_url_path=None,
|
||||||
|
template_folder=None,
|
||||||
|
url_prefix=None,
|
||||||
|
subdomain=None,
|
||||||
|
url_defaults=None,
|
||||||
|
root_path=None,
|
||||||
|
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple(),
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
app,
|
||||||
|
import_name,
|
||||||
|
static_folder,
|
||||||
|
static_url_path,
|
||||||
|
template_folder,
|
||||||
|
url_prefix,
|
||||||
|
subdomain,
|
||||||
|
url_defaults,
|
||||||
|
root_path,
|
||||||
|
cli_commands,
|
||||||
|
)
|
||||||
|
|
|
@ -150,13 +150,13 @@ class Device(Thing):
|
||||||
generation.comment = """The generation of the device."""
|
generation.comment = """The generation of the device."""
|
||||||
version = db.Column(db.CIText())
|
version = db.Column(db.CIText())
|
||||||
version.comment = """The version code of this device, like v1 or A001."""
|
version.comment = """The version code of this device, like v1 or A001."""
|
||||||
weight = Column(Float(decimal_return_scale=4), check_range('weight', 0.1, 5))
|
weight = Column(Float(decimal_return_scale=4))
|
||||||
weight.comment = """The weight of the device in Kg."""
|
weight.comment = """The weight of the device in Kg."""
|
||||||
width = Column(Float(decimal_return_scale=4), check_range('width', 0.1, 5))
|
width = Column(Float(decimal_return_scale=4))
|
||||||
width.comment = """The width of the device in meters."""
|
width.comment = """The width of the device in meters."""
|
||||||
height = Column(Float(decimal_return_scale=4), check_range('height', 0.1, 5))
|
height = Column(Float(decimal_return_scale=4))
|
||||||
height.comment = """The height of the device in meters."""
|
height.comment = """The height of the device in meters."""
|
||||||
depth = Column(Float(decimal_return_scale=4), check_range('depth', 0.1, 5))
|
depth = Column(Float(decimal_return_scale=4))
|
||||||
depth.comment = """The depth of the device in meters."""
|
depth.comment = """The depth of the device in meters."""
|
||||||
color = Column(ColorType)
|
color = Column(ColorType)
|
||||||
color.comment = """The predominant color of the device."""
|
color.comment = """The predominant color of the device."""
|
||||||
|
@ -476,7 +476,8 @@ class Device(Thing):
|
||||||
"""The trading state, or None if no Trade action has
|
"""The trading state, or None if no Trade action has
|
||||||
ever been performed to this device. This extract the posibilities for to do.
|
ever been performed to this device. This extract the posibilities for to do.
|
||||||
This method is performed for show in the web.
|
This method is performed for show in the web.
|
||||||
If you need to do one simple and generic response you can put simple=True for that."""
|
If you need to do one simple and generic response you can put simple=True for that.
|
||||||
|
"""
|
||||||
if not hasattr(lot, 'trade'):
|
if not hasattr(lot, 'trade'):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -928,6 +929,7 @@ class Device(Thing):
|
||||||
"Cellphone": "bi bi-telephone",
|
"Cellphone": "bi bi-telephone",
|
||||||
"HardDrive": "bi bi-hdd-stack",
|
"HardDrive": "bi bi-hdd-stack",
|
||||||
"SolidStateDrive": "bi bi-hdd",
|
"SolidStateDrive": "bi bi-hdd",
|
||||||
|
"SolarPanel": "bi-solar-panel",
|
||||||
}
|
}
|
||||||
return types.get(self.type, '')
|
return types.get(self.type, '')
|
||||||
|
|
||||||
|
@ -1986,3 +1988,11 @@ class Other(Device):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SolarPanel(Device):
|
||||||
|
"""
|
||||||
|
Used solar panels devices.
|
||||||
|
"""
|
||||||
|
|
||||||
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
|
|
|
@ -67,18 +67,10 @@ class Device(Thing):
|
||||||
validate=Range(1, 100), description=m.Device.generation.comment
|
validate=Range(1, 100), description=m.Device.generation.comment
|
||||||
)
|
)
|
||||||
version = SanitizedStr(description=m.Device.version)
|
version = SanitizedStr(description=m.Device.version)
|
||||||
weight = Float(
|
weight = Float(unit=UnitCodes.kgm, description=m.Device.weight.comment)
|
||||||
validate=Range(0.1, 5), unit=UnitCodes.kgm, description=m.Device.weight.comment
|
width = Float(unit=UnitCodes.m, description=m.Device.width.comment)
|
||||||
)
|
height = Float(unit=UnitCodes.m, description=m.Device.height.comment)
|
||||||
width = Float(
|
depth = Float(unit=UnitCodes.m, description=m.Device.depth.comment)
|
||||||
validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.width.comment
|
|
||||||
)
|
|
||||||
height = Float(
|
|
||||||
validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.height.comment
|
|
||||||
)
|
|
||||||
depth = Float(
|
|
||||||
validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.depth.comment
|
|
||||||
)
|
|
||||||
# TODO TimeOut 2. Comment actions and lots if there are time out.
|
# TODO TimeOut 2. Comment actions and lots if there are time out.
|
||||||
actions = NestedOn(
|
actions = NestedOn(
|
||||||
'Action', many=True, dump_only=True, description=m.Device.actions.__doc__
|
'Action', many=True, dump_only=True, description=m.Device.actions.__doc__
|
||||||
|
@ -590,5 +582,9 @@ class Racket(Recreation):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SolarPanel(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Other(Device):
|
class Other(Device):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -92,10 +92,21 @@ class Sync:
|
||||||
# We only want to perform Add/Remove to not new components
|
# We only want to perform Add/Remove to not new components
|
||||||
actions = self.add_remove(db_device, not_new_components)
|
actions = self.add_remove(db_device, not_new_components)
|
||||||
db_device.components = db_components
|
db_device.components = db_components
|
||||||
|
self.clean_parent_orphans_components(db_device)
|
||||||
|
|
||||||
self.create_placeholder(db_device)
|
self.create_placeholder(db_device)
|
||||||
return db_device, actions
|
return db_device, actions
|
||||||
|
|
||||||
|
def clean_parent_orphans_components(self, device):
|
||||||
|
all_components = Component.query.filter_by(parent_id=device.id)
|
||||||
|
for _c in all_components:
|
||||||
|
if _c not in device.components:
|
||||||
|
_c.parent = None
|
||||||
|
if _c.binding:
|
||||||
|
_c.binding.device.parent = None
|
||||||
|
if _c.placeholder and _c.placeholder.binding:
|
||||||
|
_c.placeholder.binding.parent = None
|
||||||
|
|
||||||
def execute_register_component(self, component: Component):
|
def execute_register_component(self, component: Component):
|
||||||
"""Synchronizes one component to the DB.
|
"""Synchronizes one component to the DB.
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ class DeviceView(View):
|
||||||
"""Gets many devices."""
|
"""Gets many devices."""
|
||||||
# Compute query
|
# Compute query
|
||||||
query = self.query(args)
|
query = self.query(args)
|
||||||
devices = query.paginate(page=args['page'], per_page=30) # type: Pagination
|
devices = query.paginate(page=args['page'], per_page=100) # type: Pagination
|
||||||
return things_response(
|
return things_response(
|
||||||
self.schema.dump(devices.items, many=True, nested=1),
|
self.schema.dump(devices.items, many=True, nested=1),
|
||||||
devices.page,
|
devices.page,
|
||||||
|
|
|
@ -422,26 +422,33 @@ class DeviceRow(BaseDeviceRow):
|
||||||
self['{} {} Speed (MHz)'.format(ctype, i)] = none2str(component.speed)
|
self['{} {} Speed (MHz)'.format(ctype, i)] = none2str(component.speed)
|
||||||
|
|
||||||
def get_erasure_datawipe_mobile(self, device):
|
def get_erasure_datawipe_mobile(self, device):
|
||||||
|
if isinstance(device, d.DataStorage):
|
||||||
|
if device.placeholder and device.placeholder.binding:
|
||||||
|
binding = device.placeholder.binding
|
||||||
|
return self.get_datastorage('DataStorage', 1, binding)
|
||||||
|
return self.get_datastorage('DataStorage', 1, device)
|
||||||
|
|
||||||
|
if not isinstance(device, d.Mobile):
|
||||||
|
return
|
||||||
|
|
||||||
actions = sorted(device.actions)
|
actions = sorted(device.actions)
|
||||||
erasures = [a for a in actions if a.type == 'EraseDataWipe']
|
erasures = [a for a in actions if a.type == 'EraseDataWipe']
|
||||||
erasure = erasures[-1] if erasures else None
|
erasure = erasures[-1] if erasures else None
|
||||||
if erasure:
|
|
||||||
|
if not erasure:
|
||||||
|
return
|
||||||
|
|
||||||
self['Erasure DataStorage 1'] = none2str(device.chid)
|
self['Erasure DataStorage 1'] = none2str(device.chid)
|
||||||
if isinstance(device, d.Mobile):
|
|
||||||
serial_number = none2str(device.imei)
|
serial_number = none2str(device.imei)
|
||||||
size = device.data_storage_size
|
size = device.data_storage_size
|
||||||
size = size * 1000 if size else 0
|
size = size * 1000 if size else 0
|
||||||
storage_size = none2str(size)
|
storage_size = none2str(size)
|
||||||
|
|
||||||
if isinstance(device, d.DataStorage):
|
|
||||||
serial_number = none2str(device.serial_number)
|
|
||||||
storage_size = none2str(device.size)
|
|
||||||
|
|
||||||
self['Erasure DataStorage 1 Serial Number'] = serial_number
|
self['Erasure DataStorage 1 Serial Number'] = serial_number
|
||||||
self['Erasure DataStorage 1 Size (MB)'] = storage_size
|
self['Erasure DataStorage 1 Size (MB)'] = storage_size
|
||||||
self['Erasure DataStorage 1 Software'] = erasure.document.software
|
|
||||||
self['Erasure DataStorage 1 Result'] = get_result(erasure)
|
self['Erasure DataStorage 1 Result'] = get_result(erasure)
|
||||||
self['Erasure DataStorage 1 Type'] = erasure.type
|
self['Erasure DataStorage 1 Type'] = erasure.type
|
||||||
|
self['Erasure DataStorage 1 Software'] = erasure.document.software
|
||||||
self['Erasure DataStorage 1 Date'] = format(erasure.document.date or '')
|
self['Erasure DataStorage 1 Date'] = format(erasure.document.date or '')
|
||||||
self['Erasure DataStorage 1 Certificate URL'] = (
|
self['Erasure DataStorage 1 Certificate URL'] = (
|
||||||
erasure.document.url and erasure.document.url.to_text() or ''
|
erasure.document.url and erasure.document.url.to_text() or ''
|
||||||
|
|
|
@ -43,3 +43,14 @@
|
||||||
.printLabelForm {
|
.printLabelForm {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
.bi-solar-panel {
|
||||||
|
background-image: url("/static/img/solar-panel.png");
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
line-height: 17px;
|
||||||
|
font-size: 15px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -79,6 +79,8 @@
|
||||||
{% if form.type.data == 'Keyboard' %} selected="selected"{% endif %}>Keyboard</option>
|
{% if form.type.data == 'Keyboard' %} selected="selected"{% endif %}>Keyboard</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Other Type of Device">
|
<optgroup label="Other Type of Device">
|
||||||
|
<option value="SolarPanel"
|
||||||
|
{% if form.type.data == 'SolarPanel' %} selected="selected"{% endif %}>Solar Panel</option>
|
||||||
<option value="Other"
|
<option value="Other"
|
||||||
{% if form.type.data == 'Other' %} selected="selected"{% endif %}>Other</option>
|
{% if form.type.data == 'Other' %} selected="selected"{% endif %}>Other</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
|
|
|
@ -72,6 +72,12 @@
|
||||||
<option value="Keyboard"
|
<option value="Keyboard"
|
||||||
{% if form.type.data == 'Keyboard' %} selected="selected"{% endif %}>Keyboard</option>
|
{% if form.type.data == 'Keyboard' %} selected="selected"{% endif %}>Keyboard</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
|
<optgroup label="Other Type of Device">
|
||||||
|
<option value="SolarPanel"
|
||||||
|
{% if form.type.data == 'SolarPanel' %} selected="selected"{% endif %}>Solar Panel</option>
|
||||||
|
<option value="Other"
|
||||||
|
{% if form.type.data == 'Other' %} selected="selected"{% endif %}>Other</option>
|
||||||
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
<small class="text-muted form-text">Type of devices</small>
|
<small class="text-muted form-text">Type of devices</small>
|
||||||
{% if form.type.errors %}
|
{% if form.type.errors %}
|
||||||
|
|
|
@ -125,4 +125,4 @@ def test_api_docs(client: Client):
|
||||||
'scheme': 'basic',
|
'scheme': 'basic',
|
||||||
'name': 'Authorization',
|
'name': 'Authorization',
|
||||||
}
|
}
|
||||||
assert len(docs['definitions']) == 135
|
assert len(docs['definitions']) == 136
|
||||||
|
|
Reference in New Issue