bill of materials

add delete button

https://chat.openai.com/share/99cb92bf-404a-42f2-8346-fc87a89a4bba

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)

create static/js folder and store fetch_sales_order_info.js

(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'),

]

Last updated