- Parts
+ Parts
{% if location %}
{% for path_item in location.parentpath %}
- {{ path_item.name }}
+ {{ path_item.name }}
{% endfor %}
- {{ location.name }}
+ {{ location.name }}
{% endif %}
diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html
new file mode 100644
index 0000000000..54352b0284
--- /dev/null
+++ b/InvenTree/stock/templates/stock/location.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% include "stock/loc_link.html" with location=location %}
+
+
+ {{ location.name }}
+ {{ location.description }}
+
+
+
+{% include "stock/location_list.html" with locations=location.children %}
+
+{% include "stock/stock_table.html" with items=location.items %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/stock/templates/stock/location_list.html b/InvenTree/stock/templates/stock/location_list.html
new file mode 100644
index 0000000000..d4804bffdb
--- /dev/null
+++ b/InvenTree/stock/templates/stock/location_list.html
@@ -0,0 +1,6 @@
+Storage locations:
+
\ No newline at end of file
diff --git a/InvenTree/stock/templates/stock/stock_table.html b/InvenTree/stock/templates/stock/stock_table.html
new file mode 100644
index 0000000000..d3684ffe63
--- /dev/null
+++ b/InvenTree/stock/templates/stock/stock_table.html
@@ -0,0 +1,18 @@
+
+
+ Part
+ Stock
+ Status
+ Stocktake
+
+
+{% for item in items.all %}
+
+ {{ item.part.name }}
+ {{ item.quantity }}
+ {{ item.status }}
+ {{ item.stocktake_date }}
+ Click
+
+{% endfor %}
+
\ No newline at end of file
diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py
index 3c951f29e5..c83646429b 100644
--- a/InvenTree/stock/urls.py
+++ b/InvenTree/stock/urls.py
@@ -31,15 +31,31 @@ stock_api_loc_urls = [
# URL list for web interface
-stock_detail_urls = [
- url('', views.detail, name='stock-detail'),
+stock_location_detail_urls = [
+ url(r'^edit/?', views.StockLocationEdit.as_view(), name='stock-location-edit'),
+ url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'),
+
+ # Anything else
+ url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'),
]
+
+stock_item_detail_urls = [
+ url(r'^edit/?', views.StockItemEdit.as_view(), name='stock-item-edit'),
+ url(r'^delete/?', views.StockItemDelete.as_view(), name='stock-item-delete'),
+
+ url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
+]
+
stock_urls = [
+ # Stock location
+ url(r'^location/(?P
\d+)/', include(stock_location_detail_urls)),
+
+ url(r'^location/new/', views.StockLocationCreate.as_view(), name='stock-location-create'),
+
# Individual stock items
- url(r'^(?P\d+)/', include(stock_detail_urls)),
+ url(r'^item/(?P\d+)/', include(stock_item_detail_urls)),
- url('list', views.index, name='stock-index'),
+ url(r'^item/new/', views.StockItemCreate.as_view(), name='stock-item-create'),
- # Redirect any other patterns
- url(r'^.*$', RedirectView.as_view(url='list', permanent=False), name='stock-index'),
+ url(r'^.*$', views.StockIndex.as_view(), name='stock-index'),
]
\ No newline at end of file
diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py
index 64dd293b84..7d42045a80 100644
--- a/InvenTree/stock/views.py
+++ b/InvenTree/stock/views.py
@@ -1,43 +1,95 @@
-from django.http import HttpResponse
-from django.template import loader
-
from django.shortcuts import get_object_or_404, render
+from django.http import HttpResponseRedirect
+from django.urls import reverse
+
+from django.views.generic import DetailView, ListView
+from django.views.generic.edit import UpdateView, DeleteView, CreateView
+
from .models import StockItem, StockLocation
-def index(request):
- template = loader.get_template('stock/index.html')
+from .forms import EditStockLocationForm
+from .forms import EditStockItemForm
- items = StockItem.objects.all()
+class StockIndex(ListView):
+ model = StockItem
+ template_name = 'stock/index.html'
+ context_obect_name = 'items'
+ paginate_by = 50
- location = None
+ def get_queryset(self):
+ return StockItem.objects.filter(location=None)
- if 'location' in request.GET:
- loc_id = request.GET['location']
+ def get_context_data(self, **kwargs):
+ context = super(StockIndex, self).get_context_data(**kwargs).copy()
- location = get_object_or_404(StockLocation, pk=loc_id)
+ locations = StockLocation.objects.filter(parent=None)
- items = items.filter(location = loc_id)
+ context['locations'] = locations
- children = StockLocation.objects.filter(parent = loc_id)
+ return context
- else:
- # No stock items can exist without a location
- items = None
- location = None
- children = StockLocation.objects.filter(parent__isnull=True)
-
- context = {
- 'items' : items,
- 'location' : location,
- 'children' : children,
- }
-
- return HttpResponse(template.render(context, request))
+class StockLocationDetail(DetailView):
+ context_object_name = 'location'
+ template_name = 'stock/location.html'
+ queryset = StockLocation.objects.all()
+ model = StockLocation
-def detail(request, pk):
+class StockItemDetail(DetailView):
+ context_object_name = 'item'
+ template_name = 'stock/item.html'
+ queryset = StockItem.objects.all()
+ model = StockItem
- stock = get_object_or_404(StockItem, pk=pk)
- return render(request, 'stock/detail.html', {'item' : stock})
\ No newline at end of file
+class StockLocationEdit(UpdateView):
+ model = StockLocation
+ form_class = EditStockLocationForm
+ template_name = '/stock/location-edit.html'
+ context_object_name = 'location'
+
+
+class StockItemEdit(UpdateView):
+ model = StockItem
+ form_class = EditStockItemForm
+ template_name = '/stock/item-edit.html'
+ context_object_name = 'item'
+
+
+class StockLocationCreate(CreateView):
+ model = StockLocation
+ form_class = EditStockLocationForm
+ template_name = '/stock/location-create.html'
+ context_object_name = 'location'
+
+
+class StockItemCreate(CreateView):
+ model = StockItem
+ form_class = EditStockItemForm
+ template_name = '/stock/item-create.html'
+ context_object_name = 'item'
+
+
+class StockLocationDelete(DeleteView):
+ model = StockLocation
+ success_url = '/stock/'
+ template_name = '/stock/location-delete.html'
+
+ def post(self, request, *args, **kwargs):
+ if 'confirm' in request.POST:
+ return super(StockLocationDelete, self).post(request, *args, **kwargs)
+ else:
+ return HttpResponseRedirect(self.get_object().get_absolute_url())
+
+
+class StockItemDelete(DeleteView):
+ model = StockLocation
+ success_url = '/stock/'
+ template_name = '/stock/item-delete.html'
+
+ def post(self, request, *args, **kwargs):
+ if 'confirm' in request.POST:
+ return super(StockItemDelete, self).post(request, *args, **kwargs)
+ else:
+ return HttpResponseRedirect(self.get_object().get_absolute_url())
\ No newline at end of file
diff --git a/InvenTree/supplier/migrations/0006_auto_20180415_1011.py b/InvenTree/supplier/migrations/0006_auto_20180415_1011.py
new file mode 100644
index 0000000000..e55a81e7d3
--- /dev/null
+++ b/InvenTree/supplier/migrations/0006_auto_20180415_1011.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2018-04-15 10:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('supplier', '0005_auto_20180415_0255'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='supplierpart',
+ name='manufacturer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='supplier.Manufacturer'),
+ ),
+ migrations.AlterField(
+ model_name='supplierpart',
+ name='part',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplier_parts', to='part.Part'),
+ ),
+ ]
diff --git a/Makefile b/Makefile
index 69419db9e8..ac9cb51062 100644
--- a/Makefile
+++ b/Makefile
@@ -16,11 +16,9 @@ test:
migrate:
python InvenTree/manage.py makemigrations part
- python InvenTree/manage.py makemigrations bom
- # python InvenTree/manage.py makemigrations project
python InvenTree/manage.py makemigrations stock
python InvenTree/manage.py makemigrations supplier
- # python InvenTree/manage.py makemigrations track
+ python InvenTree/manage.py makemigrations track
python InvenTree/manage.py migrate --run-syncdb
python InvenTree/manage.py check