BOM now uses DRF / ajax

This commit is contained in:
Oliver 2018-05-02 23:42:57 +10:00
parent be0797c6e6
commit 7d21c4ef1c
4 changed files with 103 additions and 31 deletions

View File

@ -7,8 +7,8 @@ from rest_framework import generics, permissions
from django.conf.urls import url from django.conf.urls import url
from .models import Part, PartCategory from .models import Part, PartCategory, BomItem
from .serializers import PartSerializer from .serializers import PartSerializer, BomItemSerializer
from InvenTree.views import TreeSerializer from InvenTree.views import TreeSerializer
@ -49,9 +49,31 @@ class PartList(generics.ListCreateAPIView):
] ]
class BomList(generics.ListAPIView):
queryset = BomItem.objects.all()
serializer_class = BomItemSerializer
permission_classes = [
permissions.IsAuthenticatedOrReadOnly,
]
filter_backends = [
DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
]
filter_fields = [
'part',
'sub_part'
]
part_api_urls = [ part_api_urls = [
url(r'^tree/?', PartCategoryTree.as_view(), name='api-part-tree'), url(r'^tree/?', PartCategoryTree.as_view(), name='api-part-tree'),
url(r'^bom/?', BomList.as_view(), name='api-bom-list'),
url(r'^.*$', PartList.as_view(), name='api-part-list'), url(r'^.*$', PartList.as_view(), name='api-part-list'),
] ]

View File

@ -1,6 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Part, PartCategory from .models import Part, PartCategory, BomItem
class CategoryBriefSerializer(serializers.ModelSerializer): class CategoryBriefSerializer(serializers.ModelSerializer):
@ -12,6 +12,7 @@ class CategoryBriefSerializer(serializers.ModelSerializer):
fields = [ fields = [
'pk', 'pk',
'name', 'name',
'description',
'pathstring', 'pathstring',
'url', 'url',
] ]
@ -27,6 +28,7 @@ class PartBriefSerializer(serializers.ModelSerializer):
'pk', 'pk',
'url', 'url',
'name', 'name',
'description',
] ]
@ -35,6 +37,7 @@ class PartSerializer(serializers.ModelSerializer):
Used when displaying all details of a single component. Used when displaying all details of a single component.
""" """
url = serializers.CharField(source='get_absolute_url', read_only=True)
category = CategoryBriefSerializer(many=False, read_only=True) category = CategoryBriefSerializer(many=False, read_only=True)
class Meta: class Meta:
@ -55,3 +58,21 @@ class PartSerializer(serializers.ModelSerializer):
'trackable', 'trackable',
'salable', 'salable',
] ]
class BomItemSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
part = PartBriefSerializer(many=False, read_only=True)
sub_part = PartBriefSerializer(many=False, read_only=True)
class Meta:
model = BomItem
fields = [
'pk',
'url',
'part',
'sub_part',
'quantity'
]

View File

@ -11,30 +11,7 @@
<h3>Bill of Materials</h3> <h3>Bill of Materials</h3>
<table class="table table-striped" id='bom-table' data-filtering='true' data-sorting='true'> <table class='table table-striped table-condensed' id='bom-table'>
<thead>
<tr>
<th>Part</th>
<th>Description</th>
<th data-type='number'>Quantity</th>
<th data-sortable='false'></th>
</tr>
</thead>
<tbody>
{% for bom_item in part.bom_items.all %}
{% with sub_part=bom_item.sub_part %}
<tr>
<td><a href="{% url 'part-detail' sub_part.id %}">{{ sub_part.name }}</a></td>
<td>{{ sub_part.description }}</td>
<td>{{ bom_item.quantity }}</td>
<td>
<button type='button' url="{% url 'bom-item-edit' bom_item.id %}" class='btn btn-success edit-row-button'>Edit</button>
<button type='button' url="{% url 'bom-item-delete' bom_item.id %}" class='btn btn-danger delete-row-button'>Delete</button>
</td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table> </table>
<div class='container-fluid'> <div class='container-fluid'>
@ -48,7 +25,7 @@
{% endblock %} {% endblock %}
{% block js_ready %} {% block js_ready %}
$('#bom-table').on('click', '.delete-row-button', function () { $('#bom-table').on('click', '.delete-button', function () {
var button = $(this); var button = $(this);
launchDeleteForm("#modal-delete", launchDeleteForm("#modal-delete",
@ -58,11 +35,14 @@
}); });
}); });
$('#bom-table').on('click', '.edit-row-button', function () { $("#bom-table").on('click', '.edit-button', function () {
var button = $(this); var button = $(this);
launchModalForm("#modal-form", launchModalForm("#modal-form",
button.attr('url')); button.attr('url'),
{
reload: true
});
}); });
@ -76,4 +56,45 @@
} }
}); });
}); });
$("#bom-table").bootstrapTable({
sortable: true,
search: true,
queryParams: function(p) {
return {
part: {{ part.id }}
}
},
columns: [
{
field: 'pk',
title: 'ID',
visible: false,
},
{
field: 'sub_part',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value.name, value.url);
}
},
{
field: 'sub_part.description',
title: 'Description',
},
{
field: 'quantity',
title: 'Quantity',
searchable: false,
sortable: true
},
{
formatter: function(value, row, index, field) {
return editButton(row.url + 'edit') + ' ' + deleteButton(row.url + 'delete');
}
}
],
url: "{% url 'api-bom-list' %}"
});
{% endblock %} {% endblock %}

View File

@ -1,3 +1,11 @@
function editButton(url, text='Edit') {
return "<button class='btn btn-success edit-button' type='button' url='" + url + "'>" + text + "</button>";
}
function deleteButton(url, text='Delete') {
return "<button class='btn btn-danger delete-button' type='button' url='" + url + "'>" + text + "</button>";
}
function renderLink(text, url) { function renderLink(text, url) {
if (text && url) { if (text && url) {
return '<a href="' + url + '">' + text + '</a>'; return '<a href="' + url + '">' + text + '</a>';