bill of materials
Last updated
Last updated
add delete button
settings.py
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
STATIC_ROOT=(BASE_DIR/ "assets/")
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'assets/media/')
models.py
class BillOfMaterials(models.Model):
code = models.CharField(max_length=20)
name = models.CharField(max_length=100)
bomtype = models.CharField(max_length=20)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
class ChildComponent(models.Model):
bill_of_materials = models.ForeignKey(BillOfMaterials, on_delete=models.CASCADE, related_name='child_components')
code = models.CharField(max_length=20)
name = models.CharField(max_length=100)
uom = models.CharField(max_length=20)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
class Production(models.Model):
name = models.CharField(max_length=100)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
def __str__(self):
return self.name
class ProductionComponent(models.Model):
production = models.ForeignKey(Production, on_delete=models.CASCADE, related_name='production_components')
code = models.CharField(max_length=20)
name = models.CharField(max_length=100)
uom = models.CharField(max_length=20)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
def __str__(self):
return self.name
admin.py
from django.contrib import admin
from django.forms import inlineformset_factory
from .models import (
BillOfMaterials,
ChildComponent,
Production,
ProductionComponent
)
# Bill Of Materials
class ChildComponentInline(admin.TabularInline):
model = ChildComponent
class BillOfMaterialsAdmin(admin.ModelAdmin):
inlines = [ChildComponentInline]
admin.site.register(BillOfMaterials, BillOfMaterialsAdmin)
# Production Order
class ProductionComponentInline(admin.TabularInline):
model = ProductionComponent
class ProductionAdmin(admin.ModelAdmin):
inlines = [ProductionComponentInline]
class Media:
js = ('js/fetch_sales_order_info.js',)
defer = True # Add the defer attribute
admin.site.register(Production, ProductionAdmin)
(function ($) {
$(document).ready(function(){
$('#id_name, #id_quantity').on('change',function(){
var initialname = $('#id_name').val();
var initialquantity = $('#id_quantity').val();
if (initialname.trim() !== '' && initialquantity.trim() !== '') {
$.ajax({
type: 'POST',
url: '/library/ajax/',
data: {
'name': initialname,
'quantity': initialquantity
},
dataType: 'json',
success: function(response){
updateFormset(response);
// $('#id_production_components-0-quantity').val(response.quantity);
}
});
}
});
function updateFormset(data) {
var formsetTable = $('table');
formsetTable.empty();
// Add table header
var tableHeader = $('<thead>').appendTo(formsetTable);
var headerRow = $('<tr>').appendTo(tableHeader);
$('<th>').addClass('column-code required').text('Code').appendTo(headerRow);
$('<th>').addClass('column-name required').text('Name').appendTo(headerRow);
$('<th>').addClass('column-uom required').text('Uom').appendTo(headerRow);
$('<th>').addClass('column-quantity required').text('Quantity').appendTo(headerRow);
$('<th>').text('Delete?').appendTo(headerRow);
// Add table body
var tableBody = $('<tbody>').appendTo(formsetTable);
data.forEach(function (component, index) {
var row = $('<tr>');
var codeCell = $('<td>');
var codeInput = $('<input type="text" maxlength="20" class="vTextField">');
codeInput.attr('name', 'production_components-' + index + '-code');
codeInput.val(component.code);
codeCell.append(codeInput);
var nameCell = $('<td>');
var nameInput = $('<input type="text" maxlength="100" class="vTextField">');
nameInput.attr('name', 'production_components-' + index + '-name');
nameInput.val(component.name);
nameCell.append(nameInput);
var uomCell = $('<td>');
var uomInput = $('<input type="text" maxlength="20" class="vTextField">');
uomInput.attr('name', 'production_components-' + index + '-uom');
uomInput.val(component.uom);
uomCell.append(uomInput);
var quantityCell = $('<td>');
var quantityInput = $('<input type="number" min="0" step="0.0001" required>');
quantityInput.attr('name', 'production_components-' + index + '-quantity');
quantityInput.val(component.quantity);
quantityCell.append(quantityInput);
var deleteCell = $('<td>');
var deleteButton = $('<button>').text('Delete');
deleteButton.addClass('delete-button');
deleteButton.on('click', function() {
// Handle delete button click
row.remove();
});
deleteCell.append(deleteButton);
row.append(codeCell, nameCell, uomCell, quantityCell,deleteCell);
formsetTable.append(row);
});
}
});
})(jQuery);
views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import BillOfMaterials
@csrf_exempt
def ajax_view(request):
if request.method == 'POST':
production_name = request.POST.get('name')
production_quantity = request.POST.get('quantity')
bill_of_materials = BillOfMaterials.objects.filter(name=production_name).first()
if bill_of_materials:
child_components = bill_of_materials.child_components.all()
updated_components = []
for component in child_components:
if bill_of_materials.quantity == production_quantity:
updated_quantity = float(component.quantity)
else:
updated_quantity = float(component.quantity) * (float(production_quantity) / float(bill_of_materials.quantity))
updated_quantity = format(updated_quantity, '.4f')
updated_components.append({
'id': component.id,
'code': component.code,
'name': component.name,
'uom': component.uom,
'quantity': updated_quantity
})
return JsonResponse(updated_components, safe=False)
return JsonResponse([], safe=False)
urls.py
from django.urls import path
from .views import ajax_view
urlpatterns = [
path('ajax/', ajax_view, name='ajax_view'),
]