Ability to delete part

- Provides confirmation form
- Shows the flow-on effects (model.CASCADE) from deleting this part
- Bootstrap makes it prettyful
This commit is contained in:
Oliver 2018-04-15 08:45:50 +10:00
parent 21e3f415c6
commit 54e78bf468
7 changed files with 109 additions and 9 deletions

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-14 22:38
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('part', '0012_auto_20180414_1032'),
]
operations = [
migrations.AlterField(
model_name='part',
name='name',
field=models.CharField(max_length=100, unique=True),
),
migrations.AlterUniqueTogether(
name='part',
unique_together=set([]),
),
]

View File

@ -77,12 +77,14 @@ class Part(models.Model):
return '/part/{id}/'.format(id=self.id)
# Short name of the part
name = models.CharField(max_length=100)
name = models.CharField(max_length=100, unique=True)
# Longer description of the part (optional)
description = models.CharField(max_length=250, blank=True)
# Internal Part Number (optional)
# Potentially multiple parts map to the same internal IPN (variants?)
# So this does not have to be unique
IPN = models.CharField(max_length=100, blank=True)
# Provide a URL for an external link
@ -117,7 +119,7 @@ class Part(models.Model):
class Meta:
verbose_name = "Part"
verbose_name_plural = "Parts"
unique_together = (("name", "category"),)
#unique_together = (("name", "category"),)
@property
def stock(self):

View File

@ -9,7 +9,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- Local stylesheet -->
<link rel="stylesheet" href="{% static 'css/inventree.css' %}">
@ -31,7 +32,7 @@ InvenTree
{% include "navbar.html" %}
<div class="inventree-content">
<div class="container-fluid inventree-content">
{% block content %}
<!-- Each view fills in here.. -->
{% endblock %}

View File

@ -1,2 +1,51 @@
{% extends 'part/part_base.html' %}
{% block details %}
<div class="panel panel-danger">
<div class="panel-heading">Are you sure you want to delete part '{{ part.name }}'?</div>
<div class="panel-body">
<p><b>Deleting this part is a permanent action and cannot be undone.</b></p>
{% if part.usedInCount > 0 %}
<p>This part is used in BOMs for {{ part.usedInCount }} other parts. If you delete this part, the BOMs for the following parts will be updated:
<ul class="list-group">
{% for child in part.used_in.all %}
<li class='list-group-item'>{{ child.part.name }} - {{ child.part.description }}</li>
{% endfor %}
</p>
{% endif %}
{% if part.locations.all|length > 0 %}
<p>There are {{ part.locations.all|length }} stock entries defined for this part. If you delete this part, the following stock entries will also be deleted:
<ul class='list-group'>
{% for stock in part.locations.all %}
<li class='list-group-item'>{{ stock.location.name }} - {{ stock.quantity }} items</li>
{% endfor %}
</ul>
</p>
{% endif %}
{% if part.supplier_parts.all|length > 0 %}
<p>There are {{ part.supplier_parts.all|length }} suppliers defined for this part. If you delete this part, the following supplier parts will also be deleted.
<ul class='list-group'>
{% for spart in part.supplier_parts.all %}
<li class='list-group-item'>{{ spart.supplier.name }} - {{ spart.SKU }}</li>
{% endfor %}
</ul>
</p>
{% endif %}
{% if part.serials.all|length > 0 %}
<p>There are {{ part.serials.all|length }} unique parts tracked for '{{ part.name }}'. Deleting this part will permanently remove this tracking information.</p>
{% endif %}
<form action="" method="post">{% csrf_token %}
<input type="submit" name='confirm' value="Confirm" />
<input type="submit" name="cancel" value="Cancel" />
</form>
</div>
</div>
{% endblock %}

View File

@ -40,7 +40,7 @@ bom_api_urls = [
part_detail_urls = [
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
url(r'^delete/?', views.delete, name='part-delete'),
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
url(r'^bom/?', views.PartDetail.as_view(template_name='part/bom.html'), name='part-bom'),
url(r'^stock/?', views.PartDetail.as_view(template_name='part/stock.html'), name='part-stock'),

View File

@ -6,7 +6,7 @@ from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views.generic import DetailView, ListView
from django.views.generic.edit import UpdateView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from .forms import EditPartForm
@ -46,5 +46,15 @@ class PartEdit(UpdateView):
template_name = 'part/edit.html'
def delete(request, pk):
return HttpResponseRedirect('/part/{pk}/'.format(pk=pk))
class PartDelete(DeleteView):
model = Part
template_name = 'part/delete.html'
success_url = '/part/'
def post(self, request, *args, **kwargs):
if 'confirm' in request.POST:
return super(PartDelete, self).post(request, *args, **kwargs)
else:
return HttpResponseRedirect(self.get_object().get_absolute_url())

View File

@ -117,4 +117,18 @@ table tr:nth-child(odd) {
border: 1px solid #ddd;
border-bottom-color: transparent;
cursor: default;
}
}
.panel-danger {
border-radius: 5px;
padding: 5px;
margin: 5px;
border-color: #ebccd1;
}
.panel-danger>.panel-heading {
background-color: #ebccd1;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}