diff --git a/ereuse_devicehub/forms.py b/ereuse_devicehub/forms.py index 087fd165..895160c5 100644 --- a/ereuse_devicehub/forms.py +++ b/ereuse_devicehub/forms.py @@ -129,7 +129,6 @@ class SanitizationEntityForm(FlaskForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # import pdb; pdb.set_trace() if isinstance(self.logo.data, URL): self.logo.data = self.logo.data.to_text() diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py index 451684e1..fc475f6e 100644 --- a/ereuse_devicehub/inventory/forms.py +++ b/ereuse_devicehub/inventory/forms.py @@ -30,7 +30,12 @@ from wtforms import ( from wtforms.fields import FormField from ereuse_devicehub.db import db -from ereuse_devicehub.inventory.models import DeliveryNote, ReceiverNote, Transfer +from ereuse_devicehub.inventory.models import ( + DeliveryNote, + ReceiverNote, + Transfer, + TransferCustomerDetails, +) from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog from ereuse_devicehub.parser.parser import ParseSnapshotLsHw from ereuse_devicehub.parser.schemas import Snapshot_lite @@ -1518,6 +1523,54 @@ class NotesForm(FlaskForm): return self._obj +class CustomerDetailsForm(FlaskForm): + company_name = StringField( + 'Company name', + [validators.Optional()], + render_kw={'class': "form-control"}, + description="Name of the company", + ) + location = StringField( + 'Location', + [validators.Optional()], + render_kw={'class': "form-control"}, + description="""Location where is the company""", + ) + logo = URLField( + 'Logo', + [validators.Optional()], + render_kw={'class': "form-control"}, + description="Url where is the logo", + ) + + def __init__(self, *args, **kwargs): + lot_id = kwargs.pop('lot_id', None) + self._tmp_lot = Lot.query.filter(Lot.id == lot_id).one() + self._obj = self._tmp_lot.transfer.customer_details + if self._obj: + kwargs['obj'] = self._obj + if not self._obj: + self._obj = TransferCustomerDetails(transfer_id=self._tmp_lot.transfer.id) + + super().__init__(*args, **kwargs) + if isinstance(self.logo.data, URL): + self.logo.data = URL(self.logo.data).to_text() + + def validate(self, extra_validators=None): + is_valid = super().validate(extra_validators) + return is_valid + + def save(self, commit=True): + self.populate_obj(self._obj) + self._obj.logo = URL(self._obj.logo) + db.session.add(self._obj) + + if commit: + db.session.commit() + + return self._obj + + class UploadPlaceholderForm(FlaskForm): type = StringField('Type', [validators.DataRequired()]) placeholder_file = FileField( diff --git a/ereuse_devicehub/inventory/models.py b/ereuse_devicehub/inventory/models.py index 45d25157..f8b4f977 100644 --- a/ereuse_devicehub/inventory/models.py +++ b/ereuse_devicehub/inventory/models.py @@ -5,7 +5,7 @@ from flask import g from sqlalchemy import Column, Integer from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import backref, relationship -from teal.db import CASCADE_OWN +from teal.db import CASCADE_OWN, URL from ereuse_devicehub.db import db from ereuse_devicehub.resources.models import Thing @@ -90,3 +90,23 @@ class ReceiverNote(Thing): backref=backref('receiver_note', lazy=True, uselist=False, cascade=CASCADE_OWN), primaryjoin='ReceiverNote.transfer_id == Transfer.id', ) + + +class TransferCustomerDetails(Thing): + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4) + company_name = Column(CIText(), nullable=True) + location = Column(CIText(), nullable=True) + logo = Column(URL(), nullable=True) + + transfer_id = db.Column( + UUID(as_uuid=True), + db.ForeignKey('transfer.id'), + nullable=False, + ) + transfer = relationship( + 'Transfer', + backref=backref( + 'customer_details', lazy=True, uselist=False, cascade=CASCADE_OWN + ), + primaryjoin='TransferCustomerDetails.transfer_id == Transfer.id', + ) diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py index 15988ddb..1f973841 100644 --- a/ereuse_devicehub/inventory/views.py +++ b/ereuse_devicehub/inventory/views.py @@ -20,6 +20,7 @@ from ereuse_devicehub.inventory.forms import ( AdvancedSearchForm, AllocateForm, BindingForm, + CustomerDetailsForm, DataWipeForm, EditTransferForm, FilterForm, @@ -79,6 +80,7 @@ class DeviceListMixin(GenericMixin): form_transfer = '' form_delivery = '' form_receiver = '' + form_customer_details = '' if lot_id: lot = lots.filter(Lot.id == lot_id).one() @@ -86,6 +88,7 @@ class DeviceListMixin(GenericMixin): form_transfer = EditTransferForm(lot_id=lot.id) form_delivery = NotesForm(lot_id=lot.id, type='Delivery') form_receiver = NotesForm(lot_id=lot.id, type='Receiver') + form_customer_details = CustomerDetailsForm(lot_id=lot.id) form_new_action = NewActionForm(lot=lot_id) self.context.update( @@ -97,6 +100,7 @@ class DeviceListMixin(GenericMixin): 'form_transfer': form_transfer, 'form_delivery': form_delivery, 'form_receiver': form_receiver, + 'form_customer_details': form_customer_details, 'form_filter': form_filter, 'form_print_labels': PrintLabelsForm(), 'lot': lot, @@ -1257,6 +1261,28 @@ class SnapshotDetailView(GenericMixin): ) +class CustomerDetailsView(GenericMixin): + methods = ['POST'] + form_class = CustomerDetailsForm + + def dispatch_request(self, lot_id): + self.get_context() + form = self.form_class(request.form, lot_id=lot_id) + next_url = url_for('inventory.lotdevicelist', lot_id=lot_id) + + if form.validate_on_submit(): + form.save() + messages.success('Customer details updated successfully!') + return flask.redirect(next_url) + + messages.error('Customer details updated error!') + for k, v in form.errors.items(): + value = ';'.join(v) + key = form[k].label.text + messages.error('Error {key}: {value}!'.format(key=key, value=value)) + return flask.redirect(next_url) + + class DeliveryNoteView(GenericMixin): methods = ['POST'] form_class = NotesForm @@ -1448,6 +1474,10 @@ devices.add_url_rule( '/lot//transfer/', view_func=EditTransferView.as_view('edit_transfer'), ) +devices.add_url_rule( + '/lot//customerdetails/', + view_func=CustomerDetailsView.as_view('customer_details'), +) devices.add_url_rule( '/lot//deliverynote/', view_func=DeliveryNoteView.as_view('delivery_note'), diff --git a/ereuse_devicehub/migrations/versions/4f33137586dd_sanitization.py b/ereuse_devicehub/migrations/versions/4f33137586dd_sanitization.py index fa5e5fd3..51fe4d61 100644 --- a/ereuse_devicehub/migrations/versions/4f33137586dd_sanitization.py +++ b/ereuse_devicehub/migrations/versions/4f33137586dd_sanitization.py @@ -5,6 +5,7 @@ Revises: 93daff872771 Create Date: 2023-02-13 18:01:00.092527 """ +import citext import sqlalchemy as sa import teal from alembic import context, op @@ -54,6 +55,31 @@ def upgrade(): schema=f'{get_inv()}', ) + op.create_table( + 'transfer_customer_details', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column( + 'updated', + sa.TIMESTAMP(timezone=True), + server_default=sa.text('CURRENT_TIMESTAMP'), + nullable=False, + ), + sa.Column( + 'created', + sa.TIMESTAMP(timezone=True), + server_default=sa.text('CURRENT_TIMESTAMP'), + nullable=False, + ), + sa.Column('company_name', citext.CIText(), nullable=True), + sa.Column('logo', teal.db.URL(), nullable=True), + sa.Column('location', citext.CIText(), nullable=True), + sa.Column('transfer_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint(['transfer_id'], [f'{get_inv()}.transfer.id']), + sa.PrimaryKeyConstraint('id'), + schema=f'{get_inv()}', + ) + def downgrade(): op.drop_table('sanitization_entity', schema=f'{get_inv()}') + op.drop_table('transfer_customer_details', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/templates/inventory/device_list.html b/ereuse_devicehub/templates/inventory/device_list.html index 78c3e39d..f89c93f6 100644 --- a/ereuse_devicehub/templates/inventory/device_list.html +++ b/ereuse_devicehub/templates/inventory/device_list.html @@ -93,6 +93,11 @@ Receiver Note + {% endif %} {% endif %} @@ -656,6 +661,37 @@ {% endif %} + +
+
Customer Details
+
+ {{ form_customer_details.csrf_token }} + + {% for field in form_customer_details %} + {% if field != form_customer_details.csrf_token %} +
+ {% if field != form_customer_details.type %} + {{ field.label(class_="form-label") }} + {{ field }} + {{ field.description }} + {% if field.errors %} +

+ {% for error in field.errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} + {% endif %} +
+ {% endif %} + {% endfor %} + +
+ Cancel + +
+
+
{% endif %} diff --git a/tests/test_basic.py b/tests/test_basic.py index 7322e77b..e9927a0e 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -71,6 +71,7 @@ def test_api_docs(client: Client): '/inventory/lot/{lot_id}/transfer/', '/inventory/lot/transfer/{type_id}/', '/inventory/lot/{lot_id}/upload-snapshot/', + '/inventory/lot/{lot_id}/customerdetails/', '/inventory/snapshots/{snapshot_uuid}/', '/inventory/snapshots/', '/inventory/tag/devices/{dhid}/add/', @@ -98,6 +99,7 @@ def test_api_docs(client: Client): '/metrics/', '/profile/', '/set_password/', + '/set_sanitization/', '/tags/', '/tags/{tag_id}/device/{device_id}', '/trade-documents/',