diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py
index 969df88c..b1fdb645 100644
--- a/ereuse_devicehub/inventory/forms.py
+++ b/ereuse_devicehub/inventory/forms.py
@@ -317,6 +317,7 @@ class NewDeviceForm(FlaskForm):
id_device_supplier = StringField('Id Supplier', [validators.Optional()])
phid = StringField('Placeholder Hardware identity (Phid)', [validators.Optional()])
pallet = StringField('Identity of pallet', [validators.Optional()])
+ components = TextAreaField('Components', [validators.Optional()])
info = TextAreaField('Info', [validators.Optional()])
serial_number = StringField('Seria Number', [validators.Optional()])
model = StringField('Model', [validators.Optional()])
@@ -392,6 +393,7 @@ class NewDeviceForm(FlaskForm):
self.phid.data = self._obj.placeholder.phid
self.pallet.data = self._obj.placeholder.pallet
self.info.data = self._obj.placeholder.info
+ self.components.data = self._obj.placeholder.components
self.serial_number.data = self._obj.serial_number
self.model.data = self._obj.model
self.manufacturer.data = self._obj.manufacturer
@@ -414,6 +416,35 @@ class NewDeviceForm(FlaskForm):
self.resolution.data = self._obj.resolution_width
self.screen.data = self._obj.size
+ if self._obj.placeholder.is_abstract:
+ self.type.render_kw = disabled
+ self.amount.render_kw = disabled
+ self.id_device_supplier.render_kw = disabled
+ self.pallet.render_kw = disabled
+ self.info.render_kw = disabled
+ self.components.render_kw = disabled
+ self.serial_number.render_kw = disabled
+ self.model.render_kw = disabled
+ self.manufacturer.render_kw = disabled
+ self.appearance.render_kw = disabled
+ self.functionality.render_kw = disabled
+ self.brand.render_kw = disabled
+ self.generation.render_kw = disabled
+ self.version.render_kw = disabled
+ self.weight.render_kw = disabled
+ self.width.render_kw = disabled
+ self.height.render_kw = disabled
+ self.depth.render_kw = disabled
+ self.variant.render_kw = disabled
+ self.sku.render_kw = disabled
+ self.image.render_kw = disabled
+ if self._obj.type in ['Smartphone', 'Tablet', 'Cellphone']:
+ self.imei.render_kw = disabled
+ self.meid.render_kw = disabled
+ if self._obj.type == 'ComputerMonitor':
+ self.resolution.render_kw = disabled
+ self.screen.render_kw = disabled
+
def validate(self, extra_validators=None): # noqa: C901
error = ["Not a correct value"]
is_valid = super().validate(extra_validators)
@@ -567,6 +598,7 @@ class NewDeviceForm(FlaskForm):
'phid': self.phid.data or None,
'id_device_supplier': self.id_device_supplier.data,
'info': self.info.data,
+ 'components': self.components.data,
'pallet': self.pallet.data,
'is_abstract': False,
}
@@ -575,40 +607,47 @@ class NewDeviceForm(FlaskForm):
def edit_device(self):
self._obj.placeholder.phid = self.phid.data or self._obj.placeholder.phid
- self._obj.placeholder.id_device_supplier = self.id_device_supplier.data or None
- self._obj.placeholder.info = self.info.data or None
- self._obj.placeholder.pallet = self.pallet.data or None
- self._obj.placeholder.is_abstract = False
- self._obj.model = self.model.data
- self._obj.manufacturer = self.manufacturer.data
- self._obj.serial_number = self.serial_number.data
- self._obj.brand = self.brand.data
- self._obj.version = self.version.data
- self._obj.generation = self.generation.data
- self._obj.sku = self.sku.data
- self._obj.weight = self.weight.data
- self._obj.width = self.width.data
- self._obj.height = self.height.data
- self._obj.depth = self.depth.data
- self._obj.variant = self.variant.data
- self._obj.image = self.image.data
+ if not self._obj.placeholder.is_abstract:
+ self._obj.placeholder.id_device_supplier = (
+ self.id_device_supplier.data or None
+ )
+ self._obj.placeholder.info = self.info.data or None
+ self._obj.placeholder.components = self.components.data or None
+ self._obj.placeholder.pallet = self.pallet.data or None
+ self._obj.model = self.model.data
+ self._obj.manufacturer = self.manufacturer.data
+ self._obj.serial_number = self.serial_number.data
+ self._obj.brand = self.brand.data
+ self._obj.version = self.version.data
+ self._obj.generation = self.generation.data
+ self._obj.sku = self.sku.data
+ self._obj.weight = self.weight.data
+ self._obj.width = self.width.data
+ self._obj.height = self.height.data
+ self._obj.depth = self.depth.data
+ self._obj.variant = self.variant.data
+ self._obj.image = self.image.data
- if self._obj.type == 'ComputerMonitor':
- self._obj.resolution_width = self.resolution.data
- self._obj.size = self.screen.data
+ if self._obj.type == 'ComputerMonitor':
+ self._obj.resolution_width = self.resolution.data
+ self._obj.size = self.screen.data
- if self._obj.type in ['Smartphone', 'Tablet', 'Cellphone']:
- self._obj.imei = self.imei.data
- self._obj.meid = self.meid.data
+ if self._obj.type in ['Smartphone', 'Tablet', 'Cellphone']:
+ self._obj.imei = self.imei.data
+ self._obj.meid = self.meid.data
- if self.appearance.data and self.appearance.data != self._obj.appearance().name:
- self._obj.set_appearance(self.appearance.data)
+ if (
+ 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)
- if (
- self.functionality.data
- and self.functionality.data != self._obj.functionality().name
- ):
- self._obj.set_functionality(self.functionality.data)
placeholder_log = PlaceholdersLog(
type="Update", source='Web form', placeholder=self._obj.placeholder
)
@@ -1519,6 +1558,7 @@ class UploadPlaceholderForm(FlaskForm):
self.path_snapshots = {}
for i in data['Phid'].keys():
placeholder = None
+ data['Phid'][i] = str(data['Phid'][i])
if data['Phid'][i]:
placeholder = Placeholder.query.filter_by(phid=data['Phid'][i]).first()
@@ -1627,14 +1667,14 @@ class BindingForm(FlaskForm):
self.phid.errors = [txt]
return False
- if self.device.placeholder:
- txt = "This is not a device Workbench."
+ if self.device.is_abstract() != 'Abstract':
+ txt = "This is not a abstract device."
self.phid.errors = [txt]
return False
if not self.placeholder:
self.placeholder = Placeholder.query.filter(
- Placeholder.phid == self.phid.data, Placeholder.owner == g.user
+ Placeholder.phid == self.phid.data.strip(), Placeholder.owner == g.user
).first()
if not self.placeholder:
diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py
index b286bf0f..6239d98c 100644
--- a/ereuse_devicehub/inventory/views.py
+++ b/ereuse_devicehub/inventory/views.py
@@ -37,7 +37,7 @@ from ereuse_devicehub.inventory.forms import (
)
from ereuse_devicehub.labels.forms import PrintLabelsForm
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
-from ereuse_devicehub.resources.action.models import Trade
+from ereuse_devicehub.resources.action.models import ActionDevice, Trade
from ereuse_devicehub.resources.device.models import (
Computer,
DataStorage,
@@ -191,15 +191,34 @@ class BindingView(GenericMixin):
.one()
)
+ if device.is_abstract() != 'Abstract':
+ next_url = url_for('inventory.device_details', id=dhid)
+ messages.error('Device "{}" not is a Abstract device!'.format(dhid))
+ return flask.redirect(next_url)
+
+ if device.placeholder:
+ device = device.placeholder.binding
+
if request.method == 'POST':
old_placeholder = device.binding
old_device_placeholder = old_placeholder.device
+
if old_placeholder.is_abstract:
for plog in PlaceholdersLog.query.filter_by(
placeholder_id=old_placeholder.id
):
db.session.delete(plog)
+
+ for ac in old_device_placeholder.actions:
+ ac.devices.add(placeholder.device)
+ ac.devices.remove(old_device_placeholder)
+ for act in ac.actions_device:
+ if act.device == old_device_placeholder:
+ db.session.delete(act)
+
db.session.delete(old_device_placeholder)
+ for tag in list(old_device_placeholder.tags):
+ tag.device = placeholder.device
device.binding = placeholder
db.session.commit()
@@ -209,11 +228,16 @@ class BindingView(GenericMixin):
)
return flask.redirect(next_url)
+ # import pdb; pdb.set_trace()
self.context.update(
{
'device': device.binding.device,
'placeholder': placeholder,
'page_title': 'Binding confirm',
+ 'actions': list(device.binding.device.actions)
+ + list(placeholder.device.actions),
+ 'tags': list(device.binding.device.tags)
+ + list(placeholder.device.tags),
}
)
@@ -242,10 +266,8 @@ class UnBindingView(GenericMixin):
self.get_context()
if request.method == 'POST':
- self.clone_device(device)
- next_url = url_for(
- 'inventory.device_details', id=placeholder.device.devicehub_id
- )
+ new_device = self.clone_device(device)
+ next_url = url_for('inventory.device_details', id=new_device.devicehub_id)
messages.success('Device "{}" unbind successfully!'.format(phid))
return flask.redirect(next_url)
@@ -678,7 +700,13 @@ class ExportsView(View):
def devices_list(self):
"""Get device query and put information in csv format."""
data = StringIO()
- cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"', quoting=csv.QUOTE_ALL)
+ cw = csv.writer(
+ data,
+ delimiter=';',
+ lineterminator="\n",
+ quotechar='"',
+ quoting=csv.QUOTE_ALL,
+ )
first = True
for device in self.find_devices():
@@ -693,7 +721,13 @@ class ExportsView(View):
def metrics(self):
"""Get device query and put information in csv format."""
data = StringIO()
- cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"', quoting=csv.QUOTE_ALL)
+ cw = csv.writer(
+ data,
+ delimiter=';',
+ lineterminator="\n",
+ quotechar='"',
+ quoting=csv.QUOTE_ALL,
+ )
first = True
devs_id = []
# Get the allocate info
@@ -757,7 +791,13 @@ class ExportsView(View):
def lots_export(self):
data = StringIO()
- cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"', quoting=csv.QUOTE_ALL)
+ cw = csv.writer(
+ data,
+ delimiter=';',
+ lineterminator="\n",
+ quotechar='"',
+ quoting=csv.QUOTE_ALL,
+ )
cw.writerow(
[
@@ -827,7 +867,13 @@ class ExportsView(View):
def devices_lots_export(self):
data = StringIO()
- cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"', quoting=csv.QUOTE_ALL)
+ cw = csv.writer(
+ data,
+ delimiter=';',
+ lineterminator="\n",
+ quotechar='"',
+ quoting=csv.QUOTE_ALL,
+ )
head = [
'DHID',
'Lot Id',
diff --git a/ereuse_devicehub/migrations/versions/2b90b41a556a_add_owner_to_placeholder.py b/ereuse_devicehub/migrations/versions/2b90b41a556a_add_owner_to_placeholder.py
index c8a80e5a..20ef7319 100644
--- a/ereuse_devicehub/migrations/versions/2b90b41a556a_add_owner_to_placeholder.py
+++ b/ereuse_devicehub/migrations/versions/2b90b41a556a_add_owner_to_placeholder.py
@@ -5,6 +5,7 @@ Revises: 2b90b41a556a
Create Date: 2022-07-27 14:40:15.513820
"""
+import citext
import sqlalchemy as sa
from alembic import context, op
from sqlalchemy.dialects import postgresql
@@ -41,6 +42,11 @@ def upgrade():
sa.Column('is_abstract', sa.Boolean(), nullable=True),
schema=f'{get_inv()}',
)
+ op.add_column(
+ 'placeholder',
+ sa.Column('components', citext.CIText(), nullable=True),
+ schema=f'{get_inv()}',
+ )
op.add_column(
'placeholder',
sa.Column('owner_id', postgresql.UUID(), nullable=True),
@@ -69,3 +75,4 @@ def downgrade():
)
op.drop_column('placeholder', 'owner_id', schema=f'{get_inv()}')
op.drop_column('placeholder', 'is_abstract', schema=f'{get_inv()}')
+ op.drop_column('placeholder', 'components', schema=f'{get_inv()}')
diff --git a/ereuse_devicehub/parser/models.py b/ereuse_devicehub/parser/models.py
index 69cd574c..769e43a1 100644
--- a/ereuse_devicehub/parser/models.py
+++ b/ereuse_devicehub/parser/models.py
@@ -2,6 +2,7 @@ from citext import CIText
from flask import g
from sqlalchemy import BigInteger, Column, Sequence, SmallInteger
from sqlalchemy.dialects.postgresql import UUID
+from sqlalchemy.orm import backref
from ereuse_devicehub.db import db
from ereuse_devicehub.resources.action.models import Snapshot
@@ -41,6 +42,8 @@ class SnapshotsLog(Thing):
def get_device(self):
if self.snapshot:
+ if self.snapshot.device.binding:
+ return self.snapshot.device.binding.device.devicehub_id
return self.snapshot.device.devicehub_id
return ''
@@ -56,7 +59,11 @@ class PlaceholdersLog(Thing):
placeholder_id = Column(BigInteger, db.ForeignKey(Placeholder.id), nullable=True)
placeholder = db.relationship(
- Placeholder, primaryjoin=placeholder_id == Placeholder.id
+ Placeholder,
+ backref=backref(
+ 'placeholder_logs', lazy=True, cascade="all, delete-orphan", uselist=True
+ ),
+ primaryjoin=placeholder_id == Placeholder.id,
)
owner_id = db.Column(
UUID(as_uuid=True),
diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py
index 3b27b327..a50d1593 100644
--- a/ereuse_devicehub/resources/device/models.py
+++ b/ereuse_devicehub/resources/device/models.py
@@ -666,6 +666,20 @@ class Device(Thing):
action = next(e for e in reversed(actions) if e.type == 'VisualTest')
action.functionality_range = value
+ def is_abstract(self):
+ if self.placeholder:
+ if self.placeholder.is_abstract:
+ return 'Abstract'
+ if self.placeholder.binding:
+ return 'Twin'
+ return 'Real'
+ if self.binding:
+ if self.binding.is_abstract:
+ return 'Abstract'
+ return 'Twin'
+
+ return ''
+
def is_status(self, action):
from ereuse_devicehub.resources.device import states
@@ -869,6 +883,7 @@ class Placeholder(Thing):
phid = Column(Unicode(), nullable=False, default=create_phid)
pallet.comment = "used for identification where from where is this placeholders"
info = db.Column(CIText())
+ components = Column(CIText())
info.comment = "more info of placeholders"
is_abstract = db.Column(Boolean, default=False)
id_device_supplier = db.Column(CIText())
@@ -883,7 +898,9 @@ class Placeholder(Thing):
)
device = db.relationship(
Device,
- backref=backref('placeholder', lazy=True, cascade="all, delete-orphan", uselist=False),
+ backref=backref(
+ 'placeholder', lazy=True, cascade="all, delete-orphan", uselist=False
+ ),
primaryjoin=device_id == Device.id,
)
device_id.comment = "datas of the placeholder"
diff --git a/ereuse_devicehub/templates/inventory/binding.html b/ereuse_devicehub/templates/inventory/binding.html
index e26fb1bb..087b4e85 100644
--- a/ereuse_devicehub/templates/inventory/binding.html
+++ b/ereuse_devicehub/templates/inventory/binding.html
@@ -139,7 +139,7 @@
- {% if placeholder.device.actions or device.actions %}
+ {% if actions %}
- {% for a in placeholder.device.actions %}
+ {% for a in actions %}
* {{ a.t }} {% endfor %} |
- {% for a in device.actions %}
- * {{ a.t }} + |
+
Info to be Entered | +Info to be Decoupled | +
---|---|
+ {% for tag in tags %}
+ * {{ tag.id }} {% endfor %} |
+ + |
+ {% for error in form.components.errors %}
+ {{ error }}
+ {% endfor %}
+