svg
This commit is contained in:
159
templates/bill/edit.html.twig
Normal file
159
templates/bill/edit.html.twig
Normal file
@@ -0,0 +1,159 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %} = {{title}}{% endblock %}
|
||||
|
||||
{% block localstyle %}
|
||||
<style>
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_widget(form.submit) }}
|
||||
<a href="{{ path(routecancel) }}" class="btn btn-secondary ms-1">Annuler</a>
|
||||
{%if mode=="update" %}<a href="{{ path(routedelete,{id:form.vars.value.id}) }}" class="btn btn-danger float-end" onclick="return confirm('Confirmez-vous la suppression de cet enregistrement ?')">Supprimer</a>{%endif%}
|
||||
|
||||
{% include('include/error.html.twig') %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mx-auto">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">Information</div>
|
||||
<div class="card-body">
|
||||
{{ form_row(form.billDate) }}
|
||||
{{ form_row(form.clientName) }}
|
||||
{{ form_row(form.clientAddress) }}
|
||||
{{ form_row(form.bill) }}
|
||||
{{ form_row(form.total) }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12 mx-auto">
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:100px">N°</th>
|
||||
<th>Description</th>
|
||||
<th style="width:100px">Qte</th>
|
||||
<th style="width:100px">PU</th>
|
||||
<th style="width:100px">Rem</th>
|
||||
<th style="width:100px">Total</th>
|
||||
<th style="width:100px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="bill_details" style="zoom:80%"
|
||||
data-prototype='
|
||||
<tr class="bill-detail">
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.rowOrder)|e('html_attr') }}</td>
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.description)|e('html_attr') }}</td>
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.quantity)|e('html_attr') }}</td>
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.price)|e('html_attr') }}</td>
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.discount)|e('html_attr') }}</td>
|
||||
<td>{{ form_widget(form.billDetails.vars.prototype.total)|e('html_attr') }}</td>
|
||||
<td><button type="button" class="btn btn-danger remove-item">X</button></td>
|
||||
</tr>
|
||||
'>
|
||||
|
||||
{% for detailForm in form.billDetails %}
|
||||
<tr class="bill-detail">
|
||||
<td>{{ form_widget(detailForm.rowOrder) }}</td>
|
||||
<td>{{ form_widget(detailForm.description) }}</td>
|
||||
<td>{{ form_widget(detailForm.quantity) }}</td>
|
||||
<td>{{ form_widget(detailForm.price) }}</td>
|
||||
<td>{{ form_widget(detailForm.discount) }}</td>
|
||||
<td>{{ form_widget(detailForm.total) }}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger remove-item">X</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button type="button" class="btn btn-primary" id="add_item">Ajouter une ligne</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ form_rest(form) }}
|
||||
|
||||
|
||||
<div style="display:none;">
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
{{ form_end(form, { render_rest: false }) }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localscript %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#accounting_billDate").focus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const container = document.getElementById('bill_details');
|
||||
const addButton = document.getElementById('add_item');
|
||||
let index = container.querySelectorAll('.bill-detail').length;
|
||||
|
||||
function recalc(row) {
|
||||
const qty = parseFloat(row.querySelector('[name$="[quantity]"]').value) || 0;
|
||||
const price = parseFloat(row.querySelector('[name$="[price]"]').value) || 0;
|
||||
const discount = parseFloat(row.querySelector('[name$="[discount]"]').value) || 0;
|
||||
|
||||
let total = qty * price;
|
||||
if (discount > 0) {
|
||||
total = total - (total * (discount / 100));
|
||||
}
|
||||
row.querySelector('[name$="[total]"]').value = total.toFixed(0);
|
||||
}
|
||||
function recalcGlobal() {
|
||||
let sum = 0;
|
||||
container.querySelectorAll('[name$="[total]"').forEach(input => {
|
||||
sum += parseFloat(input.value) || 0;
|
||||
});
|
||||
console.log(sum);
|
||||
console.log(sum.toFixed(0))
|
||||
$('#bill_total').val(sum.toFixed(0));
|
||||
}
|
||||
container.addEventListener('input', (e) => {
|
||||
if (e.target.matches('[name$="[quantity]"], [name$="[price]"], [name$="[discount]"]')) {
|
||||
const row = e.target.closest('.bill-detail');
|
||||
if (row) {
|
||||
recalc(row);
|
||||
recalcGlobal();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addButton.addEventListener('click', () => {
|
||||
const prototype = container.dataset.prototype.replace(/__name__/g, index);
|
||||
const tr = document.createElement('tr');
|
||||
tr.classList.add('bill-detail');
|
||||
tr.innerHTML = prototype;
|
||||
container.appendChild(tr);
|
||||
index++;
|
||||
});
|
||||
|
||||
container.addEventListener('click', (e) => {
|
||||
if (e.target.classList.contains('remove-item')) {
|
||||
e.target.closest('tr').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
49
templates/bill/list.html.twig
Normal file
49
templates/bill/list.html.twig
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %} = {{title}}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>{{title}}</h1>
|
||||
<a href="{{ path(routesubmit) }}" class="btn btn-success">Ajouter</a>
|
||||
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="120px" class="no-sort">Action</th>
|
||||
<th width="120px">Date</th>
|
||||
<th width="120px">Type</th>
|
||||
<th>Client</th>
|
||||
<th width="120px">Montant</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bill in bills %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ path(routeupdate,{id:bill.id}) }}"><i class="fas fa-file fa-2x"></i></a>
|
||||
<a href="{{ path(routeprint,{id:bill.id}) }}" class="ms-2"><i class="fas fa-print fa-2x"></i></a>
|
||||
</td>
|
||||
<td>{{ bill.billDate|date("Y-m-d") }}</td>
|
||||
<td>{{ bill.isBill?'Facture':'Devis' }}</td>
|
||||
<td>{{ bill.clientName }}</td>
|
||||
<td>{{ bill.total }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block localscript %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#dataTables').DataTable({
|
||||
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
|
||||
responsive: true,
|
||||
iDisplayLength: 100,
|
||||
order: [[ 1, "desc" ]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
79
templates/bill/print.html.twig
Normal file
79
templates/bill/print.html.twig
Normal file
@@ -0,0 +1,79 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block localstyle %}
|
||||
<style>
|
||||
body {
|
||||
zoom:70%;
|
||||
}
|
||||
body, .table>:not(caption)>*>* {
|
||||
background-color: #fff !important;
|
||||
color: #000;
|
||||
|
||||
}
|
||||
|
||||
.company, .client {
|
||||
width: 400px;
|
||||
border: 1px solid #000;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width:150px;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="d-flex">
|
||||
<center><img src="{{ asset(bill.company.logo)}}" class="logo mb-3"></center>
|
||||
<h1 class="ms-auto">{{bill.isBill?'Facture FA':'Devis DE' }}{{bill.billDate|date("Ymd")}}</h1>
|
||||
</div>
|
||||
<div class="company">
|
||||
<h4>{{bill.company.title}}</h4>
|
||||
{{bill.company.adress|nl2br}}<br><br>
|
||||
{{bill.company.email}}
|
||||
</div>
|
||||
|
||||
<div class="client ms-auto ms-3 mt-3">
|
||||
<h4>{{bill.clientName}}</h4>
|
||||
{{bill.clientAddress|nl2br}}
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th style="width:100px;text-align:center;">Qte</th>
|
||||
<th style="width:100px;text-align:center;">PU</th>
|
||||
<th style="width:100px;text-align:center;">Rem</th>
|
||||
<th style="width:100px;text-align:center;">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for billDetail in bill.billDetails %}
|
||||
<tr class="bill-detail">
|
||||
<td>{{ billDetail.description }}</td>
|
||||
<td style="text-align:center">{{ billDetail.quantity }}</td>
|
||||
<td style="text-align:center">{{ billDetail.price }}</td>
|
||||
<td style="text-align:center">{{ billDetail.discount }}</td>
|
||||
<td style="text-align:center">{{ billDetail.total }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td style="text-align:right" colspan="4">Total</td>
|
||||
<td style="text-align:center">{{bill.total}}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
Reference in New Issue
Block a user