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:
parent
3c844fc77f
commit
55b533d3ef
@ -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'
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 %}
|
||||||
|
@ -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 %}
|
@ -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>
|
||||||
|
@ -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)
|
||||||
|
@ -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 %}
|
5
InvenTree/stock/templates/stock/item_create.html
Normal file
5
InvenTree/stock/templates/stock/item_create.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "create_edit_obj.html" %}
|
||||||
|
|
||||||
|
{% block obj_title %}
|
||||||
|
Create a new stock item
|
||||||
|
{% endblock %}
|
9
InvenTree/stock/templates/stock/item_delete.html
Normal file
9
InvenTree/stock/templates/stock/item_delete.html
Normal 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 %}
|
5
InvenTree/stock/templates/stock/item_edit.html
Normal file
5
InvenTree/stock/templates/stock/item_edit.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "create_edit_obj.html" %}
|
||||||
|
|
||||||
|
{% block obj_title %}
|
||||||
|
Edit stock item for part '{{ item.part.name }}'
|
||||||
|
{% endblock %}
|
@ -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 %}
|
5
InvenTree/stock/templates/stock/location_create.html
Normal file
5
InvenTree/stock/templates/stock/location_create.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "create_edit_obj.html" %}
|
||||||
|
|
||||||
|
{% block obj_title %}
|
||||||
|
Create a new stock location
|
||||||
|
{% endblock %}
|
41
InvenTree/stock/templates/stock/location_delete.html
Normal file
41
InvenTree/stock/templates/stock/location_delete.html
Normal 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 %}
|
5
InvenTree/stock/templates/stock/location_edit.html
Normal file
5
InvenTree/stock/templates/stock/location_edit.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% extends "create_edit_obj.html" %}
|
||||||
|
|
||||||
|
{% block obj_title %}
|
||||||
|
Edit stock location '{{ location.name }}'
|
||||||
|
{% endblock %}
|
@ -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>
|
||||||
|
@ -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'),
|
||||||
]
|
]
|
@ -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:
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user