2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-02 05:26:45 +00:00

Added edit views for stock

- StockItem
- StockLocation
This commit is contained in:
Oliver 2018-04-15 23:27:56 +10:00
parent 3c844fc77f
commit 55b533d3ef
18 changed files with 168 additions and 22 deletions

View File

@ -68,7 +68,7 @@ ROOT_URLCONF = 'InvenTree.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], 'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -81,6 +81,8 @@ TEMPLATES = [
}, },
] ]
print(os.path.join(BASE_DIR, 'templates'))
REST_FRAMEWORK = { REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'InvenTree.utils.api_exception_handler' 'EXCEPTION_HANDLER': 'InvenTree.utils.api_exception_handler'
} }

View File

@ -23,7 +23,6 @@ class PartCategory(InvenTreeTree):
verbose_name = "Part Category" verbose_name = "Part Category"
verbose_name_plural = "Part Categories" verbose_name_plural = "Part Categories"
@property @property
def partcount(self): def partcount(self):
""" Return the total part count under this category """ Return the total part count under this category

View File

@ -18,7 +18,7 @@ Are you sure you want to delete category '{{ category.name }}'?
<ul class='list-group'> <ul class='list-group'>
{% for cat in category.children.all %} {% for cat in category.children.all %}
<li class='list-group-item'>{{ cat.name }} - {{ cat.description }}</li> <li class='list-group-item'><b>{{ cat.name }}</b> - <i>{{ cat.description }}</i></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
@ -33,7 +33,7 @@ Are you sure you want to delete category '{{ category.name }}'?
</p> </p>
<ul class='list-group'> <ul class='list-group'>
{% for part in category.parts.all %} {% for part in category.parts.all %}
<li class='list-group-item'>{{ part.name }} - {{ part.description }}</li> <li class='list-group-item'><b>{{ part.name }}</b> - <i>{{ part.description }}</i></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}

View File

@ -10,6 +10,7 @@ Total in stock: {{ part.stock }}
<table class="table table-striped"> <table class="table table-striped">
<tr> <tr>
<th>Link</th>
<th>Quantity</th> <th>Quantity</th>
<th>Location</th> <th>Location</th>
<th>Supplier part</th> <th>Supplier part</th>
@ -18,8 +19,9 @@ Total in stock: {{ part.stock }}
</tr> </tr>
{% for stock in part.locations.all %} {% for stock in part.locations.all %}
<tr> <tr>
<td><a href="{% url 'stock-item-detail' stock.id %}">Click</a></td>
<td>{{ stock.quantity }}</td> <td>{{ stock.quantity }}</td>
<td><a href="/stock/list/?location={{ stock.location.id }}">{{ stock.location.name }}</a></td> <td><a href="{% url 'stock-location-detail' stock.location.id %}">{{ stock.location.name }}</a></td>
<td> <td>
{% if stock.supplier_part %} {% if stock.supplier_part %}
<a href="{% url 'supplier-part-detail' stock.supplier_part.id %}"> <a href="{% url 'supplier-part-detail' stock.supplier_part.id %}">
@ -31,6 +33,12 @@ Total in stock: {{ part.stock }}
<td>{{ stock.notes }}</td> <td>{{ stock.notes }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table
<div class='container-fluid'>
<a href="{% url 'stock-item-create' %}?part={{ part.id }}">
<button class='btn btn-success'>Add new Stock Item</button>
</a>
</div>
{% endblock %} {% endblock %}

View File

@ -7,14 +7,14 @@
{% if part.supplier_parts.all|length > 0 %} {% if part.supplier_parts.all|length > 0 %}
<table class="table table-striped"> <table class="table table-striped">
<tr> <tr>
<th>Supplier</th>
<th>SKU</th> <th>SKU</th>
<th>Supplier</th>
<th>URL</th> <th>URL</th>
</tr> </tr>
{% for spart in part.supplier_parts.all %} {% for spart in part.supplier_parts.all %}
<tr> <tr>
<td><a href="{% url 'supplier-detail' spart.supplier.id %}">{{ spart.supplier.name }}</a></td>
<td><a href="{% url 'supplier-part-detail' spart.id %}">{{ spart.SKU }}</a></td> <td><a href="{% url 'supplier-part-detail' spart.id %}">{{ spart.SKU }}</a></td>
<td><a href="{% url 'supplier-detail' spart.supplier.id %}">{{ spart.supplier.name }}</a></td>
<td> <td>
{% if spart.URL %} {% if spart.URL %}
<a href="{{ spart.URL }}">{{ spart.URL }}</a> <a href="{{ spart.URL }}">{{ spart.URL }}</a>

View File

@ -20,6 +20,9 @@ class StockLocation(InvenTreeTree):
Stock locations can be heirarchical as required Stock locations can be heirarchical as required
""" """
def get_absolute_url(self):
return '/stock/location/{id}/'.format(id=self.id)
@property @property
def items(self): def items(self):
stock_list = self.stockitem_set.all() stock_list = self.stockitem_set.all()
@ -34,7 +37,16 @@ def before_delete_stock_location(sender, instance, using, **kwargs):
item.location = instance.parent item.location = instance.parent
item.save() item.save()
# Update each child category
for child in instance.children.all():
child.parent = instance.parent
child.save()
class StockItem(models.Model): class StockItem(models.Model):
def get_absolute_url(self):
return '/stock/item/{id}/'.format(id=self.id)
part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations') part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations')
supplier_part = models.ForeignKey(SupplierPart, blank=True, null=True, on_delete=models.SET_NULL) supplier_part = models.ForeignKey(SupplierPart, blank=True, null=True, on_delete=models.SET_NULL)

