162 lines
6.7 KiB
HTML
162 lines
6.7 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">{% trans "Unit Items" %}</h3>
|
|
<div class="form-row row g-3 mb-3 mt-5">
|
|
<div class="mb-2 col-sm-4">
|
|
<select class="form-control item" name="item[]" required>
|
|
{% for item in items %}<option value="{{ item.product.pk }}">{{ item.car.vin }} - {{ item.car }}</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-phoenix-danger removeBtn">{% trans "Remove" %}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<button id="addMoreBtn" class="btn btn-phoenix-primary">{% trans "Add More" %}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Buttons -->
|
|
<div class="d-flex mt-5 justify-content-center">
|
|
<button class="btn btn-sm btn-phoenix-success me-2" type="submit">
|
|
<i class="fa-solid fa-floppy-disk me-1"></i>{{ _("Save") }}
|
|
</button>
|
|
<a href="{{ request.META.HTTP_REFERER }}"
|
|
class="btn btn-sm btn-phoenix-danger"><i class="fa-solid fa-ban me-1"></i>{% 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 %}
|