183 lines
7.8 KiB
HTML
183 lines
7.8 KiB
HTML
{% extends "base.html" %}
|
|
{% load crispy_forms_filters %}
|
|
{% load i18n static %}
|
|
|
|
{% block title %}{{ _("Create Estimate") }}{% endblock title %}
|
|
|
|
{% block content %}
|
|
<div class="container mt-4">
|
|
<h3 class="text-center">{% trans "Create Estimate" %}</h3>
|
|
<form id="mainForm" method="post" class="needs-validation" novalidate>
|
|
{% csrf_token %}
|
|
<div class="row g-3">
|
|
{{ form|crispy }}
|
|
<div class="container mt-5">
|
|
<div id="formContainer">
|
|
<h3 class="text-start">Unit Items</h3>
|
|
<div class="form-container row g-3 mb-3 mt-5">
|
|
<div class="mb-2 col-sm-2">
|
|
<select class="form-control item" name="item[]" required>
|
|
{% for item in items %}
|
|
<option value="{{ item.pk }}">{{ item.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control quantity" type="number" placeholder="Quantity" name="quantity[]" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control unitCost" type="number" placeholder="Unit Cost" name="unitCost[]" step="0.01" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control unitSalesPrice" type="number" placeholder="Unit Sales Price" name="unitSalesPrice[]" step="0.01" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control totalCost" type="number" placeholder="Total Cost" name="totalCost[]" readonly>
|
|
</div>
|
|
<div class="mb-2 col-sm-1">
|
|
<input class="form-control totalRevenue" type="number" placeholder="Total Revenue" name="totalRevenue[]" readonly>
|
|
</div>
|
|
<div class="mb-2 col-sm-1">
|
|
<button class="btn btn-danger removeBtn">Remove</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<button id="addMoreBtn" class="btn btn-primary">Add More</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Buttons -->
|
|
<div class="mt-5 text-center">
|
|
<button type="submit" class="btn btn-success me-2">{% trans "Save" %}</button>
|
|
<a href="{% url 'estimate_list' %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
|
|
// Function to calculate Total Cost and Total Revenue
|
|
function calculateTotals(container) {
|
|
const quantity = parseFloat(container.querySelector('.quantity').value) || 0;
|
|
const unitCost = parseFloat(container.querySelector('.unitCost').value) || 0;
|
|
const unitSalesPrice = parseFloat(container.querySelector('.unitSalesPrice').value) || 0;
|
|
|
|
const totalCost = quantity * unitCost;
|
|
const totalRevenue = quantity * unitSalesPrice;
|
|
|
|
container.querySelector('.totalCost').value = totalCost.toFixed(2);
|
|
container.querySelector('.totalRevenue').value = totalRevenue.toFixed(2);
|
|
}
|
|
|
|
// Add event listeners to inputs for dynamic calculation
|
|
function addInputListeners(container) {
|
|
container.querySelectorAll('.quantity, .unitCost, .unitSalesPrice').forEach(input => {
|
|
input.addEventListener('input', () => calculateTotals(container));
|
|
});
|
|
}
|
|
|
|
// Add new form fields
|
|
document.getElementById('addMoreBtn').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const formContainer = document.getElementById('formContainer');
|
|
const newForm = document.createElement('div');
|
|
newForm.className = 'form-container row g-3 mb-3 mt-5';
|
|
newForm.innerHTML = `
|
|
<div class="mb-2 col-sm-2">
|
|
<select class="form-control item" name="item[]" required>
|
|
{% for item in items %}
|
|
<option value="{{ item.pk }}">{{ item.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control quantity" type="number" placeholder="Quantity" name="quantity[]" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control unitCost" type="number" placeholder="Unit Cost" name="unitCost[]" step="0.01" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control unitSalesPrice" type="number" placeholder="Unit Sales Price" name="unitSalesPrice[]" step="0.01" required>
|
|
</div>
|
|
<div class="mb-2 col-sm-2">
|
|
<input class="form-control totalCost" type="number" placeholder="Total Cost" name="totalCost[]" readonly>
|
|
</div>
|
|
<div class="mb-2 col-sm-1">
|
|
<input class="form-control totalRevenue" type="number" placeholder="Total Revenue" name="totalRevenue[]" readonly>
|
|
</div>
|
|
<div class="mb-2 col-sm-1">
|
|
<button class="btn btn-danger removeBtn">Remove</button>
|
|
</div>
|
|
`;
|
|
formContainer.appendChild(newForm);
|
|
addInputListeners(newForm); // Add listeners to the new form
|
|
|
|
// Add remove button functionality
|
|
newForm.querySelector('.removeBtn').addEventListener('click', function() {
|
|
newForm.remove();
|
|
});
|
|
});
|
|
|
|
// Add listeners to the initial form
|
|
document.querySelectorAll('.form-container').forEach(container => {
|
|
addInputListeners(container);
|
|
|
|
// Add remove button functionality to the initial form
|
|
container.querySelector('.removeBtn').addEventListener('click', function() {
|
|
container.remove();
|
|
});
|
|
});
|
|
const url = "{% url 'estimate_create' %}"
|
|
document.getElementById('mainForm').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Collect all form data
|
|
const formData = new FormData(this);
|
|
const csrfToken = getCookie('csrftoken');
|
|
const data = {};
|
|
formData.forEach((value, key) => {
|
|
// Handle multi-value fields (e.g., item[], quantity[])
|
|
if (data[key]) {
|
|
if (!Array.isArray(data[key])) {
|
|
data[key] = [data[key]]; // Convert to array
|
|
}
|
|
data[key].push(value);
|
|
} else {
|
|
data[key] = value;
|
|
}
|
|
});
|
|
// Send data to the server using fetch
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-CSRFToken': csrfToken,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(data)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('Success:', data);
|
|
if(data.status == "error"){
|
|
notify("error",data.message);
|
|
}
|
|
else{
|
|
notify("success","Estimate created successfully");
|
|
setTimeout(() => {
|
|
window.location.href = data.url;
|
|
}, 1000);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
notify("error",error);
|
|
alert('An error occurred while submitting the form.');
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
{% endblock %} |