View File

@ -4,10 +4,12 @@
{% include "stock/loc_link.html" with location=item.location %} {% include "stock/loc_link.html" with location=item.location %}
<h3>Stock entry details</h3>
<table class="table table-striped"> <table class="table table-striped">
<tr> <tr>
<td>Part</td> <td>Part</td>
<td><a href="{% url 'part-detail' item.part.id %}">{{ item.part.name }}</td> <td><a href="{% url 'part-stock' item.part.id %}">{{ item.part.name }}</td>
</tr> </tr>
<tr> <tr>
<td>Location</td> <td>Location</td>
@ -45,4 +47,13 @@
{% endif %} {% endif %}
</table> </table>
<div class='container-fluid'>
<a href="{% url 'stock-item-edit' item.id %}">
<button class='btn btn-info'>Edit Stock Item</button>
</a>
<a href="{% url 'stock-item-delete' item.id %}">
<button class='btn btn-danger'>Delete Stock Item</button>
</a>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,5 @@
{% extends "create_edit_obj.html" %}
{% block obj_title %}
Create a new stock item
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "delete_obj.html" %}
{% block del_title %}
Are you sure you want to delete this stock item?
{% endblock %}
{% block del_body %}
This will remove <b>{{ item.quantity }}</b> units of <b>'{{ item.part.name }}'</b> from stock.
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends "create_edit_obj.html" %}
{% block obj_title %}
Edit stock item for part '{{ item.part.name }}'
{% endblock %}

View File

@ -14,4 +14,22 @@
{% include "stock/stock_table.html" with items=location.items %} {% include "stock/stock_table.html" with items=location.items %}
<div class='container-fluid'>
<a href="{% url 'stock-location-create' %}?location={{ location.id }}">
<button class='btn btn-success'>New Stock Location</button>
</a>
<a href="{% url 'stock-item-create' %}?location={{ location.id }}">
<button class='btn btn-success'>New Stock Item</button>
</a>
<a href="{% url 'stock-location-edit' location.id %}">
<button class="btn btn-info">Edit Location</button>
</a>
<a href="{% url 'stock-location-delete' location.id %}">
<button class="btn btn-danger">Delete Location</button>
</a>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,5 @@
{% extends "create_edit_obj.html" %}
{% block obj_title %}
Create a new stock location
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends 'delete_obj.html' %}
{% block del_title %}
Are you sure you want to delete stock location '{{ location.name }}'?
{% endblock %}
{% block del_body %}
{% if location.children.all|length > 0 %}
<p>This location contains {{ location.children.all|length }} child locations.<br>
If this location is deleted, these child locations will be moved to
{% if location.parent %}
the '{{ location.parent.name }}' location.
{% else %}
the top level 'Stock' category.
{% endif %}
</p>
<ul class='list-group'>
{% for loc in location.children.all %}
<li class='list-group-item'><b>{{ loc.name }}</b> - <i>{{ loc.description}}</i></li>
{% endfor %}
</ul>
{% endif %}
{% if location.items.all|length > 0 %}
<p>This location contains {{ location.items.all|length }} stock items.<br>
{% if location.parent %}
If this location is deleted, these items will be moved to the '{{ location.parent.name }}' location.
{% else %}
If this location is deleted, these items will be deleted!
{% endif %}
</p>
<ul class='list-group'>
{% for item in location.items.all %}
<li class='list-group-item'><b>{{ item.part.name }}</b> - <i>{{ item.part.description }}</i><span class='badge'>{{ item.quantity }}</span></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,5 @@
{% extends "create_edit_obj.html" %}
{% block obj_title %}
Edit stock location '{{ location.name }}'
{% endblock %}

View File

