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 .models import Part, PartCategory
from .serializers import PartSerializer
from .models import Part, PartCategory, BomItem
from .serializers import PartSerializer, BomItemSerializer
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 = [
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'),
]

View File

@ -1,6 +1,6 @@
from rest_framework import serializers
from .models import Part, PartCategory
from .models import Part, PartCategory, BomItem
class CategoryBriefSerializer(serializers.ModelSerializer):
@ -12,6 +12,7 @@ class CategoryBriefSerializer(serializers.ModelSerializer):
fields = [
'pk',
'name',
'description',
'pathstring',
'url',
]
@ -27,6 +28,7 @@ class PartBriefSerializer(serializers.ModelSerializer):
'pk',
'url',
'name',
'description',
]
@ -35,6 +37,7 @@ class PartSerializer(serializers.ModelSerializer):
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)
class Meta:
@ -55,3 +58,21 @@ class PartSerializer(serializers.ModelSerializer):
'trackable',
'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>
<table class="table table-striped" id='bom-table' data-filtering='true' data-sorting='true'>
<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 class='table table-striped table-condensed' id='bom-table'>
</table>
<div class='container-fluid'>
@ -47,8 +24,8 @@
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% endblock %}
{% block js_ready %}
$('#bom-table').on('click', '.delete-row-button', function () {
$('#bom-table').on('click', '.delete-button', function () {
var button = $(this);
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);
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 %}

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) {
if (text && url) {
return '<a href="' + url + '">' + text + '</a>';