summaryrefslogtreecommitdiff
path: root/procurement
diff options
context:
space:
mode:
Diffstat (limited to 'procurement')
-rw-r--r--procurement/api.py16
-rw-r--r--procurement/forms.py20
-rw-r--r--procurement/serializers.py11
-rw-r--r--procurement/templates/procurement/documentation.html7
-rw-r--r--procurement/templates/procurement/includes/supplier_details.html51
-rw-r--r--procurement/templates/procurement/view_suppliers.html35
-rw-r--r--procurement/urls.py8
-rw-r--r--procurement/views.py22
8 files changed, 158 insertions, 12 deletions
diff --git a/procurement/api.py b/procurement/api.py
index 0419ce8..d1830c2 100644
--- a/procurement/api.py
+++ b/procurement/api.py
@@ -1,7 +1,7 @@
from rest_framework.generics import ListAPIView, RetrieveAPIView
-from procurement.models import Component
-from procurement.serializers import ComponentSerializer
+from procurement.models import Component, Supplier
+from procurement.serializers import ComponentSerializer, SupplierSerializer, SupplierComponentsSerializer
class ComponentAPIList(ListAPIView):
@@ -12,3 +12,15 @@ class ComponentAPIList(ListAPIView):
class ComponentAPIRetrieve(RetrieveAPIView):
queryset = Component.objects.all()
serializer_class = ComponentSerializer
+
+class SupplierAPIList(ListAPIView):
+ queryset = Supplier.objects.filter(is_authorized=True)
+ serializer_class = SupplierSerializer
+
+class SupplierAPIRetrieve(RetrieveAPIView):
+ queryset = Supplier.objects.filter(is_authorized=True)
+ serializer_class = SupplierSerializer
+
+class SupplierAPIComponents(RetrieveAPIView):
+ queryset = Supplier.objects.filter(is_authorized=True)
+ serializer_class = SupplierComponentsSerializer
diff --git a/procurement/forms.py b/procurement/forms.py
index 4e8b0aa..0aeca9b 100644
--- a/procurement/forms.py
+++ b/procurement/forms.py
@@ -1,14 +1,24 @@
from django import forms
-from procurement.models import Component
+from procurement.models import Component, Supplier
+class FormControlBase(forms.Form):
+ _formcontrol_fields = []
+ def __init__(self, *args, **kwargs):
+ super(FormControlBase, self).__init__(*args, **kwargs)
+ for fieldname in self._formcontrol_fields:
+ self.fields[fieldname].widget.attrs.update({"class": "form-control"})
-class ComponentSearchForm(forms.Form):
+class ComponentSearchForm(FormControlBase):
+ _formcontrol_fields = ["component"]
component = forms.ModelChoiceField(
queryset=Component.objects.all(),
required=False
)
- def __init__(self, *args, **kwargs):
- super(ComponentSearchForm, self).__init__(*args, **kwargs)
- self.fields['component'].widget.attrs.update({"class": "form-control"})
+class SupplierSearchForm(FormControlBase):
+ _formcontrol_fields = ["supplier"]
+ supplier = forms.ModelChoiceField(
+ queryset=Supplier.objects.filter(is_authorized=True),
+ required=False
+ )
diff --git a/procurement/serializers.py b/procurement/serializers.py
index 0466402..b3e9280 100644
--- a/procurement/serializers.py
+++ b/procurement/serializers.py
@@ -13,6 +13,17 @@ class SupplierSerializer(serializers.ModelSerializer):
model = Supplier
exclude = ('created', 'updated')
+class SupplierComponentSerializer(serializers.ModelSerializer):
+ text = serializers.CharField(source="__str__", read_only=True)
+ class Meta:
+ model = Component
+ exclude = ('created', 'updated')
+
+class SupplierComponentsSerializer(serializers.ModelSerializer):
+ components = SupplierComponentSerializer(many=True, read_only=True)
+ class Meta:
+ model = Supplier
+ exclude = ('created', 'updated')
class ComponentSerializer(serializers.ModelSerializer):
text = serializers.CharField(source='__str__', read_only=True)
diff --git a/procurement/templates/procurement/documentation.html b/procurement/templates/procurement/documentation.html
index 4775890..f482a1d 100644
--- a/procurement/templates/procurement/documentation.html
+++ b/procurement/templates/procurement/documentation.html
@@ -55,7 +55,9 @@
<p>
Components and their approved Suppliers can be located under
<a href="{% url 'component-search' %}">source components</a>. From this page you may search for a
- component, and then click the Find Suppliers button to display its Suppliers
+ component, and then click the Find Suppliers button to display its Suppliers.
+ You can also view details for any authorized Supplier in the system directly under
+ <a href="{% url 'supplier-search' %}">view suppliers</a>.
</p>
<h2><a name="api"></a>API</h2>
@@ -63,6 +65,7 @@
A simple REST api is integrated into the system, using the <a href="https://www.django-rest-framework.org/">Django Rest Framework</a>.
It provides a means of querying <a href="{% url 'api-component-list' %}">all components</a> or, by providing an id
in the url, <a href="{% url 'api-component-retrieve' pk=1 %}">a specific component</a>.
+ You may also use the API to query <a href="{% url 'api-supplier-list' %}">all authorized suppliers</a>, <a href="{% url 'api-supplier-retrieve' pk=1 %}">a specific supplier</a> by providing an id, or <a href="{% url 'api-supplier-components' pk=1 %}">the components a specific supplier provides</a>.
</p>
</div>
<!-- /.panel-body -->
@@ -73,4 +76,4 @@
-{% endblock %} \ No newline at end of file
+{% endblock %}
diff --git a/procurement/templates/procurement/includes/supplier_details.html b/procurement/templates/procurement/includes/supplier_details.html
new file mode 100644
index 0000000..0e46c67
--- /dev/null
+++ b/procurement/templates/procurement/includes/supplier_details.html
@@ -0,0 +1,51 @@
+<!-- Supplier Details -->
+<div class="panel panel-default">
+ <div class="panel-heading">
+ Supplier information for {{ supplier.name }}
+ </div>
+ <!-- /.panel-heading -->
+ <div class="panel-body">
+ <div class="table-responsive">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Representative</th>
+ <th>Email</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for representative in supplier.representatives.all %}
+ <tr>
+ <td>{{ representative.name }}</td>
+ <td>{{ representative.email }}</td>
+ </tr>
+ {% empty %}
+ <tr>
+ <td colspan="2">{{ supplier_name }} has no representatives</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ <!-- /.table-responsive -->
+ </div>
+ <!-- /.panel-body -->
+</div>
+<!-- / Supplier Details Panel -->
+<!-- Components Supplied by Panel -->
+<div class="panel panel-default">
+ <div class="panel-heading">
+ Components Supplied by {{ supplier.name }}
+ </div>
+ <div class="panel-body">
+ <form id="find-suppliers" method="post" action="{% url 'component-search' %}">
+ <div class="form-group">
+ {% csrf_token %}
+ {{ component_form }}
+ </div>
+ <div class="form-group">
+ <input type="submit" value="View Other Suppliers" id="find-suppliers-button" class="btn btn-secondary">
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/procurement/templates/procurement/view_suppliers.html b/procurement/templates/procurement/view_suppliers.html
new file mode 100644
index 0000000..918ce62
--- /dev/null
+++ b/procurement/templates/procurement/view_suppliers.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% load static %}
+
+{% block additional_css %}
+ <link href="{% static 'procurement/css/suppliers.css' %}" rel="stylesheet" type="text/css">
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
+{% endblock %}
+
+{% block main_content_area %}
+ <div class="col-lg-8">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <form id="supplier-info" method="post">
+ <div class="form-group">
+ {% csrf_token %}
+ {{ form }}
+ </div>
+ <div class="form-group">
+ <input type="submit" value="View Supplier Information" id="view-supplier-button" class="btn btn-primary">
+ </div>
+ </form>
+ </div>
+ <!-- /.panel-body -->
+ </div>
+ <!-- /.panel -->
+ {% if supplier != None %}
+ {% include 'procurement/includes/supplier_details.html' %}
+ {% endif %}
+ </div>
+{% endblock %}
+
+{% block additional_js %}
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
+ <script src="{% static 'procurement/js/component_search.js' %}"></script>
+{% endblock %}
diff --git a/procurement/urls.py b/procurement/urls.py
index d629635..be721ae 100644
--- a/procurement/urls.py
+++ b/procurement/urls.py
@@ -1,12 +1,16 @@
from django.urls import path
-from procurement.views import ComponentSearchView, DocumentationView
-from procurement.api import ComponentAPIList, ComponentAPIRetrieve
+from procurement.views import ComponentSearchView, SupplierSearchView, DocumentationView
+from procurement.api import ComponentAPIList, ComponentAPIRetrieve, SupplierAPIList, SupplierAPIRetrieve, SupplierAPIComponents
urlpatterns = [
path('', ComponentSearchView.as_view(), name='component-search'),
+ path('suppliers', SupplierSearchView.as_view(), name='supplier-search'),
path('documentation', DocumentationView.as_view(), name='documentation'),
# API Urls
path('api/components/', ComponentAPIList.as_view(), name='api-component-list'),
path('api/components/<int:pk>/', ComponentAPIRetrieve.as_view(), name='api-component-retrieve'),
+ path('api/suppliers/', SupplierAPIList.as_view(), name='api-supplier-list'),
+ path('api/suppliers/<int:pk>/', SupplierAPIRetrieve.as_view(), name='api-supplier-retrieve'),
+ path('api/suppliers/<int:pk>/components', SupplierAPIComponents.as_view(), name='api-supplier-components'),
]
diff --git a/procurement/views.py b/procurement/views.py
index 1516455..c1e66c9 100644
--- a/procurement/views.py
+++ b/procurement/views.py
@@ -1,6 +1,6 @@
from django.views.generic import FormView, TemplateView
-from procurement.forms import ComponentSearchForm
+from procurement.forms import ComponentSearchForm, SupplierSearchForm
from procurement.models import Supplier, Component, Representative
@@ -49,6 +49,26 @@ class ComponentSearchView(FormView):
return super(ComponentSearchView, self).get(self.request)
+class SupplierSearchView(FormView):
+ template_name = "procurement/view_suppliers.html"
+ form_class = SupplierSearchForm
+
+ supplier = None
+ component_form = None
+
+ def form_valid(self, form):
+ self.supplier = form.cleaned_data['supplier']
+ if self.supplier:
+ self.component_form = ComponentSearchForm()
+ self.component_form.fields["component"].queryset = self.supplier.components
+ return super(SupplierSearchView, self).get(self.request)
+
+ def get_context_data(self):
+ context = super().get_context_data()
+ context["supplier"] = self.supplier
+ context["component_form"] = self.component_form
+ context["page_name"] = "View Supplier Details"
+ return context
class DocumentationView(TemplateView):
template_name = 'procurement/documentation.html'