mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Added supplier web interface
- Display list of suppliers - Supplier detail page - Supplier part detail page - Part detail now includes list of supplier parts
This commit is contained in:
parent
ce854e3119
commit
6a98846a8f
@ -13,6 +13,7 @@ class Company(models.Model):
|
||||
abstract = True
|
||||
|
||||
name = models.CharField(max_length=100, unique=True)
|
||||
description = models.CharField(max_length=500, blank=True)
|
||||
website = models.URLField(blank=True)
|
||||
address = models.CharField(max_length=200,
|
||||
blank=True)
|
||||
|
@ -11,7 +11,8 @@ from part.urls import part_urls
|
||||
from stock.urls import stock_api_urls, stock_api_loc_urls
|
||||
from stock.urls import stock_urls
|
||||
|
||||
from supplier.urls import cust_urls, manu_urls, supplier_part_urls, price_break_urls, supplier_urls
|
||||
from supplier.urls import supplier_api_urls, supplier_api_part_urls
|
||||
from supplier.urls import supplier_urls
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
@ -41,11 +42,11 @@ apipatterns = [
|
||||
url(r'^bom/', include(bom_api_urls)),
|
||||
|
||||
# Supplier URLs
|
||||
url(r'^supplier/', include(supplier_urls)),
|
||||
url(r'^supplier-part/', include(supplier_part_urls)),
|
||||
url(r'^price-break/', include(price_break_urls)),
|
||||
url(r'^manufacturer/', include(manu_urls)),
|
||||
url(r'^customer/', include(cust_urls)),
|
||||
url(r'^supplier/', include(supplier_api_urls)),
|
||||
url(r'^supplier-part/', include(supplier_api_part_urls)),
|
||||
#url(r'^price-break/', include(price_break_urls)),
|
||||
#url(r'^manufacturer/', include(manu_urls)),
|
||||
#url(r'^customer/', include(cust_urls)),
|
||||
|
||||
# Tracking URLs
|
||||
#url(r'^track/', include(part_track_urls)),
|
||||
@ -69,6 +70,8 @@ urlpatterns = [
|
||||
url(r'^part/', include(part_urls)),
|
||||
url(r'^stock/', include(stock_urls)),
|
||||
|
||||
url(r'^supplier/', include(supplier_urls)),
|
||||
|
||||
url(r'^api-doc/', include_docs_urls(title='InvenTree API')),
|
||||
|
||||
url(r'^admin/', admin.site.urls),
|
||||
|
@ -9,10 +9,18 @@ Used in {{ part.usedInCount }} other parts.<br>
|
||||
|
||||
<a href="{% url 'part-stock' part.id %}">There are {{ part.stock }} units in stock.</a>
|
||||
|
||||
<br>
|
||||
{% if part.supplier_parts.all|length > 0 %}
|
||||
This part is available from <a href="{% url 'part-suppliers' part.id %}">{{ part.supplier_parts.all|length }} suppliers</a>.
|
||||
{% else %}
|
||||
There are no suppliers defined for this part.
|
||||
{% endif %}
|
||||
|
||||
<br><br>
|
||||
{% if part.trackable %}
|
||||
<a href="{% url 'part-track' part.id %}">Part tracking</a>
|
||||
{% else %}
|
||||
{{ part.name }} does not have part tracking enabled
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -20,7 +20,9 @@ Total in stock: {{ part.stock }}
|
||||
<td><a href="/stock/list/?location={{ stock.location.id }}">{{ stock.location.name }}</a></td>
|
||||
<td>
|
||||
{% if stock.supplier_part %}
|
||||
<a href="{% url 'supplier-part-detail' stock.supplier_part.id %}">
|
||||
{{ stock.supplier_part.supplier.name }} | {{ stock.supplier_part.SKU }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{% if stock.stocktake_date %}{{ stock.stocktake_date }}{% endif %}</td>
|
||||
|
24
InvenTree/part/templates/part/supplier.html
Normal file
24
InvenTree/part/templates/part/supplier.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if part.supplier_parts.all|length > 0 %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Supplier</th>
|
||||
<th>SKU</th>
|
||||
<th>URL</th>
|
||||
</tr>
|
||||
{% for spart in part.supplier_parts.all %}
|
||||
<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>{{ spart.URL }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
There are no suppliers defined for this part, sorry!
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -42,6 +42,7 @@ part_detail_urls = [
|
||||
url(r'^track/?', views.track, name='part-track'),
|
||||
url(r'^bom/?', views.bom, name='part-bom'),
|
||||
url(r'^stock/?', views.stock, name='part-stock'),
|
||||
url(r'^suppliers/?', views.suppliers, name='part-suppliers'),
|
||||
url('', views.detail, name='part-detail'),
|
||||
]
|
||||
|
||||
|
@ -64,3 +64,8 @@ def track(request, pk):
|
||||
|
||||
return render(request, 'part/track.html', {'part': part})
|
||||
|
||||
|
||||
def suppliers(request, pk):
|
||||
part = get_object_or_404(Part, pk=pk)
|
||||
|
||||
return render(request, 'part/supplier.html', {'part' : part})
|
||||
|
@ -7,7 +7,7 @@
|
||||
<ul>
|
||||
<li>Part: <a href="{% url 'part-detail' item.part.id %}">{{ item.part.name }}</a></li>
|
||||
{% if item.supplier_part %}
|
||||
<li>Supplier Part: {{ item.supplier_part.supplier.name }} | {{ item.supplier_part.SKU }}</li>
|
||||
<li>Supplier Part: <a href="{% url 'supplier-part-detail' item.supplier_part.id %}">{{ item.supplier_part.supplier.name }} | {{ item.supplier_part.SKU }}</a></li>
|
||||
{% endif %}
|
||||
<li>Quantity: {{ item.quantity }}</li>
|
||||
{% if item.stocktake_date %}
|
||||
|
@ -38,7 +38,7 @@ stock_urls = [
|
||||
# Individual stock items
|
||||
url(r'^(?P<pk>\d+)/', include(stock_detail_urls)),
|
||||
|
||||
url('list', views.index, name='stock=index'),
|
||||
url('list', views.index, name='stock-index'),
|
||||
|
||||
# Redirect any other patterns
|
||||
url(r'^.*$', RedirectView.as_view(url='list', permanent=False), name='stock-index'),
|
||||
|
@ -40,7 +40,10 @@ class SupplierPart(models.Model):
|
||||
part = models.ForeignKey(Part, null=True, blank=True, on_delete=models.CASCADE,
|
||||
related_name='supplier_parts')
|
||||
|
||||
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
|
||||
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE,
|
||||
related_name = 'parts')
|
||||
|
||||
|
||||
SKU = models.CharField(max_length=100)
|
||||
|
||||
manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True, on_delete=models.CASCADE)
|
||||
|
34
InvenTree/supplier/templates/supplier/detail.html
Normal file
34
InvenTree/supplier/templates/supplier/detail.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<ul>
|
||||
<li>Name: {{ supplier.name }}</li>
|
||||
<li>Description: {{ supplier.description }}</li>
|
||||
<li>Website: {{ supplier.website }}</li>
|
||||
<li>Contact: {{ supplier.contact }}</li>
|
||||
</li>
|
||||
|
||||
{% if supplier.parts.all|length > 0 %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Part</th>
|
||||
<th>SKU</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>MPN</th>
|
||||
<th>URL</th>
|
||||
</tr>
|
||||
{% for part in supplier.parts.all %}
|
||||
<tr>
|
||||
<td><a href="{% url 'part-detail' part.part.id %}">{{ part.part.name }}</a></td>
|
||||
<td>{{ part.SKU }}</td>
|
||||
<td>Manufacturer name goes here</td>
|
||||
<td>MPN goes here</td>
|
||||
<td>{{ part.URL }}</td>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
There are currently no parts sourced from this supplier.
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
19
InvenTree/supplier/templates/supplier/index.html
Normal file
19
InvenTree/supplier/templates/supplier/index.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Supplier</th>
|
||||
<th>Description</th>
|
||||
<th>URL</th>
|
||||
</tr>
|
||||
{% for supplier in suppliers %}
|
||||
<tr>
|
||||
<td><a href="{% url 'supplier-detail' supplier.id %}">{{ supplier.name }}</a></td>
|
||||
<td>{{ supplier.description }}</td>
|
||||
<td>{{ supplier.website }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
14
InvenTree/supplier/templates/supplier/partdetail.html
Normal file
14
InvenTree/supplier/templates/supplier/partdetail.html
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<ul>
|
||||
<li>Part: <a href="{% url 'part-detail' part.part.id %}">{{ part.part.name }}</a></li>
|
||||
<li>Supplier: <a href="{% url 'supplier-detail' part.supplier.id %}">{{ part.supplier.name }}</a></li>
|
||||
<li>SKU: {{ part.SKU }}</li>
|
||||
<li>Manufacturer name goes here</li>
|
||||
<li>MPN goes here</li>
|
||||
<li>URL: {{ part.URL }}</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -1,4 +1,5 @@
|
||||
from django.conf.urls import url
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
from . import views
|
||||
from . import api
|
||||
@ -21,7 +22,7 @@ manu_urls = [
|
||||
url(r'^$', api.ManufacturerList.as_view())
|
||||
]
|
||||
|
||||
supplier_part_urls = [
|
||||
supplier_api_part_urls = [
|
||||
url(r'^(?P<pk>[0-9]+)/?$', api.SupplierPartDetail.as_view(), name='supplierpart-detail'),
|
||||
|
||||
url(r'^\?.*/?$', api.SupplierPartList.as_view()),
|
||||
@ -35,7 +36,7 @@ price_break_urls = [
|
||||
url(r'^$', api.SupplierPriceBreakList.as_view())
|
||||
]
|
||||
|
||||
supplier_urls = [
|
||||
supplier_api_urls = [
|
||||
|
||||
# Display details of a supplier
|
||||
url(r'^(?P<pk>[0-9]+)/$', api.SupplierDetail.as_view(), name='supplier-detail'),
|
||||
@ -44,3 +45,12 @@ supplier_urls = [
|
||||
url(r'^\?.*/?$', api.SupplierList.as_view()),
|
||||
url(r'^$', api.SupplierList.as_view())
|
||||
]
|
||||
|
||||
supplier_urls = [
|
||||
url(r'^(?P<pk>\d+)/', views.detail, name='supplier-detail'),
|
||||
url(r'^part/(?P<pk>\d+)/', views.partDetail, name='supplier-part-detail'),
|
||||
url(r'', views.index, name='supplier-index'),
|
||||
|
||||
# Redirect any other patterns
|
||||
url(r'^.*$', RedirectView.as_view(url='', permanent=False), name='supplier-index'),
|
||||
]
|
@ -0,0 +1,34 @@
|
||||
from django.http import HttpResponse
|
||||
from django.template import loader
|
||||
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
|
||||
from .models import Supplier, SupplierPart
|
||||
|
||||
def index(request):
|
||||
""" The supplier index page simply displays all the suppliers
|
||||
"""
|
||||
|
||||
suppliers = Supplier.objects.order_by('name')
|
||||
|
||||
return render(request, 'supplier/index.html', {'suppliers' : suppliers})
|
||||
|
||||
|
||||
def detail(request, pk):
|
||||
""" The supplier detail page shown detailed information
|
||||
on a particular supplier
|
||||
"""
|
||||
|
||||
supplier = get_object_or_404(Supplier, pk=pk)
|
||||
|
||||
return render(request, 'supplier/detail.html', {'supplier' : supplier})
|
||||
|
||||
|
||||
def partDetail(request, pk):
|
||||
""" The supplier part-detail page shows detailed information
|
||||
on a particular supplier part
|
||||
"""
|
||||
|
||||
part = get_object_or_404(SupplierPart, pk=pk)
|
||||
|
||||
return render(request, 'supplier/partdetail.html', {'part': part})
|
Loading…
Reference in New Issue
Block a user