@ -8,7 +8,7 @@
</tr> </tr>
{% for item in items.all %} {% for item in items.all %}
<tr> <tr>
<td><a href="{% url 'part-detail' item.part.id %}">{{ item.part.name }}</a></td> <td><a href="{% url 'part-stock' item.part.id %}">{{ item.part.name }}</a></td>
<td>{{ item.quantity }}</td> <td>{{ item.quantity }}</td>
<td>{{ item.status }}</td> <td>{{ item.status }}</td>
<td>{{ item.stocktake_date }}</td> <td>{{ item.stocktake_date }}</td>

View File

@ -52,10 +52,10 @@ stock_urls = [
url(r'^location/new/', views.StockLocationCreate.as_view(), name='stock-location-create'), url(r'^location/new/', views.StockLocationCreate.as_view(), name='stock-location-create'),
url(r'^item/new/?', views.StockItemCreate.as_view(), name='stock-item-create'),
# Individual stock items # Individual stock items
url(r'^item/(?P<pk>\d+)/', include(stock_item_detail_urls)), url(r'^item/(?P<pk>\d+)/', include(stock_item_detail_urls)),
url(r'^item/new/', views.StockItemCreate.as_view(), name='stock-item-create'),
url(r'^.*$', views.StockIndex.as_view(), name='stock-index'), url(r'^.*$', views.StockIndex.as_view(), name='stock-index'),
] ]

View File

@ -5,7 +5,7 @@ from django.urls import reverse
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
from django.views.generic.edit import UpdateView, DeleteView, CreateView from django.views.generic.edit import UpdateView, DeleteView, CreateView
from part.models import Part
from .models import StockItem, StockLocation from .models import StockItem, StockLocation
from .forms import EditStockLocationForm from .forms import EditStockLocationForm
@ -46,35 +46,60 @@ class StockItemDetail(DetailView):
class StockLocationEdit(UpdateView): class StockLocationEdit(UpdateView):
model = StockLocation model = StockLocation
form_class = EditStockLocationForm form_class = EditStockLocationForm
template_name = '/stock/location-edit.html' template_name = 'stock/location_edit.html'
context_object_name = 'location' context_object_name = 'location'
class StockItemEdit(UpdateView): class StockItemEdit(UpdateView):
model = StockItem model = StockItem
form_class = EditStockItemForm form_class = EditStockItemForm
template_name = '/stock/item-edit.html' template_name = 'stock/item_edit.html'
context_object_name = 'item' context_object_name = 'item'
class StockLocationCreate(CreateView): class StockLocationCreate(CreateView):
model = StockLocation model = StockLocation
form_class = EditStockLocationForm form_class = EditStockLocationForm
template_name = '/stock/location-create.html' template_name = 'stock/location_create.html'
context_object_name = 'location' context_object_name = 'location'
def get_initial(self):
initials = super(StockLocationCreate, self).get_initial().copy()
loc_id = self.request.GET.get('location', None)
if loc_id:
initials['parent'] = get_object_or_404(StockLocation, pk=loc_id)
return initials
class StockItemCreate(CreateView): class StockItemCreate(CreateView):
model = StockItem model = StockItem
form_class = EditStockItemForm form_class = EditStockItemForm
template_name = '/stock/item-create.html' template_name = 'stock/item_create.html'
context_object_name = 'item' context_object_name = 'item'
def get_initial(self):
initials = super(StockItemCreate, self).get_initial().copy()
part_id = self.request.GET.get('part', None)
loc_id = self.request.GET.get('location', None)
if part_id:
initials['part'] = get_object_or_404(Part, pk=part_id)
if loc_id:
initials['location'] = get_object_or_404(StockLocation, pk=loc_id)
return initials
class StockLocationDelete(DeleteView): class StockLocationDelete(DeleteView):
model = StockLocation model = StockLocation
success_url = '/stock/' success_url = '/stock'
template_name = '/stock/location-delete.html' template_name = 'stock/location_delete.html'
context_object_name = 'location'
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if 'confirm' in request.POST: if 'confirm' in request.POST:
@ -84,9 +109,10 @@ class StockLocationDelete(DeleteView):
class StockItemDelete(DeleteView): class StockItemDelete(DeleteView):
model = StockLocation model = StockItem
success_url = '/stock/' success_url = '/stock/'
template_name = '/stock/item-delete.html' template_name = 'stock/item_delete.html'
context_object_name = 'item'
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if 'confirm' in request.POST: if 'confirm' in request.POST:

View File

@ -11,7 +11,7 @@
<td>Part</td> <td>Part</td>
<td> <td>
{% if part.part %} {% if part.part %}
<a href="{% url 'part-detail' part.part.id %}">{{ part.part.name }}</a> <a href="{% url 'part-suppliers' part.part.id %}">{{ part.part.name }}</a>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>