diff --git a/app/helpers.py b/app/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..cd8bcce47bda82f8a7df9375f8238df9f6248825 --- /dev/null +++ b/app/helpers.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +app.helpers +~~~~~~~~~~~ + +This module implements helpers functions for the models. + +:copyright: (c) 2017 European Spallation Source ERIC +:license: BSD 2-Clause, see LICENSE for more details. + +""" +import string +from flask import current_app +from . import models + + +def temporary_ics_ids(): + """Generator that returns the full list of temporary ICS ids""" + return (f'{current_app.config["TEMPORARY_ICS_ID"]}{letter}{number:0=3d}' + for letter in string.ascii_uppercase + for number in range(0, 1000)) + + +def used_temporary_ics_ids(): + """Generator that returns the list of temporary ICS ids used""" + temporary_items = models.Item.query.filter( + models.Item.ics_id.startswith( + current_app.config['TEMPORARY_ICS_ID'])).all() + return (item.ics_id for item in temporary_items) + + +def get_temporary_ics_id(): + """Return a temporary ICS id that is available""" + for ics_id in temporary_ics_ids(): + if ics_id not in used_temporary_ics_ids(): + return ics_id + else: + raise ValueError('No temporary ICS id available') diff --git a/app/inventory/views.py b/app/inventory/views.py index 24d527b6330f2c33b69310d32ab9e5defd704860..8f90f6305f5f75aa139fe6a852fc8345795a77b3 100644 --- a/app/inventory/views.py +++ b/app/inventory/views.py @@ -107,6 +107,9 @@ def edit_item(ics_id): mac_addresses = ' '.join([str(mac) for mac in item.macs]) form = ItemForm(request.form, obj=item, mac_addresses=mac_addresses) if form.validate_on_submit(): + # Only allow to update temporary ics_id + if item.ics_id.startswith(current_app.config['TEMPORARY_ICS_ID']): + item.ics_id = form.ics_id.data item.serial_number = form.serial_number.data for key in ('manufacturer_id', 'model_id', 'location_id', 'status_id', 'parent_id'): setattr(item, key, getattr(form, key).data) @@ -130,7 +133,7 @@ def edit_item(ics_id): flash(f'{e}', 'error') else: flash(f'Item {item} updated!', 'success') - return redirect(url_for('inventory.view_item', ics_id=ics_id)) + return redirect(url_for('inventory.view_item', ics_id=item.ics_id)) return render_template('inventory/edit_item.html', form=form) diff --git a/app/models.py b/app/models.py index 26be8dbff4e7cf5ea6c980763898bec557b8c425..e42df9f30c73828f3dac8a24c870c5add9bc2f26 100644 --- a/app/models.py +++ b/app/models.py @@ -233,7 +233,7 @@ class Item(db.Model): id = db.Column(db.Integer, primary_key=True) _created = db.Column(db.DateTime, default=utcnow()) _updated = db.Column(db.DateTime, default=utcnow(), onupdate=utcnow()) - ics_id = db.Column(db.Text, unique=True, index=True) + ics_id = db.Column(db.Text, unique=True, nullable=False, index=True) serial_number = db.Column(db.Text, nullable=False) manufacturer_id = db.Column(db.Integer, db.ForeignKey('manufacturer.id')) model_id = db.Column(db.Integer, db.ForeignKey('model.id')) diff --git a/app/settings.py b/app/settings.py index 27fc11d558b037e2a0d4889dfbdbbb899fc14718..19cf032df36406d61deb9476833574dfa998089f 100644 --- a/app/settings.py +++ b/app/settings.py @@ -52,3 +52,7 @@ CSENTRY_LDAP_GROUPS = { } NETWORK_DEFAULT_PREFIX = 24 +# ICS Ids starting with this prefix are considered temporary and can be changed +# (waiting for a real label to be assigned) +# WARNING: This is defined here as a global settings but should not be changed! +TEMPORARY_ICS_ID = 'ZZ' diff --git a/app/templates/inventory/edit_item.html b/app/templates/inventory/edit_item.html index 9ca6d2bb52ce3c842dc008ab74ebfa7e23943a37..2cfedb44669fbaf8a6dd3e4ce76aa57204407064 100644 --- a/app/templates/inventory/edit_item.html +++ b/app/templates/inventory/edit_item.html @@ -23,7 +23,11 @@ <form id="itemForm" method="POST"> {{ form.hidden_tag() }} - {{ render_field(form.ics_id, readonly=True) }} + {% if form.ics_id.data.startswith(config['TEMPORARY_ICS_ID']) %} + {{ render_field(form.ics_id) }} + {% else %} + {{ render_field(form.ics_id, readonly=True) }} + {% endif %} {{ render_field(form.serial_number) }} {{ render_field(form.manufacturer_id) }} {{ render_field(form.model_id) }}