From 403887a15f4daab14b8e4fd967acaa260064bdae Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 10 Nov 2025 14:29:07 +0100 Subject: [PATCH 1/6] Configuration comptes immobilisations en cours --- _archives.html | 10 +- _get_config.html | 27 ++-- _immobilisations.html | 10 +- _immobilisations_autres.html | 11 +- _unfinished.html | 10 +- add_asset.html | 6 +- config.html | 260 ++++++++++++++++++++--------------- defaut.json | 8 +- save_amort.html | 4 +- scripts.js | 35 ++++- write_exit.html | 4 +- 11 files changed, 234 insertions(+), 151 deletions(-) diff --git a/_archives.html b/_archives.html index a1bc45b..22ce879 100644 --- a/_archives.html +++ b/_archives.html @@ -6,14 +6,12 @@

{{* Immobilisation avec une écriture de sortie de bilan *}} -{{:include file="_get_config.html" keep="config.prefixes"}} +{{:include file="_get_config.html" keep="module.config"}} {{:assign condition="("}} -{{#foreach from=$config.prefixes item="code"}} - {{if $code|substr:0:2 != "23"}} - {{:assign code=$code|cat:"%"|quote_sql}} - {{:assign condition=$condition|cat:"account.code LIKE "|cat:$code|cat:" OR "}} - {{/if}} +{{#foreach from=$module.config.prefixes item="code"}} + {{:assign code=$code|cat:"%"|quote_sql}} + {{:assign condition=$condition|cat:"account.code LIKE "|cat:$code|cat:" OR "}} {{/foreach}} {{:assign condition=$condition|cat:"0)"}} {{:assign condition=$condition|cat:" AND acc2.code = account.code AND line.debit > 0 AND line.debit = line2.credit AND NOT (trans.status & 16)"}} diff --git a/_get_config.html b/_get_config.html index f18dfab..b1a9231 100644 --- a/_get_config.html +++ b/_get_config.html @@ -4,19 +4,20 @@ Récupérer la config *}} +{{* config par défaut *}} +{{:read file="./defaut.json" assign="config_defaut"}} +{{:assign config_defaut=$config_defaut|json_decode}} + +{{if $module.config.prefixes == null}} + {{:assign var="module.config.prefixes" value=$config_defaut.prefixes}} +{{/if}} + +{{if $module.config.unfinished == null}} + {{:assign var="module.config.unfinished" value=$config_defaut.unfinished}} +{{/if}} + {{* -{{if $module.config.tva != null}} - {{:assign var="config.tva" value=$module.config.tva}} -{{else}} - {{:assign var="config.tva" value=$config_defaut.tva}} +{{if $module.config.tva == null}} + {{:assign var="module.config.tva" value=$config_defaut.tva}} {{/if}} *}} - -{{if $module.config.prefixes != null}} - {{:assign var="config.prefixes" value=$module.config.prefixes}} -{{else}} - {{* config par défaut *}} - {{:read file="./defaut.json" assign="config_defaut"}} - {{:assign config_defaut=$config_defaut|json_decode}} - {{:assign var="config.prefixes" value=$config_defaut.prefixes}} -{{/if}} diff --git a/_immobilisations.html b/_immobilisations.html index 8591f23..57ca24e 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -28,14 +28,12 @@ {{* lister les immobilisations *}} - {{:include file="_get_config.html" keep="config.prefixes"}} + {{:include file="_get_config.html" keep="module.config"}} {{:assign condition="("}} - {{#foreach from=$config.prefixes item="code"}} - {{if $code|substr:0:2 != "23"}} - {{:assign code=$code|cat:"%"|quote_sql}} - {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} - {{/if}} + {{#foreach from=$module.config.prefixes item="code"}} + {{:assign code=$code|cat:"%"|quote_sql}} + {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} {{/foreach}} {{:assign condition=$condition|cat:"0)"}} {{:assign condition=$condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index 3dbf7b1..fb1970b 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -29,13 +29,12 @@ {{* lister les immobilisations *}} - {{:include file="_get_config.html" keep="config.prefixes"}} + {{:include file="_get_config.html" keep="module.config.prefixes"}} + {{:assign condition="("}} - {{#foreach from=$config.prefixes item="code"}} - {{if $code|substr:0:2 != "23"}} - {{:assign code=$code|cat:"%"|quote_sql}} - {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} - {{/if}} + {{#foreach from=$module.config.prefixes item="code"}} + {{:assign code=$code|cat:"%"|quote_sql}} + {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} {{/foreach}} {{:assign condition=$condition|cat:"0)"}} {{:assign condition=$condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} diff --git a/_unfinished.html b/_unfinished.html index e583acc..0c2d86b 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -23,7 +23,15 @@ {{* lister les immobilisations en cours de constitution *}} - {{:assign condition=$condition|cat:"account.code LIKE '23%' AND debit > 0 AND NOT (trans.status & 16)"}} + {{:include file="_get_config.html" keep="module.config.unfinished"}} + + {{:assign condition="("}} + {{#foreach from=$module.config.unfinished item="elem"}} + {{:assign code=$elem.code|cat:"%"|quote_sql}} + {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} + {{/foreach}} + {{:assign condition=$condition|cat:"0)"}} + {{:assign condition=$condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} {{:assign nb_immo=0}} {{#select diff --git a/add_asset.html b/add_asset.html index a606f15..c5f7756 100644 --- a/add_asset.html +++ b/add_asset.html @@ -1,6 +1,6 @@ {{* -*- brindille -*- *}} -{{:include file="_get_config.html" keep="config.prefixes"}} +{{:include file="_get_config.html" keep="module.config.prefixes"}} {{#years closed=false order="start_date" assign=years.}} {{:assign ts_debut=$start_date|strtotime}} @@ -74,7 +74,7 @@ file="_check_account.html" account=$debit_account chart_id=$selected_chart - prefix_array=$config.prefixes + prefix_array=$module.config.prefixes keep="account_ok" }} @@ -138,7 +138,7 @@ {{:assign var="projects.%d"|args:$id value=$label}} {{/select}} -{{#foreach from=$config.prefixes item="code"}} +{{#foreach from=$module.config.prefixes item="code"}} {{:assign var="pattern_array." value="%s*"|args:$code}} {{/foreach}} {{:assign var="patterns" value=$pattern_array|implode:"|"}} diff --git a/config.html b/config.html index 9038441..624a4ba 100644 --- a/config.html +++ b/config.html @@ -1,7 +1,6 @@ {{* -*- brindille -*- *}} {{:admin_header title="Configuration" custom_css="./style.css" current="module_amortissement"}} -{{* barre de navigation *}} {{:include file="_nav.html" current="config"}} {{if $_GET.ok == 1}} @@ -9,35 +8,48 @@ {{/if}} {{* lecture config (défaut ou enregistrée) *}} -{{:include file="./_get_config.html" keep="config"}} +{{:include file="./_get_config.html" keep="module.config, config_defaut"}} {{#form on="save"}} {{:assign ok=0}} {{#foreach from=$_POST.immo_accounts item="line"}} {{:assign elem=$line|values}} {{:assign elem=$elem.0}} - {{:assign var="fields" value=$elem|explode:" "}} - {{:assign present=false}} - {{* ne pas garder si préfixe d'un compte déjà présent *}} - {{#foreach from=$account_codes item="code"}} - {{:assign pos=$code|strpos:$fields.0}} - {{if $pos !== false}} - {{:assign present=true}} - {{:break}} + {{:assign var="fields" value=$elem|explode:" — "}} + {{if $fields.0|strpos:$config_defaut.unfinished.0.code === 0}} + {{:error message="Le compte « %s » n'est pas un compte d'immobilisation amortissable"|args:$fields.0}} + {{/if}} + {{:assign var="account_codes." value=$fields.0}} + {{/foreach}} + + {{#foreach from=$_POST.unfinished_accounts item="line"}} + {{:assign elem=$line|values}} + {{:assign elem=$elem.0}} + {{:assign var="fields" value=$elem|explode:" — "}} + {{:assign var="unfinished_codes." value=$fields.0}} + {{/foreach}} + + {{* vérifier qu'il n'y a pas d'intersection entre les deux listes de codes *}} + {{#foreach from=$account_codes item="i_code"}} + {{#foreach from=$unfinished_codes item="u_code"}} + {{if $i_code|strpos:$u_code === 0}} + {{:error message="Le compte d'immobilisation amortissable « %s » est incompatible avec le compte d'immobilisation en cours « %s »"|args:$i_code:$u_code}} + {{/if}} + {{if $u_code|strpos:$i_code === 0}} + {{:error message="Le compte d'immobilisation amortissable « %s » est incompatible avec le compte d'immobilisation en cours « %s »"|args:$i_code:$u_code}} {{/if}} {{/foreach}} - {{if ! $present}} - {{:assign var="account_codes." value=$fields.0}} - {{/if}} {{/foreach}} {{:save key="config" prefixes=$account_codes|sort + unfinished=$unfinished_codes|sort }} {{:assign ok=1}} - {{:redirect to="./config.html?ok=%d"|args:$ok}} +{{else}} + {{:form_errors}} {{/form}} {{* récupérer l'exercice courant ou sinon le plus récent *}} @@ -60,12 +72,11 @@ {{:assign selected_year=$last_year}} {{/if}} {{/if}} - {{if $selected_year != null}} - {{* libellés des comptes d'immobilisation *}} + {{* libellés des comptes d'immobilisation amortissables *}} {{:assign condition="("}} - {{#foreach from=$config.prefixes item="code"}} + {{#foreach from=$module.config.prefixes item="code"}} {{:assign code=$code|quote_sql}} {{:assign condition=$condition|cat:" account.code = "|cat:$code|cat:" OR "}} {{/foreach}} @@ -75,10 +86,7 @@ {{#select account.id as account_id, account.code, - account.id_chart, - account.label, - year.label as year_label, - chart.label as chart_label + account.label FROM acc_accounts AS account INNER JOIN acc_charts AS chart ON chart.id = account.id_chart INNER JOIN acc_years AS year ON year.id_chart = chart.id @@ -86,55 +94,127 @@ ; !condition=$condition }} - {{:assign var="accounts.%s"|args:$code label=$label id=$account_id}} + {{:assign var="immo_accounts.%s"|args:$code label=$label}} {{/select}} -

Comptes d'immobilisation

-
+ {{* libellés des comptes d'immobilisation en cours de constitution *}} + {{:assign condition="("}} + {{#foreach from=$module.config.unfinished item="elem"}} + {{:assign code=$elem.code|quote_sql}} + {{:assign condition=$condition|cat:" account.code = "|cat:$code|cat:" OR "}} + {{/foreach}} + {{:assign condition=$condition|cat:"0)"}} + {{:assign condition=$condition|cat:" AND year.id = %s"|args:$selected_year}} -

- Les immobilisations sont cherchées dans les comptes sélectionnées et leurs sous-comptes. -

+ {{#select + account.id as account_id, + account.code, + account.label + FROM acc_accounts AS account + INNER JOIN acc_charts AS chart ON chart.id = account.id_chart + INNER JOIN acc_years AS year ON year.id_chart = chart.id + WHERE !condition + ; + !condition=$condition + }} + {{:assign var="unfinished_accounts.%s"|args:$code label=$label}} + {{/select}} + {{if $unfinished_accounts|count == 0}} + {{:assign var="unfinished_accounts.%s"|args:$config_defaut.unfinished.0.code label=$config_defaut.unfinished.0.label}} + {{/if}} - - + +

Comptes d'immobilisation amortissables

+

+ Les immobilisations amortissables sont cherchées dans les comptes sélectionnés et leurs sous-comptes. +

+ +
+ + + + + + + + {{#foreach from=$immo_accounts key=code item=elem}} - - + + - - - {{#foreach from=$accounts key=code item=elem}} - - - - - {{/foreach}} - - + {{/foreach}} + + + + + + + +
Compte
Compte + {{:assign var="immo_account.%s.%s"|args:$code:$code value="%s — "|args:$code|cat:$elem.label}} + {{:assign var="current_account" from="immo_account.%s"|args:$code}} + {{:input + type="list" + name="immo_accounts[]" + target="!acc/charts/accounts/selector.php?codes=%s*&id_year=%d"|args:$code:$selected_year + default=$current_account + }} + + {{:button + label="Enlever" + title="Enlever une ligne" + shape="minus" + min="1" + name="remove_line" + }} +
- {{:assign var="immo_account.%s.%s"|args:$code:$code value="%s — "|args:$code|cat:$elem.label}} - {{:assign var="current_account" from="immo_account.%s"|args:$code}} - {{:input - type="list" - name="immo_accounts[]" - target="!acc/charts/accounts/selector.php?codes=%s&id_year=%d"|args:$code::$selected_year - default=$current_account - }} - - {{:button - label="Enlever" - title="Enlever une ligne" - shape="minus" - min="1" - name="remove_line" - }} -
{{:button shape="plus" label="Ajouter" title="Ajouter un compte"}}
+ +

Comptes d'immobilisation en cours de constitution

+

+ Ces immobilisations ne sont pas amortissables ; elles sont cherchées dans les comptes sélectionnés et leurs sous-comptes. +

+ + + + + + + + + + + {{#foreach from=$unfinished_accounts key=code item=elem}} - - + + - -
Compte
{{:button shape="plus" label="Ajouter" title="Ajouter un compte"}} + {{:assign var="unfinished_account.%s.%s"|args:$code:$code value="%s — "|args:$code|cat:$elem.label}} + {{:assign var="current_account" from="unfinished_account.%s"|args:$code}} + + {{:input + type="list" + name="unfinished_accounts[]" + target="!acc/charts/accounts/selector.php?codes=%s*&id_year=%d"|args:$code::$selected_year + default=$current_account + }} + + {{:button + label="Enlever" + title="Enlever une ligne" + shape="minus" + min="1" + name="remove_line" + }} +
+ {{/foreach}} + + + + + {{:button shape="plus" label="Ajouter" title="Ajouter un compte"}} + + +

{{:button type="submit" name="save" label="Enregistrer" shape="right" class="main"}} @@ -143,60 +223,20 @@ {{/if}} - - diff --git a/defaut.json b/defaut.json index 06771a5..df93eec 100644 --- a/defaut.json +++ b/defaut.json @@ -4,5 +4,11 @@ "20", "21", "27" - ] + ], + "unfinished": [ + { + "code" : "23", + "label" : "Immobilisations en cours" + } + ] } diff --git a/save_amort.html b/save_amort.html index 875db12..8fc110d 100644 --- a/save_amort.html +++ b/save_amort.html @@ -147,8 +147,8 @@ - que le compte d'amortissement débute par un préfixe correct (280, 281, ...) - est présent dans le PC de l'exercice correspondant à la date *}} - {{:include file="_get_config.html" keep="config.prefixes"}} - {{#foreach from=$config.prefixes item="code"}} + {{:include file="_get_config.html" keep="module.config.prefixes"}} + {{#foreach from=$module.config.prefixes item="code"}} {{* déterminer le numéro du compte d'amortissement associé au compte d'immobilisation *}} {{:include file="./_get_amort_code.html" diff --git a/scripts.js b/scripts.js index 3d91074..9764bcc 100644 --- a/scripts.js +++ b/scripts.js @@ -142,10 +142,11 @@ function setSelectorYear(button_names, f_years_selector) { // config : gestion des ajouts/suppression comptes immo +// Associer au bouton « Enlever » de chaque ligne l'action de suppression de la ligne function initLine(row) { var removeBtn = row.querySelector('button[name="remove_line"]'); removeBtn.onclick = () => { - var count = $('.transaction-lines tbody tr').length; + let count = removeBtn.closest("table").querySelectorAll('tbody tr').length; var min = removeBtn.getAttribute('min'); if (count <= min) { @@ -157,3 +158,35 @@ function initLine(row) { return true; }; } + +// Associer au bouton « Ajouter » de chaque table l'action d'ajouter une ligne +function addLine(button, codes) { + console.log("codes=" + JSON.stringify(codes)); + button.onclick = () => { + let lines = button.closest("table").querySelectorAll('tbody tr'); + let line = lines[lines.length - 1]; + let newNode = line.cloneNode(true); + + // Réinitialiser le sélecteur de compte + let selectButton = newNode.querySelector('.input-list button'); + let url = selectButton.value; + let new_url = url.replace(/codes=[0-9]+\*?/, "codes=" + codes); + selectButton.value = new_url; + + // gestionnaire d'événement du sélecteur + selectButton.onclick = () => { + g.current_list_input = selectButton.parentNode; + let url = selectButton.value + (selectButton.value.indexOf('?') > 0 ? '&' : '?') + '_dialog'; + g.openFrameDialog(url); + return false; + }; + + // réinitialiser le libellé associé au sélecteur + let lib = newNode.querySelector('.input-list span.label'); + lib.innerText = ''; + + // ajouter la nouvelle ligne + line.parentNode.appendChild(newNode); + initLine(newNode); + }; +} diff --git a/write_exit.html b/write_exit.html index 0fe32a0..340d5fa 100644 --- a/write_exit.html +++ b/write_exit.html @@ -311,8 +311,8 @@ {{:assign var="%s.%s"|args:$name:$code value="%s — %s"|args:$code:$acc_label}} {{/foreach}} -{{:include file="_get_config.html" keep="config.prefixes"}} -{{#foreach from=$config.prefixes item="code"}} +{{:include file="_get_config.html" keep="module.config.prefixes"}} +{{#foreach from=$module.config.prefixes item="code"}} {{:assign var="pattern_array." value="%s*"|args:$code}} {{/foreach}} {{:assign patterns=$pattern_array|implode:"|"}} From 668e73951972f5888986263e7df9a82070e5b36a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 12 Nov 2025 20:38:03 +0100 Subject: [PATCH 2/6] Harmonisation style --- amortization.html | 46 ++++++++++++++++++++++++---------------------- style.css | 4 ---- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/amortization.html b/amortization.html index 0ead87c..1801ea8 100644 --- a/amortization.html +++ b/amortization.html @@ -170,28 +170,30 @@ -

-
Immobilisation
-
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
-
Montant
-
{{"%f"|math:$ligne_immo.montant|money_currency}}
-
Début d'amortissement
-
{{$date_debut|date_short}}
- {{if $duree != null}} -
Durée
-
{{$duree}} ans
- {{/if}} - {{if $valeur_residuelle > 0}} -
Montant déjà amorti
-
{{"%d-%d"|math:$ligne_immo.montant:$valeur_residuelle|money_currency:false}}
-
Valeur résiduelle
-
{{$valeur_residuelle|money_currency}}
- {{/if}} - {{if $duree != null && $valeur_residuelle > 0}} -
Annuité estimée
-
{{"%f/%d"|math:$ligne_immo.montant:$duree|money_currency}}
- {{/if}} -
+
+
+
Immobilisation
+
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
+
Montant
+
{{"%f"|math:$ligne_immo.montant|money_currency}}
+
Début d'amortissement
+
{{$date_debut|date_short}}
+ {{if $duree != null}} +
Durée
+
{{$duree}} ans
+ {{/if}} + {{if $valeur_residuelle > 0}} +
Montant déjà amorti
+
{{"%d-%d"|math:$ligne_immo.montant:$valeur_residuelle|money_currency:false}}
+
Valeur résiduelle
+
{{$valeur_residuelle|money_currency}}
+ {{/if}} + {{if $duree != null && $valeur_residuelle > 0}} +
Annuité estimée
+
{{"%f/%d"|math:$ligne_immo.montant:$duree|money_currency}}
+ {{/if}} +
+

Amortissements enregistrés

{{if $linked_lines != null}} diff --git a/style.css b/style.css index fd1cbfb..c9c23f9 100644 --- a/style.css +++ b/style.css @@ -41,7 +41,3 @@ h2[class="aide"], h3[class="aide"] { nav.amort aside { margin-top : 0; } - -.describe dt::after { - content: ' :'; -} From 9bfc389fa222f6086fd3822e48d762a08c1e2a99 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 12 Nov 2025 20:38:24 +0100 Subject: [PATCH 3/6] Correction typos --- add_asset.html | 4 ++-- config.html | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/add_asset.html b/add_asset.html index c5f7756..898042d 100644 --- a/add_asset.html +++ b/add_asset.html @@ -153,7 +153,7 @@
{{:input type="select" name="id_year" label="Exercice" default=$selected_year required=true default_empty="— Faire un choix —" options=$open_years}} {{:input type="date" name="date_achat" label="Date d'acquisition" required=true default=$now|date_short}} - {{:input type="text" name="designation" label="Désignation" required=true}} + {{:input type="text" name="designation" label="Libellé" required=true}} {{:input type="money" name="montant" label="Montant" required=true}} {{:input type="list" @@ -180,7 +180,7 @@
Amortissement
- {{:input id="amortir" type="checkbox" value=1 name="amortir" label="Amortir cette immobilisation sur plusieurs années" checked="checked" help="Dé-cocher pour ne pas amortir"}} + {{:input id="amortir" type="checkbox" value=1 name="amortir" label="Amortir cette immobilisation sur une ou plusieurs années" checked="checked" help="Dé-cocher pour ne pas amortir"}}
{{:input type="number" name="duree" label="Durée d'amortissement" required=true min=0 default=1 suffix="année(s)"}} {{:input type="date" name="date_mes" label="Date de mise en service" help="C'est la date de première utilisation ; à renseigner uniquement si différente de la date d'acquisition"}} diff --git a/config.html b/config.html index 624a4ba..25b2dc3 100644 --- a/config.html +++ b/config.html @@ -188,11 +188,10 @@ {{:assign var="unfinished_account.%s.%s"|args:$code:$code value="%s — "|args:$code|cat:$elem.label}} {{:assign var="current_account" from="unfinished_account.%s"|args:$code}} - {{:input type="list" name="unfinished_accounts[]" - target="!acc/charts/accounts/selector.php?codes=%s*&id_year=%d"|args:$code::$selected_year + target="!acc/charts/accounts/selector.php?codes=%s*&id_year=%d"|args:$code:$selected_year default=$current_account }} @@ -226,7 +225,7 @@ + diff --git a/scripts.js b/scripts.js index 9764bcc..818d3ed 100644 --- a/scripts.js +++ b/scripts.js @@ -119,7 +119,6 @@ function displayAmort(id_immo, id_duree, id_amort, id_years, id_exercices, id_mo } if (id_date != null) { const date_choisie = str2sec(document.getElementById(id_date).value); - console.log("date_choisie = " + date_choisie + ", date_debut=" + date_debut + ", date_fin = " + date_fin); if (date_debut <= date_choisie && date_choisie <= date_fin) { date_fin = date_choisie; } else { @@ -161,7 +160,6 @@ function initLine(row) { // Associer au bouton « Ajouter » de chaque table l'action d'ajouter une ligne function addLine(button, codes) { - console.log("codes=" + JSON.stringify(codes)); button.onclick = () => { let lines = button.closest("table").querySelectorAll('tbody tr'); let line = lines[lines.length - 1]; @@ -190,3 +188,50 @@ function addLine(button, codes) { initLine(newNode); }; } + +// calculer et afficher le total des lignes sélectionnées +function computeTotal(id_total, id_url) { + + // calculer le total par compte + let total = new Object; + const transactions = []; + let lines = document.querySelectorAll('.list tbody tr'); + for (const line of lines) { + let button = line.querySelector('input[type=checkbox]'); + if (button.checked) { + let money = line.querySelector('.money'); + let code = line.querySelector('.account_code a').innerText; + if (code in total) { + total[code] += getNumber(money.innerText) * 100; + } else { + total[code] = getNumber(money.innerText) * 100; + } + const number = line.querySelector('.num a').innerText.slice(1); + transactions.push(number); + } + } + // afficher les totaux + const liste = document.getElementById(id_total).querySelector('ul'); + while (liste.firstChild) { + liste.removeChild(liste.firstChild); + } + for (const code in total) { + const node = document.createElement("li"); + const para = document.createElement("p"); + const libelle = document.createTextNode("Compte " + code + " : "); + const span = document.createElement("strong"); + span.classList.add("money"); + const montant = document.createTextNode(new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR" }).format(total[code] / 100., )); + + span.appendChild(montant); + para.appendChild(libelle); + para.appendChild(span); + node.appendChild(para); + liste.appendChild(node); + } + + // mettre à jour les paramètres de l'url + let url = document.getElementById(id_url); + let new_href = url.href.replace(/trans=.*/, 'trans=' + Object.values(transactions)); + url.href = new_href; +} diff --git a/style.css b/style.css index c9c23f9..40922ee 100644 --- a/style.css +++ b/style.css @@ -41,3 +41,9 @@ h2[class="aide"], h3[class="aide"] { nav.amort aside { margin-top : 0; } + +fieldset.shortFormLeft div.informations { + border: 1px solid var(--gLightBorderColor); + background: rgba(var(--gSecondColor), 0.2); + border-radius: .5em; +} diff --git a/transfer.html b/transfer.html new file mode 100644 index 0000000..c7f5dfc --- /dev/null +++ b/transfer.html @@ -0,0 +1,317 @@ +{{* -*- brindille -*- *}} + +{{:admin_header title="Transfert d'immobilisation en cours" current="module_amortissement"}} +{{:include file="_get_config.html" keep="module.config.prefixes"}} + +{{#years closed=false order="start_date" assign=years.}} + {{:assign ts_debut=$start_date|strtotime}} + {{:assign ts_fin=$end_date|strtotime}} + {{:assign debut=$start_date|date_short}} + {{:assign fin=$end_date|date_short}} + {{:assign var="years_data.%d"|args:$id value=$ts_debut|cat:" "|cat:$ts_fin}} + {{:assign var="open_years.%d"|args:$id value=$label|cat:" ("|cat:$debut|cat:" - "|cat:$fin|cat:")"}} + {{if $ts_debut <= $now && $now <= $ts_fin}} + {{:assign selected_year=$id}} + {{/if}} +{{else}} + {{:error message="Aucun exercice ouvert"}} +{{/years}} + +{{* Traiter l'envoi du formulaire *}} +{{#form on="transfer"}} + {{* vérifier que la date de mise en service est située dans l'exercice sélectionné *}} + {{:assign ts_date = $_POST.date_mes|parse_date|strtotime}} + {{:assign ok=false}} + {{#foreach from=$years}} + {{if $id == $_POST.id_year}} + {{:assign selected_chart=$id_chart}} + {{if $start_date|strtotime <= $ts_date && $ts_date <= $end_date|strtotime}} + {{:assign ok=true}} + {{:break}} + {{/if}} + {{/if}} + {{/foreach}} + {{if ! $ok}} + {{:error message="La date saisie n'est pas dans l'exercice choisi !"}} + {{/if}} + + {{if ! $_POST.amortir}} + {{* ne pas amortir *}} + {{:assign duration=0}} + {{:assign date_debut=$_POST.date_achat|parse_date}} + {{:assign status="ignored"}} + {{else}} + {{* vérifier que la date d'acquisition est antérieure à la date de mise en service *}} + {{:assign date_debut=$_POST.date_mes|parse_date}} + {{:assign duration=$_POST.duree|intval}} + {{:assign status="managed"}} + {{/if}} + + {{* comptes de débit *}} + {{#foreach from=$_POST.credit_accounts key="rang" item="elem"}} + {{:include + file="_get_codes.html" + account=$elem + keep="account_code" + }} + {{:assign debit_account=$account_code|keys|key:0}} + {{:assign var="amount" from="_POST.credit_lines.%s"|args:$rang}} + {{:assign var="label" from="_POST.line_labels.%s"|args:$rang}} + {{:assign + var="lines." + account=$debit_account + credit=$amount + label=$label + }} + {{/foreach}} + + {{* compte de crédit *}} + {{:include + file="_get_codes.html" + account=$_POST.debit_account + keep="account_code" + }} + {{:assign credit_account=$account_code|keys|key:0}} + {{:assign var="amount" from="_POST.debit_lines.%s"|args:0}} + {{:assign count=$_POST.line_labels|count}} + {{:assign count="%d-1"|math:$count}} + {{:assign var="label" from="_POST.line_labels.%s"|args:$count}} + {{:assign + var="lines." + account=$credit_account + debit=$amount + label=$label + }} + + {{* vérifier : + - que le compte d'immo débute par un préfixe correct (20, 21, ...) + - est présent dans le PC de l'exercice correspondant à la date + *}} + + {{:include + file="_check_account.html" + account=$account_code + chart_id=$selected_chart + prefix_array=$module.config.prefixes + keep="account_ok" + }} + + {{if $account_ok == null}} + {{:assign compte=$credit_account|implode:""}} + {{:error message="Le compte « %s » n'est pas un compte d'immobilisation ou n'est pas dans le plan comptable de l'exercice choisi"|args:$compte}} + {{/if}} + + {{* écritures liées *}} + {{:assign var="linked_transactions" value=$_GET.trans|explode:","}} + + {{* enregistrer l'écriture *}} + {{:api + method="POST" + path="accounting/transaction" + assign="result" + id_year=$_POST.id_year + type="advanced" + date=$_POST.date_mes + label=$_POST.designation|trim + lines=$lines + linked_transactions=$linked_transactions + }} + + {{:assign lines_count=$lines|count}} + {{:assign lines_count="%d-1"|math:$lines_count}} + {{:assign var="immo_id" from="result.lines.%s.id"|args:$lines_count}} + + {{* enregistrer les infos de l'immobilisation *}} + {{:save + key=""|uuid + validate_schema="schema.json" + type="immo" + line=$immo_id + duration=$duration + date=$date_debut + status=$status + }} + {{if $_POST.amortir}} + {{:assign type_immo="managed"}} + {{else}} + {{:assign type_immo="other"}} + {{/if}} + {{:redirect force="index.html?ok=1&msg=immobilisation&type_immo=%s"|args:$type_immo}} + +{{/form}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{:include file="_nav.html" current="index"}} +{{/if}} + +{{:form_errors}} + +{{* formulaire d'ajout d'immobilisation *}} + +{{#select id,label FROM acc_projects WHERE archived = 0;}} + {{:assign var="projects.%d"|args:$id value=$label}} +{{/select}} + +{{#foreach from=$module.config.prefixes item="code"}} + {{:assign var="pattern_array." value="%s*"|args:$code}} +{{/foreach}} +{{:assign var="patterns" value=$pattern_array|implode:"|"}} + + + +{{if $_GET.trans == null}} + {{:error message="Vous n'avez sélectionné aucune écriture !"}} +{{/if}} + +{{* déterminer les comptes d'immo en cours *}} +{{:include file="_get_config.html" keep="module.config.unfinished"}} +{{:assign condition="("}} +{{#foreach from=$module.config.unfinished item="elem"}} + {{:assign code=$elem.code|cat:"%"|quote_sql}} + {{:assign condition=$condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} +{{/foreach}} +{{:assign condition=$condition|cat:"0)"}} + +{{* détails des écritures paramètres *}} +{{:assign trans=$_GET.trans|explode:","}} +{{:assign var="trans_list" value=$trans|map:quote_sql}} +{{:assign trans_list=$trans_list|implode:","}} +{{:assign trans_list="("|cat:$trans_list|cat:")"}} +{{:assign condition=$condition|cat:" AND trans.id IN "|cat:$trans_list}} +{{:assign condition=$condition|cat:" AND NOT (trans.status & 16)"}} + +{{#select + trans.id as trans_id, + trans.label AS trans_label, + trans.date AS trans_date, + SUM(line.debit) AS line_debit, + account.code AS account_code, + account.label AS account_label, + line.id_project as project_id + FROM acc_transactions AS trans + INNER JOIN acc_transactions_lines AS line ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS account ON line.id_account = account.id + WHERE !condition + GROUP BY trans.id + ; + !condition=$condition +}} + {{:assign var="transactions.%s"|args:$trans_id amount=$line_debit date=$trans_date code=$account_code label=$account_label project=$project_id}} +{{/select}} + +
+
+ Données de l'immobilisation +
+ {{:input type="select" name="id_year" label="Exercice" default=$selected_year required=true + default_empty="— Faire un choix —" options=$open_years}} + {{:input type="date" name="date_mes" label="Date de mise en service" required=true default=$now|date_short}} + {{:input type="text" name="designation" label="Libellé" required=true}} +
+
+ +
+ Comptes +
+ + + + + + + + + + + + {{:assign total=0}} + {{#foreach from=$transactions key="id"}} + {{:assign total="%f+%f"|math:$total:$amount}} + {{:assign current_account=null}} + {{:assign var="current_account.%s"|args:$code value="%s — %s"|args:$code:$label}} + + + + + + + + {{/foreach}} + + + + + + + + + + +
CompteDébitCréditLibellé ligneProjet
+ {{:input + type="list" + name="credit_accounts[]" + required=true + target="!acc/charts/accounts/selector.php?codes=%s&id_year=%d"|args:$code:$selected_year + default=$current_account + }} + {{:input name="credit_lines[]" type="text" class="money" size="8" default=$amount|money}}{{:input name="debit_lines[]" type="text" class="money" size="8" disabled=true}}{{:input type="text" name="line_labels[]" size="40"}} + {{if $projects != null}} + {{:input type="select" name="id_project" options=$projects default_empty="— Aucun —"}} + {{/if}} +
+ {{:input + type="list" + name="debit_account" + label="Compte d'immobilisation amortissable" + required=true + target="!acc/charts/accounts/selector.php?codes=%s&id_year=%d"|args:$patterns:$selected_year + }} + {{:input name="credit_lines[]" type="text" class="money" size="8" disabled=true}}{{:input name="debit_lines[]" type="text" class="money" size="8" default=$total|money}}{{:input type="text" name="line_labels[]" size="40"}} + {{if $projects != null}} + {{:input type="select" name="id_project" options=$projects default_empty="— Aucun —"}} + {{/if}} +
+ + +
+
+ +
+ Amortissement +
+ {{:input id="amortir" type="checkbox" value=1 name="amortir" label="Amortir cette immobilisation sur une ou plusieurs années" checked="checked" help="Dé-cocher pour ne pas amortir"}} +
+ {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=0 default=1 suffix="année(s)"}} +
+
+
+ +

+ {{:button type="submit" name="transfer" label="Transférer" shape="right" class="main"}} +

+ +
+{{:admin_footer}} + + + From 262b25889bab8ab3be00ead50e596f98039ec03f Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 18 Nov 2025 12:03:38 +0100 Subject: [PATCH 5/6] =?UTF-8?q?Classer=20ou=20d=C3=A9classer=20manuellemen?= =?UTF-8?q?t=20une=20=C3=A9criture=20=C2=AB=20=C3=A0=20ignorer=20=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _unfinished.html | 31 +++++++++++++++++- ignore.html | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 5 +++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 ignore.html diff --git a/_unfinished.html b/_unfinished.html index 5db1083..3565470 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -31,6 +31,9 @@

+
+ {{:input type="checkbox" value=1 name="unhide" label="Afficher les écritures marquées ignorées" }} +
@@ -79,6 +82,15 @@ ORDER BY trans.date DESC; !condition=$condition }} + {{* voir si l'écriture a été marquée ignorée *}} + {{:assign ignore=false}} + {{#load type="immo" assign="info_immo" where="$$.line = :line_id AND $$.status = 'ignored'" :line_id=$immo_id|intval}} + {{:assign ignore=true}} + {{/load}} + {{if $ignore && $_POST.unhide == null}} + {{:continue}} + {{/if}} + {{* voir s'il existe une écriture qui solde l'immobilisation *}} {{#select count(*) AS count @@ -92,6 +104,7 @@ }} {{:assign count=$count}} {{/select}} + {{* S'il y a plus d'une écriture de même montant on ne peut pas décider *}} {{if $count == 1}} {{:continue}} @@ -109,7 +122,14 @@ - + {{/select}} @@ -132,4 +152,13 @@ } +function changeVisibility(evt, idcheck = 'f_unhide_1') { + this.form.dispatchEvent(new Event('submit')); + this.form.submit(); +} + +(function () { + document.getElementById('f_unhide_1').onclick = changeVisibility; +})(); + diff --git a/ignore.html b/ignore.html new file mode 100644 index 0000000..a8d4ec6 --- /dev/null +++ b/ignore.html @@ -0,0 +1,85 @@ +{{* -*- brindille -*- *}} + +{{* + Marquer la ligne d'écriture « à ignorer » + @param immo_id : numéro de ligne +*}} + +{{#select + trans.id AS trans_id, + trans.date AS date, + trans.label AS label, + line.debit AS amount + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + WHERE line.id = :line_id + ; + :line_id = $_GET.immo_id + assign=ligne_immo +}} +{{else}} + {{:error message="Il n'y a aucune écriture avec le numéro de ligne %s !"|args:$_GET.immo_id}} +{{/select}} +{{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_id|intval}}{{/load}} + +{{* Traiter l'envoi du formulaire *}} +{{#form on="proceed"}} + {{if $_POST.ignore != null && $info_immo == null}} + {{* ignorer l'écriture *}} + {{:assign duration=0}} + {{:assign status="ignored"}} + {{:save + key=""|uuid + validate_schema="schema.json" + type="immo" + line=$_GET.immo_id|intval + duration=$duration + date=$ligne_immo.date + status=$status + }} + {{:redirect force="index.html?ok=1&msg=infos&type_immo=unfinished"}} + {{elseif $_POST.ignore == null && $info_immo != null}} + {{* dés-ignorer l'écriture *}} + {{:delete id=$info_immo.id}} + {{:redirect force="index.html?ok=1&msg=infos&type_immo=unfinished"}} + {{else}} + {{:redirect force="index.html?type_immo=unfinished"}} + {{/if}} +{{else}} + {{:form_errors}} +{{/form}} + +{{:admin_header title="Ignorer l'écriture" custom_css="./style.css" current="module_amortissement"}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{:include file="_nav.html" current="index"}} +{{/if}} + + +
+ Ignorer +
+
+
Écriture
+
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
+
Montant
+
{{"%f"|math:$ligne_immo.amount|money_currency}}
+
+
+
+ {{if $info_immo != null && $info_immo.status == "ignored"}} + {{:input type="checkbox" name="ignore" checked="checked" value="1" label="Ignoré" help="Décocher pour ne plus ignorer l'écriture"}} + {{else}} + {{:input type="checkbox" name="ignore" value="1" label="Ignoré" help="Cocher pour ignorer l'écriture ; elle n'apparaitra plus dans la liste des immobilisations"}} + {{/if}} +
+
+ +

+ {{:button type="submit" name="proceed" label="Confirmer" shape="right" class="main"}} +

+ + + +{{:admin_footer}} diff --git a/style.css b/style.css index 40922ee..5c0e9c6 100644 --- a/style.css +++ b/style.css @@ -38,6 +38,11 @@ h2[class="aide"], h3[class="aide"] { margin-right: 0; } +.informations dl.describe > dd { + margin-left: 0; + margin-right: 0; +} + nav.amort aside { margin-top : 0; } From 9dd8c018f0f9e151bf0b52040f04fe86b70a9d8a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 19 Nov 2025 11:27:59 +0100 Subject: [PATCH 6/6] =?UTF-8?q?Filtrer=20les=20libell=C3=A9s=20des=20?= =?UTF-8?q?=C3=A9critures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations.html | 10 +++- _immobilisations_autres.html | 12 ++++- _nav.html | 8 +++ _unfinished.html | 13 ++++- config.html | 6 +-- filters.html | 96 ++++++++++++++++++++++++++++++++++++ scripts.js | 17 ++++++- 7 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 filters.html diff --git a/_immobilisations.html b/_immobilisations.html index 57ca24e..337fc0b 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -37,8 +37,16 @@ {{/foreach}} {{:assign condition=$condition|cat:"0)"}} {{:assign condition=$condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} - {{:assign nb_immo=0}} + {{:assign filter_condition=" NOT ("}} + {{#foreach from=$module.config.filters item="filter"}} + {{:assign filter="%"|cat:$filter|cat:"%"|quote_sql}} + {{:assign filter_condition=$filter_condition|cat:" trans_label LIKE "|cat:$filter|cat:" OR "}} + {{/foreach}} + {{:assign filter_condition=$filter_condition|cat:"0)"}} + {{:assign condition=$condition|cat:" AND "|cat:$filter_condition}} + + {{:assign nb_immo=0}} {{#select trans.id as trans_id, trans.label as trans_label, diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index fb1970b..41a547f 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -29,7 +29,7 @@ {{* lister les immobilisations *}} - {{:include file="_get_config.html" keep="module.config.prefixes"}} + {{:include file="_get_config.html" keep="module.config"}} {{:assign condition="("}} {{#foreach from=$module.config.prefixes item="code"}} @@ -38,8 +38,16 @@ {{/foreach}} {{:assign condition=$condition|cat:"0)"}} {{:assign condition=$condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} - {{:assign nb_immo=0}} + {{:assign filter_condition=" NOT ("}} + {{#foreach from=$module.config.filters item="filter"}} + {{:assign filter="%"|cat:$filter|cat:"%"|quote_sql}} + {{:assign filter_condition=$filter_condition|cat:" trans_label LIKE "|cat:$filter|cat:" OR "}} + {{/foreach}} + {{:assign filter_condition=$filter_condition|cat:"0)"}} + {{:assign condition=$condition|cat:" AND "|cat:$filter_condition}} + + {{:assign nb_immo=0}} {{#select trans.id as trans_id, trans.label as trans_label, diff --git a/_nav.html b/_nav.html index 1cc3608..9c56bfb 100644 --- a/_nav.html +++ b/_nav.html @@ -33,4 +33,12 @@
  • Sortie de bilan
  • {{/if}} + + {{if $current == "config"}} + + {{/if}} diff --git a/_unfinished.html b/_unfinished.html index 3565470..ab7e1e0 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -52,7 +52,7 @@ {{* lister les immobilisations en cours de constitution *}} - {{:include file="_get_config.html" keep="module.config.unfinished"}} + {{:include file="_get_config.html" keep="module.config"}} {{:assign accounts_condition="("}} {{#foreach from=$module.config.unfinished item="elem"}} @@ -61,8 +61,17 @@ {{/foreach}} {{:assign accounts_condition=$accounts_condition|cat:"0)"}} {{:assign condition=$accounts_condition|cat:" AND debit > 0 AND NOT (trans.status & 16)"}} - {{:assign nb_immo=0}} + {{:assign filter_condition=" NOT ("}} + {{#foreach from=$module.config.filters item="filter"}} + {{:assign filter="%"|cat:$filter|cat:"%"|quote_sql}} + {{:assign filter_condition=$filter_condition|cat:" trans_label LIKE "|cat:$filter|cat:" OR "}} + {{/foreach}} + {{:assign filter_condition=$filter_condition|cat:"0)"}} + {{:assign condition=$condition|cat:" AND "|cat:$filter_condition}} + {{*:debug condition=$condition*}} + + {{:assign nb_immo=0}} {{#select trans.id as trans_id, trans.label as trans_label, diff --git a/config.html b/config.html index 25b2dc3..7695c17 100644 --- a/config.html +++ b/config.html @@ -1,8 +1,5 @@ {{* -*- brindille -*- *}} -{{:admin_header title="Configuration" custom_css="./style.css" current="module_amortissement"}} -{{:include file="_nav.html" current="config"}} - {{if $_GET.ok == 1}}

    Configuration enregistrée.

    {{/if}} @@ -52,6 +49,9 @@ {{:form_errors}} {{/form}} +{{:admin_header title="Configuration" custom_css="./style.css" current="module_amortissement"}} +{{:include file="_nav.html" current="config"}} + {{* récupérer l'exercice courant ou sinon le plus récent *}} {{:assign var="selected_year" from="logged_user.preferences.accounting_year"}} {{if $selected_year == null}} diff --git a/filters.html b/filters.html new file mode 100644 index 0000000..7c89fb9 --- /dev/null +++ b/filters.html @@ -0,0 +1,96 @@ +{{* -*- brindille -*- *}} + +{{:admin_header title="Configuration" custom_css="./style.css" current="module_amortissement"}} +{{:include file="_nav.html" current="config" subcurrent="filters"}} + +{{if $_GET.ok == 1}} +

    Configuration enregistrée.

    +{{/if}} + +{{* lecture config *}} +{{:include file="./_get_config.html" keep="module.config"}} + +{{#form on="save"}} + {{* enregistrer les filtres dans la config *}} + {{#foreach from=$_POST.filters item="filter"}} + {{if $filter != ""}} + {{:assign var="filters." value=$filter}} + {{/if}} + {{/foreach}} + {{:save key="config" filters=$filters}} + {{:redirect to="./misc.html"}} +{{/form}} + + +

    Liste de libellés à ignorer

    +

    + Les écritures dont le libellé contient un des textes ci-dessous seront ignorées +

    + +
    {{"%f"|math:$debit|money:false}} {{$account_label}} + {{:linkbutton + label="Modifier" + href="ignore.html?immo_id=%s"|args:$immo_id + shape="edit" + target="_dialog" + }} +
    + + + + + + + + {{if $module.config.filters == null}} + + + + + {{else}} + {{#foreach from=$module.config.filters item="filter"}} + + + + + {{/foreach}} + {{/if}} + + + + + + + +
    Libellé
    + {{:input type="text" name="filters[]" required=false}} + + {{:button + label="Enlever" + title="Enlever une ligne" + shape="minus" + min="1" + name="remove_line" + }} +
    + {{:input type="text" name="filters[]" default=$filter required=false}} + + {{:button + label="Enlever" + title="Enlever une ligne" + shape="minus" + min="1" + name="remove_line" + }} +
    {{:button shape="plus" label="Ajouter" title="Ajouter un libellé"}}
    +

    + {{:button type="submit" name="save" label="Enregistrer" shape="right" class="main"}} +

    + + + + diff --git a/scripts.js b/scripts.js index 818d3ed..15369ff 100644 --- a/scripts.js +++ b/scripts.js @@ -149,7 +149,7 @@ function initLine(row) { var min = removeBtn.getAttribute('min'); if (count <= min) { - alert("Il n'est pas possible d'avoir moins de " + min + " compte(s)."); + alert("Il n'est pas possible d'avoir moins de " + min + " ligne(s)."); return false; } @@ -235,3 +235,18 @@ function computeTotal(id_total, id_url) { let new_href = url.href.replace(/trans=.*/, 'trans=' + Object.values(transactions)); url.href = new_href; } + +// dupliquer la dernière ligne d'une table +function copyLine(button) { + button.onclick = () => { + let lines = button.closest("table").querySelectorAll('tbody tr'); + let line = lines[lines.length - 1]; + let newNode = line.cloneNode(true); + let libelle = newNode.querySelector('input'); + libelle.value = ''; + + // ajouter la nouvelle ligne + line.parentNode.appendChild(newNode); + initLine(newNode); + }; +}