diff --git a/.github/workflows/selenium.yml b/.github/workflows/selenium.yml index fab0faab..1408a3d3 100644 --- a/.github/workflows/selenium.yml +++ b/.github/workflows/selenium.yml @@ -1,10 +1,8 @@ name: Selenium on: - push: - branches: [master, testing] pull_request: - branches: [master, testing] + types: [ready_for_review, review_requested] jobs: build: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 35bfc9bf..4d3d3d8d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,5 +19,13 @@ repos: hooks: - id: build-js name: build-js + # pre-commit pass as parameters files included on the commit + # so babel command should be wrapped to ignore these files on + # package.json script entry: npm run babel language: node + files: ^ereuse_devicehub/static/js/main_inventory.js + - repo: https://github.com/jazzband/pip-tools + rev: 6.8.0 + hooks: + - id: pip-compile diff --git a/CHANGELOG.md b/CHANGELOG.md index f96447f9..2d69d4a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,31 @@ ml). ## testing +## [2.4.2] - 2022-10-18 +- [added] #373 Enhancement - UX Lots. +- [added] #377 add prefix in lots in device list. +- [added] #378 add new button transfer. +- [added] #381 add servers erase and show storage disk in list of device. +- [added] #383 new setup page and add server_erase in placeholder. +- [added] #384 add redirect snapshot to twin public page. +- [changed] #371 changes phid. +- [changed] #372 remove logo. +- [changed] #374 changes links UI management and Data Storage Erasure. +- [changed] #375 changes columns in snapshot logs. +- [changed] #379 changes representation date times. +- [fixed] #380 fix layout print label. +- [fixed] #382 fix template device list. +- [fixed] #385 components in unbinding process. + +## [2.4.1] - 2022-10-05 +- [added] #365 Manage dependencies using pip-tools. +- [added] #368 add migrations of monitors and mobiles. +- [changed]] #371 changes about phid, incremental per user. +- [fixed] #364 bad redirect to all devices. +- [fixed] #367 column PHID Erasure host. +- [fixed] #369 bug in test data storage. +- [fixed] #370 print label in details of the label. + ## [2.4.0] - 2022-09-23 - [added] #312 Placeholder: new, edit, update. (manually and with excel). - [added] #316 Placeholder: binding/unbinding. (manually). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 142fd954..90d9b598 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,3 +30,29 @@ pre-commit install Do this: `device_detail.html` Don't do this: `DeviceDetail.html`, `Device-detail.html` + + +## Adding a new dependency to the project +This project tracks its packages using pip-tools, it could be installed by running: +``` +pip install pip-tools +``` + +Whenever you need to install a new package using pip install : +1. Put the package name into `requirements.in` instead. +``` +# requirements.in +... +new_package +``` + +2. Compile the requirements +``` +pip-compile requirements.in --output-file=requirements.txt + +``` + +3. Then install upgraded dependencies: +``` +pip install -U -r requirements.txt +``` diff --git a/ereuse_devicehub/__init__.py b/ereuse_devicehub/__init__.py index 3d67cd6b..60be088d 100644 --- a/ereuse_devicehub/__init__.py +++ b/ereuse_devicehub/__init__.py @@ -1 +1 @@ -__version__ = "2.4.0" +__version__ = "2.4.2" diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py index 1dc9cff2..69f0b4ba 100644 --- a/ereuse_devicehub/inventory/forms.py +++ b/ereuse_devicehub/inventory/forms.py @@ -86,12 +86,18 @@ DEVICES = { "Smartphone", "Cellphone", ], + "Drives & Storage": [ + "All DataStorage", + "HardDrives", + "SolidStageDrive", + ], } COMPUTERS = ['Desktop', 'Laptop', 'Server', 'Computer'] MONITORS = ["ComputerMonitor", "Monitor", "TelevisionSet", "Projector"] MOBILE = ["Mobile", "Tablet", "Smartphone", "Cellphone"] +STORAGE = ["HardDrive", "SolidStateDrive"] class AdvancedSearchForm(FlaskForm): @@ -175,9 +181,16 @@ class FilterForm(FlaskForm): elif "All Mobile" == self.device_type: filter_type = MOBILE + elif "All DataStorage" == self.device_type: + filter_type = STORAGE + if filter_type: self.devices = self.devices.filter(Device.type.in_(filter_type)) + # if self.device_type in STORAGE + ["All DataStorage"]: + # import pdb; pdb.set_trace() + # self.devices = self.devices.filter(Component.parent_id.is_(None)) + return self.devices.order_by(Device.updated.desc()) @@ -322,7 +335,7 @@ class NewDeviceForm(FlaskForm): default=1, ) id_device_supplier = StringField('Id Supplier', [validators.Optional()]) - phid = StringField('Placeholder Hardware identity (Phid)', [validators.Optional()]) + id_device_internal = StringField('Id Internal', [validators.Optional()]) pallet = StringField('Identity of pallet', [validators.Optional()]) components = TextAreaField('Components', [validators.Optional()]) info = TextAreaField('Info', [validators.Optional()]) @@ -382,7 +395,7 @@ class NewDeviceForm(FlaskForm): self.type.data = self._obj.type self.amount.render_kw = disabled self.id_device_supplier.data = self._obj.placeholder.id_device_supplier - self.phid.data = self._obj.placeholder.phid + self.id_device_internal.data = self._obj.placeholder.id_device_internal self.pallet.data = self._obj.placeholder.pallet self.info.data = self._obj.placeholder.info self.components.data = self._obj.placeholder.components @@ -411,7 +424,7 @@ class NewDeviceForm(FlaskForm): if self._obj.placeholder.is_abstract: self.type.render_kw = disabled self.amount.render_kw = disabled - self.id_device_supplier.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 @@ -476,28 +489,6 @@ class NewDeviceForm(FlaskForm): self.meid.errors = error is_valid = False - if self.phid.data and self.amount.data == 1 and not self._obj: - dev = Placeholder.query.filter( - Placeholder.phid == self.phid.data, Placeholder.owner == g.user - ).first() - if dev: - msg = "Error, exist one Placeholder device with this PHID" - self.phid.errors = [msg] - is_valid = False - - if ( - self.phid.data - and self._obj - and self.phid.data != self._obj.placeholder.phid - ): - dev = Placeholder.query.filter( - Placeholder.phid == self.phid.data, Device.owner == g.user - ).first() - if dev: - msg = "Error, exist one Placeholder device with this PHID" - self.phid.errors = [msg] - is_valid = False - if not is_valid: return False @@ -579,8 +570,8 @@ class NewDeviceForm(FlaskForm): def reset_ids(self): if self.amount.data > 1: - self.phid.data = None self.id_device_supplier.data = None + self.id_device_internal.data = None self.serial_number.data = None self.part_number.data = None self.sku.data = None @@ -590,8 +581,8 @@ class NewDeviceForm(FlaskForm): def get_placeholder(self): self.placeholder = Placeholder( **{ - 'phid': self.phid.data or None, 'id_device_supplier': self.id_device_supplier.data, + 'id_device_internal': self.id_device_internal.data, 'info': self.info.data, 'components': self.components.data, 'pallet': self.pallet.data, @@ -601,11 +592,13 @@ class NewDeviceForm(FlaskForm): return self.placeholder def edit_device(self): - self._obj.placeholder.phid = self.phid.data or self._obj.placeholder.phid if not self._obj.placeholder.is_abstract: self._obj.placeholder.id_device_supplier = ( self.id_device_supplier.data or None ) + self._obj.placeholder.id_device_internal = ( + self.id_device_internal.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 @@ -1279,6 +1272,12 @@ class TradeDocumentForm(FlaskForm): class TransferForm(FlaskForm): + lot_name = StringField( + 'Lot Name', + [validators.DataRequired()], + render_kw={'class': "form-control"}, + description="You need put a lot name", + ) code = StringField( 'Code', [validators.DataRequired()], @@ -1295,14 +1294,14 @@ class TransferForm(FlaskForm): def __init__(self, *args, **kwargs): self._type = kwargs.get('type') lot_id = kwargs.pop('lot_id', None) - self._tmp_lot = Lot.query.filter(Lot.id == lot_id).one() + self._tmp_lot = None + if lot_id: + self._tmp_lot = Lot.query.filter(Lot.id == lot_id).one() super().__init__(*args, **kwargs) self._obj = None def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) - if not self._tmp_lot: - return False if self._type and self.type.data not in ['incoming', 'outgoing']: return False @@ -1323,8 +1322,10 @@ class TransferForm(FlaskForm): return self._obj def set_obj(self): - self.newlot = Lot(name=self._tmp_lot.name) - self.newlot.devices = self._tmp_lot.devices + name = self.lot_name.data + self.newlot = Lot(name=name) + if self._tmp_lot: + self.newlot.devices = self._tmp_lot.devices db.session.add(self.newlot) self._obj = Transfer(lot=self.newlot) @@ -1355,6 +1356,7 @@ class EditTransferForm(TransferForm): self.code.data = self._obj.code self.description.data = self._obj.description self.date.data = self._obj.date + self.lot_name.data = self._obj.lot.name def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) @@ -1366,6 +1368,7 @@ class EditTransferForm(TransferForm): def set_obj(self, commit=True): self.populate_obj(self._obj) + self._obj.lot.name = self.lot_name.data class NotesForm(FlaskForm): @@ -1514,9 +1517,7 @@ class UploadPlaceholderForm(FlaskForm): else: self.source = "Excel File: {}".format(_file.filename) try: - data = ( - pd.read_excel(_file, converters={'Phid': str}).fillna('').to_dict() - ) + data = pd.read_excel(_file).fillna('').to_dict() except ValueError: txt = ["File don't have a correct format"] self.placeholder_file.errors = txt @@ -1538,12 +1539,12 @@ class UploadPlaceholderForm(FlaskForm): return False header = [ - 'Phid', 'Model', 'Manufacturer', 'Serial Number', 'Part Number', 'Id device Supplier', + 'Id device Internal', 'Pallet', 'Info', ] @@ -1557,32 +1558,7 @@ class UploadPlaceholderForm(FlaskForm): self.placeholders = [] schema = SnapshotSchema() 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() - - # update one - if placeholder: - self.dev_update += 1 - device = placeholder.device - device.model = "{}".format(data['Model'][i]).lower() - device.manufacturer = "{}".format(data['Manufacturer'][i]).lower() - device.serial_number = "{}".format(data['Serial Number'][i]).lower() - device.part_number = "{}".format(data['Part Number'][i]).lower() - placeholder.id_device_supplier = "{}".format( - data['Id device Supplier'][i] - ) - placeholder.pallet = "{}".format(data['Pallet'][i]) - placeholder.info = "{}".format(data['Info'][i]) - - placeholder_log = PlaceholdersLog( - type="Update", source=self.source, placeholder=device.placeholder - ) - self.placeholders.append((device, placeholder_log)) - continue - + for i in data['Model'].keys(): # create a new one json_snapshot = { 'type': 'Snapshot', @@ -1597,8 +1573,8 @@ class UploadPlaceholderForm(FlaskForm): }, } json_placeholder = { - 'phid': data['Phid'][i] or None, 'id_device_supplier': data['Id device Supplier'][i], + 'id_device_internal': data['Id device Internal'][i], 'pallet': data['Pallet'][i], 'info': data['Info'][i], 'is_abstract': False, @@ -1635,7 +1611,6 @@ class EditPlaceholderForm(FlaskForm): serial_number = StringField('Serial Number', [validators.Optional()]) part_number = StringField('Part Number', [validators.Optional()]) id_device_supplier = StringField('Id Supplier', [validators.Optional()]) - phid = StringField('Phid', [validators.DataRequired()]) pallet = StringField('Pallet', [validators.Optional()]) info = StringField('Info', [validators.Optional()]) diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py index 684be46f..9682e0c1 100644 --- a/ereuse_devicehub/inventory/views.py +++ b/ereuse_devicehub/inventory/views.py @@ -296,6 +296,8 @@ class BindingView(GenericMixin): self.real_phid = self.new_placeholder.phid self.abstract_dhid = self.old_device.devicehub_id self.abstract_phid = self.old_placeholder.phid + if self.old_placeholder.kangaroo: + self.new_placeholder.kangaroo = True # to do a backup of abstract_dhid and abstract_phid in # workbench device @@ -380,9 +382,14 @@ class UnBindingView(GenericMixin): return flask.render_template(self.template_name, **self.context) def clone_device(self, device): - if device.binding.is_abstract: + if device.binding and device.binding.is_abstract: return + kangaroo = False + if device.binding: + kangaroo = device.binding.kangaroo + device.binding.kangaroo = False + dict_device = copy.copy(device.__dict__) dict_device.pop('_sa_instance_state') dict_device.pop('id', None) @@ -401,8 +408,14 @@ class UnBindingView(GenericMixin): for c in device.components: if c.binding: c.binding.device.parent = new_device + else: + new_c = self.clone_device(c) + new_c.parent = new_device + + placeholder = Placeholder( + device=new_device, binding=device, is_abstract=True, kangaroo=kangaroo + ) - placeholder = Placeholder(device=new_device, binding=device, is_abstract=True) if ( device.dhid_bk and not Device.query.filter_by(devicehub_id=device.dhid_bk).first() @@ -545,7 +558,7 @@ class DeviceCreateView(GenericMixin): tpy = form.type.data txt = f'{amount} placeholders Device "{tpy}" created successfully.' placeholder = ( - Placeholder.query.filter_by(owner=g.user) + Placeholder.query.filter(Placeholder.owner == g.user) .order_by(Placeholder.id.desc()) .first() ) @@ -753,9 +766,11 @@ class NewTransferView(GenericMixin): form_class = TransferForm title = "Add new transfer" - def dispatch_request(self, lot_id, type_id): + def dispatch_request(self, type_id, lot_id=None): self.form = self.form_class(lot_id=lot_id, type=type_id) self.get_context() + referrer = request.referrer or url_for('inventory.devicelist') + self.context.update({'referrer': referrer}) if self.form.validate_on_submit(): self.form.save() @@ -767,7 +782,12 @@ class NewTransferView(GenericMixin): next_url = url_for('inventory.lotdevicelist', lot_id=str(new_lot_id)) return flask.redirect(next_url) - self.context.update({'form': self.form, 'title': self.title}) + self.context.update( + { + 'form': self.form, + 'title': self.title, + } + ) return flask.render_template(self.template_name, **self.context) @@ -1355,6 +1375,10 @@ devices.add_url_rule( ) devices.add_url_rule( '/lot//transfer//', + view_func=NewTransferView.as_view('lot_new_transfer'), +) +devices.add_url_rule( + '/lot/transfer//', view_func=NewTransferView.as_view('new_transfer'), ) devices.add_url_rule( diff --git a/ereuse_devicehub/labels/views.py b/ereuse_devicehub/labels/views.py index 421effcb..13766bfe 100644 --- a/ereuse_devicehub/labels/views.py +++ b/ereuse_devicehub/labels/views.py @@ -114,21 +114,35 @@ class PrintLabelsView(View): class LabelDetailView(View): + """This View is used to print labels from multiple devices""" + + methods = ['POST', 'GET'] decorators = [login_required] - template_name = 'labels/label_detail.html' + template_name = 'labels/print_labels.html' + title = 'Design and implementation of labels' def dispatch_request(self, id): lots = Lot.query.filter(Lot.owner_id == current_user.id) tag = ( Tag.query.filter(Tag.owner_id == current_user.id).filter(Tag.id == id).one() ) - context = { 'lots': lots, - 'tag': tag, - 'page_title': '{} Tag'.format(tag.code), + 'page_title': self.title, 'version': __version__, + 'referrer': request.referrer, } + + devices = [] + if tag.device: + form = PrintLabelsForm(devices=str(tag.device.id)) + devices = [tag.device] + else: + form = PrintLabelsForm() + + form._devices = devices + context['form'] = form + context['devices'] = devices return flask.render_template(self.template_name, **context) diff --git a/ereuse_devicehub/migrations/versions/626c17026ca7_id_internal_in_placeholder.py b/ereuse_devicehub/migrations/versions/626c17026ca7_id_internal_in_placeholder.py new file mode 100644 index 00000000..8c5f28db --- /dev/null +++ b/ereuse_devicehub/migrations/versions/626c17026ca7_id_internal_in_placeholder.py @@ -0,0 +1,59 @@ +"""id internal in placeholder + +Revision ID: 626c17026ca7 +Revises: e919fe0611ff +Create Date: 2022-10-03 19:25:00.581699 + +""" +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = '626c17026ca7' +down_revision = 'e919fe0611ff' +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_datas(): + con = op.get_bind() + sql = 'select id from common.user where phantom=false and active=true' + users = con.execute(sql) + for user in users: + phid = 1 + user_id = user.id + sql = f""" + select id from {get_inv()}.placeholder where owner_id='{user_id}' + order by id + """ + placeholders = con.execute(sql) + + for p in placeholders: + p_id = p.id + sql = f""" + update {get_inv()}.placeholder set phid='{phid}' + where id='{p_id}' + """ + con.execute(sql) + phid += 1 + + +def upgrade(): + op.add_column( + 'placeholder', + sa.Column('id_device_internal', sa.Unicode(), nullable=True), + schema=f'{get_inv()}', + ) + + upgrade_datas() + + +def downgrade(): + op.drop_column('placeholder', 'id_device_internal', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/migrations/versions/a13ed6ad0e3e_add_kangaroo_in_placeholder.py b/ereuse_devicehub/migrations/versions/a13ed6ad0e3e_add_kangaroo_in_placeholder.py new file mode 100644 index 00000000..bc3b6790 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/a13ed6ad0e3e_add_kangaroo_in_placeholder.py @@ -0,0 +1,34 @@ +"""add kangaroo in placeholder + +Revision ID: a13ed6ad0e3e +Revises: 626c17026ca7 +Create Date: 2022-10-13 11:56:15.303218 + +""" +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = 'a13ed6ad0e3e' +down_revision = '626c17026ca7' +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(): + op.add_column( + 'placeholder', + sa.Column('kangaroo', sa.Boolean(), nullable=True), + schema=f'{get_inv()}', + ) + + +def downgrade(): + op.drop_column('placeholder', 'kangaroo', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/migrations/versions/d65745749e34_add_is_server_erase.py b/ereuse_devicehub/migrations/versions/d65745749e34_add_is_server_erase.py new file mode 100644 index 00000000..20d001db --- /dev/null +++ b/ereuse_devicehub/migrations/versions/d65745749e34_add_is_server_erase.py @@ -0,0 +1,34 @@ +"""add is_server_erase + +Revision ID: d65745749e34 +Revises: a13ed6ad0e3e +Create Date: 2022-10-17 13:20:29.875274 + +""" +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = 'd65745749e34' +down_revision = 'a13ed6ad0e3e' +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(): + op.add_column( + 'snapshot', + sa.Column('is_server_erase', sa.Boolean(), nullable=True), + schema=f'{get_inv()}', + ) + + +def downgrade(): + op.drop_column('snapshot', 'is_server_erase', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 496eed34..87a9d392 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -676,6 +676,7 @@ class Snapshot(JoinedWithOneDeviceMixin, ActionWithOneDevice): of time it took to complete. """ sid = Column(CIText(), nullable=True) + is_server_erase = Column(Boolean(), nullable=True) def get_last_lifetimes(self): """We get the lifetime and serial_number of the first disk""" diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 56165555..f24e2c83 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -296,6 +296,14 @@ class TestDataStorage(Test): offline_uncorrectable = Integer(data_key='offlineUncorrectable') remaining_lifetime_percentage = Integer(data_key='remainingLifetimePercentage') + @post_load + def default_remaining_lifetime_percentage(self, data): + if not data.get('remaining_lifetime_percentage'): + return + + if data.get('remaining_lifetime_percentage') > 100: + data['remaining_lifetime_percentage'] = None + class StressTest(Test): __doc__ = m.StressTest.__doc__ diff --git a/ereuse_devicehub/resources/action/views/snapshot.py b/ereuse_devicehub/resources/action/views/snapshot.py index bca48f84..dd967fee 100644 --- a/ereuse_devicehub/resources/action/views/snapshot.py +++ b/ereuse_devicehub/resources/action/views/snapshot.py @@ -115,8 +115,15 @@ class SnapshotMixin: if snapshot.device.hid is None: snapshot.severity = Severity.Warning + self.is_server_erase(snapshot) + return snapshot + def is_server_erase(self, snapshot): + if snapshot.device.binding: + if snapshot.device.binding.kangaroo: + snapshot.is_server_erase = True + def get_old_smbios_version(self, debug): capabilities = debug.get('lshw', {}).get('capabilities', {}) for x in capabilities.values(): diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 5a40cfc6..86d8c834 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -10,7 +10,6 @@ from boltons import urlutils from citext import CIText from ereuse_utils.naming import HID_CONVERSION_DOC, Naming from flask import g, request -from flask_sqlalchemy import event from more_itertools import unique_everseen from sqlalchemy import BigInteger, Boolean, Column from sqlalchemy import Enum as DBEnum @@ -75,11 +74,15 @@ def create_code(context): return hashcode.encode(_id) -def create_phid(context): - _hid = Placeholder.query.order_by(Placeholder.id.desc()).first() - if _hid: - return str(_hid.id + 1) - return '1' +def create_phid(context, count=1): + phid = str(Placeholder.query.filter(Placeholder.owner == g.user).count() + count) + if ( + Placeholder.query.filter(Placeholder.owner == g.user) + .filter(Placeholder.phid == phid) + .count() + ): + return create_phid(context, count=count + 1) + return phid class Device(Thing): @@ -650,6 +653,21 @@ class Device(Thing): args[POLYMORPHIC_ON] = cls.type return args + def get_lots_for_template(self): + lots = [] + for lot in self.lots: + if lot.is_incoming: + name = "IN - " + lot.name + lots.append(name) + if lot.is_outgoing: + name = "OUT - " + lot.name + lots.append(name) + if lot.is_temporary: + name = "TEMP - " + lot.name + lots.append(name) + lots.sort() + return lots + def phid(self): if self.placeholder: return self.placeholder.phid @@ -901,8 +919,8 @@ class DisplayMixin: class Placeholder(Thing): id = Column(BigInteger, Sequence('placeholder_seq'), primary_key=True) - pallet = Column(Unicode(), nullable=True) phid = Column(Unicode(), nullable=False, default=create_phid) + pallet = Column(Unicode(), nullable=True) pallet.comment = "used for identification where from where is this placeholders" info = db.Column(CIText()) components = Column(CIText()) @@ -912,6 +930,9 @@ class Placeholder(Thing): id_device_supplier.comment = ( "Identification used for one supplier of one placeholders" ) + id_device_internal = db.Column(CIText()) + id_device_internal.comment = "Identification used internaly for the user" + kangaroo = db.Column(Boolean, default=False, nullable=True) device_id = db.Column( BigInteger, @@ -1593,4 +1614,5 @@ def create_code_tag(mapper, connection, device): db.session.add(tag) +# from flask_sqlalchemy import event # event.listen(Device, 'after_insert', create_code_tag, propagate=True) diff --git a/ereuse_devicehub/resources/device/views.py b/ereuse_devicehub/resources/device/views.py index e6e158a4..6896089c 100644 --- a/ereuse_devicehub/resources/device/views.py +++ b/ereuse_devicehub/resources/device/views.py @@ -137,7 +137,10 @@ class DeviceView(View): return self.one_private(id) def one_public(self, id: int): - device = Device.query.filter_by(devicehub_id=id, active=True).one() + devices = Device.query.filter_by(devicehub_id=id, active=True).all() + if not devices: + devices = [Device.query.filter_by(dhid_bk=id, active=True).one()] + device = devices[0] abstract = None if device.binding: return flask.redirect(device.public_link) diff --git a/ereuse_devicehub/static/css/devicehub.css b/ereuse_devicehub/static/css/devicehub.css index 169d7fd2..46fae783 100644 --- a/ereuse_devicehub/static/css/devicehub.css +++ b/ereuse_devicehub/static/css/devicehub.css @@ -26,3 +26,10 @@ .help { color: #993365; } +.doTransfer { + margin-top: -8px; + margin-right: 15px;" +} +.printLabelForm { + margin-left: 10px; +} \ No newline at end of file diff --git a/ereuse_devicehub/static/js/create_device.js b/ereuse_devicehub/static/js/create_device.js index 04533411..4acece0f 100644 --- a/ereuse_devicehub/static/js/create_device.js +++ b/ereuse_devicehub/static/js/create_device.js @@ -29,14 +29,18 @@ function amountInputs() { if ($("#amount").val() > 1) { $("#Phid").hide(); $("#Id_device_supplier").hide(); + $("#Id_device_internal").hide(); $("#Serial_number").hide(); + $("#Part_number").hide(); $("#Sku").hide(); $("#imei").hide(); $("#meid").hide(); } else { $("#Phid").show(); $("#Id_device_supplier").show(); + $("#Id_device_internal").show(); $("#Serial_number").show(); + $("#Part_number").show(); $("#Sku").show(); deviceInputs(); }; diff --git a/ereuse_devicehub/templates/ereuse_devicehub/base_site.html b/ereuse_devicehub/templates/ereuse_devicehub/base_site.html index 6fdf1129..a4deb465 100644 --- a/ereuse_devicehub/templates/ereuse_devicehub/base_site.html +++ b/ereuse_devicehub/templates/ereuse_devicehub/base_site.html @@ -3,11 +3,7 @@ {% block body %}