158 lines
6.0 KiB
HTML
158 lines
6.0 KiB
HTML
{% extends "base.html" %}
|
|
{% load crispy_forms_filters %}
|
|
{% load i18n static %}
|
|
|
|
{% block title %}{{ _("Create Bill") }}{% endblock title %}
|
|
|
|
{% block content %}
|
|
<div class="row mt-4">
|
|
<h3 class="text-center">{% trans "Create Bill" %}</h3>
|
|
<form id="mainForm" method="post" class="needs-validation">
|
|
{% csrf_token %}
|
|
<div class="row g-3">
|
|
{{ form|crispy }}
|
|
<div class="row mt-5">
|
|
<div id="formrow">
|
|
<h3 class="text-start">Unit Items</h3>
|
|
<div class="form-row 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.product.pk }}">{{ item.car.id_car_model }}</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-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" {% if not items %}disabled{% endif %}>{% trans "Save" %}</button>
|
|
<a href="{% url 'bill_list' %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock content %}
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
const Toast = Swal.mixin({
|
|
toast: true,
|
|
position: "top-end",
|
|
showConfirmButton: false,
|
|
timer: 2000,
|
|
timerProgressBar: false,
|
|
didOpen: (toast) => {
|
|
toast.onmouseenter = Swal.stopTimer;
|
|
toast.onmouseleave = Swal.resumeTimer;
|
|
}
|
|
});
|
|
// Add new form fields
|
|
document.getElementById('addMoreBtn').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const formrow = document.getElementById('formrow');
|
|
const newForm = document.createElement('div');
|
|
newForm.className = 'form-row 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.product.pk }}">{{ item.car.id_car_model }}</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-1">
|
|
<button class="btn btn-danger removeBtn">Remove</button>
|
|
</div>
|
|
`;
|
|
formrow.appendChild(newForm);
|
|
|
|
// Add remove button functionality
|
|
newForm.querySelector('.removeBtn').addEventListener('click', function() {
|
|
newForm.remove();
|
|
});
|
|
});
|
|
|
|
// Add remove button functionality to the initial form
|
|
document.querySelectorAll('.form-row').forEach(row => {
|
|
row.querySelector('.removeBtn').addEventListener('click', function() {
|
|
row.remove();
|
|
});
|
|
});
|
|
|
|
// Handle form submission
|
|
document.getElementById('mainForm').addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
/*const titleInput = document.querySelector('[name="title"]');
|
|
if (titleInput.value.length < 5) {
|
|
notify("error", "Customer billte Title must be at least 5 characters long.");
|
|
return; // Stop form submission
|
|
}*/
|
|
|
|
// Collect all form data
|
|
const formData = {
|
|
csrfmiddlewaretoken: document.querySelector('[name=csrfmiddlewaretoken]').value,
|
|
vendor: document.querySelector('[name=vendor]').value,
|
|
xref: document.querySelector('[name=xref]').value,
|
|
date_draft: document.querySelector('[name=date_draft]').value,
|
|
terms: document.querySelector('[name=terms]').value,
|
|
item: [],
|
|
quantity: []
|
|
};
|
|
|
|
|
|
// Collect multi-value fields (e.g., item[], quantity[])
|
|
document.querySelectorAll('[name="item[]"]').forEach(input => {
|
|
formData.item.push(input.value);
|
|
});
|
|
document.querySelectorAll('[name="quantity[]"]').forEach(input => {
|
|
formData.quantity.push(input.value);
|
|
});
|
|
|
|
try {
|
|
// Send data to the server using fetch
|
|
const response = await fetch("{% url 'bill_create' %}", {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRFToken': formData.csrfmiddlewaretoken,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(formData)
|
|
});
|
|
|
|
// Parse the JSON response
|
|
const data = await response.json();
|
|
|
|
// Handle the response
|
|
if (data.status === "error") {
|
|
notify("error", data.message); // Display an error message
|
|
} else if (data.status === "success") {
|
|
notify("success","Bill created successfully");
|
|
setTimeout(() => {
|
|
window.location.assign(data.url); // Redirect to the provided URL
|
|
}, 1000);
|
|
} else {
|
|
notify("error","Unexpected response from the server");
|
|
}
|
|
} catch (error) {
|
|
|
|
notify("error", error);
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock customJS %} |