Merge pull request #441 from eReuse/feature/4125-remove-documents

allow remove a document
This commit is contained in:
cayop 2023-03-29 11:32:04 +02:00 committed by GitHub
commit 8f8883242e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 11 deletions

View File

@ -1274,8 +1274,14 @@ class TradeDocumentForm(FlaskForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
lot_id = kwargs.pop('lot') lot_id = kwargs.pop('lot')
doc_id = kwargs.pop('document', None)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._lot = Lot.query.filter(Lot.id == lot_id).one() self._lot = Lot.query.filter(Lot.id == lot_id).one()
self.object = None
if doc_id:
self.object = TradeDocument.query.filter_by(
id=doc_id, lot=self._lot, owner=g.user
).one()
if not self._lot.transfer: if not self._lot.transfer:
self.form_errors = ['Error, this lot is not a transfer lot.'] self.form_errors = ['Error, this lot is not a transfer lot.']
@ -1307,6 +1313,12 @@ class TradeDocumentForm(FlaskForm):
return self._obj return self._obj
def remove(self):
if self.object:
self.object.delete()
db.session.commit()
return self.object
class TransferForm(FlaskForm): class TransferForm(FlaskForm):
lot_name = StringField( lot_name = StringField(

View File

@ -547,6 +547,27 @@ class LotDeleteView(View):
return flask.redirect(next_url) return flask.redirect(next_url)
class DocumentDeleteView(View):
methods = ['GET']
decorators = [login_required]
template_name = 'inventory/device_list.html'
form_class = TradeDocumentForm
def dispatch_request(self, lot_id, doc_id):
next_url = url_for('inventory.lotdevicelist', lot_id=lot_id)
form = self.form_class(lot=lot_id, document=doc_id)
try:
form.remove()
except Exception as err:
msg = "{}".format(err)
messages.error(msg)
return flask.redirect(next_url)
msg = "Document removed successfully."
messages.success(msg)
return flask.redirect(next_url)
class UploadSnapshotView(GenericMixin): class UploadSnapshotView(GenericMixin):
methods = ['GET', 'POST'] methods = ['GET', 'POST']
decorators = [login_required] decorators = [login_required]
@ -1515,6 +1536,10 @@ devices.add_url_rule(
'/lot/<string:lot_id>/trade-document/add/', '/lot/<string:lot_id>/trade-document/add/',
view_func=NewTradeDocumentView.as_view('trade_document_add'), view_func=NewTradeDocumentView.as_view('trade_document_add'),
) )
devices.add_url_rule(
'/lot/<string:lot_id>/document/del/<string:doc_id>',
view_func=DocumentDeleteView.as_view('document_del'),
)
devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist')) devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist'))
devices.add_url_rule( devices.add_url_rule(
'/all/device/', view_func=AllDeviceListView.as_view('alldevicelist') '/all/device/', view_func=AllDeviceListView.as_view('alldevicelist')

View File

@ -1,4 +1,5 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from flask_sqlalchemy import event from flask_sqlalchemy import event
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
@ -16,18 +17,23 @@ class Thing(db.Model):
`schema.org's Thing class <https://schema.org/Thing>`_ `schema.org's Thing class <https://schema.org/Thing>`_
using only needed fields. using only needed fields.
""" """
__abstract__ = True __abstract__ = True
updated = db.Column(db.TIMESTAMP(timezone=True), updated = db.Column(
db.TIMESTAMP(timezone=True),
nullable=False, nullable=False,
index=True, index=True,
server_default=db.text('CURRENT_TIMESTAMP')) server_default=db.text('CURRENT_TIMESTAMP'),
)
updated.comment = """The last time Devicehub recorded a change for updated.comment = """The last time Devicehub recorded a change for
this thing. this thing.
""" """
created = db.Column(db.TIMESTAMP(timezone=True), created = db.Column(
db.TIMESTAMP(timezone=True),
nullable=False, nullable=False,
index=True, index=True,
server_default=db.text('CURRENT_TIMESTAMP')) server_default=db.text('CURRENT_TIMESTAMP'),
)
created.comment = """When Devicehub created this.""" created.comment = """When Devicehub created this."""
def __init__(self, **kwargs) -> None: def __init__(self, **kwargs) -> None:
@ -36,11 +42,15 @@ class Thing(db.Model):
self.created = kwargs.get('created', datetime.now(timezone.utc)) self.created = kwargs.get('created', datetime.now(timezone.utc))
super().__init__(**kwargs) super().__init__(**kwargs)
def delete(self):
db.session.delete(self)
def update_object_timestamp(mapper, connection, thing_obj): def update_object_timestamp(mapper, connection, thing_obj):
""" This function update the stamptime of field updated """ """This function update the stamptime of field updated"""
thing_obj.updated = datetime.now(timezone.utc) thing_obj.updated = datetime.now(timezone.utc)
def listener_reset_field_updated_in_actual_time(thing_obj): def listener_reset_field_updated_in_actual_time(thing_obj):
""" This function launch a event than listen like a signal when some object is saved """ """This function launch a event than listen like a signal when some object is saved"""
event.listen(thing_obj, 'before_update', update_object_timestamp, propagate=True) event.listen(thing_obj, 'before_update', update_object_timestamp, propagate=True)

View File

@ -530,6 +530,7 @@
<tr> <tr>
<th scope="col">File</th> <th scope="col">File</th>
<th scope="col" data-type="date" data-format="YYYY-MM-DD hh:mm">Uploaded on</th> <th scope="col" data-type="date" data-format="YYYY-MM-DD hh:mm">Uploaded on</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -545,6 +546,38 @@
<td> <td>
{{ doc.created.strftime('%Y-%m-%d %H:%M')}} {{ doc.created.strftime('%Y-%m-%d %H:%M')}}
</td> </td>
<td>
<a href="javascript:javascript:void(0)" data-bs-toggle="modal" data-bs-target="#btnRemoveDocument{{ loop.index }}">
<i class="bi bi-trash-fill"></i>
</a>
<div class="modal fade" id="btnRemoveDocument{{ loop.index }}" tabindex="-1" style="display: none;" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Document</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Are you sure that you want to delete this Document?<br />
<strong>{{ doc.file_name }}</strong>
<p class="text-danger">
This action cannot be undone.
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary-outline" data-bs-dismiss="modal">Cancel</button>
<a href="{{ url_for('inventory.document_del', lot_id=lot.id, doc_id=doc.id) }}" type="button" class="btn btn-danger">
Delete it!
</a>
</div>
</div>
</div>
</div>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% for doc in lot.trade.documents %} {% for doc in lot.trade.documents %}
@ -559,6 +592,9 @@
<td> <td>
{{ doc.created.strftime('%Y-%m-%d %H:%M')}} {{ doc.created.strftime('%Y-%m-%d %H:%M')}}
</td> </td>
<td>
<a href="javascript:void(0)"><i class="bi bi-trash-fill"></i></a>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -73,6 +73,7 @@ def test_api_docs(client: Client):
'/inventory/lot/transfer/{type_id}/', '/inventory/lot/transfer/{type_id}/',
'/inventory/lot/{lot_id}/upload-snapshot/', '/inventory/lot/{lot_id}/upload-snapshot/',
'/inventory/lot/{lot_id}/customerdetails/', '/inventory/lot/{lot_id}/customerdetails/',
'/inventory/lot/{lot_id}/document/del/{doc_id}',
'/inventory/snapshots/{snapshot_uuid}/', '/inventory/snapshots/{snapshot_uuid}/',
'/inventory/snapshots/', '/inventory/snapshots/',
'/inventory/tag/devices/{dhid}/add/', '/inventory/tag/devices/{dhid}/add/',