From 578450da42954e43098c82e38c35887f301b7ff4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 20 Apr 2026 11:18:44 +0200 Subject: [PATCH 001/133] Corrections syntaxiques href --- _archives.html | 4 ++-- _immobilisations.html | 4 ++-- _immobilisations_autres.html | 4 ++-- _unfinished.html | 4 ++-- add_infos.html | 2 +- amortization.html | 6 +++--- ignore.html | 2 +- other_amortizations.html | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/_archives.html b/_archives.html index 56f6b14..9f06778 100644 --- a/_archives.html +++ b/_archives.html @@ -149,12 +149,12 @@ {{/select}} - #{{$trans_id}} + #{{$trans_id}} {{$trans_date|date_short}} {{$exit_date|date_short}} {{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}} {{"%f"|math:$montant_immo|money_html:false|raw}} - {{$account_code}} + {{$account_code}} {{$account_label}} {{$project_label}} diff --git a/_immobilisations.html b/_immobilisations.html index d287632..9c4b6e6 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -193,14 +193,14 @@ {{:assign var="montant" from="sommes_immo.%s"|args:$account_code}} {{:assign var="sommes_immo.%s"|args:$account_code value="%d+%d"|math:$montant:$montant_immo}} - #{{$immo_trans_id}} + #{{$immo_trans_id}} {{$trans_date|date_short}} {{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}} {{$montant_immo|money_html:false|raw}} {{if $duration != null}}{{$duration}}{{/if}} {{$amort_amount|money_html:false|raw}} {{"%d-%d"|math:$montant_immo:$amort_amount|money_html:false|raw}} - {{$account_code}} + {{$account_code}} {{if ! $exist_amort || $status == "unknown"}} {{:linkbutton diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index 1f08e9b..5327a7b 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -172,11 +172,11 @@ {{:assign nb_immo="%d+1"|math:$nb_immo}} - #{{$immo_trans_id}} + #{{$immo_trans_id}} {{$trans_date|date_short}} {{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}} {{"%f"|math:$debit|money_html:false|raw}} - {{$account_code}} + {{$account_code}} {{$account_label}} {{:linkbutton diff --git a/_unfinished.html b/_unfinished.html index a222475..37ab4c9 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -154,11 +154,11 @@ {{:input type="checkbox" name="selected[]" value=$trans_id}} - #{{$trans_id}} + #{{$trans_id}} {{$trans_date|date_short}} {{$trans_label}} {{"%f"|math:$debit|money_html:false|raw}} - {{$account_code}} + {{$account_code}} {{$account_label}} {{:linkbutton diff --git a/add_infos.html b/add_infos.html index 1ee848b..718f8a1 100644 --- a/add_infos.html +++ b/add_infos.html @@ -172,7 +172,7 @@
Immobilisation
-
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
+
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
Montant
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
Date de l'écriture d'immobilisation
diff --git a/amortization.html b/amortization.html index cf162a2..12df9fa 100644 --- a/amortization.html +++ b/amortization.html @@ -238,7 +238,7 @@
Immobilisation
-
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
+
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
Montant
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
Début d'amortissement
@@ -283,7 +283,7 @@ {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.amort_year}} {{:assign solde="%f-%d"|math:$solde:$line.amort_amount}} - #{{$line.amort_trans_id}} + #{{$line.amort_trans_id}} {{$line.amort_date|date_short}} {{"%f"|math:$line.amort_amount|money_html:false|raw}} {{"%f"|math:$solde|money_html:false|raw}} @@ -293,7 +293,7 @@ — {{$line.amort_line_label}} {{/if}} - {{$line.account_code}} + {{$line.account_code}} {{$line.account_label}} {{:linkbutton label="Détacher" href="detach_amort.html?amort_line_id=%d&immo_line_id=%d"|args:$line.amort_line_id:$ligne_immo.immo_line_id shape="minus"}} diff --git a/ignore.html b/ignore.html index e396a77..96254fd 100644 --- a/ignore.html +++ b/ignore.html @@ -62,7 +62,7 @@
Écriture
-
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
+
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
Montant
{{"%f"|math:$ligne_immo.amount|money_currency_html:false|raw}}
diff --git a/other_amortizations.html b/other_amortizations.html index 91b379a..632c37e 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -140,13 +140,13 @@ {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.amort_trans_id}} {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.amort_year}} - #{{$line.amort_trans_id}} + #{{$line.amort_trans_id}} {{$line.trans_date|date_short}} {{"%f"|math:$line.amort_amount|money_html:false|raw}} {{$line.trans_label}} {{if $line.line_label != null && $line.line_label != $line.trans_label}} - {{$line.line_label}}{{/if}} - {{$line.account_code}} + {{$line.account_code}} {{$line.account_label}} {{:linkbutton label="Attacher" href="attach_amort.html?amort_line_id=%d&immo_line_id=%d"|args:$line.amort_line_id:$_GET.immo_line_id shape="plus"}} From f34af9b3fdc24e713221bfb1f7613025e4923533 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 23 Apr 2026 11:32:29 +0200 Subject: [PATCH 002/133] Correction erreur sortie bilan --- balance_sheet_exit.html | 6 ++++-- write_exit.html | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/balance_sheet_exit.html b/balance_sheet_exit.html index e7d9ba7..c9a0c0d 100644 --- a/balance_sheet_exit.html +++ b/balance_sheet_exit.html @@ -77,9 +77,11 @@ WHERE l_immo.id = :line_id AND account.code LIKE '28%' ; :line_id = $_GET.immo_line_id|intval - assign="amort_line" + assign="amort_lines." }} +{{/select}} +{{#foreach from=$amort_lines item="amort_line"}} {{#load type="link" where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id" assign="line" @@ -113,7 +115,7 @@ {{:assign last_amort_date=$amort_line.date}} {{/if}} {{/load}} -{{/select}} +{{/foreach}} {{if $total_amort == 0}} {{if $info_immo.status == "amortized"}} diff --git a/write_exit.html b/write_exit.html index a4de1cd..252a462 100644 --- a/write_exit.html +++ b/write_exit.html @@ -3,7 +3,7 @@ {{* Enregistrer les écritures de sortie du bilan paramètres : - - immo_line_id : numéro de ligne de l'écriture d'immobilisation + - immo_line_id : numéro de ligne de l'écriture d'immobilisation - amort_amount : montant des amortissements - year : exercice de la date de sortie de l'immobilisation - date_mes : date de mise en service de l'immobilisation @@ -30,6 +30,9 @@ }} {{/select}} +{{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} +{{/load}} + {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} From 463d5d109e66722c0ee40da80d3922d76a730cd5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 11:37:08 +0200 Subject: [PATCH 003/133] =?UTF-8?q?Affichage=20d=C3=A9tails=20immo=20;=20a?= =?UTF-8?q?jout=20montant=20au=20cr=C3=A9dit=20du=20compte=20d'une=20l'imm?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attach_immo.html | 153 ++++++++++++++++++++++++++++++++++++++++++++ details_immo.html | 159 ++++++++++++++++++++++++++++++++++++++++++++++ link_immo.html | 142 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 attach_immo.html create mode 100644 details_immo.html create mode 100644 link_immo.html diff --git a/attach_immo.html b/attach_immo.html new file mode 100644 index 0000000..f2ed727 --- /dev/null +++ b/attach_immo.html @@ -0,0 +1,153 @@ +{{* -*- brindille -*- *}} +{{:admin_header title="Écritures au crédit du compte d'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* + Enregistrer la liaison entre une ligne d'immobilisation et + une ligne d'écriture au crédit du compte de l'immobilisation + @param credit_line_id : ligne d'écriture au crédit du compte de l'immobilisation + @param immo_doc_id : numéro du doc d'immo +*}} + +{{* chercher l'écriture d'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="doc_immo"}} +{{else}} + {{:error message="Immobilisation non gérée ; vous devez d'abord renseigner ses informations"}} +{{/load}} +{{#select + line.id as immo_line_id, + line.id_transaction as immo_trans_id, + line.label as line_label, + trans.label as trans_label + 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 = $doc_immo.line + assign="ligne_immo" +}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/select}} + +{{:assign label_immo=$doc_immo.label|or:$ligne_immo.trans_label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} + +{{* chercher l'écriture au crédit du compte d'immobilisation *}} +{{#select + line.id_transaction as credit_trans_id, + line.credit as amount, + trans.label as trans_label, + line.label as line_label + 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.credit_line_id|intval + assign="credit_line" +}} +{{else}} + {{:error message="Impossible de trouver l'écriture au crédit du compte de l'immobilisation de la ligne « %s »"|args:$ligne_immo.trans_label}} +{{/select}} +{{:assign credit_trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$credit_line.credit_trans_id}} + +{{:assign montant_affecte=0}} +{{#load type="immo_link" assign="linked_immo." + where="$$.credit_line_id = :credit_line_id" + :credit_line_id = $_GET.credit_line_id|intval +}} + {{:assign montant_affecte="%d+%d"|math:$montant_affecte:$amount}} +{{/load}} +{{:assign reste="%d-%d"|math:$credit_line.amount:$montant_affecte}} + +{{* Traiter l'envoi du formulaire *}} +{{#form on="save"}} + {{* vérifier que le montant est inférieur au reste *}} + {{if $_POST.montant == null}} + {{:assign montant_credit=null}} + {{else}} + {{:assign montant_credit=$_POST.montant|floatval}} + {{:assign montant_credit="%f*100"|math:$montant_credit}} + {{if $montant_credit > $reste}} + {{:assign reste_nb="%f"|math:$reste|money_currency:false}} + {{:error message="Le montant de l'avoir ne peut être supérieur au reste (%s)"|args:$reste_nb}} + {{/if}} + {{/if}} + +{{* chercher les liaisons de l'écriture d'immobilisation *}} +{{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as linked_id + FROM acc_transactions_links as links + WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; + :immo_trans_id = $ligne_immo.immo_trans_id +}} + {{:assign var="linked_transactions." value=$linked_id}} +{{/select}} + +{{* ajouter la nouvelle liaison *}} +{{:assign var="linked_transactions." value=$credit_line.credit_trans_id}} + +{{* Enregistrer les liaisons *}} +{{:api + method="POST" + path="accounting/transaction/%s/transactions"|args:$ligne_immo.immo_trans_id + assign="result" + assign_code="result_code" + transactions=$linked_transactions +}} + +{{* + TODO ? vérifier le succès avant d'enregistrer le doc ? +*}} + +{{* enregistrer la liaison des lignes d'immo *}} +{{:save + key=""|uuid + type="immo_link" + immo_doc_id=$_GET.immo_doc_id|intval + credit_line_id=$_GET.credit_line_id|intval + amount=$montant_credit|intval +}} + +{{:redirect force="details_immo.html?immo_doc_id=%s&ok=1&msg=attach_immo"|args:$_GET.immo_doc_id}} +{{/form}} + +{{if ! $dialog}} + {{:include + file="_nav.html" + current="config" + subcurrent="other" + subsubcurrent="immo" + type_immo="other" +}} +{{/if}} +{{:form_errors}} + +
+
+
Immobilisation
+
{{$label_immo}}
+
Écriture au crédit du compte d'immobilisation
+
#{{$credit_line.credit_trans_id}} {{$credit_line.trans_label}}{{if $credit_line.line_label != null && $credit_line.line_label != $credit_line.trans_label}} — {{$credit_line.line_label}}{{/if}}
+
Montant de l'écriture
+
{{$credit_line.amount|money_currency_html:false|raw}}
+
Montant déjà affecté
+
{{"%f"|math:$montant_affecte|money_currency_html:false|raw}}
+
Montant restant à affecter
+
{{"%f"|math:$reste|money_currency_html:false|raw}}
+
+
+ +
+
+
+ {{:input type="money" name="montant" label="Montant" help="Montant de l'avoir ; à renseigner uniquement si différent du montant de l'écriture"}} +
+
+

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

+
+ diff --git a/details_immo.html b/details_immo.html new file mode 100644 index 0000000..0954f68 --- /dev/null +++ b/details_immo.html @@ -0,0 +1,159 @@ +{{* -*- brindille -*- *}} + +{{:admin_header title="Détails de l'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* + Afficher les détails d'une immmo + - permettre l'association d'une immo au crédit du compte de l'immo + - permettre de modifier les paramètres de l'immo + @param (OBSOLÈTE ?) immo_line_id : numéro de ligne de l'écriture d'immobilisation + @param immo_doc_id : numéro du doc d'immo +*}} + +{{* + TODO : permettre la modification des param (en cas d'erreur de saisie) + TODO : permettre de corriger le montant de l'amort et/ou de supprimer l'attachement + FAIT : déduire montant au crédit de la ligne d'immo +*}} + +{{* données de l'immobilisation *}} +{{#load type="immo" id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + +{{#select + trans.id as immo_trans_id, + trans.label as label, + trans.date as date_achat, + line.id as immo_line_id, + line.debit as montant, + line.label as line_label, + account.code as account_code, + account.label as account_label + FROM acc_transactions_lines AS line + INNER join acc_transactions AS trans ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS account ON line.id_account = account.id + WHERE line.id = :line_id; + :line_id = $info_immo.line + assign="ligne_immo" + }} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/select}} + +{{:assign var="info_immo.amount" value=$info_immo.amount|or:$ligne_immo.montant}} +{{:assign var="info_immo.date_achat" value=$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{:assign var="info_immo.date_mes" value=$info_immo.date_mes|or:$ligne_immo.date_achat}} +{{:assign var="info_immo.label" value=$info_immo.label|or:$ligne_immo.label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $info_immo.label}} + {{:assign var="info_immo.label" value=$info_immo.label|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} + +{{* + chercher des écritures liées à l'immo courante au crédit du même compte + et déduire leur montant de celui de l'immo +*}} +{{:assign linked_immos=null}} +{{:assign total_credits=0}} +{{#load type="immo_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} + {{#select + line.credit, + trans.id + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + WHERE line.id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign credit=$credit}} + {{:assign credit_trans_id=$id}} + {{/select}} + {{:assign var="linked_immos." value=$credit_trans_id}} + {{if $amount == null}} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{/load}} +{{:assign solde="%d-%d"|math:$info_immo.amount:$total_credits}} + +{{:assign total_amort=0}} +{{* lister les docs d'amortissement liées à la ligne d'immobilisation *}} +{{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id=$_GET.immo_doc_id|intval +}} + {{if $amount != null}} + {{:assign total_amort="%d+%d"|math:$total_amort:$amount}} + {{else}} + {{#select credit FROM acc_transactions_lines WHERE id = :amort_line_id; + :amort_line_id=$amort_line_id + }} + {{:assign total_amort="%d+%d"|math:$total_amort:$credit}} + {{/select}} + {{/if}} +{{/load}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{if $total_credits == 0 && $total_amort == 0}} + {{:assign subsubcurrent="credit"}} + {{else}} + {{:assign subsubcurrent=null}} + {{/if}} + {{:include file="_nav.html" current="index" subcurrent="details" subsubcurrent=$subsubcurrent}} +{{/if}} +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} + +{{if $_GET.ok}} + {{if $_GET.msg|match:"attach_amort"}} + {{:assign msg="Attachement amortissement effectué"}} + {{elseif $_GET.msg|match:"attach_immo"}} + {{:assign msg="Attachement avoir effectué"}} + {{elseif $_GET.msg|match:"info"}} + {{:assign msg="Données de l'immobilisation enregistrées"}} + {{/if}} +

{{$msg}}

+{{elseif $_GET.err}} + {{:assign msg="L'opération a échoué"}} +

{{$msg}}

+{{/if}} + +

+ Paramètres de l'immobilisation + #{{$ligne_immo.immo_trans_id}} +

+
+
+
Immobilisation
+
#{{$ligne_immo.immo_trans_id}} {{$info_immo.label}}
+
Compte d'immobilisation
+
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
+
Montant de l'immobilisation
+
{{"%f"|math:$info_immo.amount|money_currency_html:false|raw}}
+ {{if $total_credits > 0}} +
Montant des avoirs
+
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+
Écritures d'avoir
+
+ {{#foreach from=$linked_immos item="id"}} + {{:assign url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$id}} + #{{$id}} + {{/foreach}} + {{*:debug linked_immos=$linked_immos*}} +
+
Montant à amortir
+
{{"%f"|math:$solde|money_currency_html:false|raw}}
+ {{/if}} +
Date d'acquisition
+
{{$info_immo.date_achat|date_short}}
+ {{if $info_immo.date_mes != null && $info_immo.date_mes != $info_immo.date_achat}} +
Date de mise en service
+
{{$info_immo.date_mes|date_short}}
+ {{/if}} +
Durée d'amortissement
+
{{$info_immo.duration}} ans
+
Montant des amortissements
+
{{$total_amort|money_currency_html:false|raw}}
+
+
diff --git a/link_immo.html b/link_immo.html new file mode 100644 index 0000000..3543ab8 --- /dev/null +++ b/link_immo.html @@ -0,0 +1,142 @@ +{{* -*- brindille -*- *}} + +{{* + Lister les écritures au crédit du compte de l'immobilisation + paramètre et proposer de les attacher à l'immo paramètre + @param immo_doc_id : document associé à l'immo + *}} + +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Informations de l'immobilisation non trouvées"}} +{{/load}} + +{{* récupérer les infos de l'immobilisation *}} +{{#select + trans.id as immo_trans_id, + trans.label as label, + trans.date as date_achat, + line.id as immo_line_id, + line.label as line_label, + line.debit as montant, + account.code as account_code + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS account ON line.id_account = account.id + WHERE line.id = :line_id; + :line_id = $info_immo.line + assign="ligne_immo" + }} +{{else}} + {{:error message="Immobilisation « %s » non trouvée"|args:$info_immo.line}} +{{/select}} +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} +{{:assign label_immo=$ligne_immo.label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} + +{{* + lister les écritures au crédit du compte de l'immobilisation + variante : utiliser une jointure ; pas forcément plus efficace +*}} +{{#select + line.id as credit_line_id, + line.id_transaction as credit_trans_id, + line.credit as credit_amount, + line.label as line_label, + trans.id as immo_trans_id, + trans.date as trans_date, + trans.label as trans_label, + trans.id_year as credit_year, + account.id as account_id, + account.code as account_code, + account.label as account_label + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON trans.id = line.id_transaction + INNER JOIN acc_accounts AS account ON account.id = line.id_account + INNER JOIN acc_years AS y ON y.id = trans.id_year + WHERE account.code = :account_code AND credit > 0 + AND credit_trans_id NOT IN ( + SELECT + CASE WHEN id_transaction = credit_trans_id THEN id_transaction + ELSE id_related + END AS other_id + FROM acc_transactions_links WHERE other_id = credit_trans_id) + ORDER BY trans.date, trans.label; + :account_code = $ligne_immo.account_code + assign="other_immos." + }} +{{/select}} + +{{:admin_header title="Écritures au crédit du compte d'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{:include + file="_nav.html" + current="config" + subcurrent="other" + subsubcurrent="immo" + type_immo="other" +}} +{{/if}} + +
+
+ + Écritures au crédit du compte d'immobilisation « {{$ligne_immo.account_code}} » + + +
+
+
Immobilisation
+
#{{$ligne_immo.immo_trans_id}} {{$label_immo}}
+
Montant
+
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
+
Date de l'écriture d'immobilisation
+
{{$ligne_immo.date_achat|date_short}}
+
+
+
+ + {{if $other_immos != null}} + + + + + + + + + + + + + + {{#foreach from=$other_immos item="line"}} + {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.credit_trans_id}} + {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.credit_year}} + + + + + + + + + + {{/foreach}} + +
DateMontantLibelléN° compteCompte
#{{$line.credit_trans_id}}{{$line.trans_date|date_short}}{{"%f"|math:$line.credit_amount|money_html:false|raw}}{{$line.trans_label}} + {{if $line.line_label != null && $line.line_label != $line.trans_label}} - {{$line.line_label}}{{/if}} + {{$line.account_code}}{{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_immo.html?credit_line_id=%d&immo_doc_id=%s"|args:$line.credit_line_id:$_GET.immo_doc_id shape="plus"}} +
+

Sélectionner une écriture d'avoir ou autre réduction du montant de l'acquisition pour l'associer à l'immobilisation

+ {{else}} +

Aucune écriture au crédit du compte « {{$ligne_immo.account_code}} »

+ {{/if}} +
+{{:form_errors}} +{{:admin_footer}} From f8f4da59b6a4e8163920ca41d93faba7fc365ea4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 11:38:32 +0200 Subject: [PATCH 004/133] =?UTF-8?q?Prise=20en=20compte=20=C3=A9critures=20?= =?UTF-8?q?g=C3=A9r=C3=A9es=20uniquement=20(immo,=20cr=C3=A9dit,=20amort)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations.html | 205 +++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 135 deletions(-) diff --git a/_immobilisations.html b/_immobilisations.html index d287632..fa31b31 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -3,16 +3,16 @@ {{* Liste des immobilisations en cours d'amortissement ou amorties *}} {{:include file="_get_config.html" keep="module.config"}} -
-

- {{if $type_immo == "managed"}} - Cette page liste les immobilisations en cours d'amortissement - {{elseif $type_immo == "amortized"}} - Cette page liste les immobilisations dont l'amortissement est terminé - {{/if}} -

+

+ {{if $type_immo == "managed"}} + Cette page liste les immobilisations en cours d'amortissement + {{elseif $type_immo == "amortized"}} + Cette page liste les immobilisations dont l'amortissement est terminé + {{/if}} +

+{{if $module.table != null}} @@ -29,14 +29,6 @@ - {{* vérifier l'existence de la table du module *}} - {{#load limit="1"}} - {{:assign table_presente=true}} - {{else}} - {{:assign table_presente=false}} - {{/load}} - - {{if $table_presente}} {{* lister les immobilisations *}} {{:assign account_condition="("}} {{#foreach from=$module.config.prefixes item="code"}} @@ -44,17 +36,8 @@ {{:assign account_condition=$account_condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} {{/foreach}} {{:assign account_condition=$account_condition|cat:"0)"}} - {{:assign doc_condition="($$.status <> 'ignored' AND $$.status <> 'archived')"}} - - {{: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 filter_condition="($$.status IS NULL AND NOT (trans.status & 16) AND "|cat:$filter_condition|cat:")"}} - - {{:assign condition=$account_condition|cat:" AND debit > 0 AND ("|cat:$filter_condition|cat:" OR "|cat:$doc_condition|cat:")"}} + {{:assign status_condition="($$.status = 'managed' OR $$.status = 'amortized')"}} + {{:assign condition=$account_condition|cat:" AND line.debit > 0 AND "|cat:$status_condition}} {{:assign nb_immo=0}} {{:assign total_immo = 0}} @@ -68,152 +51,105 @@ account.id as account_id, account.code as account_code, trans.id_year as trans_id_year, + info.id as immo_doc_id, $$.duration as duration, + $$.label as doc_label, + $$.amount as doc_amount, + $$.date_achat as doc_date_achat, + $$.date as doc_date_mes, $$.status as status 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 INNER JOIN acc_years AS years ON trans.id_year = years.id - LEFT JOIN !table AS info ON $$.line = line.id + INNER JOIN !table AS info ON $$.line = line.id WHERE !condition - ORDER BY trans.date DESC; + ORDER BY COALESCE(doc_date_achat, trans_date) DESC; !table=$module.table !condition=$condition }} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$immo_trans_id}} {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$account_id:$trans_id_year}} - {{:assign duration=$duration}} - {{:assign montant_immo=$debit}} - {{if $status == null}} - {{:assign status="unknown"}} + {{:assign montant_immo=$doc_amount|or:$debit}} + {{:assign immo_date = $doc_date_achat|or:$trans_date}} + {{:assign label_immo=$doc_label|or:$trans_label}} + {{if $line_label != null && $line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$line_label}} {{/if}} - {{* chercher des écritures liées à l'immo courante au crédit du même compte + {{* + chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} - {{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$immo_trans_id - :account=$account_code - }} - {{:assign montant_immo="%d-%d"|math:$montant_immo:$credit}} - {{/select}} + {{#load + type="immo_link" + where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $immo_doc_id + }} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign montant_immo="%d-%d"|math:$montant_immo:$credit}} + {{/select}} + {{else}} + {{:assign montant_immo="%d-%d"|math:$montant_immo:$amount}} + {{/if}} + {{/load}} {{* Immobilisation soldée ? *}} - {{* TODO marquer archivée *}} + {{* TODO ¿ marquer archivée ? *}} {{if $montant_immo == 0}} {{:continue}} {{/if}} - {{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} + {{* chercher des lignes des écritures d'amortissement liées à la ligne d'immobilisation *}} {{:assign amort_lines=null}} - {{#select - l_amort.credit as amount, - CASE links.id_related = t_immo.id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as amort_trans_id, - l_amort.id AS amort_line_id - FROM acc_transactions_lines as l_immo - INNER JOIN acc_transactions as t_immo on t_immo.id = l_immo.id_transaction - INNER JOIN acc_transactions_links as links - ON (t_immo.id = links.id_transaction OR t_immo.id = links.id_related) - INNER JOIN acc_transactions_lines as l_amort on amort_trans_id = l_amort.id_transaction - INNER JOIN acc_accounts AS account ON l_amort.id_account = account.id - WHERE l_immo.id = :line_id AND l_amort.credit <> 0 AND account.code LIKE '28%'; - :line_id = $immo_line_id|intval - assign="line" - }} - {{:assign var="amort_lines.%d."|args:$amort_trans_id value=$line}} - {{/select}} - {{:assign amort_amount=0}} - {{#foreach from=$amort_lines key="amort_trans_id" item="lines"}} - {{:assign nb=$lines|count}} - {{* lister les docs de liaison de l'écriture d'amortissement *}} - {{:assign links=null}} - {{#load type="link" - where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id" - :immo_line_id = $immo_line_id - :amort_trans_id = $amort_trans_id - assign="links." + {{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $immo_doc_id + assign="amort_link" }} - {{/load}} - - {{#foreach from=$lines item="line"}} - {{* voir s'il existe une ligne associée à l'écriture d'amortissement *}} - {{:assign line_link_exist=false}} - {{#foreach from=$links item="link"}} - {{if $link.amort_line_id == $line.amort_line_id}} - {{:assign amort_amount="%d+%d"|math:$amort_amount:$line.amount}} - {{:assign line_link_exist=true}} - {{/if}} - {{/foreach}} - {{if ! $line_link_exist}} - {{if $nb == 1}} - {{* créer la liaison ligne immo <-> ligne amort *}} -{{*:debug lier_immo_line_id=$immo_line_id lier_amort_trans_id=$amort_trans_id avec_amort_line_id=$amort_line_id*}} - {{:save - key=""|uuid - type="link" - immo_line_id=$immo_line_id - amort_line_id=$amort_line_id - amort_trans_id=$amort_trans_id - }} - {{:assign amort_amount="%d+%d"|math:$amort_amount:$line.amount}} - {{/if}} - {{/if}} - {{/foreach}} - {{/foreach}} - - {{if $amort_amount == 0}} - {{:assign exist_amort=false}} - {{else}} - {{:assign exist_amort=true}} - {{:assign amort_amount=$amort_amount}} - {{/if}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :amort_line_id; + :amort_line_id = $amort_line_id + }} + {{:assign amort_amount="%d+%d"|math:$amort_amount:$credit}} + {{/select}} + {{else}} + {{:assign amort_amount="%d+%d"|math:$amort_amount:$amount}} + {{/if}} + {{/load}} {{* classement par onglet *}} {{if $type_immo == "managed" && $amort_amount >= $montant_immo}}{{:continue}}{{/if}} - {{if $status == "unknown" && ! $exist_amort}}{{:continue}}{{/if}} - {{if $type_immo == "amortized" && $amort_amount < $montant_immo}}{{:continue}}{{/if}} {{* ?? *}} + {{if $type_immo == "amortized" && $amort_amount < $montant_immo}}{{:continue}}{{/if}} {{:assign nb_immo="%d+1"|math:$nb_immo}} {{:assign total_immo="%d+%d"|math:$total_immo:$montant_immo}} {{:assign var="montant" from="sommes_immo.%s"|args:$account_code}} {{:assign var="sommes_immo.%s"|args:$account_code value="%d+%d"|math:$montant:$montant_immo}} - - - + + + - + @@ -250,9 +186,8 @@ {{/if}} -{{/if}}
#{{$immo_trans_id}}{{$trans_date|date_short}}{{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}}#{{$immo_trans_id}}{{$immo_date|date_short}}{{$label_immo}} {{$montant_immo|money_html:false|raw}} {{if $duration != null}}{{$duration}}{{/if}} {{$amort_amount|money_html:false|raw}} {{"%d-%d"|math:$montant_immo:$amort_amount|money_html:false|raw}}{{$account_code}}{{$account_code}} - {{if ! $exist_amort || $status == "unknown"}} + {{*if $amort_amount == 0*}} {{:linkbutton - label="Paramètres" - href="add_infos.html?immo_line_id=%s&type_immo=%s"|args:$immo_line_id:$type_immo - shape="settings" + label="Détails" + href="details_immo.html?immo_doc_id=%s"|args:$immo_doc_id + shape="search" }} -{{* target="_dialog"*}} - {{/if}} + {{* target="_dialog"*}} + {{*/if*}} {{:linkbutton label="Amortissements" - href="amortization.html?immo_line_id=%s&type_immo=%s"|args:$immo_line_id:$type_immo - shape="table" + href="amortization.html?immo_line_id=%s&type_immo=%s&immo_doc_id=%s"|args:$immo_line_id:$type_immo:$immo_doc_id shape="table" }}
- {{if $nb_immo == 0 || ! $table_presente}} -

Aucune immobilisation

- {{/if}} -
+{{/if}} +{{if $nb_immo == 0 || $module.table == null}} +

Aucune immobilisation

+{{/if}} From d5c62b6ef31f36c4fc7a2ffd5db29f71e10dd830 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 11:43:17 +0200 Subject: [PATCH 005/133] =?UTF-8?q?Prise=20en=20compte=20=C3=A9critures=20?= =?UTF-8?q?BOI=20avec=20montant=20immo=20subdivis=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations_autres.html | 346 +++++++++++++++++------------------ add_infos.html | 253 ++++++++++++------------- link.schema.json | 36 ++++ schema.json | 13 +- 4 files changed, 329 insertions(+), 319 deletions(-) create mode 100644 link.schema.json diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index 1f08e9b..781940a 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -1,199 +1,187 @@ {{* -*- brindille -*- *}} -{{* Liste des immobilisations non amortissables ou non (encore) gérées *}} +{{* Liste des immobilisations non gérées ou non entièrement affectées *}} {{:include file="_get_config.html" keep="module.config"}} -
+

+ Cette page liste les immobilisations pas encore prises en charge + par le module ou les écritures de la balance d'ouverture initiale + dont le montant n'est pas encore totalement affecté +

-

- Cette page liste les écritures pas (encore) prises en charge par le module et sans écriture d'amortissement associée. -

+{{:assign saved_hides=$module.config.hides}} +{{:assign var="user_hides" from="saved_hides.%s"|args:$logged_user.id}} - {{:assign saved_hides=$module.config.hides}} - {{:assign var="user_hides" from="saved_hides.%s"|args:$logged_user.id}} - - {{if $_POST|count == 0}} - {{:assign unhide=$user_hides.unhide_other}} +{{if $_POST|count == 0}} + {{:assign unhide=$user_hides.unhide_other}} +{{else}} + {{if $_POST.unhide == null}} + {{:assign unhide=0}} {{else}} - {{if $_POST.unhide == null}} - {{:assign unhide=0}} - {{else}} - {{:assign unhide=1}} + {{:assign unhide=1}} + {{/if}} + {{:assign var="user_hides.unhide_other" value=$unhide"}} + {{:assign var="saved_hides.%s"|args:$logged_user.id value=$user_hides}} + {{:save key="config" hides=$saved_hides}} +{{/if}} +{{if $unhide}} + {{:assign checked="checked"}} +{{/if}} + +{{* vérifier l'existence de la table du module *}} +{{if $module.table != null}} + {{:assign columns="$$.status as status, SUM($$.amount) as amount,"}} + {{:assign table_join="LEFT JOIN !table AS info ON $$.line = line.id"}} + {{:assign doc_condition="($$.status IS NULL OR $$.status == 'managed' OR $$.status == 'ignored')"}} +{{else}} + {{:assign columns=""}} + {{:assign table_join=""}} + {{:assign doc_condition="1"}} +{{/if}} + +{{* + lister les immobilisations non prises en charge par le module + ou dont le montant n'a pas été totalement affecté +*}} +{{:assign account_condition="("}} +{{#foreach from=$module.config.prefixes item="code"}} + {{:assign code=$code|cat:"%"|quote_sql}} + {{:assign account_condition=$account_condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} +{{/foreach}} +{{:assign account_condition=$account_condition|cat:"0)"}} + +{{if $unhide == null}} + {{: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)"}} +{{else}} + {{:assign filter_condition="1"}} +{{/if}} + +{{:assign condition=$account_condition|cat:" AND debit > 0 AND NOT (trans.status & 16) AND "|cat:$filter_condition|cat:" AND "|cat:$doc_condition}} + +{{:assign nb_managed=0}} +{{:assign nb_ignored=0}} +{{:assign nb_null=0}} +{{:assign nb_other=0}} +{{#select + trans.id as immo_trans_id, + trans.label as trans_label, + trans.date as trans_date, + line.id as immo_line_id, + line.debit AS debit, + line.label AS line_label, + account.id as account_id, + account.code as account_code, + account.label as account_label, + !columns + trans.id_year as trans_id_year + 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 + INNER JOIN acc_years AS years ON trans.id_year = years.id + !table_join + WHERE !condition + GROUP BY immo_line_id + ORDER BY trans.date DESC; + !columns=$columns + !table_join=$table_join + !table=$module.table + !condition=$condition + assign="immo_line" + }} + {{* + parmi les immos gérées, ne conserver que celles dont le montant dans le doc est non nul + et inférieur au montant de l'écriture d'immo + *}} + {{if $immo_line.status == 'managed'}} + {{if $immo_line.amount == null || $immo_line.amount == 0 || $immo_line.amount == $immo_line.debit}} + {{:continue}} {{/if}} - {{:assign var="user_hides.unhide_other" value=$unhide"}} - {{:assign var="saved_hides.%s"|args:$logged_user.id value=$user_hides}} - {{:save key="config" hides=$saved_hides}} {{/if}} - {{if $unhide}} - {{:assign checked="checked"}} + {{if $status == null}} + {{:assign nb_null="%d+1"|math:$nb_null}} + {{elseif $status == 'managed'}} + {{:assign nb_managed="%d+1"|math:$nb_managed}} + {{elseif $status == 'ignored'}} + {{:assign nb_ignored="%d+1"|math:$nb_ignored}} + {{else}} + {{:assign nb_other="%d+1"|math:$nb_other}} {{/if}} -
-
- {{:input type="checkbox" value=1 name="unhide" checked="%s"|args:$checked label="Afficher toutes les écritures" }} -
-
+ {{:assign var="immo_lines." value=$immo_line}} +{{/select}} +{{*:debug lines=$immo_lines nb_lines=$immo_lines|count nb_null=$nb_null nb_managed=$nb_managed nb_ignored=$nb_ignored nb_other=$nb_other unhide=$unhide*}} - - - - - - - - - - - - - + +
+ {{:input type="checkbox" value=1 name="unhide" checked="%s"|args:$checked label="Afficher les écritures ignorées" }} +
+ - {{* vérifier l'existence de la table du module *}} - {{#load limit="1"}} - {{:assign columns="$$.duration as duration, $$.status as status,"}} - {{:assign table_join="LEFT JOIN !table AS info ON $$.line = line.id"}} - {{:assign doc_condition1="($$.status == 'ignored')"}} - {{:assign doc_condition2="$$.status IS NULL"}} - {{else}} - {{:assign columns=""}} - {{:assign table_join=""}} - {{:assign doc_condition1="0"}} - {{:assign doc_condition2="1"}} - {{/load}} +{{if $immo_lines|count > 0}} +
DateLibelléMontantN° compteCompte
+ + + + + + + + + + + + + + + + {{#foreach from=$immo_lines item="line"}} - {{* lister les immobilisations *}} - {{:assign account_condition="("}} - {{#foreach from=$module.config.prefixes item="code"}} - {{:assign code=$code|cat:"%"|quote_sql}} - {{:assign account_condition=$account_condition|cat:" account.code LIKE "|cat:$code|cat:" OR "}} - {{/foreach}} - {{:assign account_condition=$account_condition|cat:"0)"}} - - {{if $unhide == null}} - {{: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)"}} - {{else}} - {{:assign filter_condition="1"}} - {{/if}} - {{:assign filter_condition="("|cat:$doc_condition2|cat:" AND NOT (trans.status & 16) AND "|cat:$filter_condition|cat:")"}} - - {{:assign condition=$account_condition|cat:" AND debit > 0 AND ("|cat:$filter_condition|cat:" OR "|cat:$doc_condition1|cat:")"}} - - {{:assign nb_immo=0}} - {{#select - trans.id as immo_trans_id, - trans.label as trans_label, - trans.date as trans_date, - line.id as immo_line_id, - line.debit AS debit, - line.label AS line_label, - account.id as account_id, - account.code as account_code, - account.label as account_label, - !columns - trans.id_year as trans_id_year - 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 - INNER JOIN acc_years AS years ON trans.id_year = years.id - !table_join - WHERE !condition - ORDER BY trans.date DESC; - !columns=$columns - !table_join=$table_join - !table=$module.table - !condition=$condition - }} - {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$immo_trans_id}} - {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$account_id:$trans_id_year}} - - {{if $status == null}} - {{:assign status="unknown"}} - {{/if}} - - {{if $unhide == null}} - {{if $status != "unknown"}} - {{:continue}} - {{/if}} - {{else}} - {{if $status != "ignored" && $status != "unknown"}} - {{:continue}} - {{/if}} - {{* vérifier si le libellé aurait pu être filtré *}} - {{#foreach from=$module.config.filters item="filter"}} - {{if $filter|strpos:$trans_label !== false}} - {{:assign status="ignored"}} - {{/if}} - {{/foreach}} - {{/if}} - - {{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} - {{:assign amort_lines=null}} - {{#select - l_amort.credit as amort_amount, - CASE links.id_related = t_immo.id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as amort_trans_id, - l_amort.id AS amort_line_id - FROM acc_transactions_lines as l_immo - INNER JOIN acc_transactions as t_immo on t_immo.id = l_immo.id_transaction - INNER JOIN acc_transactions_links as links - ON (t_immo.id = links.id_transaction OR t_immo.id = links.id_related) - INNER JOIN acc_transactions_lines as l_amort on amort_trans_id = l_amort.id_transaction - INNER JOIN acc_accounts AS account ON l_amort.id_account = account.id - WHERE l_immo.id = :line_id AND l_amort.credit <> 0 AND account.code LIKE '28%'; - :line_id = $immo_line_id|intval - assign="amort_lines." - }} - {{/select}} - {{:assign amort_amount=0}} - {{#foreach from=$amort_lines item="line"}} - {{* voir s'il existe un doc associé à l'écriture d'amortissement *}} - {{#load type="link" - where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id AND $$.amort_line_id = :amort_line_id" - :immo_line_id = $immo_line_id - :amort_trans_id = $line.amort_trans_id - :amort_line_id = $line.amort_line_id - }} - {{:assign amort_amount="%d+%d"|math:$amort_amount:$line.amount}} - {{else}} - {{* TODO À VÉRIFIER (cas multi-lignes) *}} - {{:assign amort_amount="%d+%d"|math:$amort_amount:$line.amount}} - {{/load}} - {{/foreach}} - {{if $amort_amount != 0}} + {{if $unhide == null}} + {{if $status == "ignored"}} {{:continue}} {{/if}} + {{else}} + {{* vérifier si le libellé aurait pu être filtré *}} + {{#foreach from=$module.config.filters item="filter"}} + {{if $filter|strpos:$trans_label !== false}} + {{:assign status="ignored"}} + {{/if}} + {{/foreach}} + {{/if}} - {{:assign nb_immo="%d+1"|math:$nb_immo}} - - - - - - - - - - {{/select}} - -
LigneDateLibelléMontantAffectéResteN° compteCompte
#{{$immo_trans_id}}{{$trans_date|date_short}}{{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}}{{"%f"|math:$debit|money_html:false|raw}}{{$account_code}}{{$account_label}} - {{:linkbutton - label="Paramètres" - href="add_infos.html?immo_line_id=%s&type_immo=other"|args:$immo_line_id - shape="settings" - target="_dialog" - }} -
- {{if $nb_immo == 0}} -

Aucune immobilisation

- {{/if}} -
+ {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.immo_trans_id}} + {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.trans_id_year}} + {{:assign reste="%d-%d"|math:$line.debit:$line.amount}} + + #{{$line.immo_trans_id}} + {{$line.immo_line_id}} + {{$trans_date|date_short}} + {{$line.trans_label}}{{if $line.line_label != null && $line.line_label != $line.trans_label}} — {{$line.line_label}}{{/if}} + {{"%f"|math:$line.debit|money_html:false|raw}} + {{"%f"|math:$line.amount|money_html:false|raw}} + {{"%f"|math:$reste|money_html:false|raw}} + {{$line.account_code}} + {{$line.account_label}} + + {{:linkbutton + label="Paramètres" + href="add_infos.html?immo_line_id=%s&type_immo=other"|args:$immo_line_id + shape="settings" + }} +{{* target="_dialog"*}} + + + {{/foreach}} + + +{{else}} +

Aucune immobilisation

+{{/if}} diff --git a/link.schema.json b/link.schema.json new file mode 100644 index 0000000..1524b55 --- /dev/null +++ b/link.schema.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Schéma des liens entre documents", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["amort_link", "immo_link"] + }, + "immo_doc_id" : { + "description": "identifiant du document d'immobilisation associé", + "type" : "integer", + "exclusiveMinimum": 0 + }, + "amort_line_id" : { + "description": "numéro de ligne d'amortissement associée à l'immobilisation", + "type": "integer", + "exclusiveMinimum": 0 + }, + "credit_line_id": { + "description": "numéro de ligne au crédit du compte de l'immobilisation", + "type": "integer", + "exclusiveMinimum": 0 + }, + "amount": { + "description": "montant de la ligne d'amortissement ou de crédit", + "type": ["number", "null"] + } + }, + "required": ["type", "immo_doc_id"], + "if": {"properties": {"type": {"const": "amort_link"}}, "required": ["type"]}, + "then": {"required": ["amort_line_id"]}, + "else": + "if": {"properties": {"type": {"const": "immo_link"}}, "required": ["type"]}, + "then": {"required": ["credit_line_id"]}, +} diff --git a/schema.json b/schema.json index 2acebc3..23a924b 100644 --- a/schema.json +++ b/schema.json @@ -14,11 +14,20 @@ "description": "durée de l'amortissement en années", "type": "integer" }, + "label" : { + "description" : "libellé de l'immobilisation si besoin", + "type" : ["string", "null"] + }, "amount" : { "description": "montant de l'immobilisation si besoin", "type": ["integer", "null"] }, - "date" : { + "date_achat" : { + "description" : "date d'achat de l'immobilisation si besoin", + "type" : ["string", "null"], + "format" : "date" + }, + "date_mes" : { "description" : "date de mise en service de l'immobilisation", "type" : ["string", "null"], "format" : "date" @@ -28,5 +37,5 @@ "enum" : ["managed", "amortized", "archived", "ignored"] } }, - "required": ["type", "line", "duration", "date"] + "required": ["type", "line", "duration", "status"] } From 87a1f31bb36e1be0568e71cbe100a45155481d34 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 12:01:24 +0200 Subject: [PATCH 006/133] =?UTF-8?q?liaisons=20=C3=A9critures=20remplac?= =?UTF-8?q?=C3=A9es=20par=20liaisons=20lignes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amortization.html | 259 ++++++++++++++++----------------------- other_amortizations.html | 85 ++++++------- save_amort.html | 154 +++++++++++------------ 3 files changed, 216 insertions(+), 282 deletions(-) diff --git a/amortization.html b/amortization.html index cf162a2..710bb6d 100644 --- a/amortization.html +++ b/amortization.html @@ -3,10 +3,16 @@ {{* Lister les écritures d'amortissement associées à une immobilisation @param immo_line_id : id de la ligne d'immo + @param immo_doc_id : id du doc associé à l'immo @param type_immo : managed, amortized, archived, others *}} -{{* récupérer les infos de l'immobilisation *}} +{{* données de l'immobilisation *}} +{{#load type="immo" id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select line.id as immo_line_id, line.debit as montant, @@ -14,167 +20,113 @@ trans.id as immo_trans_id, trans.label as label, trans.date, - account.code as account_code + account.code as account_code, + account.label as account_label FROM acc_transactions_lines AS line INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id INNER JOIN acc_accounts AS account ON line.id_account = account.id WHERE line.id = :line_id; - :line_id = $_GET.immo_line_id|intval - assign=ligne_immo + :line_id = $info_immo.line + assign="ligne_immo" }} {{else}} - {{:error message="Immobilisation %s non trouvée"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} -{{:assign date_debut=$ligne_immo.date}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} -{{#load type="immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} - {{:assign duree=$duration}} - {{:assign date_debut=$date}} - {{:assign status=$status}} -{{/load}} +{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date}} +{{:assign label_immo=$info_immo.label|or:$ligne_immo.label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.montant" value=$info_immo.amount}} +{{/if}} -{{if $status == 'ignored'}} +{{if $info_immo.status == 'ignored'}} {{:error message="Cette immobilisation ne doit pas être amortie"}} {{/if}} -{{* chercher des écritures liées à l'immo courante au crédit du même compte +{{* + chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$ligne_immo.immo_trans_id - :account=$ligne_immo.account_code - }} - {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} -{{/select}} +{{#load type="immo_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{/load}} {{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} {{:assign solde=$ligne_immo.montant}} +{{*:debug info_immo=$info_immo ligne_immo=$ligne_immo total_credits=$total_credits solde=$solde*}} -{{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} -{{#select - l_amort.credit as amort_amount, - l_amort.label as amort_line_label, - l_amort.id as amort_line_id, - CASE WHEN links.id_related = t_immo.id - THEN links.id_transaction - ELSE links.id_related - END as amort_trans_id, - trans.date as amort_date, - trans.label as amort_trans_label, - trans.id_year as amort_year, - account.id as account_id, - account.code as account_code, - account.label as account_label - FROM acc_transactions_lines as l_immo - INNER JOIN acc_transactions as t_immo on t_immo.id = l_immo.id_transaction - INNER JOIN acc_transactions_links as links - ON (t_immo.id = links.id_transaction OR t_immo.id = links.id_related) - INNER JOIN acc_transactions_lines as l_amort on amort_trans_id = l_amort.id_transaction - INNER join acc_transactions as trans on l_amort.id_transaction = trans.id - INNER join acc_accounts as account on l_amort.id_account = account.id - WHERE l_immo.id = :line_id AND account.code LIKE '28%' - ORDER BY trans.date; - :line_id = $_GET.immo_line_id|intval - assign="amort_line" -}} - {{* lister les lignes d'amortissement liées à la ligne d'immobilisation *}} - {{#load type="link" - where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id AND $$.amort_line_id = :amort_line_id" - assign="line" - :immo_line_id=$_GET.immo_line_id|intval - :amort_trans_id=$amort_line.amort_trans_id - :amort_line_id = $amort_line.amort_line_id - }} - {{:assign var="linked_amort." value=$amort_line}} - {{/load}} - {{if $date_debut == null}} - {{:assign date_debut=$amort_date}} - {{/if}} -{{/select}} - -{{if $status == "amortized"}} +{{if $info_immo.status == "amortized"}} {{:assign amort_amount=$ligne_immo.montant}} {{:assign valeur_residuelle=0}} {{else}} {{:assign valeur_residuelle=$ligne_immo.montant}} - {{#foreach from=$linked_amort}} - {{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$amort_amount}} - {{/foreach}} {{/if}} -{{* Autres amortissements non rattachés *}} -{{:include file="_get_config.html" keep="module.config"}} -{{: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 autres_amortissements=false}} -{{#select - line.id_transaction AS amort_trans_id - FROM acc_transactions_lines AS line - INNER JOIN acc_accounts AS account ON account.id = line.id_account - INNER JOIN acc_transactions AS trans ON trans.id = line.id_transaction - INNER JOIN acc_years AS y ON y.id = trans.id_year - WHERE account.code LIKE "28%" AND credit > 0 AND (NOT trans.status & 16) AND !filter_condition - ORDER BY trans.date, trans.label; - !filter_condition=$filter_condition - assign="amort" +{{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} +{{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $_GET.immo_doc_id|intval }} - {{* voir s'il existe des écritures liées avec un numéro de compte d'immobilisation *}} {{#select - links.id_transaction, - links.id_related, - trans.id AS trans_id - FROM acc_transactions_links AS links - INNER JOIN acc_transactions AS trans ON ( - CASE - WHEN links.id_transaction = :id_amort THEN links.id_related - WHEN links.id_related = :id_amort THEN links.id_transaction - END) = trans.id - INNER JOIN acc_transactions_lines AS line ON line.id_transaction = trans.id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE - links.id_transaction = :id_amort OR links.id_related = :id_amort - AND acc.code LIKE '21%' - LIMIT 1 + line.id as amort_line_id, + line.credit, + line.label as amort_line_label, + trans.id as amort_trans_id, + trans.label as amort_trans_label, + trans.date as amort_date, + trans.id_year as amort_year, + account.id as account_id, + account.code as account_code, + account.label as account_label + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + INNER join acc_accounts AS account on line.id_account = account.id + WHERE line.id = :amort_line_id ; - :id_amort=$amort.amort_trans_id + :amort_line_id = $amort_line_id + assign="amort_line" }} - {{* voir s'il existe un doc associé à une ligne de l'amortissement *}} - {{:assign keep=true}} - {{#load type="link" - where="$$.amort_trans_id = :amort_trans_id" - :amort_trans_id = $amort.amort_trans_id - }} - {{if $amort_line_id == $amort.amort_line_id}} - {{:assign keep=false}} - {{:break}} - {{/if}} - {{else}} - {{:assign keep=false}} - {{/load}} - {{if $keep}} - {{:assign autres_amortissements=true}} - {{/if}} - {{else}} - {{:assign autres_amortissements=true}} + {{:assign var="amort_line.amort_amount" value=$amount|or:$credit}} + {{:assign var="linked_amort.%s_%d"|args:$amort_date:$id value=$amort_line}} + {{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$amort_line.amort_amount}} {{/select}} -{{/select}} +{{/load}} + +{{if $_GET.type_immo == null || $_GET.type_immo != "amortized"}} + {{* Chercher des amortissements non rattachés à une immo *}} + {{:assign autres_amortissements=false}} + {{#select + line.id as amort_line_id, + line.id_transaction AS amort_trans_id + FROM acc_transactions_lines AS line + INNER JOIN acc_accounts AS account ON account.id = line.id_account + INNER JOIN acc_transactions AS trans ON trans.id = line.id_transaction + INNER JOIN acc_years AS y ON y.id = trans.id_year + WHERE account.code LIKE "28%" AND credit > 0 AND (NOT trans.status & 16) + ORDER BY trans.date, trans.label; + }} + {{* cette ligne d'amortissement a-t-elle un doc associé ? *}} + {{#load type="amort_link" + where="$$.amort_line_id = :amort_line_id" + :amort_line_id = $amort_line_id + }} + {{else}} + {{:assign autres_amortissements=true}} + {{/load}} + {{/select}} +{{/if}} {{:admin_header title="Liste des amortissements" custom_css="./style.css" current="module_amortization"}} @@ -200,16 +152,16 @@ {{if $_GET.ok}} {{if $_GET.msg|match:"attach"}} - {{:assign msg="Attachement écriture %s effectué"|args:$_GET.trans_id}} + {{:assign msg="Attachement amortissement %s effectué"|args:$_GET.trans_id}} {{elseif $_GET.msg|match:"detach"}} - {{:assign msg="Détachement écriture %s affectué"|args:$_GET.trans_id}} + {{:assign msg="Détachement amortissement %s affectué"|args:$_GET.trans_id}} {{elseif $_GET.msg|match:"amortissement"}} {{:assign msg="Amortissement enregistré"}} {{/if}}

{{$msg}}

{{elseif $_GET.err}} {{if $_GET.msg|match:"attach"}} - {{:assign msg="Échec attachement"}} + {{:assign msg="Échec attachement amortissement"}} {{elseif $_GET.msg|match:"amortissement"}} {{:assign msg="Échec enregistrement amortissement"}} {{/if}} @@ -222,7 +174,7 @@

{{:linkbutton label="Sortir du bilan" - href="balance_sheet_exit.html?immo_line_id=%s&type_immo=%s"|args:$_GET.immo_line_id:$_GET.type_immo + href="balance_sheet_exit.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$_GET.type_immo shape="export" class="main" }} @@ -238,14 +190,22 @@

Immobilisation
-
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
-
Montant
+
#{{$ligne_immo.immo_trans_id}} {{$label_immo}}
+
Compte d'immobilisation
+
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
+
Montant de l'immobilisation
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
+ {{if $total_credits > 0}} +
Montant des avoirs
+
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+
Montant à amortir
+
{{"%f"|math:$solde|money_currency_html:false|raw}}
+ {{/if}}
Début d'amortissement
{{$date_debut|date_short}}
- {{if $duree != null}} + {{if $info_immo.duration != null}}
Durée
-
{{$duree}} ans
+
{{$info_immo.duration}} ans
{{/if}} {{if $valeur_residuelle > 0}}
Montant des amortissements
@@ -253,9 +213,9 @@
Valeur nette comptable
{{$valeur_residuelle|money_currency_html:false|raw}}
{{/if}} - {{if $duree != null && $valeur_residuelle > 0}} + {{if $info_immo.duration != null && $valeur_residuelle > 0}}
Annuité estimée
-
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$ligne_immo.montant:$duree|money_currency_html:false|raw}}
+
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$ligne_immo.montant:$info_immo.duration|money_currency_html:false|raw}}
{{/if}}
@@ -277,13 +237,13 @@ - {{#foreach from=$linked_amort item="line"}} + {{#foreach from=$linked_amort|ksort item="line"}} {{* données de l'écriture *}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.amort_trans_id}} {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.amort_year}} {{:assign solde="%f-%d"|math:$solde:$line.amort_amount}} - #{{$line.amort_trans_id}} + #{{$line.amort_trans_id}} {{$line.amort_date|date_short}} {{"%f"|math:$line.amort_amount|money_html:false|raw}} {{"%f"|math:$solde|money_html:false|raw}} @@ -293,10 +253,10 @@ — {{$line.amort_line_label}} {{/if}} - {{$line.account_code}} + {{$line.account_code}} {{$line.account_label}} - {{:linkbutton label="Détacher" href="detach_amort.html?amort_line_id=%d&immo_line_id=%d"|args:$line.amort_line_id:$ligne_immo.immo_line_id shape="minus"}} + {{:linkbutton label="Détacher" href="detach_amort.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$ligne_immo.immo_line_id:$_GET.immo_doc_id shape="minus"}} {{/foreach}} @@ -308,13 +268,10 @@ {{/if}} {{if $_GET.type_immo == null || $_GET.type_immo != "amortized"}} - - {{* Autres amortissements non rattachés *}} - {{if $autres_amortissements}}

- Il existe des écritures d'amortissement qui ne sont pas rattachées à une immobilisation !
- Utilisez le bouton « Rattacher une écriture » pour les afficher ; vous pourrez choisir d'en attacher certaines à cette immobilisation. + Il y a des écritures d'amortissement qui ne sont pas rattachées à une immobilisation !
+ Utilisez le bouton « Rattacher un amortissement » pour les afficher ; vous pourrez choisir d'en attacher certaines à cette immobilisation.

{{/if}} {{/if}} diff --git a/other_amortizations.html b/other_amortizations.html index 91b379a..ec439b7 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -4,6 +4,7 @@ Lister les écritures d'amortissement indépendantes et proposer des les attacher à l'immo sélectionnée @param immo_line_id = id de la ligne d'immo + @param immo_doc_id id du doc d'immo associé *}} {{* récupérer les infos de l'immobilisation *}} @@ -17,11 +18,19 @@ assign=ligne_immo }} {{else}} - {{:error message="Immobilisation %s non trouvée"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} -{{:include file="_get_config.html" keep="module.config"}} +{{#load id=$_GET.immo_doc_id|intval}} + {{:assign label_immo=$label|or:$ligne_immo.label}} +{{else}} + {{:error message="Informations de l'immobilisation %s (%s) non trouvées"|args:$_GET.immo_line_id:$ligne_immo.label}} +{{/load}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} +{{:include file="_get_config.html" keep="module.config"}} {{if $_POST.unhide == null}} {{:assign filter_condition=" NOT ("}} {{#foreach from=$module.config.filters item="filter"}} @@ -54,46 +63,26 @@ !filter_condition=$filter_condition assign="amort" }} - - {{* voir s'il existe des écritures liées avec un numéro de compte d'immobilisation *}} - {{#select - links.id_transaction, - links.id_related, - trans.id AS trans_id - FROM acc_transactions_links AS links - INNER JOIN acc_transactions AS trans ON ( - CASE - WHEN links.id_transaction = :id_amort THEN links.id_related - WHEN links.id_related = :id_amort THEN links.id_transaction - END) = trans.id - INNER JOIN acc_transactions_lines AS line ON line.id_transaction = trans.id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE - links.id_transaction = :id_amort OR links.id_related = :id_amort - AND acc.code LIKE '21%' - LIMIT 1 - ; - :id_amort=$amort.amort_trans_id + {{* voir s'il existe des lignes d'immo liées à cette ligne d'amortissement *}} + {{:assign amort_amount=0}} + {{:assign keep_amort=true}} + {{#load type="amort_link" + where="$$.amort_line_id = :amort_line_id" + :amort_line_id=$amort.amort_line_id|intval + assign="amort_link" }} - {{* voir s'il existe un doc associé à une ligne de l'amortissement *}} - {{:assign keep=true}} - {{#load type="link" - where="$$.amort_trans_id = :amort_trans_id" - :amort_trans_id = $amort.amort_trans_id - }} - {{if $amort_line_id == $amort.amort_line_id}} - {{:assign keep=false}} - {{:break}} - {{/if}} + {{if $amort_link.amount == null || $amort_link.amount == 0}} + {{:assign amort_amount=$amort.amort_amount}} + {{:assign keep_amort=false}} {{else}} - {{:assign keep=false}} - {{/load}} - {{if $keep}} - {{:assign var="autres_amortissements." value=$amort}} + {{:assign amort_amount="%d+%d"|math:$amort_amount:$amort_link.amount}} {{/if}} {{else}} - {{:assign var="autres_amortissements." value=$amort}} - {{/select}} + {{* pas de ligne d'immo liée à cette ligne d'amort => garder cette ligne d'amortissement *}} + {{/load}} + {{if $keep_amort && $amort_amount < $amort.amort_amount}} + {{:assign var="free_amort_lines." value=$amort}} + {{/if}} {{/select}} {{:admin_header title="Amortissements non rattachés" custom_css="./style.css" current="module_amortization"}} @@ -106,7 +95,7 @@ subcurrent="other" subsubcurrent="amortization" type_immo="other" - autres_amort=$autres_amortissements + autres_amort=$free_amort_lines }} {{/if}} @@ -116,13 +105,13 @@
- {{:input type="checkbox" value=1 name="unhide" checked="%s"|args:$checked label="Afficher toutes les écritures" }} + {{:input type="checkbox" value=1 name="unhide" checked="%s"|args:$checked label="Afficher les écritures ignorées"}}
-{{if $autres_amortissements != null}} +{{if $free_amort_lines != null}}
-

Immobilisation « {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}} »

+

Immobilisation « {{$label_immo}} »

@@ -136,20 +125,24 @@ - {{#foreach from=$autres_amortissements item="line"}} + {{#foreach from=$free_amort_lines item="line"}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.amort_trans_id}} {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.amort_year}} - + - + {{/foreach}} diff --git a/save_amort.html b/save_amort.html index 4aa8e64..6a8459c 100644 --- a/save_amort.html +++ b/save_amort.html @@ -3,6 +3,7 @@ {{* Créer une écriture d'amortissement @param immo_line_id : id de la ligne d'immobilisation + @param immo_doc_id : id du doc associé à l'immo *}} {{* Infos de l'immobilisation *}} @@ -11,7 +12,7 @@ line.debit as montant, line.id_project as project_id, line.label as line_label, - trans.id as trans_id, + trans.id as immo_trans_id, trans.label, trans.date, account.code as account_code @@ -21,106 +22,90 @@ LEFT JOIN acc_projects AS project ON line.id_project = project.id WHERE line.id = :line_id; :line_id = $_GET.immo_line_id|intval - assign=ligne_immo + assign="ligne_immo" }} {{else}} - {{:error message="Immobilisation %s non trouvée"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} {{:assign date_debut=$ligne_immo.date}} -{{:assign var="amort_label" value="Amortissement %s"|args:$ligne_immo.label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} + +{{#load id=$_GET.immo_doc_id|intval}} + {{:assign duree=$duration}} + {{if $date_mes != null}} + {{:assign date_debut=$date_mes}} + {{/if}} + {{:assign status=$status}} + {{:assign amort_label=$label|or:$ligne_immo.label}} + {{if $amount != null}} + {{:assign var="ligne_immo.montant" value=$amount}} + {{/if}} +{{else}} + {{:error message="Informations de l'immobilisation « %s » non trouvées ; vous devez d'abord les renseigner"|args:$ligne_immo.label}} +{{/load}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $amort_label}} {{:assign amort_label=$amort_label|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} - -{{#load type="immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} - {{:assign duree=$duration}} - {{:assign date_debut=$date}} - {{:assign status=$status}} -{{else}} - {{:error message="Vous devez renseigner la date de mise en service et la durée d'immobilisation"}} -{{/load}} +{{:assign var="amort_label" value="Amortissement %s"|args:$amort_label}} {{if $status == "amortized" || $status == "archived"}} {{:error message="Cette immobilisation est complètement amortie ; il est impossible d'ajouter une écriture d'amortissement"}} {{/if}} -{{* chercher des écritures liées à l'immo courante au crédit du même compte +{{* + chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$ligne_immo.trans_id - :account=$ligne_immo.account_code +{{#load + type="immo_link" + where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $_GET.immo_doc_id|intval }} - {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} -{{/select}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{/load}} {{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} {{:assign solde=$ligne_immo.montant}} -{{* chercher des écritures d'amortissement liées à l'immobilisation *}} -{{#select - l_amort.credit as amort_amount, - l_amort.label as amort_label, - l_amort.id as amort_line_id, - CASE WHEN links.id_related = t_immo.id - THEN links.id_transaction - ELSE links.id_related - END as amort_trans_id, - trans.date as amort_date, - trans.label as trans_label, - trans.id_year as amort_year, - account.id as account_id, - account.code as account_code, - account.label as account_label - FROM acc_transactions_lines as l_immo - INNER JOIN acc_transactions as t_immo on t_immo.id = l_immo.id_transaction - INNER JOIN acc_transactions_links as links - ON (t_immo.id = links.id_transaction OR t_immo.id = links.id_related) - INNER JOIN acc_transactions_lines as l_amort on amort_trans_id = l_amort.id_transaction - INNER join acc_transactions as trans on l_amort.id_transaction = trans.id - INNER join acc_accounts as account on l_amort.id_account = account.id - WHERE - l_immo.id = :line_id - AND account.code LIKE '28%' - ORDER BY trans.date; - :line_id = $_GET.immo_line_id|intval - assign="amort_line" -}} - {{#load type="link" - where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id" - order="$$.date" - assign="line" - :immo_line_id=$_GET.immo_line_id|intval :amort_trans_id=$amort_line.amort_trans_id +{{* chercher des écritures d'amortissement liées à la ligne d'immobilisation *}} +{{#load + type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + order="$$.date" + :immo_doc_id=$_GET.immo_doc_id|intval }} - {{if $line.amort_line_id == $amort_line.amort_line_id}} - {{:assign var="linked_amort." value=$amort_line}} - {{/if}} - {{else}} - {{:assign var="linked_amort." value=$amort_line}} - {{/load}} -{{/select}} - + {{#select + line.credit, + trans.date as amort_date, + account.code as account_code, + account.label as account_label + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + INNER join acc_accounts AS account on line.id_account = account.id + WHERE line.id = :amort_line_id + ; + :amort_line_id = $amort_line_id + assign="amort_line" + }} + {{:assign var="amort_line.amort_amount" value=$amount|or:$credit}} + {{:assign var="linked_amort.%s_%d"|args:$amort_date:$id value=$amort_line}} + {{/select}} +{{/load}} {{:assign total_amort=0}} {{:assign valeur_residuelle=$ligne_immo.montant}} -{{#foreach from=$linked_amort}} - {{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$amort_amount}} - {{:assign total_amort="%d+%d"|math:$total_amort:$amort_amount}} - {{:assign date_debut=$amort_date}} - {{:assign code_amort=$account_code}} - {{:assign amort_account_label=$account_label}} - {{:assign amort_label=$amort_label}} +{{#foreach from=$linked_amort|ksort item="line"}} + {{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$line.amort_amount}} + {{:assign total_amort="%d+%d"|math:$total_amort:$line.amort_amount}} + {{:assign date_debut=$line.amort_date}} + {{:assign code_amort=$line.account_code}} + {{:assign amort_account_label=$line.account_label}} {{/foreach}} {{if $valeur_residuelle == 0}} @@ -221,7 +206,7 @@ }} {{if $account_ok == null}} {{:assign compte=$credit_account|implode:""}} - {{:redirect url="add_account.html?account=%s&chart=%s&immo_line_id=%s"|args:$compte:$selected_chart:$_GET.immo_line_id}} + {{:redirect url="add_account.html?account=%s&chart=%s"|args:$compte:$selected_chart}} {{/if}} {{* vérifier que le montant ne dépasse pas le solde restant *}} @@ -256,7 +241,7 @@ date=$_POST.date_amort label=$_POST.designation lines=$lines - linked_transactions=$ligne_immo.trans_id|intval + linked_transactions=$ligne_immo.immo_trans_id|intval }} {{* enregistrer la liaison des lignes *}} @@ -275,14 +260,13 @@ {{if $amort_trans_id != null}} {{:save key=""|uuid - type="link" - immo_line_id=$_GET.immo_line_id|intval + type="amort_link" + immo_doc_id=$_GET.immo_doc_id|intval amort_line_id=$amort_line_id|intval - amort_trans_id=$result.id }} {{/if}} - {{:redirect force="amortization.html?immo_line_id=%s&ok=1&msg=amortissement"|args:$_GET.immo_line_id}} + {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&ok=1&msg=amortissement"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} {{/form}} {{:admin_header title="Ajout amortissement" custom_css="./style.css" current="module_amortization"}} From faccd71ef8bbe5dcf5b380829e845e0729c4d304 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 12:02:07 +0200 Subject: [PATCH 007/133] =?UTF-8?q?liaison=20lignes=20+=20possibilit=C3=A9?= =?UTF-8?q?=20saisir=20montant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attach_amort.html | 199 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 147 insertions(+), 52 deletions(-) diff --git a/attach_amort.html b/attach_amort.html index 4770afa..b320848 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -1,74 +1,169 @@ {{* -*- brindille -*- *}} {{* - Enregistrer la liaison entre une écriture d'amortissement et - l'écriture d'immobilisation correspondante + Enregistrer la liaison entre une ligne d'écriture d'amortissement + et une ligne d'écriture d'immobilisation + @param immo_line_id : numéro de ligne de l'écriture d'immobilisation + @param amort_line_id : numéro de ligne de l'écriture d'amortissement + @param immo_doc_id : numéro du doc d'immo *}} {{* chercher l'écriture d'immobilisation *}} {{#select - id_transaction - FROM acc_transactions_lines - WHERE id = :line_id; + line.id_transaction as immo_trans_id, + trans.label as trans_label, + line.label as line_label + 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_line_id|intval + assign="ligne_immo" }} - {{:assign immo_trans_id=$id_transaction}} {{else}} - {{:error message="Impossible de trouver l'écriture d'immobilisation de la ligne « %s »"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} +{{* chercher le doc associé à l'immo *}} +{{#load id=$_GET.immo_doc_id|intval}} + {{:assign label_immo=$label|or:$ligne_immo.trans_label}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} + {{* chercher l'écriture d'amortissement *}} {{#select - id_transaction - FROM acc_transactions_lines - WHERE id = :line_id; + line.credit as amount, + line.label as line_label, + trans.date as amort_date, + trans.label as trans_label, + trans.id as trans_id, + acc.code as account_code, + acc.label as account_label + FROM acc_transactions_lines as line + INNER JOIN acc_transactions as trans on line.id_transaction = trans.id + INNER JOIN acc_accounts as acc on line.id_account = acc.id + WHERE line.id = :line_id; :line_id = $_GET.amort_line_id|intval + assign="amort_line" }} - {{:assign amort_trans_id=$id_transaction}} {{else}} - {{:error message="Impossible de trouver l'écriture d'amortissement de la ligne « %s »"|args:$_GET.amort_line_id}} + {{:error message="Amortissement non trouvé"}} {{/select}} +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$amort_line.trans_id}} -{{* chercher les liaisons de l'écriture d'immobilisation *}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as linked_id - FROM acc_transactions_links as links - WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; - :immo_trans_id = $immo_trans_id -}} - {{:assign var="linked_transactions." value=$linked_id}} -{{/select}} - -{{* ajouter la nouvelle liaison *}} -{{:assign var="linked_transactions." value=$amort_trans_id}} -{{:api - method="POST" - path="accounting/transaction/%s/transactions"|args:$immo_trans_id - assign="result" - assign_code="result_code" - transactions=$linked_transactions -}} - -{{* vérifier si cette liaison est déjà présente dans les documents pour éviter les doublons *}} -{{#load type="link" - where="$$.immo_line_id = :immo_line_id AND - $$.amort_trans_id = :amort_trans_id AND - $$.amort_line_id = :amort_line_id" - :immo_line_id=$_GET.immo_line_id|intval - :amort_trans_id = $amort_trans_id +{{* montant de l'écriture d'amortissement déjà affecté *}} +{{:assign montant_affecte=0}} +{{#load type="amort_link" assign="linked_amort." + where="$$.amort_line_id = :amort_line_id" :amort_line_id = $_GET.amort_line_id|intval - limit=1 }} -{{else}} - {{:save - key=""|uuid - type="link" - immo_line_id=$_GET.immo_line_id|intval - amort_line_id=$_GET.amort_line_id|intval - amort_trans_id=$amort_trans_id - }} + {{:assign montant_affecte="%d+%d"|math:$montant_affecte:$amount}} {{/load}} -{{:redirect force="amortization.html?immo_line_id=%s&ok=1&msg=attach&trans_id=%s"|args:$_GET.immo_line_id:$amort_trans_id}} +{{:assign reste="%d-%d"|math:$amort_line.amount:$montant_affecte}} + +{{* Traiter l'envoi du formulaire *}} +{{#form on="save"}} + + {{* vérifier que le montant saisi est inférieur au reste *}} + {{if $_POST.montant == null}} + {{if $montant_affecte == 0}} + {{:assign saved_amount=null}} + {{else}} + {{:assign saved_amount=$reste}} + {{/if}} + {{else}} + {{:assign montant_amort=$_POST.montant|floatval}} + {{:assign montant_amort="%f*100"|math:$montant_amort}} + {{if $montant_amort > $reste}} + {{:assign reste_nb="%f"|math:$reste|money_currency:false}} + {{:error message="Le montant de l'amortissement ne peut être supérieur au reste (%s)"|args:$reste_nb}} + {{/if}} + {{if $montant_amort == $amort_line.amount}} + {{:assign saved_amount=null}} + {{else}} + {{:assign saved_amount=$montant_amort|intval}} + {{/if}} + {{/if}} + + {{* chercher les liaisons de l'écriture d'immobilisation *}} + {{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as linked_id + FROM acc_transactions_links as links + WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; + :immo_trans_id = $ligne_immo.immo_trans_id + }} + {{:assign var="linked_transactions." value=$linked_id}} + {{/select}} + + {{* ajouter la nouvelle liaison *}} + {{:assign var="linked_transactions." value=$amort_line.trans_id}} + {{:api + method="POST" + path="accounting/transaction/%s/transactions"|args:$ligne_immo.immo_trans_id + assign="result" + assign_code="result_code" + transactions=$linked_transactions + }} + + {{* vérifier si cette liaison est déjà présente dans les documents pour éviter les doublons *}} + {{* TODO voir si nécessaire ? *}} + {{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id AND $$.amort_line_id = :amort_line_id" + :immo_doc_id=$_GET.immo_doc_id|intval + :amort_line_id = $_GET.amort_line_id|intval + limit=1 + }} + {{else}} + {{:save + key=""|uuid + type="amort_link" + immo_doc_id=$_GET.immo_doc_id|intval + amort_line_id=$_GET.amort_line_id|intval + amount=$saved_amount + }} + {{/load}} + + {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&ok=1&msg=attach_amort"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} +{{/form}} + +{{:admin_header title="Amortir l'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{:include file="_nav.html" current="config" subcurrent="init" subsubcurrent="parameter"}} +{{/if}} +{{:form_errors}} + +
+
+
Immobilisation
+
{{$label_immo}}
+
Amortissement
+
#{{$amort_line.trans_id}} {{$label_immo}}
+
Montant de l'écriture d'amortissement
+
{{$amort_line.amount|money_currency_html:false|raw}}
+
Montant déjà affecté
+
{{"%f"|math:$montant_affecte|money_currency_html:false|raw}}
+
Montant restant à affecter
+
{{"%f"|math:$reste|money_currency_html:false|raw}}
+
+
+ +
+
+
+ {{:input type="money" name="montant" label="Montant" default=$reste help="Montant de l'amortissement"}} +
+
+

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

+ + From e31286f440462b66f69366eb7271a908c235d708 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 12:03:03 +0200 Subject: [PATCH 008/133] =?UTF-8?q?Adaptation=20nouveau=20sch=C3=A9ma=20do?= =?UTF-8?q?c=20immo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_asset.html | 7 ++++--- detach_amort.html | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/add_asset.html b/add_asset.html index 5cbe061..2ee28bd 100644 --- a/add_asset.html +++ b/add_asset.html @@ -141,7 +141,7 @@ type="immo" line=$immo_line_id duration=$duration - date=$date_debut + date_mes=$date_debut status=$status }} {{/if}} @@ -243,8 +243,9 @@ function changeYear(evt, f_accounts = ['credit_account', 'debit_account'], f_yea setSelectorYear(f_accounts, f_years_select); } -function changeVisibility(evt, idcheck = 'f_amortir_1', fields = ['div_amort']) { - toggleVisibility(idcheck, fields); +function changeVisibility(evt, idcheck = 'f_amortir_1', iddiv = 'div_amort') +{ + toggleVisibility(idcheck, document.querySelectorAll('#' + iddiv)); } (function () { diff --git a/detach_amort.html b/detach_amort.html index c078c3f..caae1a0 100644 --- a/detach_amort.html +++ b/detach_amort.html @@ -3,6 +3,9 @@ {{* Supprimer l'association entre une écriture d'amortissement et une écriture d'immobilisation + @param immo_line_id : id de la ligne d'immo + @param amort_line_id : id de la ligne d'amortissement + @param immo_doc_id : id du doc associé à l'immo *}} {{* chercher l'écriture d'immobilisation *}} @@ -14,7 +17,7 @@ }} {{:assign immo_trans_id=$id_transaction}} {{else}} - {{:error message="Impossible de trouver l'écriture d'immobilisation de la ligne « %s »"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} {{* chercher l'écriture d'amortissement *}} @@ -26,7 +29,7 @@ }} {{:assign amort_id=$id_transaction}} {{else}} - {{:error message="Impossible de trouver l'écriture d'amortissement de la ligne « %s »"|args:$_GET.amort_line_id}} + {{:error message="Amortissement non trouvé"}} {{/select}} {{* @@ -57,15 +60,13 @@ }} {{* supprimer le doc de liaison entre les lignes *}} -{{#load type="link" - where="$$.immo_line_id = :immo_line_id AND - $$.amort_trans_id = :amort_trans_id AND - $$.amort_line_id = :amort_line_id" - :immo_line_id=$_GET.immo_line_id|intval - :amort_trans_id = $amort_id|intval +{{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id AND $$.amort_line_id = :amort_line_id" + :immo_doc_id=$_GET.immo_doc_id|intval :amort_line_id = $_GET.amort_line_id|intval }} {{:delete id=$id}} {{/load}} -{{:redirect to="amortization.html?immo_line_id=%s&ok=1&msg=detach&trans_id=%s"|args:$_GET.immo_line_id:$amort_id}} +{{:redirect + to="amortization.html?immo_line_id=%s&ok=1&msg=detach&immo_doc_id=%s"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} From d6fd5b404702e6a8b9b6ea4ab3386b416a8acda3 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 12:03:51 +0200 Subject: [PATCH 009/133] =?UTF-8?q?Petites=20am=C3=A9liorations=20et=20cor?= =?UTF-8?q?rections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _unfinished.html | 4 ++-- ignore.html | 2 +- scripts.js | 9 ++++----- style.css | 20 +++++++++++++++++--- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/_unfinished.html b/_unfinished.html index a222475..37ab4c9 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -154,11 +154,11 @@
- + - + - - + + - + diff --git a/add_asset.html b/add_asset.html index 8c76039..97eeeb6 100644 --- a/add_asset.html +++ b/add_asset.html @@ -75,7 +75,7 @@ {{if $account_ok == null}} {{:assign compte=$debit_account|implode:""}} - {{:redirect url="add_account.html?account=%s&chart=%s&immo_line_id=%s"|args:$compte:$selected_chart:$_GET.immo_line_id}} + {{:redirect url="add_account.html?account=%s&chart=%s"|args:$compte:$selected_chart}} {{/if}} {{:assign debit_account=$debit_account|keys|value:0}} diff --git a/amortization.html b/amortization.html index 119b78a..2d3e951 100644 --- a/amortization.html +++ b/amortization.html @@ -2,7 +2,6 @@ {{* Lister les écritures d'amortissement associées à une immobilisation - @param immo_line_id : id de la ligne d'immo @param immo_doc_id : id du doc associé à l'immo @param type_immo : managed, amortized, archived, others *}} @@ -172,7 +171,7 @@

{{:linkbutton label="Sortir du bilan" - href="balance_sheet_exit.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$_GET.type_immo + href="balance_sheet_exit.html?immo_doc_id=%s&type_immo=%s"|args:$_GET.immo_doc_id:$_GET.type_immo shape="export" class="main" }} @@ -253,7 +252,7 @@

{{/foreach}} diff --git a/attach_amort.html b/attach_amort.html index f369cd4..31e0ae9 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -3,12 +3,17 @@ {{* Enregistrer la liaison entre une ligne d'écriture d'amortissement et une ligne d'écriture d'immobilisation - @param immo_line_id : numéro de ligne de l'écriture d'immobilisation - @param amort_line_id : numéro de ligne de l'écriture d'amortissement @param immo_doc_id : numéro du doc d'immo + @param amort_line_id : numéro de ligne de l'écriture d'amortissement *}} -{{* chercher l'écriture d'immobilisation *}} +{{* données de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} + {{:assign label_immo=$label|or:$ligne_immo.trans_label}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select line.id_transaction as immo_trans_id, line.debit as montant, @@ -17,19 +22,13 @@ 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_line_id|intval + :line_id = $info_immo.line assign="ligne_immo" }} {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} -{{* chercher le doc associé à l'immo *}} -{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} - {{:assign label_immo=$label|or:$ligne_immo.trans_label}} -{{else}} - {{:error message="Immobilisation non trouvée"}} -{{/load}} {{:assign montant_immo=$info_immo.amount|or:$ligne_immo.montant}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} @@ -191,7 +190,7 @@ }} {{/if}} - {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s&ok=1&msg=attach_amort"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$status}} + {{:redirect force="amortization.html?immo_doc_id=%s&type_immo=%s&ok=1&msg=attach_amort"|args:$_GET.immo_doc_id:$status}} {{/form}} {{:admin_header title="Amortir l'immobilisation" custom_css="./style.css" current="module_amortization"}} diff --git a/detach_amort.html b/detach_amort.html index 06b99ff..e2b7b85 100644 --- a/detach_amort.html +++ b/detach_amort.html @@ -3,24 +3,29 @@ {{* Supprimer l'association entre une écriture d'amortissement et une écriture d'immobilisation - @param immo_line_id : id de la ligne d'immo - @param amort_line_id : id de la ligne d'amortissement @param immo_doc_id : id du doc associé à l'immo + @param amort_line_id : id de la ligne d'amortissement *}} -{{* chercher l'écriture d'immobilisation *}} +{{* données de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + +{{* écriture d'immobilisation *}} {{#select id_transaction FROM acc_transactions_lines WHERE id = :line_id; - :line_id = $_GET.immo_line_id|intval + :line_id = $info_immo.line }} {{:assign immo_trans_id=$id_transaction}} {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} -{{* chercher l'écriture d'amortissement *}} +{{* écriture d'amortissement *}} {{#select id_transaction FROM acc_transactions_lines @@ -69,11 +74,9 @@ {{/load}} {{* marquer immo non soldée *}} -{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}}{{/load}} {{:save key=$info_immo.key status="managed" }} -{{:redirect - to="amortization.html?immo_line_id=%s&ok=1&msg=detach&immo_doc_id=%s"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} +{{:redirect to="amortization.html?immo_doc_id=%s&ok=1&msg=detach"|args:$_GET.immo_doc_id:}} diff --git a/detach_immo.html b/detach_immo.html index 37b4397..7a67513 100644 --- a/detach_immo.html +++ b/detach_immo.html @@ -3,17 +3,21 @@ {{* Supprimer l'association entre une écriture d'immobilisation et une écriture au crédit du compte d'immobilisation - @param immo_line_id : id de la ligne d'immo - @param credit__line_id : id de la ligne de crédit @param immo_doc_id : id du doc associé à l'immo + @param credit_line_id : id de la ligne de crédit *}} -{{* chercher l'écriture d'immobilisation *}} +{{* données de l'immobilisation *}} +{{#load type="immo" id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select id_transaction FROM acc_transactions_lines WHERE id = :line_id; - :line_id = $_GET.immo_line_id|intval + :line_id = $info_immo.line }} {{:assign immo_trans_id=$id_transaction}} {{else}} @@ -68,6 +72,4 @@ {{:delete id=$id}} {{/load}} -{{:redirect - to="details_immo.html?immo_doc_id=%s&ok=1&msg=detach&"|args:$_GET.immo_doc_id}} -*}} +{{:redirect to="details_immo.html?immo_doc_id=%s&ok=1&msg=detach&"|args:$_GET.immo_doc_id}} diff --git a/details_immo.html b/details_immo.html index 148308a..f84f08b 100644 --- a/details_immo.html +++ b/details_immo.html @@ -5,7 +5,6 @@ Afficher les détails d'une immmo - permettre l'association d'une immo au crédit du compte de l'immo - permettre de modifier les paramètres de l'immo - @param (OBSOLÈTE ?) immo_line_id : numéro de ligne de l'écriture d'immobilisation @param immo_doc_id : numéro du doc d'immo *}} @@ -112,7 +111,7 @@ {{*/if*}} {{/foreach}} diff --git a/other_amortizations.html b/other_amortizations.html index ec439b7..5163e78 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -3,29 +3,29 @@ {{* Lister les écritures d'amortissement indépendantes et proposer des les attacher à l'immo sélectionnée - @param immo_line_id = id de la ligne d'immo @param immo_doc_id id du doc d'immo associé *}} -{{* récupérer les infos de l'immobilisation *}} +{{* données de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} + {{:assign label_immo=$label|or:$ligne_immo.label}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select trans.label as label, line.label as line_label 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_line_id|intval - assign=ligne_immo + :line_id = $info_immo.line + assign="ligne_immo" }} {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} -{{#load id=$_GET.immo_doc_id|intval}} - {{:assign label_immo=$label|or:$ligne_immo.label}} -{{else}} - {{:error message="Informations de l'immobilisation %s (%s) non trouvées"|args:$_GET.immo_line_id:$ligne_immo.label}} -{{/load}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} @@ -138,11 +138,7 @@ {{/foreach}} diff --git a/save_amort.html b/save_amort.html index d548c44..95ee7dc 100644 --- a/save_amort.html +++ b/save_amort.html @@ -2,11 +2,15 @@ {{* Créer une écriture d'amortissement - @param immo_line_id : id de la ligne d'immobilisation @param immo_doc_id : id du doc associé à l'immo *}} {{* Infos de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select line.id_account as account_id, line.debit as montant, @@ -21,37 +25,24 @@ INNER JOIN acc_accounts AS account ON line.id_account = account.id LEFT JOIN acc_projects AS project ON line.id_project = project.id WHERE line.id = :line_id; - :line_id = $_GET.immo_line_id|intval + :line_id = $info_immo.line assign="ligne_immo" }} {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} -{{:assign date_debut=$ligne_immo.date}} - -{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} - {{:assign duree=$duration}} - {{if $date_achat != null}} - {{:assign date_debut=$date_achat}} - {{/if}} - {{if $date_mes != null}} - {{:assign date_debut=$date_mes}} - {{/if}} - {{:assign status=$status}} - {{:assign amort_label=$label|or:$ligne_immo.label}} - {{if $amount != null}} - {{:assign var="ligne_immo.montant" value=$amount}} - {{/if}} -{{else}} - {{:error message="Informations de l'immobilisation « %s » non trouvées ; vous devez d'abord les renseigner"|args:$ligne_immo.label}} -{{/load}} +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.montant" value=$info_immo.amount}} +{{/if}} +{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date}} +{{:assign amort_label=$info_immo.label|or:$ligne_immo.label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $amort_label}} {{:assign amort_label=$amort_label|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign var="amort_label" value="Amortissement %s"|args:$amort_label}} -{{if $status == "amortized" || $status == "archived"}} +{{if $info_immo.status == "amortized" || $info_immo.status == "archived"}} {{:error message="Cette immobilisation est complètement amortie ; il est impossible d'ajouter une écriture d'amortissement"}} {{/if}} @@ -264,14 +255,14 @@ {{* immo soldée ? *}} {{if $_POST.montant|trim|money_int == $solde}} - {{:assign status="amortized"}} + {{:assign var="info_immo.status" value="amortized"}} {{:save key=$info_immo.key - status=$status + status=$info_immo.status }} {{/if}} - {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s&ok=1&msg=amortissement"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$status}} + {{:redirect force="amortization.html?immo_doc_id=%s&type_immo=%s&ok=1&msg=amortissement"|args:$_GET.immo_doc_id:$info_immo.status}} {{/form}} {{:admin_header title="Ajout amortissement" custom_css="./style.css" current="module_amortization"}} @@ -288,7 +279,7 @@ {{:include file="_calcul_dates.html" date_debut=$date_debut date_fin=$date_amort keep="nbjours"}} {{* montant de l'amortissement *}} -{{:assign montant_amort="%f/%f/365*%d"|math:$ligne_immo.montant:$duree:$nbjours|intval}} +{{:assign montant_amort="%f/%f/365*%d"|math:$ligne_immo.montant:$info_immo.duration:$nbjours|intval}} {{:assign montant_amort="min(%f, %d-%d)"|math:$montant_amort:$ligne_immo.montant:$total_amort}} {{:assign var="debit_account.6811" value="6811 — Dot. aux amortissements des immobilisations"}} {{:assign var="credit_account.%s"|args:$code_amort value="%s — "|args:$code_amort|cat:$amort_account_label}} @@ -325,7 +316,7 @@ }} From a35885857595aa9817f54646bef2c18df67ae4a5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 18 May 2026 10:57:22 +0200 Subject: [PATCH 039/133] Suppression code inutile --- _immobilisations_autres.html | 2 +- _unfinished.html | 8 +++++++- add_infos.html | 18 +++--------------- modify_infos.html | 8 +++----- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index 781940a..992e20c 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -170,7 +170,7 @@
#{{$line.amort_trans_id}}#{{$line.amort_trans_id}} {{$line.trans_date|date_short}} {{"%f"|math:$line.amort_amount|money_html:false|raw}} {{$line.trans_label}} {{if $line.line_label != null && $line.line_label != $line.trans_label}} - {{$line.line_label}}{{/if}} {{$line.account_code}}{{$line.account_code}} {{$line.account_label}} - {{:linkbutton label="Attacher" href="attach_amort.html?amort_line_id=%d&immo_line_id=%d"|args:$line.amort_line_id:$_GET.immo_line_id shape="plus"}} + {{if $_GET.init == null}} + {{:linkbutton label="Attacher" href="attach_amort.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$_GET.immo_line_id:$_GET.immo_doc_id shape="plus"}} + {{elseif $_GET.init}} + {{:linkbutton label="Attacher" href="attach_amort_init.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$_GET.immo_line_id:$_GET.immo_doc_id shape="plus"}} + {{/if}}
{{:input type="checkbox" name="selected[]" value=$trans_id}}#{{$trans_id}}#{{$trans_id}} {{$trans_date|date_short}} {{$trans_label}} {{"%f"|math:$debit|money_html:false|raw}} {{$account_label}} {{:linkbutton diff --git a/ignore.html b/ignore.html index e396a77..96254fd 100644 --- a/ignore.html +++ b/ignore.html @@ -62,7 +62,7 @@
Écriture
-
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
+
#{{$ligne_immo.trans_id}} {{$ligne_immo.label}}
Montant
{{"%f"|math:$ligne_immo.amount|money_currency_html:false|raw}}
diff --git a/scripts.js b/scripts.js index 7496328..babf511 100644 --- a/scripts.js +++ b/scripts.js @@ -14,14 +14,13 @@ function toggleInputs(idcb, idfields) { function toggleVisibility(idcheck, fields) { const elem = document.getElementById(idcheck); - for (let id of fields) { - const field = document.getElementById(id); + fields.forEach(function (field) { if (elem.checked) { - field.setAttribute('class', ''); + field.classList.remove('hidden'); } else { - field.setAttribute('class', 'hidden'); + field.classList.add('hidden'); } - } + }); } // fixer l'exercice des sélecteurs de compte diff --git a/style.css b/style.css index 6836da9..8998179 100644 --- a/style.css +++ b/style.css @@ -35,17 +35,15 @@ h2[class="aide"], h3[class="aide"] { } .informations dl.describe { - grid-template-columns : 20rem 1fr; + grid-template-columns : 25rem 1fr; } .informations dl.describe > dt { - flex: 0 0 15rem; margin-right: 0; white-space: nowrap; } .informations dl.describe > dd { - flex: 0 0 calc(100% - 20rem); margin-right: 0; } @@ -76,7 +74,23 @@ table.list tbody tr.ignored:nth-child(even) { font-style: italic; background: rgba(255, 255, 200, 0.5); } +html.dark table.list tbody tr.ignored:nth-child(odd) { + font-style: italic; + background: rgba(100, 100, 0, 0.4); +} +html.dark table.list tbody tr.ignored:nth-child(even) { + font-style: italic; + background: rgba(100, 100, 0, 0.4); +} html.dialog.dark { filter: none !important; } + +html.dialog.dark main { + background-color : #ddd; +} + +html.dark .block.alert { + background-color : rgba(87, 206, 235, 0.5); +} From b74ef8ae9c2222df8366ed79f176e82bc8862973 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 29 Apr 2026 14:23:46 +0200 Subject: [PATCH 010/133] Correction erreur conversion montant saisi --- add_infos.html | 5 ++--- attach_amort.html | 5 ++--- attach_immo.html | 21 +++++++++++++++------ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/add_infos.html b/add_infos.html index 9b638b1..1739c81 100644 --- a/add_infos.html +++ b/add_infos.html @@ -77,15 +77,14 @@ {{:assign libelle=$_POST.libelle}} {{/if}} - {{if $_POST.montant == null || $_POST.montant|intval == 0 }} + {{if $_POST.montant == null || $_POST.montant|money_int == 0 }} {{if $montant_affecte > 0}} {{:assign montant=$reste}} {{else}} {{:assign montant=null}} {{/if}} {{else}} - {{:assign montant=$_POST.montant|intval}} - {{:assign montant="%d*100"|math:$montant}} + {{:assign montant=$_POST.montant|money_int}} {{if $montant == $reste}} {{:assign montant=null}} {{/if}} diff --git a/attach_amort.html b/attach_amort.html index b320848..afffa20 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -76,8 +76,7 @@ {{:assign saved_amount=$reste}} {{/if}} {{else}} - {{:assign montant_amort=$_POST.montant|floatval}} - {{:assign montant_amort="%f*100"|math:$montant_amort}} + {{:assign montant_amort=$_POST.montant|money_int}} {{if $montant_amort > $reste}} {{:assign reste_nb="%f"|math:$reste|money_currency:false}} {{:error message="Le montant de l'amortissement ne peut être supérieur au reste (%s)"|args:$reste_nb}} @@ -85,7 +84,7 @@ {{if $montant_amort == $amort_line.amount}} {{:assign saved_amount=null}} {{else}} - {{:assign saved_amount=$montant_amort|intval}} + {{:assign saved_amount=$montant_amort}} {{/if}} {{/if}} diff --git a/attach_immo.html b/attach_immo.html index f2ed727..3fa8001 100644 --- a/attach_immo.html +++ b/attach_immo.html @@ -50,6 +50,7 @@ {{/select}} {{:assign credit_trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$credit_line.credit_trans_id}} +{{* montant de l'écriture de crédit déjà affecté *}} {{:assign montant_affecte=0}} {{#load type="immo_link" assign="linked_immo." where="$$.credit_line_id = :credit_line_id" @@ -61,16 +62,24 @@ {{* Traiter l'envoi du formulaire *}} {{#form on="save"}} - {{* vérifier que le montant est inférieur au reste *}} + {{* vérifier que le montant saisi est inférieur au reste *}} {{if $_POST.montant == null}} - {{:assign montant_credit=null}} + {{if $montant_affecte == 0}} + {{:assign saved_credit=null}} + {{else}} + {{:assign saved_credit=$reste}} + {{/if}} {{else}} - {{:assign montant_credit=$_POST.montant|floatval}} - {{:assign montant_credit="%f*100"|math:$montant_credit}} + {{:assign montant_credit=$_POST.montant|money_int}} {{if $montant_credit > $reste}} {{:assign reste_nb="%f"|math:$reste|money_currency:false}} {{:error message="Le montant de l'avoir ne peut être supérieur au reste (%s)"|args:$reste_nb}} {{/if}} + {{if $montant_credit == $credit_line.amount}} + {{:assign saved_credit=null}} + {{else}} + {{:assign saved_credit=$montant_credit}} + {{/if}} {{/if}} {{* chercher les liaisons de l'écriture d'immobilisation *}} @@ -108,7 +117,7 @@ type="immo_link" immo_doc_id=$_GET.immo_doc_id|intval credit_line_id=$_GET.credit_line_id|intval - amount=$montant_credit|intval + amount=$saved_credit }} {{:redirect force="details_immo.html?immo_doc_id=%s&ok=1&msg=attach_immo"|args:$_GET.immo_doc_id}} @@ -143,7 +152,7 @@
- {{:input type="money" name="montant" label="Montant" help="Montant de l'avoir ; à renseigner uniquement si différent du montant de l'écriture"}} + {{:input type="money" name="montant" label="Montant" default=$reste help="Montant de l'avoir"}}

From 401aac686b78043f3cd30c0e404e8e44ea0f68dd Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 30 Apr 2026 11:54:30 +0200 Subject: [PATCH 011/133] Correction erreur saisie montant --- add_infos.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/add_infos.html b/add_infos.html index 1739c81..a8beee0 100644 --- a/add_infos.html +++ b/add_infos.html @@ -85,7 +85,7 @@ {{/if}} {{else}} {{:assign montant=$_POST.montant|money_int}} - {{if $montant == $reste}} + {{if $montant == $ligne_immo.montant}} {{:assign montant=null}} {{/if}} {{/if}} @@ -186,7 +186,7 @@ {{:input type="date" name="date_achat" label="Date d'acquisition" help="à renseigner uniquement si différente de la date de l'écriture d'immobilisation"}} {{:input type="date" name="date_mes" label="Date de mise en service" help="à renseigner uniquement si différente de la date d'acquisition"}} {{:input type="text" name="libelle" label="Libellé" help="à renseigner uniquement si différent du libellé de l'écriture d'immobilisation"}} - {{:input type="money" name="montant" label="Montant de l'immobilisation" default=$reste}} + {{:input type="money" name="montant" label="Montant de l'immobilisation" required=true default=$reste}} From 62692ef550f7c49cb5f41d166f1b38c0e7cfcc58 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 30 Apr 2026 11:55:12 +0200 Subject: [PATCH 012/133] =?UTF-8?q?Am=C3=A9lioration=20pr=C3=A9sentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amortization.html | 16 +++++++--------- attach_amort.html | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/amortization.html b/amortization.html index 710bb6d..926eb52 100644 --- a/amortization.html +++ b/amortization.html @@ -104,9 +104,9 @@ {{/select}} {{/load}} -{{if $_GET.type_immo == null || $_GET.type_immo != "amortized"}} +{{:assign autres_amortissements=false}} +{{if $valeur_residuelle > 0}} {{* Chercher des amortissements non rattachés à une immo *}} - {{:assign autres_amortissements=false}} {{#select line.id as amort_line_id, line.id_transaction AS amort_trans_id @@ -267,13 +267,11 @@

Aucun amortissement enregistré pour cette immobilisation

{{/if}} -{{if $_GET.type_immo == null || $_GET.type_immo != "amortized"}} - {{if $autres_amortissements}} -

- Il y a des écritures d'amortissement qui ne sont pas rattachées à une immobilisation !
- Utilisez le bouton « Rattacher un amortissement » pour les afficher ; vous pourrez choisir d'en attacher certaines à cette immobilisation. -

- {{/if}} +{{if $autres_amortissements}} +

+ Il y a des écritures d'amortissement qui ne sont pas rattachées à une immobilisation !
+ Utilisez le bouton « Rattacher un amortissement » pour les afficher ; vous pourrez choisir d'en attacher certaines à cette immobilisation. +

{{/if}} {{:form_errors}} {{:admin_footer}} diff --git a/attach_amort.html b/attach_amort.html index afffa20..f643f9a 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -158,7 +158,7 @@
- {{:input type="money" name="montant" label="Montant" default=$reste help="Montant de l'amortissement"}} + {{:input type="money" name="montant" label="Montant" default=$reste required=true help="Montant de l'amortissement"}}

From d06dd424b3726c9865104bf4387e013dc5eb4838 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 4 May 2026 08:34:39 +0200 Subject: [PATCH 013/133] =?UTF-8?q?Am=C3=A9lioration=20recherche=20=C3=A9c?= =?UTF-8?q?ritures=20au=20cr=C3=A9dit=20du=20compte=20d'une=20immobilisati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- link_immo.html | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/link_immo.html b/link_immo.html index 3543ab8..2757db0 100644 --- a/link_immo.html +++ b/link_immo.html @@ -38,7 +38,6 @@ {{* lister les écritures au crédit du compte de l'immobilisation - variante : utiliser une jointure ; pas forcément plus efficace *}} {{#select line.id as credit_line_id, @@ -57,14 +56,12 @@ INNER JOIN acc_accounts AS account ON account.id = line.id_account INNER JOIN acc_years AS y ON y.id = trans.id_year WHERE account.code = :account_code AND credit > 0 - AND credit_trans_id NOT IN ( - SELECT - CASE WHEN id_transaction = credit_trans_id THEN id_transaction - ELSE id_related - END AS other_id - FROM acc_transactions_links WHERE other_id = credit_trans_id) + AND credit_line_id NOT IN ( + SELECT json_extract(link.document, '$.credit_line_id') AS credit_line_id FROM !table as link + WHERE json_extract(link.document, '$.type') == "immo_link") ORDER BY trans.date, trans.label; :account_code = $ligne_immo.account_code + !table =$module.table assign="other_immos." }} {{/select}} From c620ac769e912d2680bfee1e6552d6f8cf842f91 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 4 May 2026 13:48:48 +0200 Subject: [PATCH 014/133] Changement nom : immo_link => credit_link --- _immobilisations.html | 4 ++-- amortization.html | 11 +++++------ attach_immo.html | 4 ++-- link.schema.json | 16 ++++++++++++---- link_immo.html | 2 +- save_amort.html | 2 +- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/_immobilisations.html b/_immobilisations.html index fa31b31..5b257f4 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -82,7 +82,7 @@ et déduire leur montant de celui de l'immo *}} {{#load - type="immo_link" + type="credit_link" where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $immo_doc_id }} {{if $amount == null}} @@ -143,7 +143,7 @@ {{:linkbutton label="Détails" href="details_immo.html?immo_doc_id=%s"|args:$immo_doc_id - shape="search" + shape="eye" }} {{* target="_dialog"*}} {{*/if*}} diff --git a/amortization.html b/amortization.html index 926eb52..0caed6c 100644 --- a/amortization.html +++ b/amortization.html @@ -19,7 +19,7 @@ line.label as line_label, trans.id as immo_trans_id, trans.label as label, - trans.date, + trans.date as date_achat, account.code as account_code, account.label as account_label FROM acc_transactions_lines AS line @@ -34,7 +34,7 @@ {{/select}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} -{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date}} +{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} @@ -52,7 +52,7 @@ et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#load type="immo_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} +{{#load type="credit_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} {{if $amount == null}} {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; :credit_line_id=$credit_line_id @@ -180,9 +180,8 @@ }}

- Il sera possible de choisir la date de sortie, d'indiquer - le montant de la cession le cas échéant et de modifier les - comptes associés. + Il sera possible de choisir la date de sortie et d'indiquer + le montant de la cession le cas échéant.

diff --git a/attach_immo.html b/attach_immo.html index 3fa8001..a824041 100644 --- a/attach_immo.html +++ b/attach_immo.html @@ -52,7 +52,7 @@ {{* montant de l'écriture de crédit déjà affecté *}} {{:assign montant_affecte=0}} -{{#load type="immo_link" assign="linked_immo." +{{#load type="credit_link" assign="linked_immo." where="$$.credit_line_id = :credit_line_id" :credit_line_id = $_GET.credit_line_id|intval }} @@ -114,7 +114,7 @@ {{* enregistrer la liaison des lignes d'immo *}} {{:save key=""|uuid - type="immo_link" + type="credit_link" immo_doc_id=$_GET.immo_doc_id|intval credit_line_id=$_GET.credit_line_id|intval amount=$saved_credit diff --git a/link.schema.json b/link.schema.json index 1524b55..88968ed 100644 --- a/link.schema.json +++ b/link.schema.json @@ -5,7 +5,7 @@ "properties": { "type": { "type": "string", - "enum": ["amort_link", "immo_link"] + "enum": ["amort_link", "credit_link", "exit_link"] }, "immo_doc_id" : { "description": "identifiant du document d'immobilisation associé", @@ -13,12 +13,17 @@ "exclusiveMinimum": 0 }, "amort_line_id" : { - "description": "numéro de ligne d'amortissement associée à l'immobilisation", + "description": "ligne d'amortissement associée à l'immobilisation", "type": "integer", "exclusiveMinimum": 0 }, "credit_line_id": { - "description": "numéro de ligne au crédit du compte de l'immobilisation", + "description": "ligne au crédit du compte de l'immobilisation", + "type": "integer", + "exclusiveMinimum": 0 + }, + "exit_line_id": { + "description": "ligne d'amortissement de sortie du bilan de l'immobilisation", "type": "integer", "exclusiveMinimum": 0 }, @@ -31,6 +36,9 @@ "if": {"properties": {"type": {"const": "amort_link"}}, "required": ["type"]}, "then": {"required": ["amort_line_id"]}, "else": - "if": {"properties": {"type": {"const": "immo_link"}}, "required": ["type"]}, + "if": {"properties": {"type": {"const": "credit_link"}}, "required": ["type"]}, "then": {"required": ["credit_line_id"]}, + "else": + "if": {"properties": {"type": {"const": "exit_link"}}, "required": ["type"]}, + "then": {"required": ["exit_line_id"]}, } diff --git a/link_immo.html b/link_immo.html index 2757db0..ef12192 100644 --- a/link_immo.html +++ b/link_immo.html @@ -58,7 +58,7 @@ WHERE account.code = :account_code AND credit > 0 AND credit_line_id NOT IN ( SELECT json_extract(link.document, '$.credit_line_id') AS credit_line_id FROM !table as link - WHERE json_extract(link.document, '$.type') == "immo_link") + WHERE json_extract(link.document, '$.type') == "credit_link") ORDER BY trans.date, trans.label; :account_code = $ligne_immo.account_code !table =$module.table diff --git a/save_amort.html b/save_amort.html index 6a8459c..5b852bc 100644 --- a/save_amort.html +++ b/save_amort.html @@ -57,7 +57,7 @@ *}} {{:assign total_credits=0}} {{#load - type="immo_link" + type="credit_link" where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $_GET.immo_doc_id|intval }} {{if $amount == null}} From 78407592a10ff6db9a88dcf1258b2e8e19c22c0d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 4 May 2026 18:45:13 +0200 Subject: [PATCH 015/133] Ajout page modification des infos d'une immobilisation --- modify_infos.html | 247 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 modify_infos.html diff --git a/modify_infos.html b/modify_infos.html new file mode 100644 index 0000000..b0dd9f0 --- /dev/null +++ b/modify_infos.html @@ -0,0 +1,247 @@ +{{* -*- brindille -*- *}} +{{:admin_header title="Modifier l'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* + @param immo_line_id + @param immo_doc_id + ¿ @param type_immo : managed, amortized, archived, other ? + + TODO : + - ¿ faire une ligne modifiable pour chaque avoir avec un bouton de suppression ? + - séparer les cas des immo simples et complexes (BOI) + par exemple pour la durée d'amort par défaut {{:input ...}} + - prise en charge immo => param = immo_line_id + - modif param immo => param = immo_doc_id +*}} + +{{* données de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} +{{#select + trans.id as immo_trans_id, + trans.label as trans_label, + trans.date as date_achat, + line.debit as montant, + line.label as line_label, + acc.code, + acc.label as account_label + FROM acc_transactions_lines AS line + INNER join acc_transactions AS trans ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE line.id = :line_id; + :line_id = $info_immo.line + assign="ligne_immo" + }} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/select}} +{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.montant}} + +{{:assign immo_label=$info_immo.label|or:$ligne_immo.trans_label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $immo_label}} + {{:assign immo_label=$immo_label|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} +{{* + chercher des écritures liées à l'immo courante au crédit du même compte + et déduire leur montant de celui de l'immo +*}} +{{:assign linked_immos=null}} +{{:assign total_credits=0}} +{{#load type="credit_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} + {{#select + line.credit, + trans.id + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + WHERE line.id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign credit=$credit}} + {{:assign credit_trans_id=$id}} + {{/select}} + {{:assign var="linked_immos." value=$credit_trans_id}} + {{if $amount == null}} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{/load}} +{{:assign solde="%d-%d"|math:$montant_immo:$total_credits}} + +{{:assign autres_amount=0}} +{{#load + type="immo" + where="$$.line = :line_id AND id != :doc_id" + :line_id = $info_immo.line + :doc_id = $info_immo.id + }} + {{:assign autres_amount="%d+%d"|math:$autres_amount:$amount}} +{{/load}} +{{:assign max_disponible="%d-%d"|math:$ligne_immo.montant:$autres_amount}} + +{{* traiter la saisie *}} +{{#form on="save"}} + {{if ! $_POST.amortir}} + {{* ne pas amortir *}} + {{:assign duration=0}} + {{:assign libelle=null}} + {{:assign montant=null}} + {{:assign date_achat=null}} + {{:assign date_mes=null}} + {{:assign status="ignored"}} + {{else}} + + {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $ligne_immo.date_achat}} + {{:assign date_achat=null}} + {{elseif $_POST.date_achat|parse_date == $info_immo.date_achat}} + {{:assign date_achat=$info_immo.date_achat}} + {{else}} + {{:assign date_achat=$_POST.date_achat|parse_date}} + {{/if}} + {{if $_POST.date_mes == null || $_POST.date_mes|parse_date == $ligne_immo.date_achat}} + {{:assign date_mes=null}} + {{elseif $_POST.date_mes|parse_date == $info_immo.date_achat}} + {{:assign date_mes=null}} + {{else}} + {{:assign date_mes=$_POST.date_mes|parse_date}} + {{if $date_mes < $ligne_immo.date_achat || $date_mes < $info_immo.date_achat}} + {{:assign da=$date_achat|or:$info_immo.date_achat|or:$ligne_immo.date_achat|date_short}} + {{:error message="Erreur : la date de mise en service (%s) ne peut être antérieure à la date d'acquisition (%s)"|args:$_POST.date_mes:$da}} + {{/if}} + {{/if}} + + {{:assign duration=$_POST.duree|intval}} + {{if $duration <= 0}} + {{:error message="Erreur : la durée d'amortissement doit être strictement positive"}} + {{/if}} + + {{if $_POST.libelle != $ligne_immo.line_label && $_POST.libelle != $ligne_immo.trans_label}} + {{:assign libelle=$_POST.libelle}} + {{else}} + {{:assign libelle=null}} + {{/if}} + + {{:assign montant=null}} + {{if $_POST.montant == null || $_POST.montant|money_int == 0 || $_POST.montant|money_int == $info_immo.amount}} + {{:assign montant=$info_immo.amount}} + {{else}} + {{:assign montant=$_POST.montant|money_int}} + {{if $montant < 0 || $montant > $max_disponible}} + {{:assign montant_aff="%f"|math:$montant|money_currency:false}} + {{:assign max_aff="%f"|math:$max_disponible|money_currency:false}} + {{:error message="Le montant (%s) doit être positif et ne peut être supérieur à %s"|args:$montant_aff:$max_aff}} + {{/if}} + {{/if}} + + {{:assign status="managed"}} + {{/if}} + + {{* enregistrer les infos de l'immobilisation *}} + {{:save + key=$info_immo.key + validate_schema="schema.json" + type="immo" + line=$info_immo.line + duration=$duration + label=$libelle + amount=$montant + date_achat=$date_achat + date_mes=$date_mes + status=$status + assign_new_id="new_id" + }} + + {{if $_POST.amortir}} + {{:assign type_immo="managed"}} + {{else}} + {{:assign type_immo="other"}} + {{/if}} + {{:redirect force="index.html?ok=1&msg=infos&type_immo=%s"|args:$type_immo}} +{{/form}} +{{:form_errors}} + +{{* barre de navigation *}} +{{if ! $dialog}} + {{:include file="_nav.html" current="index" subcurrent="%s"|args:$_GET.type_immo subsubcurrent="parameter"}} +{{/if}} + +{{:assign choix_defaut=$_GET.type_immo}} + +{{* + modifier la date de mise en service, les écritures associées ou la durée d'amortissement +*}} + +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} +

Paramètres de l'immobilisation

+
+
+
Immobilisation
+
#{{$ligne_immo.immo_trans_id}} {{$immo_label}}
+
Compte d'immobilisation
+
{{$ligne_immo.code}} — {{$ligne_immo.account_label}} +
Montant
+
{{"%f"|math:$montant_immo|money_currency_html:false|raw}}
+ {{if $total_credits > 0}} +
Montant des avoirs
+
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+
Montant à amortir
+
{{"%f"|math:$solde|money_currency_html:false|raw}}
+ {{/if}} +
Date de l'écriture d'immobilisation
+
{{$ligne_immo.date_achat|date_short}}
+
+
+ +
+
+ Paramètres de l'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" min=1 default=$info_immo.duration}} + {{:input type="text" name="libelle" label="Libellé" default=$info_immo.label}} + {{if $info_immo.amount != null}} + {{:assign max_aff="%f"|math:$max_disponible|money_currency:false}} + {{:input type="money" name="montant" label="Montant de l'immobilisation" default=$montant_immo help="Montant maximum = %s"|args:$max_aff}} + {{/if}} + {{:input type="date" name="date_achat" label="Date d'acquisition" default=$info_immo.date_achat}} + {{:input type="date" name="date_mes" label="Date de mise en service" default=$info_immo.date_mes}} + {{if $linked_immos}} +
+
+ + + {{#foreach from=$linked_immos item="id"}} + + {{:input type="hidden" name="credit_id" value=$id}}{{$id}} + + + {{/foreach}} + +
+ {{/if}} +
+
+
+

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

+
+ +{{:admin_footer}} + + + From 3169fe9268f7efa7c82369dcf07aa7ec8ab78865 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 5 May 2026 12:25:11 +0200 Subject: [PATCH 016/133] =?UTF-8?q?Corrections=20contr=C3=B4les=20validit?= =?UTF-8?q?=C3=A9=20date=20et=20affichage=20=C3=A9tat=20immo=20ignor=C3=A9?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_asset.html | 7 ++++++- add_infos.html | 25 ++++++++++++++++++++----- modify_infos.html | 14 +++++++++++--- scripts.js | 2 +- style.css | 4 ++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/add_asset.html b/add_asset.html index 2ee28bd..f4800f2 100644 --- a/add_asset.html +++ b/add_asset.html @@ -108,6 +108,11 @@ {{/if}} {{:assign duration=$_POST.duree|intval}} {{:assign status="managed"}} + {{if $_POST.date_mes == null || $_POST.date_mes == $_POST.date_achat}} + {{:assign date_mes=null}} + {{else}} + {{:assign date_mes=$_POST.date_mes|date_short}} + {{/if}} {{/if}} {{* enregistrer l'écriture *}} @@ -141,7 +146,7 @@ type="immo" line=$immo_line_id duration=$duration - date_mes=$date_debut + date_mes=$date_mes status=$status }} {{/if}} diff --git a/add_infos.html b/add_infos.html index a8beee0..a6c96ea 100644 --- a/add_infos.html +++ b/add_infos.html @@ -60,6 +60,11 @@ {{:assign status="ignored"}} {{else}} + {{if $_POST.date_achat|parse_date > $ligne_immo.date_achat}} + {{:assign da=$ligne_immo.date_achat|date_short}} + {{:error message="Erreur : la date d'achat (%s) ne peut être postérieure à la date de l'écriture d'immobilisation (%s)"|args:$_POST.date_achat:$da}} + {{/if}} + {{* vérifier que la date de mise en service est postérieure à la date d'acquisition *}} {{:assign d1=$_POST.date_achat|or:$ligne_immo.date_achat|parse_date}} {{:assign d2=$_POST.date_mes|or:$d1|parse_date}} @@ -126,7 +131,6 @@ date_achat=$date_achat date_mes=$date_mes status=$status - assign_new_id="new_id" }} {{if $_POST.amortir}} @@ -136,14 +140,13 @@ {{/if}} {{:redirect force="index.html?ok=1&msg=infos&type_immo=%s"|args:$type_immo}} {{/form}} -{{:form_errors}} {{:admin_header title="Classer l'immobilisation" custom_css="./style.css" current="module_amortization"}} - {{* barre de navigation *}} {{if ! $dialog}} {{:include file="_nav.html" current="index" subcurrent="%s"|args:$_GET.type_immo subsubcurrent="parameter"}} {{/if}} +{{:form_errors}} {{:assign choix_defaut=$_GET.type_immo}} @@ -174,7 +177,12 @@
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"}} + {{if $info_immo.status == 'ignored'}} + {{:assign checked=null}} + {{else}} + {{:assign checked="checked"}} + {{/if}} + {{:input id="amortir" type="checkbox" value=1 name="amortir" label="Amortir cette immobilisation sur une ou plusieurs années" checked="%s"|args:$checked help="Dé-cocher pour ne pas amortir"}}
{{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1}}
@@ -201,13 +209,20 @@ diff --git a/modify_infos.html b/modify_infos.html index b0dd9f0..2016a52 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -92,7 +92,6 @@ {{:assign date_mes=null}} {{:assign status="ignored"}} {{else}} - {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $ligne_immo.date_achat}} {{:assign date_achat=null}} {{elseif $_POST.date_achat|parse_date == $info_immo.date_achat}} @@ -100,14 +99,23 @@ {{else}} {{:assign date_achat=$_POST.date_achat|parse_date}} {{/if}} + {{if $_POST.date_achat|parse_date > $ligne_immo.date_achat}} + {{:assign da=$ligne_immo.date_achat|date_short}} + {{:error message="Erreur : la date d'achat (%s) ne peut être postérieure à la date de l'écriture d'immobilisation (%s)"|args:$_POST.date_achat:$da}} + {{/if}} + {{if $_POST.date_mes == null || $_POST.date_mes|parse_date == $ligne_immo.date_achat}} {{:assign date_mes=null}} {{elseif $_POST.date_mes|parse_date == $info_immo.date_achat}} {{:assign date_mes=null}} {{else}} {{:assign date_mes=$_POST.date_mes|parse_date}} - {{if $date_mes < $ligne_immo.date_achat || $date_mes < $info_immo.date_achat}} - {{:assign da=$date_achat|or:$info_immo.date_achat|or:$ligne_immo.date_achat|date_short}} + {{:assign date_achat_comp=$ligne_immo.date_achat}} + {{if $date_achat != null}} + {{:assign date_achat_comp=$date_achat}} + {{/if}} + {{if $date_mes < $date_achat_comp}} + {{:assign da=$date_achat_comp|date_short}} {{:error message="Erreur : la date de mise en service (%s) ne peut être antérieure à la date d'acquisition (%s)"|args:$_POST.date_mes:$da}} {{/if}} {{/if}} diff --git a/scripts.js b/scripts.js index babf511..e6298ca 100644 --- a/scripts.js +++ b/scripts.js @@ -79,7 +79,7 @@ function setDateEnd(id_exercices, id_date, id_years) { // renvoyer la valeur numérique d'un montant formaté en € function getNumber(text) { - return Number(text.replace(/[^0-9,]/g, '').replace(/,/, '.')); + return Number(text.replace(/[^0-9,]/g, '').replace(/,/, '.')); } // calculer le montant d'un amortissement diff --git a/style.css b/style.css index 8998179..1a8ed6d 100644 --- a/style.css +++ b/style.css @@ -94,3 +94,7 @@ html.dialog.dark main { html.dark .block.alert { background-color : rgba(87, 206, 235, 0.5); } + +span.input-list.avoirs label { + padding : 0.4rem 0.6rem; +} From 4e131e1f5b4b4647b30f67d44bd259723fe63be5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 6 May 2026 09:52:35 +0200 Subject: [PATCH 017/133] =?UTF-8?q?Suppression=20libell=C3=A9=20ligne=20?= =?UTF-8?q?=C3=A9criture=20amortissement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- save_amort.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/save_amort.html b/save_amort.html index 5b852bc..5f20c53 100644 --- a/save_amort.html +++ b/save_amort.html @@ -222,14 +222,12 @@ debit=$_POST.montant account=$debit_account|keys|value:0 id_project=$ligne_immo.project_id - label=$_POST.designation }} {{:assign var="lines." credit=$_POST.montant account=$credit_account|keys|value:0 id_project=$ligne_immo.project_id - label=$_POST.designation }} {{:api method="POST" From a1ce03a7b444f27e4060f2eb7ed320d76040742d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 6 May 2026 10:32:09 +0200 Subject: [PATCH 018/133] =?UTF-8?q?Marquer=20immo=20sold=C3=A9e=20apr?= =?UTF-8?q?=C3=A8s=20enregistrement=20dernier=20amortissement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attach_amort.html | 80 ++++++++++++++++++++++++++++++++++++++++++----- detach_amort.html | 7 +++++ save_amort.html | 39 ++++++++++++----------- 3 files changed, 99 insertions(+), 27 deletions(-) diff --git a/attach_amort.html b/attach_amort.html index f643f9a..f369cd4 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -11,6 +11,7 @@ {{* chercher l'écriture d'immobilisation *}} {{#select line.id_transaction as immo_trans_id, + line.debit as montant, trans.label as trans_label, line.label as line_label FROM acc_transactions_lines as line @@ -24,11 +25,12 @@ {{/select}} {{* chercher le doc associé à l'immo *}} -{{#load id=$_GET.immo_doc_id|intval}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} {{:assign label_immo=$label|or:$ligne_immo.trans_label}} {{else}} {{:error message="Immobilisation non trouvée"}} {{/load}} +{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.montant}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} @@ -67,9 +69,9 @@ {{* Traiter l'envoi du formulaire *}} {{#form on="save"}} - {{* vérifier que le montant saisi est inférieur au reste *}} - {{if $_POST.montant == null}} + {{if $_POST.montant == null || $_POST.montant == 0}} + {{:assign montant_amort=$reste}} {{if $montant_affecte == 0}} {{:assign saved_amount=null}} {{else}} @@ -88,6 +90,57 @@ {{/if}} {{/if}} + {{* vérifier que le montant total des amortissements ne dépasse pas la valeur de l'immo *}} + {{* montant de l'immo *}} + {{:assign total_credits=0}} + {{#load + type="credit_link" + where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $_GET.immo_doc_id|intval + }} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} + {{/load}} + {{:assign montant_immo="%d-%d"|math:$montant_immo:$total_credits}} + + {{* montant des amortissements *}} + {{:assign total_amort=0}} + {{#load + type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id=$_GET.immo_doc_id|intval + }} + {{if $amount == null || $amount == 0}} + {{#select + line.credit + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + INNER join acc_accounts AS account on line.id_account = account.id + WHERE line.id = :amort_line_id + ; + :amort_line_id = $amort_line_id + }} + {{:assign total_amort="%d+%d"|math:$total_amort:$credit}} + {{/select}} + {{else}} + {{:assign total_amort="%d+%d"|math:$total_amort:$amount}} + {{/if}} + {{/load}} + + {{:assign vnc="%d-%d"|math:$montant_immo:$total_amort}} + {{:assign total_amort="%d+%d"|math:$total_amort:$montant_amort}} + {{if $total_amort > $montant_immo}} + {{:assign ma="%f"|math:$montant_amort|money_currency:false}} + {{:assign vnc="%f"|math:$vnc|money_currency:false}} + {{:error message="Le montant de l'amortissement (%s) dépasse la valeur résiduelle de l'immobilisation (%s)"|args:$ma:$vnc}} + {{/if}} + {{* chercher les liaisons de l'écriture d'immobilisation *}} {{#select CASE links.id_related = :immo_trans_id @@ -129,7 +182,16 @@ }} {{/load}} - {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&ok=1&msg=attach_amort"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} + {{* immo soldée ? *}} + {{if $total_amort == $montant_immo}} + {{:assign status="amortized"}} + {{:save + key=$info_immo.key + status=$status + }} + {{/if}} + + {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s&ok=1&msg=attach_amort"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$status}} {{/form}} {{:admin_header title="Amortir l'immobilisation" custom_css="./style.css" current="module_amortization"}} @@ -148,10 +210,12 @@
#{{$amort_line.trans_id}} {{$label_immo}}
Montant de l'écriture d'amortissement
{{$amort_line.amount|money_currency_html:false|raw}}
-
Montant déjà affecté
-
{{"%f"|math:$montant_affecte|money_currency_html:false|raw}}
-
Montant restant à affecter
-
{{"%f"|math:$reste|money_currency_html:false|raw}}
+ {{if $montant_affecte > 0}} +
Montant déjà affecté
+
{{"%f"|math:$montant_affecte|money_currency_html:false|raw}}
+
Montant restant à affecter
+
{{"%f"|math:$reste|money_currency_html:false|raw}}
+ {{/if}}
diff --git a/detach_amort.html b/detach_amort.html index caae1a0..06b99ff 100644 --- a/detach_amort.html +++ b/detach_amort.html @@ -68,5 +68,12 @@ {{:delete id=$id}} {{/load}} +{{* marquer immo non soldée *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}}{{/load}} +{{:save + key=$info_immo.key + status="managed" +}} + {{:redirect to="amortization.html?immo_line_id=%s&ok=1&msg=detach&immo_doc_id=%s"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} diff --git a/save_amort.html b/save_amort.html index 5f20c53..1b199c0 100644 --- a/save_amort.html +++ b/save_amort.html @@ -29,7 +29,7 @@ {{/select}} {{:assign date_debut=$ligne_immo.date}} -{{#load id=$_GET.immo_doc_id|intval}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} {{:assign duree=$duration}} {{if $date_mes != null}} {{:assign date_debut=$date_mes}} @@ -229,6 +229,7 @@ account=$credit_account|keys|value:0 id_project=$ligne_immo.project_id }} + {{:api method="POST" path="accounting/transaction" @@ -243,28 +244,28 @@ }} {{* enregistrer la liaison des lignes *}} - {{#select - trans.id AS trans_id, - line.id AS line_id - FROM acc_transactions AS trans - INNER JOIN acc_transactions_lines AS line ON line.id_transaction = trans.id - WHERE trans.id = :trans_id - ; - :trans_id = $result.id - }} - {{:assign amort_trans_id=$trans_id}} - {{:assign amort_line_id=$line_id}} - {{/select}} - {{if $amort_trans_id != null}} + {{#foreach from=$result.lines item="line"}} + {{if $line.account_code == $credit_account|keys|value:0}} + {{:save + key=""|uuid + type="amort_link" + immo_doc_id=$_GET.immo_doc_id|intval + amort_line_id=$line.id + }} + {{:break}} + {{/if}} + {{/foreach}} + + {{* immo soldée ? *}} + {{if $_POST.montant|trim|money_int == $solde}} + {{:assign status="amortized"}} {{:save - key=""|uuid - type="amort_link" - immo_doc_id=$_GET.immo_doc_id|intval - amort_line_id=$amort_line_id|intval + key=$info_immo.key + status=$status }} {{/if}} - {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&ok=1&msg=amortissement"|args:$_GET.immo_line_id:$_GET.immo_doc_id}} + {{:redirect force="amortization.html?immo_line_id=%s&immo_doc_id=%s&type_immo=%s&ok=1&msg=amortissement"|args:$_GET.immo_line_id:$_GET.immo_doc_id:$status}} {{/form}} {{:admin_header title="Ajout amortissement" custom_css="./style.css" current="module_amortization"}} From c07b77e942f0764d73cc34ddf79a6b945d884bf4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 6 May 2026 13:09:11 +0200 Subject: [PATCH 019/133] Correction erreur solde immo --- amortization.html | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/amortization.html b/amortization.html index 0caed6c..237ee0c 100644 --- a/amortization.html +++ b/amortization.html @@ -63,15 +63,14 @@ {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} {{/if}} {{/load}} -{{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} -{{:assign solde=$ligne_immo.montant}} +{{:assign solde="%d-%d"|math:$ligne_immo.montant:$total_credits}} {{*:debug info_immo=$info_immo ligne_immo=$ligne_immo total_credits=$total_credits solde=$solde*}} {{if $info_immo.status == "amortized"}} - {{:assign amort_amount=$ligne_immo.montant}} + {{:assign amort_amount=$solde}} {{:assign valeur_residuelle=0}} {{else}} - {{:assign valeur_residuelle=$ligne_immo.montant}} + {{:assign valeur_residuelle=$solde}} {{/if}} {{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} @@ -208,13 +207,13 @@ {{/if}} {{if $valeur_residuelle > 0}}
Montant des amortissements
-
{{"%d-%d"|math:$ligne_immo.montant:$valeur_residuelle|money_currency_html:false|raw}}
+
{{"%d-%d"|math:$solde:$valeur_residuelle|money_currency_html:false|raw}}
Valeur nette comptable
{{$valeur_residuelle|money_currency_html:false|raw}}
{{/if}} {{if $info_immo.duration != null && $valeur_residuelle > 0}}
Annuité estimée
-
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$ligne_immo.montant:$info_immo.duration|money_currency_html:false|raw}}
+
{{"min(%d, %f/%d)"|math:$valeur_residuelle:solde:$info_immo.duration|money_currency_html:false|raw}}
{{/if}} From e62b2a9f706cecf36254bbf3c5469ded7ae3cd1f Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 8 May 2026 08:09:03 +0200 Subject: [PATCH 020/133] =?UTF-8?q?Ajout=20possibilit=C3=A9=20choisir=20co?= =?UTF-8?q?mpte=20404=20=C3=A0=20cr=C3=A9ation=20immobilisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_asset.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add_asset.html b/add_asset.html index f4800f2..8c76039 100644 --- a/add_asset.html +++ b/add_asset.html @@ -206,7 +206,7 @@ name="credit_account" label="Compte de décaissement" required=true - target="!acc/charts/accounts/selector.php?types=%s&id_year=%d"|args:"1|2|3":$selected_year + target="!acc/charts/accounts/selector.php?types=%s&id_year=%d"|args:"1|2|3|4":$selected_year }} {{:input type="list" From 49b207c0e1ff3487a6eb710a01e6e24aa80a292a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 8 May 2026 08:31:28 +0200 Subject: [PATCH 021/133] =?UTF-8?q?Ajout=20possibilit=C3=A9=20supprimer=20?= =?UTF-8?q?liaison=20=C3=A9criture=20cr=C3=A9dit=20immo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modify_infos.html | 50 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/modify_infos.html b/modify_infos.html index 2016a52..edd3c92 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -2,16 +2,15 @@ {{:admin_header title="Modifier l'immobilisation" custom_css="./style.css" current="module_amortization"}} {{* - @param immo_line_id @param immo_doc_id ¿ @param type_immo : managed, amortized, archived, other ? TODO : - - ¿ faire une ligne modifiable pour chaque avoir avec un bouton de suppression ? - séparer les cas des immo simples et complexes (BOI) par exemple pour la durée d'amort par défaut {{:input ...}} - prise en charge immo => param = immo_line_id - modif param immo => param = immo_doc_id + - DONE possibilité supprimer liaison écriture avoir *}} {{* données de l'immobilisation *}} @@ -61,7 +60,7 @@ {{:assign credit=$credit}} {{:assign credit_trans_id=$id}} {{/select}} - {{:assign var="linked_immos." value=$credit_trans_id}} + {{:assign var="linked_immos." doc=$id trans=$credit_trans_id}} {{if $amount == null}} {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} {{else}} @@ -146,6 +145,44 @@ {{:assign status="managed"}} {{/if}} + {{* écritures de crédit *}} + {{#foreach from=$linked_immos item="elem"}} + {{if ! $_POST.credit_id|has:$elem.trans}} + {{:assign var="docs_to_remove." value=$elem.doc}} + {{:assign var="links_to_remove." value=$elem.trans}} + {{/if}} + {{/foreach}} + + {{if $docs_to_remove != null}} + {{:assign remove_set=$docs_to_remove|implode:","}} + {{:assign remove_set="("|cat:$remove_set|cat:")"}} + {{:delete where="id IN %s"|args:$remove_set}} + + {{* idem avec acc_transactions_links *}} + {{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as linked_id + FROM acc_transactions_links as links + WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; + :immo_trans_id = $ligne_immo.immo_trans_id + }} + {{if ! $linked_id|in:$links_to_remove}} + {{:assign var="linked_transactions." value=$linked_id}} + {{/if}} + {{/select}} + + {{* Enregistrer les liaisons *}} + {{:api + method="POST" + path="accounting/transaction/%s/transactions"|args:$ligne_immo.immo_trans_id + assign="result" + assign_code="result_code" + transactions=$linked_transactions + }} + {{/if}} + {{* enregistrer les infos de l'immobilisation *}} {{:save key=$info_immo.key @@ -167,6 +204,7 @@ {{:assign type_immo="other"}} {{/if}} {{:redirect force="index.html?ok=1&msg=infos&type_immo=%s"|args:$type_immo}} + {{/form}} {{:form_errors}} @@ -216,14 +254,14 @@ {{/if}} {{:input type="date" name="date_achat" label="Date d'acquisition" default=$info_immo.date_achat}} {{:input type="date" name="date_mes" label="Date de mise en service" default=$info_immo.date_mes}} - {{if $linked_immos}} + {{if $linked_immos != null}}
- {{#foreach from=$linked_immos item="id"}} + {{#foreach from=$linked_immos item="elem"}} - {{:input type="hidden" name="credit_id" value=$id}}{{$id}} + {{$elem.trans}} {{/foreach}} From f3ce9858ef5bb1e8a145369c1a0e3d95a92173ab Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 9 May 2026 10:51:45 +0200 Subject: [PATCH 022/133] Ajout affichage montant avoir --- add_infos.html | 11 ++++++++++- amortization.html | 20 +++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/add_infos.html b/add_infos.html index 718f8a1..65eddda 100644 --- a/add_infos.html +++ b/add_infos.html @@ -27,11 +27,13 @@ {{/select}} {{* chercher les liaisons de l'écriture d'immobilisation *}} +{{:assign total_credits=0}} {{#select CASE links.id_related = :immo_trans_id WHEN true THEN links.id_transaction WHEN false THEN links.id_related END as linked_id, + line.credit, acc.code FROM acc_transactions_links as links INNER JOIN acc_transactions_lines AS line on line.id_transaction = linked_id @@ -41,6 +43,7 @@ ; :immo_trans_id = $ligne_immo.immo_trans_id }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} {{:assign var="linked_transactions.%d."|args:$code value=$linked_id}} {{/select}} {{:assign var="immo_transactions" from="linked_transactions.%d"|args:$ligne_immo.code}} @@ -173,8 +176,14 @@
Immobilisation
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
-
Montant
+
Montant de l'immobilisation
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
+ {{if $total_credits > 0}} +
Montant des avoirs
+
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+
Montant à amortir
+
{{"%d-%d"|math:$ligne_immo.montant:$total_credits|money_currency_html:false|raw}}
+ {{/if}}
Date de l'écriture d'immobilisation
{{$ligne_immo.date_achat|date_short}}
diff --git a/amortization.html b/amortization.html index 12df9fa..3875a05 100644 --- a/amortization.html +++ b/amortization.html @@ -59,8 +59,8 @@ }} {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} {{/select}} -{{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} -{{:assign solde=$ligne_immo.montant}} +{{:assign montant_amortissable="%d-%d"|math:$ligne_immo.montant:$total_credits}} +{{:assign solde=$montant_amortissable}} {{* lister les lignes des écritures d'amortissement liées à l'immobilisation *}} {{#select @@ -105,10 +105,10 @@ {{/select}} {{if $status == "amortized"}} - {{:assign amort_amount=$ligne_immo.montant}} + {{:assign amort_amount=$montant_amortissable}} {{:assign valeur_residuelle=0}} {{else}} - {{:assign valeur_residuelle=$ligne_immo.montant}} + {{:assign valeur_residuelle=$montant_amortissable}} {{#foreach from=$linked_amort}} {{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$amort_amount}} {{/foreach}} @@ -239,8 +239,14 @@
Immobilisation
#{{$ligne_immo.immo_trans_id}} {{$ligne_immo.label}}{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $ligne_immo.label}} — {{$ligne_immo.line_label}}{{/if}}
-
Montant
+
Montant de l'immobilisation
{{"%f"|math:$ligne_immo.montant|money_currency_html:false|raw}}
+ {{if $total_credits > 0}} +
Montant des avoirs
+
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+
Montant à amortir
+
{{"%f"|math:$montant_amortissable|money_currency_html:false|raw}}
+ {{/if}}
Début d'amortissement
{{$date_debut|date_short}}
{{if $duree != null}} @@ -249,13 +255,13 @@ {{/if}} {{if $valeur_residuelle > 0}}
Montant des amortissements
-
{{"%d-%d"|math:$ligne_immo.montant:$valeur_residuelle|money_currency_html:false|raw}}
+
{{"%d-%d"|math:$montant_amortissable:$valeur_residuelle|money_currency_html:false|raw}}
Valeur nette comptable
{{$valeur_residuelle|money_currency_html:false|raw}}
{{/if}} {{if $duree != null && $valeur_residuelle > 0}}
Annuité estimée
-
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$ligne_immo.montant:$duree|money_currency_html:false|raw}}
+
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$montant_amortissable:$duree|money_currency_html:false|raw}}
{{/if}}
From a89ec26574d3fa4b33e0dacd56e1521ec3dae930 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 9 May 2026 13:20:40 +0200 Subject: [PATCH 023/133] Version initiale aide --- aide.md | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 aide.md diff --git a/aide.md b/aide.md new file mode 100644 index 0000000..9f020ad --- /dev/null +++ b/aide.md @@ -0,0 +1,145 @@ +# Module de gestion d'immobilisations et amortissements pour Paheko + +## Préambule +* Ce module recense les écritures d'immobilisation et d'amortissement + présentes dans la comptabilité et offre la possibilité de saisir de + nouvelles écritures d'immobilisation, de calculer et d'enregistrer + les écritures d'amortissement. +* Les écritures d'amortissement **liées à une écriture + d'immobilisation** lui sont automatiquement associées par le module + ; par contre, les écritures d'amortissement qui ne sont **pas liées + à une écriture d'immobilisation** sont détectées mais doivent être + associées manuellement à leur immobilisation. + +### Fonctionnalités + * créer une immobilisation + * créer des écritures d'amortissement pour une immobilisation + * associer une écriture d'amortissement « orpheline » à une écriture + d'immobilisation + * sortir une immobilisation du bilan en fin de de vie ou par cession + * réunir des écritures d'immobilisation en cours de constitution + pour créer une immobilisation amortissable + * filtrer les écritures d'immobilisation et d'amortissement par + libellé + * classer manuellement une écriture d'immobilisation (utile pour les + immobilisations créées avant la mise en service du module) + +## Comment faire pour ... + +### Enregistrer une écriture d'immobilisation +Il s'agit de créer une nouvelle écriture d'immobilisation ; pour cela, +cliquer le bouton « Ajouter une immobilisation » qui est présent sur +la plupart des onglets ; dans la fenêtre de saisie qui s'affiche il +suffit de saisir les données de l'immobilisation puis de cliquer +« Ajouter » : + * Exercice : sélectionner l'exercice dans lequel enregistrer l'écriture + * Date d'acquisition : doit être située dans l'exercice sélectionné + * Libellé + * Montant + * Compte de décaissement + * Compte d'immobilisation + * Projet + * case Amortir : laisser cochée pour amortir l'immobilisation, + dé-cocher pour ne pas l'amortir + * Durée d'amortissement en années : à saisir uniquement si + l'immobilisation doit être amortie + * Date de mise en service : c'est la date de première utilisation ; + à renseigner uniquement si différente de la date d'acquisition ; + doit être postérieure ou égale à la date d'acquisition + +### Enregistrer une écriture d'amortissement + * Il n'est possible d'enregistrer une nouvelle écriture + d'amortissement pour une immobilisation que si la date + d'acquisition et la durée d'immobilisation ont été préalablement + définies. + * À partir de l'onglet « Amortissables », cliquer le bouton + « Amortissements » en face de l'immobilisation choisie ; dans la + page suivante, cliquer le bouton « Enregistrer un amortissement » + ; dans la fenêtre de saisie qui s'affiche, il faut renseigner les + informations suivantes : + * Exercice : sélectionner l'exercice dans lequel enregistrer l'écriture + * Date de l'écriture : doit être située dans l'exercice + sélectionné et postérieure à la date de mise en service + * Libellé + * Montant : caclculé par le module ; il peut être modifié si + nécessaire, par exemple pour l'arrondir à un nombre entier + * Compte de débit : par défaut c'est le compte *6811 : Dotation + aux amortissements des immobilisations* + * Compte d'amortissement : par défaut c'est le compte qui + correspond au compte de l'immobilisation + +### Attacher une écriture d'amortissement à une immobilisation +* Il se peut qu'il existe des écritures d'amortissement qui ont été + saisies à l'extérieur du module et qui ne sont pas liées à une + écriture d'immobilisation : le module ne peut donc pas les associer + automatiquement à leur écriture d'immobilisation. +* Quand on affiche la liste des amortissements d'une immobilisation en + cliquant le bouton « Amortissements », on peut voir la liste des + écritures d'amortissements qui ne sont associées à aucune + immobilisation en cliquant le bouton « Rattacher une écriture » ; on + peut alors choisir d'en attacher certaines à l'immobilisation + courante. + +### Sortir une immobilisation du bilan + +### Incorporer une écriture d'immobilisation existante dans le module + +### Transformer des immobilisations en cours en immobilisation amortissable + +### Marquer « à ignorer » des écritures + +### Ignorer des écritures selon leur libellé + + + +## Description de l'interface + +Les écritures d'immobilisation sont réparties en plusieurs onglets. + +### Amortissables +Cet onglet liste les immobilisations en cours d'amortissement. + +##### bouton Paramètres + +Ce bouton affiche une page qui permet de modifier les caractéristiques +d'une immobilisation ; + +On peut décider de son classement : + * Amortir ; c'est le choix par défaut pour les immobilisations de + cet onglet + * Amortissement terminé : cette immobilisation sera alors classée + parmi les immobilisations amorties ; c'est le choix par défaut + pour les immobilisations de l'onglet Amorties + * Ignorer l'écriture : cette écriture n'apparaîtra plus dans la + liste des immobilisations + +Pour les immobilisations à amortir, on peut préciser : + * obligatoirement la durée d'amortissement en années + * optionnellement la date de mise en service si elle est différente + de la date d'acquisition + +###### bouton Amortissements + +Ce bouton affiche la liste des amortissements déjà réalisés pour une +immobilisation ; à partir de cette page, il est possible d'enregistrer +un nouvel amortissement ou bien d'attacher une écriture +d'amortissement à l'immobilisation + +### Amorties +Cet onglet liste les immobilisations dont l'amortissement est terminé +mais toujours en service dans l'association. + +### Sorties du bilan +Cette page liste les immobilisations sorties du bilan, donc qui ne sont +plus en service dans l'association, soit parce qu'elles sont hors +d'usage, soit parce qu'elles ont été cédées. + +### En cours +Cette page liste les immobilisations en cours de constitution, donc +non amortissables ; à terme, elles sont destinées à être regroupées +pour être transformées en immobilisation amortissable. + +### Autres +Cette page liste les écritures d'immobilisation pas (encore) prises en +charge par le module et sans écriture d'amortissement associée. + From 82d42352e61cb555ad9ae98327d90fd0a8e3f279 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 11 May 2026 09:07:13 +0200 Subject: [PATCH 024/133] =?UTF-8?q?Ajout=20Incorporer=20une=20=C3=A9critur?= =?UTF-8?q?e=20d'immobilisation=20et=20modif=20Attacher=20une=20=C3=A9crit?= =?UTF-8?q?ure=20d'amortissement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aide.md | 78 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/aide.md b/aide.md index 9f020ad..90849fa 100644 --- a/aide.md +++ b/aide.md @@ -14,7 +14,7 @@ ### Fonctionnalités * créer une immobilisation * créer des écritures d'amortissement pour une immobilisation - * associer une écriture d'amortissement « orpheline » à une écriture + * associer une écriture d'amortissement *orpheline* à une écriture d'immobilisation * sortir une immobilisation du bilan en fin de de vie ou par cession * réunir des écritures d'immobilisation en cours de constitution @@ -26,12 +26,63 @@ ## Comment faire pour ... +### Incorporer une écriture d'immobilisation existante dans le module +Si on a créé des immobilisations et éventuellement des amortissements +avec Paheko *avant* la mise en service du module *Amortissements*, +il est possible de les prendre en charge avec le module. Les +immobilisations concernées sont regroupées dans l'onglet Autres. + +- cliquer le bouton *Paramètres* en face de l'immobilisation à prendre + en charge +- cocher *Immobilisation à amortir* pour spécifier qu'on veut amortir + l'immobilisation ; plusieurs champs d'informations s'affichennt : + - Durée d'amortissement : renseigner la durée (obligatoire) + - Écritures liées au crédit du compte d'immobilisation : lorsqu'on + acquiert une immobilisation, il se peut que par la suite on + obtienne une ristourne ou un avoir ; cet avoir est enregistré + dans Paheko par une écriture dont le montant est au crédit du + compte d'immobilisation ; le module offre la possibilité + d'associer cette écriture d'avoir à l'écriture + d'immobilisation. En effet, le montant amortissable est égal au + montant d'acquisition de l'immobilisation moins la somme des + avoirs. Pour cela, cliquer le bouton *Ajouter* puis sélectionner + une écriture : cette écriture sera associée à l'écriture + d'immobilisation et son montant déduit du montant de + l'immobilisation pour donner le montant à amortir + - Date de mise en service : c'est la date à laquelle + l'immobilisation est en état de fonctionner, qui peut être + postérieure à la date d'acquisition ; c'est cette date qui est + prise en compte dans le calcul des amortissements ; si elle + coïncide avec la date d'acquisition, inutile de la renseigner. +- L'immobilisation apparait ensuite dans l'onglet *Amortissables* ; on + peut vérifier et éventuellement modifier ses paramètres grâce au + bouton Paramètres + +### Attacher une écriture d'amortissement à une immobilisation +Si des écritures d'amortissement ont été saisies avec Paheko *avant* +la mise en service du module *Amortissements*, on peut les associer à +leur immobilisation : + +- cliquer le bouton *Amortissements* en face de l'immobilisation concernée ; si la mention + +> « Il existe des écritures d'amortissement qui ne sont pas rattachées à une immobilisation ! +> Utilisez le bouton « Rattacher une écriture » pour les afficher ; vous pourrez choisir d'en attacher certaines à cette immobilisation. » + +est présente, c'est qu'il existe des écritures d'amortissement saisies avec Paheko *avant* +la mise en service du module. + +- cliquer le bouton *Rattacher une écriture* pour en afficher la liste +- le cas échéant, cliquer *Attacher* en face de l'écriture à rattacher + +De retour sur la page des amortissements, on constate la présence de l'écriture d'amortissement qu'on vient d'attacher ; on peut répéter le processus plusieurs fois si nécessaire. On peut aussi détacher une écriture si on s'est trompé. + + ### Enregistrer une écriture d'immobilisation Il s'agit de créer une nouvelle écriture d'immobilisation ; pour cela, -cliquer le bouton « Ajouter une immobilisation » qui est présent sur +cliquer le bouton *Ajouter une immobilisation* qui est présent sur la plupart des onglets ; dans la fenêtre de saisie qui s'affiche il suffit de saisir les données de l'immobilisation puis de cliquer -« Ajouter » : +*Ajouter* : * Exercice : sélectionner l'exercice dans lequel enregistrer l'écriture * Date d'acquisition : doit être située dans l'exercice sélectionné * Libellé @@ -52,9 +103,9 @@ suffit de saisir les données de l'immobilisation puis de cliquer d'amortissement pour une immobilisation que si la date d'acquisition et la durée d'immobilisation ont été préalablement définies. - * À partir de l'onglet « Amortissables », cliquer le bouton - « Amortissements » en face de l'immobilisation choisie ; dans la - page suivante, cliquer le bouton « Enregistrer un amortissement » + * À partir de l'onglet *Amortissables*, cliquer le bouton + *Amortissements* en face de l'immobilisation choisie ; dans la + page suivante, cliquer le bouton *Enregistrer un amortissement* ; dans la fenêtre de saisie qui s'affiche, il faut renseigner les informations suivantes : * Exercice : sélectionner l'exercice dans lequel enregistrer l'écriture @@ -68,25 +119,12 @@ suffit de saisir les données de l'immobilisation puis de cliquer * Compte d'amortissement : par défaut c'est le compte qui correspond au compte de l'immobilisation -### Attacher une écriture d'amortissement à une immobilisation -* Il se peut qu'il existe des écritures d'amortissement qui ont été - saisies à l'extérieur du module et qui ne sont pas liées à une - écriture d'immobilisation : le module ne peut donc pas les associer - automatiquement à leur écriture d'immobilisation. -* Quand on affiche la liste des amortissements d'une immobilisation en - cliquant le bouton « Amortissements », on peut voir la liste des - écritures d'amortissements qui ne sont associées à aucune - immobilisation en cliquant le bouton « Rattacher une écriture » ; on - peut alors choisir d'en attacher certaines à l'immobilisation - courante. ### Sortir une immobilisation du bilan -### Incorporer une écriture d'immobilisation existante dans le module - ### Transformer des immobilisations en cours en immobilisation amortissable -### Marquer « à ignorer » des écritures +### Marquer *à ignorer* des écritures ### Ignorer des écritures selon leur libellé From e4a637c6525ba2b84c17cb9767ca857aa8461884 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 11 May 2026 10:23:28 +0200 Subject: [PATCH 025/133] =?UTF-8?q?Correction=20erreur=20affichage=20annui?= =?UTF-8?q?t=C3=A9=20estim=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amortization.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/amortization.html b/amortization.html index 237ee0c..60fb1c4 100644 --- a/amortization.html +++ b/amortization.html @@ -64,7 +64,6 @@ {{/if}} {{/load}} {{:assign solde="%d-%d"|math:$ligne_immo.montant:$total_credits}} -{{*:debug info_immo=$info_immo ligne_immo=$ligne_immo total_credits=$total_credits solde=$solde*}} {{if $info_immo.status == "amortized"}} {{:assign amort_amount=$solde}} @@ -213,7 +212,7 @@ {{/if}} {{if $info_immo.duration != null && $valeur_residuelle > 0}}
Annuité estimée
-
{{"min(%d, %f/%d)"|math:$valeur_residuelle:solde:$info_immo.duration|money_currency_html:false|raw}}
+
{{"min(%d, %f/%d)"|math:$valeur_residuelle:$solde:$info_immo.duration|money_currency_html:false|raw}}
{{/if}} From b15eab168c9f2dbd81c143fde22d4da4dd12fd4e Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 11 May 2026 11:14:31 +0200 Subject: [PATCH 026/133] =?UTF-8?q?Correction=20d=C3=A9termination=20dates?= =?UTF-8?q?=20achat=20et=20mise=20en=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_infos.html | 23 ++++++++++++----------- modify_infos.html | 28 ++++++++++++++++++---------- save_amort.html | 6 ++++++ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/add_infos.html b/add_infos.html index a6c96ea..72ec2c1 100644 --- a/add_infos.html +++ b/add_infos.html @@ -73,6 +73,18 @@ {{:error message="Erreur : la date de mise en service (%s) ne peut être antérieure à la date d'acquisition (%s)"|args:$_POST.date_mes:$da}} {{/if}} + {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $ligne_immo.date_achat}} + {{:assign date_achat=null}} + {{else}} + {{:assign date_achat=$_POST.date_achat|parse_date}} + {{/if}} + + {{if $_POST.date_mes == null || $_POST.date_mes == $_POST.date_achat}} + {{:assign date_mes=null}} + {{else}} + {{:assign date_mes=$_POST.date_mes|parse_date}} + {{/if}} + {{:assign duration=$_POST.duree|intval}} {{if $duration <= 0}} {{:error message="Erreur : la durée d'amortissement doit être strictement positive"}} @@ -100,17 +112,6 @@ {{:error message="Le montant (%s) ne peut être supérieur au reste (%s)"|args:$montant_nb:$reste_nb}} {{/if}} - {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $ligne_immo.date_achat}} - {{:assign date_achat=null}} - {{else}} - {{:assign date_achat=$_POST.date_achat|parse_date}} - {{/if}} - - {{if $_POST.date_mes == null || $_POST.date_mes == $_POST.date_achat || $_POST.date_mes|parse_date == $ligne_immo.date_achat}} - {{:assign date_mes=null}} - {{else}} - {{:assign date_mes=$_POST.date_mes|parse_date}} - {{/if}} {{:assign status="managed"}} {{/if}} diff --git a/modify_infos.html b/modify_infos.html index edd3c92..826a106 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -91,22 +91,30 @@ {{:assign date_mes=null}} {{:assign status="ignored"}} {{else}} - {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $ligne_immo.date_achat}} - {{:assign date_achat=null}} - {{elseif $_POST.date_achat|parse_date == $info_immo.date_achat}} - {{:assign date_achat=$info_immo.date_achat}} - {{else}} - {{:assign date_achat=$_POST.date_achat|parse_date}} - {{/if}} {{if $_POST.date_achat|parse_date > $ligne_immo.date_achat}} {{:assign da=$ligne_immo.date_achat|date_short}} {{:error message="Erreur : la date d'achat (%s) ne peut être postérieure à la date de l'écriture d'immobilisation (%s)"|args:$_POST.date_achat:$da}} {{/if}} - {{if $_POST.date_mes == null || $_POST.date_mes|parse_date == $ligne_immo.date_achat}} - {{:assign date_mes=null}} + {{if $_POST.date_achat == null || $_POST.date_achat|parse_date == $info_immo.date_achat}} + {{:assign date_achat=$info_immo.date_achat}} + {{elseif $_POST.date_achat|parse_date == $ligne_immo.date_achat}} + {{:assign date_achat=null}} + {{else}} + {{:assign date_achat=$_POST.date_achat|parse_date}} + {{/if}} + + {{* TODO : simplifier ? *}} + {{if $_POST.date_mes == null || $_POST.date_mes|parse_date == $info_immo.date_mes}} + {{:assign date_mes=$info_immo.date_mes}} {{elseif $_POST.date_mes|parse_date == $info_immo.date_achat}} {{:assign date_mes=null}} + {{elseif $_POST.date_mes|parse_date == $ligne_immo.date_achat}} + {{if $info_immo.date_achat == null}} + {{:assign date_mes=null}} + {{else}} + {{:assign date_mes=$ligne_immo.date_achat}} + {{/if}} {{else}} {{:assign date_mes=$_POST.date_mes|parse_date}} {{:assign date_achat_comp=$ligne_immo.date_achat}} @@ -250,7 +258,7 @@ {{:input type="text" name="libelle" label="Libellé" default=$info_immo.label}} {{if $info_immo.amount != null}} {{:assign max_aff="%f"|math:$max_disponible|money_currency:false}} - {{:input type="money" name="montant" label="Montant de l'immobilisation" default=$montant_immo help="Montant maximum = %s"|args:$max_aff}} + {{:input type="money" name="montant" label="Montant de l'immobilisation" default=$montant_immo help="Montant maximum : %s"|args:$max_aff}} {{/if}} {{:input type="date" name="date_achat" label="Date d'acquisition" default=$info_immo.date_achat}} {{:input type="date" name="date_mes" label="Date de mise en service" default=$info_immo.date_mes}} diff --git a/save_amort.html b/save_amort.html index 1b199c0..d548c44 100644 --- a/save_amort.html +++ b/save_amort.html @@ -31,6 +31,9 @@ {{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} {{:assign duree=$duration}} + {{if $date_achat != null}} + {{:assign date_debut=$date_achat}} + {{/if}} {{if $date_mes != null}} {{:assign date_debut=$date_mes}} {{/if}} @@ -42,6 +45,7 @@ {{else}} {{:error message="Informations de l'immobilisation « %s » non trouvées ; vous devez d'abord les renseigner"|args:$ligne_immo.label}} {{/load}} + {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $amort_label}} {{:assign amort_label=$amort_label|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} @@ -83,6 +87,7 @@ {{#select line.credit, trans.date as amort_date, + COALESCE(trans.label, line.label) as amort_label, account.code as account_code, account.label as account_label FROM acc_transactions_lines AS line @@ -106,6 +111,7 @@ {{:assign date_debut=$line.amort_date}} {{:assign code_amort=$line.account_code}} {{:assign amort_account_label=$line.account_label}} + {{:assign amort_label=$amort_label}} {{/foreach}} {{if $valeur_residuelle == 0}} From b83942efd234e935bb7eb977574714894b9f6793 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 11 May 2026 11:31:21 +0200 Subject: [PATCH 027/133] Ajout delete_infos.html --- delete_infos.html | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 delete_infos.html diff --git a/delete_infos.html b/delete_infos.html new file mode 100644 index 0000000..5e5d2a0 --- /dev/null +++ b/delete_infos.html @@ -0,0 +1,100 @@ +{{* -*- brindille -*- *}} + +{{* + Supprimer les infos d'une immo et les liaisons d'immo associées + @param immo_doc_id +*}} + +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} +{{#select + trans.id as immo_trans_id, + trans.label as trans_label, + trans.date as date_achat, + line.debit as montant, + line.label as line_label, + acc.code, + acc.label as account_label + FROM acc_transactions_lines AS line + INNER join acc_transactions AS trans ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE line.id = :line_id; + :line_id = $info_immo.line + assign="ligne_immo" + }} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/select}} + +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} +{{:assign immo_label=$info_immo.label|or:$ligne_immo.trans_label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $immo_label}} + {{:assign immo_label=$immo_label|cat::" — "|cat:$ligne_immo.line_label}} +{{/if}} + +{{#form on="delete"}} + {{#select + trans.id + FROM acc_transactions_lines AS line + INNER JOIN !table ON $$.credit_line_id = line.id + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + WHERE $$.type = + "credit_link" AND $$.immo_doc_id = :immo_doc_id + ; + !table = $module.table + :immo_doc_id = $_GET.immo_doc_id|intval + }} + {{:assign var="linked_trans." value=$id}} + {{/select}} + + {{:debug linked_trans=$linked_trans}} + {{if $linked_trans != null}} + {{* chercher et supprimer les écritures liées *}} + {{#select + CASE links.id_related = trans.id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as linked_id + FROM acc_transactions AS trans + INNER JOIN acc_transactions_links as links + ON (links.id_transaction = trans.id OR links.id_related = trans.id) + WHERE trans.id = :immo_trans_id + ; + :immo_trans_id=$ligne_immo.immo_trans_id + }} + {{if ! $linked_trans|has:$linked_id}} + {{:assign var="linked_transactions." value=$linked_id}} + {{/if}} + {{/select}} + + {{* enregistrer les liaisons restantes *}} + {{:api + method="POST" + path="accounting/transaction/%s/transactions"|args:$ligne_immo.immo_trans_id + assign="result" + assign_code="result_code" + transactions=$linked_transactions + }} + + {{* supprimer les docs de liaison *}} + {{:delete type="immo_link" where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $_GET.immo_doc_id|intval}} + + {{/if}} + + {{* supprimer les infos de l'immobilisation *}} + {{:delete id=$_GET.immo_doc_id|intval}} + {{:redirect force="index.html?ok=1&msg=suppr_infos&type_immo=other"}} +{{/form}} + + +{{:admin_header title="Supprimer" current="module_amortization"}} +{{:form_errors}} +{{:delete_form + legend="Immobilisation « #%s %s »"|args:$ligne_immo.immo_trans_id:$immo_label + warning="Supprimer les paramètres de l'immobilisation « #%s %s » ?"|args:$ligne_immo.immo_trans_id:$immo_label + info="L'écriture d'immobilisation ne sera pas supprimée ; les nouveaux paramètres pourront être saisis depuis l'onglet « À classer »" +}} + +{{:admin_footer}} From 18ce7b0edd13002a6b9cd402a9352296576fed6c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 12 May 2026 09:56:08 +0200 Subject: [PATCH 028/133] =?UTF-8?q?Modification=20pr=C3=A9sentation=20?= =?UTF-8?q?=C3=A9critures=20avoir=20li=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- details_immo.html | 71 +++++++++++++++++++++++++++++++++++++---------- style.css | 9 ++++++ 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/details_immo.html b/details_immo.html index 0954f68..70fc845 100644 --- a/details_immo.html +++ b/details_immo.html @@ -1,6 +1,5 @@ {{* -*- brindille -*- *}} -{{:admin_header title="Détails de l'immobilisation" custom_css="./style.css" current="module_amortization"}} {{* Afficher les détails d'une immmo @@ -32,7 +31,7 @@ account.code as account_code, account.label as account_label FROM acc_transactions_lines AS line - INNER join acc_transactions AS trans ON line.id_transaction = trans.id + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id INNER JOIN acc_accounts AS account ON line.id_account = account.id WHERE line.id = :line_id; :line_id = $info_immo.line @@ -44,7 +43,7 @@ {{:assign var="info_immo.amount" value=$info_immo.amount|or:$ligne_immo.montant}} {{:assign var="info_immo.date_achat" value=$info_immo.date_achat|or:$ligne_immo.date_achat}} -{{:assign var="info_immo.date_mes" value=$info_immo.date_mes|or:$ligne_immo.date_achat}} +{{:assign var="info_immo.date_mes" value=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{:assign var="info_immo.label" value=$info_immo.label|or:$ligne_immo.label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $info_immo.label}} {{:assign var="info_immo.label" value=$info_immo.label|cat:" — "|cat:$ligne_immo.line_label}} @@ -56,19 +55,20 @@ *}} {{:assign linked_immos=null}} {{:assign total_credits=0}} -{{#load type="immo_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} +{{#load type="credit_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} {{#select line.credit, - trans.id + trans.id, + trans.label, + trans.date FROM acc_transactions_lines AS line INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id WHERE line.id = :credit_line_id; :credit_line_id=$credit_line_id }} {{:assign credit=$credit}} - {{:assign credit_trans_id=$id}} + {{:assign var="linked_immos." id=$id label=$label amount=$credit date=$date}} {{/select}} - {{:assign var="linked_immos." value=$credit_trans_id}} {{if $amount == null}} {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} {{else}} @@ -94,17 +94,37 @@ {{/if}} {{/load}} -{{* barre de navigation *}} +{{:admin_header title="Détails de l'immobilisation" custom_css="./style.css" current="module_amortization"}} + +{{* {{if ! $dialog}} + {{:assign subsubcurrent=null}} {{if $total_credits == 0 && $total_amort == 0}} {{:assign subsubcurrent="credit"}} - {{else}} - {{:assign subsubcurrent=null}} + {{/if}} + {{if $total_amort == 0}} + {{:assign subsubcurrent=$subsubcurrent|cat:"-modif"}} {{/if}} {{:include file="_nav.html" current="index" subcurrent="details" subsubcurrent=$subsubcurrent}} {{/if}} +*}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.immo_trans_id}} + + {{if $_GET.ok}} {{if $_GET.msg|match:"attach_amort"}} {{:assign msg="Attachement amortissement effectué"}} @@ -119,14 +139,34 @@

{{$msg}}

{{/if}} +{{*

Paramètres de l'immobilisation #{{$ligne_immo.immo_trans_id}}

+*}} +{{if $linked_immos != null}} + +{{/if}}
Immobilisation
-
#{{$ligne_immo.immo_trans_id}} {{$info_immo.label}}
+
#{{$ligne_immo.immo_trans_id}} {{$info_immo.label}}
Compte d'immobilisation
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
Montant de l'immobilisation
@@ -134,14 +174,15 @@ {{if $total_credits > 0}}
Montant des avoirs
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
+{{*
Écritures d'avoir
- {{#foreach from=$linked_immos item="id"}} - {{:assign url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$id}} - #{{$id}} + {{#foreach from=$linked_immos item="elem"}} + {{:assign url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$elem.id}} + #{{$elem.id}} {{/foreach}} - {{*:debug linked_immos=$linked_immos*}}
+*}}
Montant à amortir
{{"%f"|math:$solde|money_currency_html:false|raw}}
{{/if}} diff --git a/style.css b/style.css index 1a8ed6d..e7ed568 100644 --- a/style.css +++ b/style.css @@ -98,3 +98,12 @@ html.dark .block.alert { span.input-list.avoirs label { padding : 0.4rem 0.6rem; } + +aside.right { + float: right; +} + +span.label { + font-size : 120%; + font-weight : bold; +} From 91ec943e6d7a920a9229f513eca6c492401518f0 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 12 May 2026 11:52:01 +0200 Subject: [PATCH 029/133] =?UTF-8?q?Ajout=20possibilit=C3=A9=20d=C3=A9tache?= =?UTF-8?q?ment=20=C3=A9criture=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- detach_immo.html | 73 +++++++++++++++++++++++++++++++++++++++++ details_immo.html | 83 +++++++++++++++++++++++++---------------------- 2 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 detach_immo.html diff --git a/detach_immo.html b/detach_immo.html new file mode 100644 index 0000000..37b4397 --- /dev/null +++ b/detach_immo.html @@ -0,0 +1,73 @@ +{{* -*- brindille -*- *}} + +{{* + Supprimer l'association entre une écriture d'immobilisation et + une écriture au crédit du compte d'immobilisation + @param immo_line_id : id de la ligne d'immo + @param credit__line_id : id de la ligne de crédit + @param immo_doc_id : id du doc associé à l'immo +*}} + +{{* chercher l'écriture d'immobilisation *}} +{{#select + id_transaction + FROM acc_transactions_lines + WHERE id = :line_id; + :line_id = $_GET.immo_line_id|intval +}} + {{:assign immo_trans_id=$id_transaction}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/select}} + +{{* chercher l'écriture au crédit *}} +{{#select + id_transaction + FROM acc_transactions_lines + WHERE id = :line_id; + :line_id = $_GET.credit_line_id|intval +}} + {{:assign credit_id=$id_transaction}} +{{else}} + {{:error message="Écriture au crédit non trouvée"}} +{{/select}} + +{{* + chercher les liaisons de l'écriture d'immobilisation + et supprimer la liaison avec l'écriture au crédit +*}} +{{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as linked_id + FROM acc_transactions_links as links + WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; + :immo_trans_id = $immo_trans_id + }} + {{if $linked_id != $credit_id}} + {{:assign var="linked_transactions." value=$linked_id}} + {{/if}} +{{/select}} + +{{* Enregistrer les liaisons *}} +{{:api + method="POST" + path="accounting/transaction/%s/transactions"|args:$immo_trans_id + assign="result" + assign_code="result_code" + transactions=$linked_transactions +}} + +{{* supprimer le doc de liaison entre les lignes *}} +{{#load type="credit_link" + where="$$.immo_doc_id = :immo_doc_id AND $$.credit_line_id = :credit_line_id" + :immo_doc_id=$_GET.immo_doc_id|intval + :credit_line_id = $_GET.credit_line_id|intval +}} + {{:delete id=$id}} +{{/load}} + +{{:redirect + to="details_immo.html?immo_doc_id=%s&ok=1&msg=detach&"|args:$_GET.immo_doc_id}} +*}} diff --git a/details_immo.html b/details_immo.html index 70fc845..c576ba6 100644 --- a/details_immo.html +++ b/details_immo.html @@ -9,12 +9,6 @@ @param immo_doc_id : numéro du doc d'immo *}} -{{* - TODO : permettre la modification des param (en cas d'erreur de saisie) - TODO : permettre de corriger le montant de l'amort et/ou de supprimer l'attachement - FAIT : déduire montant au crédit de la ligne d'immo -*}} - {{* données de l'immobilisation *}} {{#load type="immo" id=$_GET.immo_doc_id|intval assign="info_immo"}} {{else}} @@ -58,7 +52,8 @@ {{#load type="credit_link" where="$$.immo_doc_id=:immo_doc_id" :immo_doc_id=$_GET.immo_doc_id|intval}} {{#select line.credit, - trans.id, + line.id as line_id, + trans.id as trans_id, trans.label, trans.date FROM acc_transactions_lines AS line @@ -67,7 +62,7 @@ :credit_line_id=$credit_line_id }} {{:assign credit=$credit}} - {{:assign var="linked_immos." id=$id label=$label amount=$credit date=$date}} + {{:assign var="linked_immos." trans_id=$trans_id credit_line_id=$line_id label=$label amount=$credit date=$date}} {{/select}} {{if $amount == null}} {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} @@ -127,11 +122,15 @@ {{if $_GET.ok}} {{if $_GET.msg|match:"attach_amort"}} - {{:assign msg="Attachement amortissement effectué"}} + {{:assign msg="Écriture d'amortissement attachée"}} {{elseif $_GET.msg|match:"attach_immo"}} - {{:assign msg="Attachement avoir effectué"}} + {{:assign msg="Écriture au crédit attachée"}} {{elseif $_GET.msg|match:"info"}} {{:assign msg="Données de l'immobilisation enregistrées"}} + {{elseif $_GET.msg|match:"detach"}} + {{:assign msg="Écriture au crédit détachée"}} + {{else}} + {{:assign msg="Opération effectuée avec succès"}} {{/if}}

{{$msg}}

{{elseif $_GET.err}} @@ -139,24 +138,26 @@

{{$msg}}

{{/if}} -{{*

- Paramètres de l'immobilisation + Immobilisation #{{$ligne_immo.immo_trans_id}} + {{$info_immo.label}}

-*}} {{if $linked_immos != null}}
From 85bc1316b5b1337e9f3c6dded87c467fa80f5be4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 13 May 2026 14:25:48 +0200 Subject: [PATCH 033/133] =?UTF-8?q?Adaptation=20nouvelles=20liaisons=20+?= =?UTF-8?q?=20am=C3=A9liorations=20v=C3=A9rif=20dates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- balance_sheet_exit.html | 245 +++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 115 deletions(-) diff --git a/balance_sheet_exit.html b/balance_sheet_exit.html index e7d9ba7..195841b 100644 --- a/balance_sheet_exit.html +++ b/balance_sheet_exit.html @@ -3,6 +3,7 @@ {{* Sortir une immobilisation du bilan @param immo_line_id : id de la ligne d'immobilisation + @param immo_doc_id : id du doc associé à l'immo *}} {{* Infos de l'immobilisation *}} @@ -20,110 +21,120 @@ assign="ligne_immo" }} {{else}} - {{:error message="Immobilisation %s non trouvée"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} {{:assign date_debut=$ligne_immo.date_achat}} {{:assign ts_mes=$ligne_immo.date_achat|strtotime}} -{{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} - {{:assign ts_mes=$date|strtotime}} - {{:assign date_debut=$date}} +{{* TODO : traiter le cas des immos sans doc *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} + {{:assign ts_mes=$date_mes|strtotime}} + {{if $date_mes != null}} + {{:assign date_debut=$date_mes}} + {{/if}} {{:assign duree_amort=$duration}} + {{if $amount != null}} + {{:assign var="ligne_immo.montant" value=$amount}} + {{/if}} +{{else}} + {{* TODO *}} + {{:error message="Immobilisation non trouvée"}} {{/load}} {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$ligne_immo.trans_id - :account=$ligne_immo.account_code +{{#load + type="credit_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $info_immo.id + assign="credit_link" }} - {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} -{{/select}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{else}} + {{* pas de doc => voir liaison écritures *}} + {{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as other_id, + line.credit + FROM acc_transactions AS trans + INNER JOIN acc_transactions_links as links + ON (trans.id = links.id_transaction OR trans.id = links.id_related) + INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; + :immo_trans_id=$ligne_immo.trans_id + :account=$ligne_immo.account_code + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} +{{/load}} {{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} -{{* chercher des écritures d'amortissement liées à l'immobilisation *}} {{:assign total_amort=0}} -{{:assign amort_number=0}} -{{#select - l_amort.credit as amort_amount, - l_amort.id as amort_line_id, - CASE - WHEN links.id_related = t_immo.id - THEN links.id_transaction - ELSE links.id_related - END as amort_trans_id, - trans.date - FROM acc_transactions_lines as l_immo - INNER JOIN acc_transactions as t_immo on t_immo.id = l_immo.id_transaction - INNER JOIN acc_transactions_links as links - ON (t_immo.id = links.id_transaction OR t_immo.id = links.id_related) - INNER JOIN acc_transactions_lines as l_amort on amort_trans_id = l_amort.id_transaction - INNER join acc_transactions as trans on l_amort.id_transaction = trans.id - INNER JOIN acc_accounts AS account ON l_amort.id_account = account.id - WHERE l_immo.id = :line_id AND account.code LIKE '28%' - ; - :line_id = $_GET.immo_line_id|intval - assign="amort_line" +{{#load type="amort_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $_GET.immo_doc_id|intval }} - - {{#load type="link" - where="$$.immo_line_id = :immo_line_id AND $$.amort_trans_id = :amort_trans_id" - assign="line" - :immo_line_id=$_GET.immo_line_id|intval :amort_trans_id=$amort_line.amort_trans_id + {{#select + line.id as amort_line_id, + line.credit, + line.label as amort_line_label, + trans.id as amort_trans_id, + trans.label as amort_trans_label, + trans.date as amort_date, + trans.id_year as amort_year, + account.id as account_id, + account.code as account_code, + account.label as account_label + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + INNER join acc_accounts AS account on line.id_account = account.id + WHERE line.id = :amort_line_id + ; + :amort_line_id = $amort_line_id + assign="amort_line" }} - {{if $line.amort_line_id == $amort_line.amort_line_id}} - {{:assign amort_number="%d+1"|math:$amort_number}} - {{:assign total_amort="%d+%d"|math:$total_amort:$amort_line.amort_amount}} - {{if $first_amort_date == null}} - {{:assign first_amort_date=$amort_line.date}} - {{elseif $amort_line.date < $first_amort_date}} - {{:assign first_amort_date=$amort_line.date}} - {{/if}} - {{if $last_amort_date == null}} - {{:assign last_amort_date=$amort_line.date}} - {{elseif $amort_line.date > $last_amort_date}} - {{:assign last_amort_date=$amort_line.date}} - {{/if}} - {{/if}} - {{else}} - {{:assign amort_number="%d+1"|math:$amort_number}} + {{:assign var="amort_line.amort_amount" value=$amount|or:$credit}} {{:assign total_amort="%d+%d"|math:$total_amort:$amort_line.amort_amount}} - {{if $first_amort_date == null}} - {{:assign first_amort_date=$amort_line.date}} - {{elseif $amort_line.date < $first_amort_date}} - {{:assign first_amort_date=$amort_line.date}} - {{/if}} - {{if $last_amort_date == null}} - {{:assign last_amort_date=$amort_line.date}} - {{elseif $amort_line.date > $last_amort_date}} - {{:assign last_amort_date=$amort_line.date}} - {{/if}} - {{/load}} -{{/select}} + {{:assign var="linked_amort.%s_%d"|args:$amort_date:$id value=$amort_line}} + {{/select}} +{{/load}} +{{:assign amort_number=$linked_amort|count}} + +{{#foreach from=$linked_amort|ksort item="line"}} + {{if $first_amort_date == null}} + {{:assign first_amort_date=$line.amort_date}} + {{/if}} + {{if $last_amort_date == null}} + {{:assign last_amort_date=$line.amort_date}} + {{elseif $line.amort_date > $last_amort_date}} + {{:assign last_amort_date=$line.amort_date}} + {{/if}} +{{/foreach}} {{if $total_amort == 0}} {{if $info_immo.status == "amortized"}} {{:assign total_amort=$ligne_immo.montant}} {{/if}} {{else}} - {{:assign date_debut=$last_amort_date|strtotime}} - {{:assign date_debut="%d+(60*60*24)"|math:$date_debut|date:"Y-m-d"}} + {{:assign date_debut=$last_amort_date}} {{/if}} {{:assign ts_debut=$date_debut|strtotime}} +{{:assign ts_debut="%d+(60*60*24)"|math:$ts_debut}} +{{:assign date_debut=$ts_debut|date:"Y-m-d"}} {{:assign valeur_nette="%f-%f"|math:$ligne_immo.montant:$total_amort}} {{* @@ -139,7 +150,8 @@ {{:assign fin=$end_date|date_short}} {{:assign var="open_years.%d"|args:$id value=$label|cat:" (du "|cat:$debut|cat:" au "|cat:$fin|cat:")"}} {{else}} - {{:error message="Aucun exercice ouvert pour enregistrer un amortissement"}} + {{:assign debut=$date_debut|date_short}} + {{:error message="Aucun exercice ouvert pour enregistrer un amortissement à partir du %s"|args:$debut}} {{/years}} {{if $years|count == 1}} {{:assign default_year=$years.0.id}} @@ -178,9 +190,9 @@ {{/if}} {{* vérifier la validité de la date de sortie *}} - {{if $info_immo.date != null}} - {{if $_POST.date_sortie|parse_date < $info_immo.date}} - {{:assign immo_date=$info_immo.date|date_short}} + {{if $info_immo.date_mes != null}} + {{if $_POST.date_sortie|parse_date < $info_immo.date_mes}} + {{:assign immo_date=$info_immo.date_mes|date_short}} {{:error message="La date de sortie doit être postérieure à la date de mise en service de l'immobilisation (%s)"|args:$immo_date}} {{/if}} {{elseif $_POST.date_mes != null}} @@ -196,31 +208,34 @@ {{:error message="La date de sortie doit être postérieure à la date du dernier amortissement (%s)"|args:$last_amort_date}} {{/if}} - {{* vérifier que la date de sortie est située dans un exercice ouvert *}} {{:assign ts_exit = $_POST.date_sortie|parse_date|strtotime}} - {{:assign ok=false}} - {{:assign msg_amort=""}} - {{#foreach from=$years}} - {{if $id == $_POST.id_year}} - {{:assign selected_year=$id}} + {{:assign exercice_ok=false}} + {{* vérifier que la date de sortie est dans l'exercice choisi *}} + {{#foreach from=$years item="current_year"}} + {{if $current_year.id == $_POST.id_year}} + {{:assign selected_year=$current_year.id}} {{if $start_date|strtotime <= $ts_exit && $ts_exit <= $end_date|strtotime}} - {{:assign ok=true}} + {{:assign current_year=$current_year}} + {{:assign exercice_ok=true}} {{:break}} {{/if}} {{/if}} - - {{* voir si des amortissements ont été oubliés *}} - {{if $valeur_nette > 0 && $info_immo.status != "amortized" && $start_date|strtotime > $last_amort_date|strtotime && $end_date|strtotime < $now}} - {{:assign debut=$start_date|date_short}} - {{:assign fin=$end_date|date_short}} - {{:assign msg_amort=$msg_amort|cat:"\n"|cat:" - "|cat:$label|cat:" : du "|cat:$debut|cat:" au "|cat:$fin}} - {{/if}} {{/foreach}} - {{if ! $ok}} + {{if ! $exercice_ok}} {{:error message="La date choisie n'est pas dans l'exercice sélectionné !"}} {{/if}} - {{if $msg_amort != ""}} - {{:error message="Vous devez d'abord enregistrer les amortissements des exercices suivants : %s"|args:$msg_amort}} + + {{* voir si des amortissements ont été oubliés *}} + {{if $valeur_nette > 0 && $info_immo.status != "amortized"}} + {{if $current_year.start_date <= $date_debut && $date_debut <= $current_year.end_date}} + {{:assign amort_ok=true}} + {{else}} + {{:assign amort_ok=false}} + {{/if}} + + {{if ! $amort_ok}} + {{:error message="Vous devez d'abord enregistrer les amortissements des exercices précédents"}} + {{/if}} {{/if}} {{:redirect to="compute_exit_data.html?immo_line_id=%s&amort_amount=%s&year=%s&date_mes=%s&date_debut=%s&exit_date=%s&duree_amort=%s"|args:$_GET.immo_line_id:$total_amort:$selected_year:$ts_mes:$ts_debut:$ts_exit:$duree_amort}} @@ -243,10 +258,10 @@
Montant
{{$ligne_immo.montant|money_currency_html:false|raw}}
Date d'acquisition
-
{{$ligne_immo.date_achat|date_short}}
- {{if $info_immo.date != null && $info_immo.date != $ligne_immo.date_achat}} +
{{$info_immo.date_achat|or:$ligne_immo.date_achat|date_short}}
+ {{if $info_immo.date_mes != null && $info_immo.date_mes != $ligne_immo.date_achat}}
Date de mise en service
-
{{$info_immo.date|date_short}}
+
{{$info_immo.date_mes|date_short}}
{{/if}} {{if $info_immo.duration != null}}
Durée de l'amortissement
@@ -256,23 +271,23 @@
{{$total_amort|money_currency_html:false|raw}} (à la date de début de l'exercice)
Valeur nette résiduelle
{{$valeur_nette|money_currency_html:false|raw}} (à la date de début de l'exercice)
+ {{if $last_amort_date != null}} +
Date du dernier amortissement
+
{{$last_amort_date|date_short}}
+ {{/if}}
- {{if $valeur_nette > 0}} - {{if $info_immo.date == null || $info_immo.duration == null}} -
- Informations sur l'immobilisation -
- {{if $info_immo.date == null}} - {{: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"}} - {{/if}} - {{if $info_immo.duration == null}} - {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 help="La durée est nécessaire pour calculer l'amortissement complémentaire"}} - {{/if}} -
-
- {{/if}} + + {{if $info_immo == null && $total_amort == 0 }} +
+ Autres informations +
+ {{: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"}} + {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 help="La durée est nécessaire pour calculer l'amortissement complémentaire"}} +
+
{{/if}} +
Informations de sortie
From 40ad2a0e3034ccc57d75fdb0319cb6e7a143bf1a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 13 May 2026 14:28:34 +0200 Subject: [PATCH 034/133] =?UTF-8?q?Ajout=20liaisons=20=C3=A9critures=20sor?= =?UTF-8?q?tie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- write_exit.html | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/write_exit.html b/write_exit.html index a4de1cd..ac0d459 100644 --- a/write_exit.html +++ b/write_exit.html @@ -3,7 +3,7 @@ {{* Enregistrer les écritures de sortie du bilan paramètres : - - immo_line_id : numéro de ligne de l'écriture d'immobilisation + - immo_line_id : numéro de ligne de l'écriture d'immobilisation - amort_amount : montant des amortissements - year : exercice de la date de sortie de l'immobilisation - date_mes : date de mise en service de l'immobilisation @@ -30,6 +30,9 @@ }} {{/select}} +{{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} +{{/load}} + {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} @@ -161,6 +164,18 @@ lines=$lines linked_transactions=$ligne_immo.id_transaction }} + {{#foreach from=$result.lines item="line"}} +{{* TODO : cas où pas de doc ? (info_immo = null) *}} + {{if $line.account_code == $amort_account_code}} + {{:save + key=""|uuid + type="amort_link" + immo_doc_id=$info_immo.id + amort_line_id=$line.id + }} + {{:break}} + {{/if}} + {{/foreach}} {{/if}} {{* écriture de sortie du bilan *}} @@ -214,6 +229,17 @@ lines=$lines linked_transactions=$ligne_immo.id_transaction }} + {{#foreach from=$result.lines item="line"}} + {{if $line.account_code == $immo_account_code}} + {{:save + key=""|uuid + type="exit_link" + immo_doc_id=$info_immo.id + exit_line_id=$line.id + }} + {{:break}} + {{/if}} + {{/foreach}} {{if $montant_cession > 0}} {{* Cession de l'immobilisation *}} From c427e8900f3b1c8e1864dadc49ec885ea32ed701 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 14 May 2026 11:16:34 +0200 Subject: [PATCH 035/133] =?UTF-8?q?Am=C3=A9lioration=20cosm=C3=A9tique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_infos.html | 2 +- style.css | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/add_infos.html b/add_infos.html index 72ec2c1..e8efb82 100644 --- a/add_infos.html +++ b/add_infos.html @@ -185,7 +185,7 @@ {{/if}} {{:input id="amortir" type="checkbox" value=1 name="amortir" label="Amortir cette immobilisation sur une ou plusieurs années" checked="%s"|args:$checked help="Dé-cocher pour ne pas amortir"}}
- {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1}} + {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 suffix="année(s)"}}
diff --git a/style.css b/style.css index e7ed568..9811b17 100644 --- a/style.css +++ b/style.css @@ -102,8 +102,3 @@ span.input-list.avoirs label { aside.right { float: right; } - -span.label { - font-size : 120%; - font-weight : bold; -} From bb8d27b6167283dd4eaca9aa4ff15ff9f15ad39e Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 14 May 2026 12:00:01 +0200 Subject: [PATCH 036/133] Adaptation sortie bilan aux nouveaux documents --- balance_sheet_exit.html | 90 +++++++------------------------ compute_exit_data.html | 93 ++++++++++++++++++++------------ write_exit.html | 115 ++++++++++++++++++++++------------------ 3 files changed, 138 insertions(+), 160 deletions(-) diff --git a/balance_sheet_exit.html b/balance_sheet_exit.html index 195841b..227adf4 100644 --- a/balance_sheet_exit.html +++ b/balance_sheet_exit.html @@ -2,11 +2,15 @@ {{* Sortir une immobilisation du bilan - @param immo_line_id : id de la ligne d'immobilisation @param immo_doc_id : id du doc associé à l'immo *}} {{* Infos de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select line.debit as montant, trans.id AS trans_id, @@ -17,30 +21,17 @@ INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id INNER JOIN acc_accounts AS account ON line.id_account = account.id WHERE line.id = :line_id; - :line_id = $_GET.immo_line_id|intval + :line_id = $info_immo.line assign="ligne_immo" }} {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} -{{:assign date_debut=$ligne_immo.date_achat}} -{{:assign ts_mes=$ligne_immo.date_achat|strtotime}} - -{{* TODO : traiter le cas des immos sans doc *}} -{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} - {{:assign ts_mes=$date_mes|strtotime}} - {{if $date_mes != null}} - {{:assign date_debut=$date_mes}} - {{/if}} - {{:assign duree_amort=$duration}} - {{if $amount != null}} - {{:assign var="ligne_immo.montant" value=$amount}} - {{/if}} -{{else}} - {{* TODO *}} - {{:error message="Immobilisation non trouvée"}} -{{/load}} +{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.montant" value=$info_immo.amount}} +{{/if}} {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo @@ -62,7 +53,10 @@ {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} {{/if}} {{else}} - {{* pas de doc => voir liaison écritures *}} + {{* + TODO : à garder ? + pas de doc => voir liaison écritures + *}} {{#select CASE links.id_related = :immo_trans_id WHEN true THEN links.id_transaction @@ -89,26 +83,17 @@ :immo_doc_id = $_GET.immo_doc_id|intval }} {{#select - line.id as amort_line_id, line.credit, - line.label as amort_line_label, - trans.id as amort_trans_id, - trans.label as amort_trans_label, - trans.date as amort_date, - trans.id_year as amort_year, - account.id as account_id, - account.code as account_code, - account.label as account_label + trans.date as amort_date FROM acc_transactions_lines AS line INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id - INNER join acc_accounts AS account on line.id_account = account.id WHERE line.id = :amort_line_id ; :amort_line_id = $amort_line_id assign="amort_line" }} - {{:assign var="amort_line.amort_amount" value=$amount|or:$credit}} - {{:assign total_amort="%d+%d"|math:$total_amort:$amort_line.amort_amount}} + {{:assign amort_amount=$amount|or:$credit}} + {{:assign total_amort="%d+%d"|math:$total_amort:$amort_amount}} {{:assign var="linked_amort.%s_%d"|args:$amort_date:$id value=$amort_line}} {{/select}} {{/load}} @@ -166,39 +151,12 @@ {{:error message="Vous devez renseigner la date de sortie"}} {{/if}} - {{* vérifier la validité de la date de mise en service *}} - {{if $_POST.date_mes != null}} - {{:assign ts_mes=$_POST.date_mes|parse_date|strtotime}} - {{if $ts_mes < $ligne_immo.date_achat|strtotime || $ts_mes > $first_amort_date|strtotime}} - {{:assign immo_date=$ligne_immo.date_achat|date_short}} - {{:assign amort_date=$first_amort_date|date_short}} - {{:error message="La date de mise en service doit être postérieure à la date d'acquisition de l'immobilisation (%s) et antérieure à la date du premier amortissement (%s)"|args:$immo_date:$amort_date}} - {{/if}} - {{/if}} - - {{* vérifier la validité de la durée d'immobilisation *}} - {{if $valeur_nette > 0}} - {{if $info_immo.duration == null}} - {{if $_POST.duree == null}} - {{:error message="Vous devez renseigner la durée de l'immobilisation"}} - {{elseif $_POST.duree < $amort_number}} - {{:error message="La durée de l'amortissement ne peut être inférieure au nombre d'écritures d'amortissement (%d)"|args:$amort_number}} - {{else}} - {{:assign duree_amort=$_POST.duree}} - {{/if}} - {{/if}} - {{/if}} - {{* vérifier la validité de la date de sortie *}} {{if $info_immo.date_mes != null}} {{if $_POST.date_sortie|parse_date < $info_immo.date_mes}} {{:assign immo_date=$info_immo.date_mes|date_short}} {{:error message="La date de sortie doit être postérieure à la date de mise en service de l'immobilisation (%s)"|args:$immo_date}} {{/if}} - {{elseif $_POST.date_mes != null}} - {{if $_POST.date_sortie|parse_date < $_POST.date_mes|parse_date}} - {{:error message="La date de sortie doit être postérieure à la date de mise en service de l'immobilisation (%s)"|args:$_POST.date_mes}} - {{/if}} {{elseif $_POST.date_sortie|parse_date < $ligne_immo.date_achat}} {{:assign immo_date=$ligne_immo.date_achat|date_short}} {{:error message="La date de sortie doit être postérieure à la date d'acquisition de l'immobilisation (%s)"|args:$immo_date}} @@ -232,17 +190,15 @@ {{else}} {{:assign amort_ok=false}} {{/if}} - {{if ! $amort_ok}} {{:error message="Vous devez d'abord enregistrer les amortissements des exercices précédents"}} {{/if}} {{/if}} - {{:redirect to="compute_exit_data.html?immo_line_id=%s&amort_amount=%s&year=%s&date_mes=%s&date_debut=%s&exit_date=%s&duree_amort=%s"|args:$_GET.immo_line_id:$total_amort:$selected_year:$ts_mes:$ts_debut:$ts_exit:$duree_amort}} + {{:redirect to="compute_exit_data.html?immo_doc_id=%s&amort_amount=%s&year=%s&date_debut=%s&exit_date=%s"|args:$_GET.immo_doc_id:$total_amort:$selected_year:$ts_debut:$ts_exit}} {{/form}} {{:admin_header title="Sortie de bilan" custom_css="./style.css" current="module_amortization"}} -{{* barre de navigation *}} {{if ! $dialog}} {{:include file="_nav.html" current="index" subcurrent="%s"|args:$_GET.type_immo subsubcurrent="balance_exit"}} {{/if}} @@ -278,16 +234,6 @@ - {{if $info_immo == null && $total_amort == 0 }} -
- Autres informations -
- {{: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"}} - {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 help="La durée est nécessaire pour calculer l'amortissement complémentaire"}} -
-
- {{/if}} -
Informations de sortie
diff --git a/compute_exit_data.html b/compute_exit_data.html index 25231bd..c8c50af 100644 --- a/compute_exit_data.html +++ b/compute_exit_data.html @@ -3,14 +3,18 @@ {{* Calculer les valeurs de la sortie et saisir le montant de la cession (optionnel) paramètres : - - immo_line_id : numéro de ligne de l'écriture d'immobilisation - - amort_amount : montant des amortissements - - year : exercice de la date de sortie de l'immobilisation - - date_mes : datede mise en service de l'immobilisation - - date_debut : date de début de la période d'amortissement complémentaire - - exit_date : date de sortie de l'immobilisation - - duree_amort : durée de l'amortiseement (optionnel) + @param immo_doc_id : id du doc associé à l'immo + @param amort_amount : montant des amortissements + @param year : exercice de la date de sortie de l'immobilisation + @param date_debut : date de début de la période d'amortissement complémentaire + @param exit_date : date de sortie de l'immobilisation *}} +{{* TODO *}} +{{* Infos de l'immobilisation *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} {{#select line.debit as montant, @@ -22,41 +26,62 @@ INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id INNER JOIN acc_accounts AS account ON line.id_account = account.id WHERE line.id = :line_id; - :line_id = $_GET.immo_line_id|intval + :line_id = $info_immo.line assign="ligne_immo" }} {{else}} - {{:error message="Immobilisation %s non trouvée"|args:$_GET.immo_line_id}} + {{:error message="Immobilisation non trouvée"}} {{/select}} {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$ligne_immo.trans_id - :account=$ligne_immo.account_code - }} - {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} -{{/select}} +{{#load + type="credit_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $info_immo.id + assign="credit_link" +}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{else}} + {{* + TODO : à garder ? + pas de doc => voir liaison écritures + *}} + {{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as other_id, + line.credit + FROM acc_transactions AS trans + INNER JOIN acc_transactions_links as links + ON (trans.id = links.id_transaction OR trans.id = links.id_related) + INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; + :immo_trans_id=$ligne_immo.trans_id + :account=$ligne_immo.account_code + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} +{{/load}} {{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} - {{:assign valeur_nette="%f-%f"|math:$ligne_immo.montant:$_GET.amort_amount}} + {{:assign amort_comp=0}} {{* amortissement complémentaire jqà date sortie *}} {{if $valeur_nette > 0}} {{:assign nbjours="1+(%d-%d)/(60*60*24)"|math:$_GET.exit_date:$_GET.date_debut}} - {{:assign annuite="%f/%f"|math:$ligne_immo.montant:$_GET.duree_amort}} + {{:assign annuite="%f/%f"|math:$ligne_immo.montant:$info_immo.duration}} {{:assign amort_comp="round(%f/365*%f, 0)"|math:$annuite:$nbjours}} {{:assign amort_comp="min(%f, %f)"|math:$valeur_nette:$amort_comp}} {{/if}} @@ -69,7 +94,7 @@ {{/if}} {{/if}} - {{:redirect to="write_exit.html?immo_line_id=%s&amort_amount=%s&year=%s&date_mes=%s&date_debut=%s&exit_date=%s&duree_amort=%s&cession=%s"|args:$_GET.immo_line_id:$_GET.amort_amount:$_GET.year:$_GET.date_mes:$_GET.date_debut:$_GET.exit_date:$_GET.duree_amort:$_POST.montant_cession}} + {{:redirect to="write_exit.html?immo_doc_id=%s&amort_amount=%s&year=%s&date_debut=%s&exit_date=%s&cession=%s"|args:$_GET.immo_doc_id:$_GET.amort_amount:$_GET.year:$_GET.date_debut:$_GET.exit_date:$_POST.montant_cession}} {{/form}} {{:admin_header title="Sortie du bilan" custom_css="./style.css" current="module_amortization"}} @@ -91,14 +116,12 @@
{{$ligne_immo.montant|money_currency_html:false|raw}}
Date d'acquisition
{{$ligne_immo.date_achat|date_short}}
- {{if $_GET.date_mes != $ligne_immo.date_achat|strtotime}} + {{if $info_immo.date_mes != null && $info_immo.date_mes != $ligne_immo.date_achat}}
Date de mise en service
-
{{$_GET.date_mes|date:"d/m/Y"}}
- {{/if}} - {{if $_GET.duree_amort != null && $_GET.duree_amort != 0}} -
Durée de l'amortissement
-
{{$_GET.duree_amort}} ans
+
{{$info_immo.date_mes|date_short}}
{{/if}} +
Durée de l'amortissement
+
{{$info_immo.duration}} ans
Montant des amortissements
{{$_GET.amort_amount|money_currency_html:false|raw}} (à la date de début de l'exercice)
Valeur nette résiduelle
diff --git a/write_exit.html b/write_exit.html index ac0d459..44cfbda 100644 --- a/write_exit.html +++ b/write_exit.html @@ -3,16 +3,19 @@ {{* Enregistrer les écritures de sortie du bilan paramètres : - - immo_line_id : numéro de ligne de l'écriture d'immobilisation + - immo_doc_id : id du doc associé à l'immobilisation - amort_amount : montant des amortissements - year : exercice de la date de sortie de l'immobilisation - - date_mes : date de mise en service de l'immobilisation - date_debut : date de début de la période d'amortissement complémentaire - exit_date : date de sortie de l'immobilisation - - duree_amort : durée de l'amortiseement (optionnel) - cession : montant de la cession (optionnel) *}} +{{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} +{{else}} + {{:error message="Immobilisation non trouvée"}} +{{/load}} + {{#select line.debit as montant, line.id_transaction, @@ -25,43 +28,63 @@ INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id INNER JOIN acc_accounts AS acc ON line.id_account = acc.id WHERE line.id = :immo_line_id; - :immo_line_id = $_GET.immo_line_id|intval + :immo_line_id = $info_immo.line assign="ligne_immo" }} +{{else}} + {{:error message="Immobilisation non trouvée"}} {{/select}} -{{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}} -{{/load}} - {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} {{:assign total_credits=0}} -{{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; - :immo_trans_id=$ligne_immo.trans_id - :account=$ligne_immo.account_code - }} - {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} -{{/select}} +{{#load + type="credit_link" + where="$$.immo_doc_id = :immo_doc_id" + :immo_doc_id = $info_immo.id + assign="credit_link" +}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} +{{else}} + {{* + TODO : à garder ? + pas de doc => voir liaison écritures + *}} + {{#select + CASE links.id_related = :immo_trans_id + WHEN true THEN links.id_transaction + WHEN false THEN links.id_related + END as other_id, + line.credit + FROM acc_transactions AS trans + INNER JOIN acc_transactions_links as links + ON (trans.id = links.id_transaction OR trans.id = links.id_related) + INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account; + :immo_trans_id=$ligne_immo.trans_id + :account=$ligne_immo.account_code + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} +{{/load}} {{:assign var="ligne_immo.montant" value="%d-%d"|math:$ligne_immo.montant:$total_credits}} - {{:assign valeur_nette="%f-%f"|math:$ligne_immo.montant:$_GET.amort_amount}} + {{:assign amort_comp=0}} {{* amortissement complémentaire jqà date sortie *}} {{:assign amort_except=0}} {{* amortissement exceptionnel jqà date fin amortissement *}} {{if $valeur_nette > 0}} {{:assign nbjours="1+(%d-%d)/(60*60*24)"|math:$_GET.exit_date:$_GET.date_debut}} - {{:assign annuite="%f/%f"|math:$ligne_immo.montant:$_GET.duree_amort}} + {{:assign annuite="%f/%f"|math:$ligne_immo.montant:$info_immo.duration}} {{:assign amort_comp="round(%f/365*%f, 0)"|math:$annuite:$nbjours}} {{:assign amort_comp="min(%f, %f)"|math:$valeur_nette:$amort_comp}} @@ -164,8 +187,9 @@ lines=$lines linked_transactions=$ligne_immo.id_transaction }} + + {{* liaisons lignes d'amortissement *}} {{#foreach from=$result.lines item="line"}} -{{* TODO : cas où pas de doc ? (info_immo = null) *}} {{if $line.account_code == $amort_account_code}} {{:save key=""|uuid @@ -173,7 +197,6 @@ immo_doc_id=$info_immo.id amort_line_id=$line.id }} - {{:break}} {{/if}} {{/foreach}} {{/if}} @@ -229,6 +252,8 @@ lines=$lines linked_transactions=$ligne_immo.id_transaction }} + + {{* liaison écriture de sortie *}} {{#foreach from=$result.lines item="line"}} {{if $line.account_code == $immo_account_code}} {{:save @@ -273,30 +298,16 @@ }} {{/if}} - {{if $info_immo != null}} - {{* mettre à jour l'état de l'immobilisation *}} - {{:save - key=$info_immo.key - status="archived" - }} - {{else}} - {{:save - key=""|uuid - validate_schema="schema.json" - type="immo" - line=$_GET.immo_line_id|intval - duration=$_GET.duree_amort|intval - date=$_GET.date_mes|date:"Y-m-d" - status="archived" - }} - {{/if}} + {{* mettre à jour l'état de l'immobilisation *}} + {{:save + key=$info_immo.key + status="archived" + }} {{:redirect to="index.html?type_immo=archived"}} {{/form}} {{:admin_header title="Sortie du bilan" custom_css="./style.css" current="module_amortization"}} - -{{* barre de navigation *}} {{if ! $dialog}} {{:include file="_nav.html" current="index" subcurrent="balance_exit"}} {{/if}} @@ -370,14 +381,12 @@
{{$ligne_immo.montant|money_currency_html:false|raw}}
Date d'acquisition
{{$ligne_immo.date_achat|date_short}}
- {{if $_GET.date_mes != $ligne_immo.date_achat|strtotime}} + {{if $info_immo.date_mes != null && $info_immo.date_mes != $ligne_immo.date_achat}}
Date de mise en service
-
{{$_GET.date_mes|date:"d/m/Y"}}
- {{/if}} - {{if $_GET.duree_amort != null}} -
Durée de l'amortissement
-
{{$_GET.duree_amort}} ans
+
{{$info_immo.date_mes|date_short}}
{{/if}} +
Durée de l'amortissement
+
{{$info_immo.duration}} ans
Montant des amortissements
{{$_GET.amort_amount|money_currency_html:false|raw}} (à la date de début de l'exercice)
Valeur nette résiduelle
From 3d1109018e9aee148e9825a6681e2bc838b37af9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Thu, 14 May 2026 14:17:41 +0200 Subject: [PATCH 037/133] Adaptation onglet Sorties aux nouveaux documents --- _archives.html | 75 +++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/_archives.html b/_archives.html index 56f6b14..da3f19c 100644 --- a/_archives.html +++ b/_archives.html @@ -5,7 +5,6 @@ Cette page liste les immobilisations sorties du bilan

-{{* Immobilisation avec une écriture de sortie de bilan *}} {{:include file="_get_config.html" keep="module.config"}} {{* lister les immobilisations *}} @@ -66,47 +65,54 @@ ORDER BY trans.date DESC; !condition=$condition }} - {{:assign montant_immo=$debit}} {{* voir si l'immo est prise en charge *}} - {{#load type="immo" where="$$.line = :line_id" :line_id=$immo_line_id|intval}} + {{#load type="immo" where="$$.line = :line_id" :line_id=$immo_line_id assign="info_immo"}} {{:assign status=$status}} {{else}} - {{:assign amortissable="nsp"}} - {{:assign status="unknown"}} + {{:assign status=null}} {{/load}} - {{if $status == "ignored"}} + {{if $status != "archived"}} {{:continue}} {{/if}} + {{:assign date_mes=$info_immo.date_mes|or:$trans_date}} + {{:assign montant_immo=$debit}} + + {{* chercher le doc de sortie du bilan *}} + {{:assign exit_date=null}} + {{#load type="exit_link" where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id=$info_immo.id}} + {{:assign exit_line_id=$exit_line_id}} + {{#select + trans.date + FROM acc_transactions_lines AS line + INNER JOIN acc_transactions AS trans ON line.id_transaction = trans.id + WHERE line.id = :exit_line_id; + :exit_line_id=$exit_line_id + }} + {{:assign exit_date=$date}} + {{/select}} + {{/load}} {{* chercher des écritures liées à l'immo courante au crédit du même compte et déduire leur montant de celui de l'immo *}} - {{:assign solde_immo=$montant_immo}} {{:assign credit_immo=null}} - {{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as other_id, - line.credit, - MAX(trans2.date) as exit_date - FROM acc_transactions AS trans - INNER JOIN acc_transactions_links as links - ON (trans.id = links.id_transaction OR trans.id = links.id_related) - INNER JOIN acc_transactions_lines AS line on line.id_transaction = other_id - INNER JOIN acc_accounts AS acc ON line.id_account = acc.id - INNER JOIN acc_transactions AS trans2 ON trans2.id = other_id - WHERE trans.id = :immo_trans_id AND line.credit > 0 AND acc.code = :account - ORDER BY trans2.date, trans2.id - ; - :immo_trans_id=$trans_id - :account=$account_code - assign="credit_immo." + {{:assign total_credits=0}} + {{#load + type="credit_link" + where="$$.immo_doc_id = :immo_doc_id" :immo_doc_id = $info_immo.id }} - {{:assign solde_immo="%d-%d"|math:$solde_immo:$credit}} - {{:assign exit_date=$exit_date}} - {{/select}} + {{if $amount == null}} + {{#select credit FROM acc_transactions_lines WHERE id = :credit_line_id; + :credit_line_id=$credit_line_id + }} + {{:assign total_credits="%d+%d"|math:$total_credits:$credit}} + {{/select}} + {{else}} + {{:assign total_credits="%d+%d"|math:$total_credits:$amount}} + {{/if}} + {{/load}} + {{:assign solde_immo="%d-%d"|math:$montant_immo:$total_credits}} {{if $solde_immo == 0}} {{:assign status="archived"}} @@ -116,11 +122,6 @@ {{:continue}} {{/if}} - {{:assign nb=$credit_immo|count}} - {{:assign nb="%d-1"|math:$nb}} - {{:assign var="last_credit" from="credit_immo.%d"|args:$nb}} - {{:assign montant_immo=$last_credit.credit}} - {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$trans_id}} {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$account_id:$trans_id_year}} {{:assign nb_immo="%d+1"|math:$nb_immo}} @@ -149,12 +150,12 @@ {{/select}}
#{{$trans_id}}{{$trans_date|date_short}}#{{$trans_id}}{{$date_mes|date_short}} {{$exit_date|date_short}} {{$trans_label}}{{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}} {{"%f"|math:$montant_immo|money_html:false|raw}}{{$account_code}}{{$account_code}} {{$account_label}} {{$project_label}} From 9649d6af0e0bb9140893a209405df9fc43a84c39 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 18 May 2026 10:56:23 +0200 Subject: [PATCH 038/133] =?UTF-8?q?Suppression=20param=C3=A8tre=20ligne=20?= =?UTF-8?q?immobilisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations.html | 2 +- add_asset.html | 2 +- amortization.html | 5 ++--- attach_amort.html | 21 ++++++++++---------- detach_amort.html | 19 ++++++++++-------- detach_immo.html | 16 ++++++++------- details_immo.html | 5 ++--- other_amortizations.html | 24 ++++++++++------------ save_amort.html | 43 ++++++++++++++++------------------------ 9 files changed, 63 insertions(+), 74 deletions(-) diff --git a/_immobilisations.html b/_immobilisations.html index 5b257f4..1546725 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -149,7 +149,7 @@ {{*/if*}} {{:linkbutton label="Amortissements" - href="amortization.html?immo_line_id=%s&type_immo=%s&immo_doc_id=%s"|args:$immo_line_id:$type_immo:$immo_doc_id shape="table" + href="amortization.html?immo_doc_id=%s&type_immo=%s"|args:$immo_doc_id:$type_immo shape="table" }}
{{$line.account_code}} {{$line.account_label}} - {{:linkbutton label="Détacher" href="detach_amort.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$ligne_immo.immo_line_id:$_GET.immo_doc_id shape="minus"}} + {{:linkbutton label="Détacher" href="detach_amort.html?immo_doc_id=%s&amort_line_id=%s"|args:$_GET.immo_doc_id:$line.amort_line_id shape="minus"}}
{{$line.date|date_short}} {{"%f"|math:$line.amount|money_currency_html:false|raw}} - {{:linkbutton label="Détacher" href="detach_immo.html?credit_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.credit_line_id:$ligne_immo.immo_line_id:$_GET.immo_doc_id shape="minus"}} + {{:linkbutton label="Détacher" href="detach_immo.html?immo_doc_id=%s&credit_line_id=%s"|args:$_GET.immo_doc_id:$line.credit_line_id shape="minus"}}
{{$line.account_code}} {{$line.account_label}} - {{if $_GET.init == null}} - {{:linkbutton label="Attacher" href="attach_amort.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$_GET.immo_line_id:$_GET.immo_doc_id shape="plus"}} - {{elseif $_GET.init}} - {{:linkbutton label="Attacher" href="attach_amort_init.html?amort_line_id=%d&immo_line_id=%d&immo_doc_id=%s"|args:$line.amort_line_id:$_GET.immo_line_id:$_GET.immo_doc_id shape="plus"}} - {{/if}} + {{:linkbutton label="Attacher" href="attach_amort.html?immo_doc_id=%s&amort_line_id=%s"|args:$_GET.immo_doc_id:$line.amort_line_id shape="plus"}}
{{:linkbutton label="Paramètres" - href="add_infos.html?immo_line_id=%s&type_immo=other"|args:$immo_line_id + href="add_infos.html?immo_line_id=%s"|args:$immo_line_id shape="settings" }} {{* target="_dialog"*}} diff --git a/_unfinished.html b/_unfinished.html index 37ab4c9..ab561a9 100644 --- a/_unfinished.html +++ b/_unfinished.html @@ -126,7 +126,13 @@ {{:continue}} {{/if}} - {{* voir s'il existe une écriture qui solde l'immobilisation *}} + {{* + TODO cas où : + - il y a (au moins) une écriture d'avoir + - il y a une écriture dui solde l'immo (montant = montant immo - avoir + *}} + + {{* voir s'il existe une écriture qui solde l'immobilisation (voir ci-dessus) *}} {{#select count(*) AS count FROM acc_transactions AS trans diff --git a/add_infos.html b/add_infos.html index e8efb82..e06b6bb 100644 --- a/add_infos.html +++ b/add_infos.html @@ -2,9 +2,8 @@ {{* @param immo_line_id - @param type_immo : managed, amortized, archived, other - TODO : + TODO ? : - séparer les cas des immo simples et complexes (BOI) par exemple pour la durée d'amort par défaut {{:input ...}} - prise en charge immo => param = immo_line_id @@ -36,17 +35,8 @@ {{else}} {{:error message="Immobilisation non trouvée"}} {{/select}} - {{:assign reste="%d-%d"|math:$ligne_immo.montant:$montant_affecte}} -{{* -{{if $info_immo != null}} - {{:assign date_defaut=$info_immo.date}} - {{:assign duree_defaut=$info_immo.duration}} - {{:assign choix_defaut=$info_immo.status}} -{{else}} - {{:assign duree_defaut=null}} -{{/if}} -*}} + {{#form on="save"}} @@ -145,12 +135,10 @@ {{:admin_header title="Classer l'immobilisation" custom_css="./style.css" current="module_amortization"}} {{* barre de navigation *}} {{if ! $dialog}} - {{:include file="_nav.html" current="index" subcurrent="%s"|args:$_GET.type_immo subsubcurrent="parameter"}} + {{:include file="_nav.html" current="index" subcurrent="other" subsubcurrent="parameter"}} {{/if}} {{:form_errors}} -{{:assign choix_defaut=$_GET.type_immo}} - {{* - classer l'immobilisation - renseigner ou modifier la date de mise en service, les écritures associées ou la durée d'amortissement diff --git a/modify_infos.html b/modify_infos.html index 826a106..7ee2501 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -1,11 +1,9 @@ {{* -*- brindille -*- *}} -{{:admin_header title="Modifier l'immobilisation" custom_css="./style.css" current="module_amortization"}} {{* @param immo_doc_id - ¿ @param type_immo : managed, amortized, archived, other ? - TODO : + TODO ? : - séparer les cas des immo simples et complexes (BOI) par exemple pour la durée d'amort par défaut {{:input ...}} - prise en charge immo => param = immo_line_id @@ -214,12 +212,12 @@ {{:redirect force="index.html?ok=1&msg=infos&type_immo=%s"|args:$type_immo}} {{/form}} -{{:form_errors}} -{{* barre de navigation *}} +{{:admin_header title="Modifier l'immobilisation" custom_css="./style.css" current="module_amortization"}} {{if ! $dialog}} {{:include file="_nav.html" current="index" subcurrent="%s"|args:$_GET.type_immo subsubcurrent="parameter"}} {{/if}} +{{:form_errors}} {{:assign choix_defaut=$_GET.type_immo}} From 2e8492b02500da0dc221ddaf2de0080e84e86fc5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 19 May 2026 11:43:40 +0200 Subject: [PATCH 040/133] =?UTF-8?q?Am=C3=A9lioration=20d=C3=A9tection=20am?= =?UTF-8?q?ortissements=20orphelins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _nav.html | 28 +++++++++++++++++++++++----- amortization.html | 25 +++++++++++++++++++------ index.html | 7 ++++++- other_amortizations.html | 2 ++ 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/_nav.html b/_nav.html index 57b9dee..fac14e4 100644 --- a/_nav.html +++ b/_nav.html @@ -1,17 +1,35 @@ {{* -*- brindille -*- *}}
+{{else}} +

Aucun amortissement à rattacher

{{/if}} {{:form_errors}} {{:admin_footer}} From 6319275d6710c3e931482e31d3ed269faecd0b41 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 19 May 2026 12:11:10 +0200 Subject: [PATCH 041/133] Transfert : adaptation date mise en service au nouveau format doc --- transfer.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/transfer.html b/transfer.html index 6f5bbcb..fdcbe3e 100644 --- a/transfer.html +++ b/transfer.html @@ -75,12 +75,12 @@ {{/if}} {{* 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 ts_date = $_POST.date_mes|parse_date}} {{: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}} + {{if $start_date <= $ts_date && $ts_date <= $end_date}} {{:assign ok=true}} {{:break}} {{/if}} @@ -93,11 +93,8 @@ {{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}} @@ -182,7 +179,7 @@ type="immo" line=$immo_line_id duration=$duration - date=$date_debut + date_mes=null status=$status }} {{if $_POST.amortir}} From 91795c69a8a423b6dda867a0146bc3d2021416c8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 22 May 2026 09:46:28 +0200 Subject: [PATCH 042/133] =?UTF-8?q?Am=C3=A9lioration=20et=20correction=20l?= =?UTF-8?q?ibell=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attach_amort.html | 11 +++++++---- details_immo.html | 2 +- index.html | 2 +- other_amortizations.html | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/attach_amort.html b/attach_amort.html index 31e0ae9..4676ce3 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -9,7 +9,6 @@ {{* données de l'immobilisation *}} {{#load id=$_GET.immo_doc_id|intval assign="info_immo"}} - {{:assign label_immo=$label|or:$ligne_immo.trans_label}} {{else}} {{:error message="Immobilisation non trouvée"}} {{/load}} @@ -29,11 +28,11 @@ {{:error message="Immobilisation non trouvée"}} {{/select}} -{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.montant}} - +{{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} +{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.montant}} {{* chercher l'écriture d'amortissement *}} {{#select @@ -54,6 +53,10 @@ {{else}} {{:error message="Amortissement non trouvé"}} {{/select}} +{{:assign amort_label=$amort_line.trans_label}} +{{if $amort_line.line_label != null && $amort_line.line_label != $amort_label}} + {{:assign amort_label=$amort_label|cat:"— "|cat:$amort_line.line_label}} +{{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$amort_line.trans_id}} {{* montant de l'écriture d'amortissement déjà affecté *}} @@ -206,7 +209,7 @@
Immobilisation
{{$label_immo}}
Amortissement
-
#{{$amort_line.trans_id}} {{$label_immo}}
+
#{{$amort_line.trans_id}} {{$amort_label}}
Montant de l'écriture d'amortissement
{{$amort_line.amount|money_currency_html:false|raw}}
{{if $montant_affecte > 0}} diff --git a/details_immo.html b/details_immo.html index f84f08b..4d060dc 100644 --- a/details_immo.html +++ b/details_immo.html @@ -107,7 +107,7 @@
-

Avoirs

- +{{if $valeur_residuelle > 0 || $linked_immos != null}} +

Avoirs

+ +{{/if}} {{if $linked_immos != null}} From 73b0dff14d32c2bc578efe92eb45afee6ba16dce Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 29 Jun 2026 10:48:21 +0200 Subject: [PATCH 102/133] =?UTF-8?q?Ajout=20valeurs=20par=20d=C3=A9faut=20m?= =?UTF-8?q?odification=20immo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modify_infos.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modify_infos.html b/modify_infos.html index 7694e83..0378939 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -14,6 +14,8 @@ {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $immo_label}} {{:assign immo_label=$immo_label|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} +{{:assign date_achat_defaut=$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{:assign date_mes_defaut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{* déduire le montant des écritures liées à l'immo courante au crédit du même compte *}} {{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="linked_immos, total_credits"}} @@ -186,16 +188,16 @@
- Paramètres de l'amortissement + Informations
{{:input type="number" name="duree" label="Durée d'amortissement" min=1 default=$info_immo.duration suffix="année(s)"}} {{if $info_immo.amount != null}} {{:assign max_aff="%f"|math:$max_disponible|money_currency:false}} {{:input type="money" name="montant" label="Montant de l'immobilisation" default=$montant_immo help="Montant maximum : %s"|args:$max_aff}} {{/if}} - {{:input type="date" name="date_achat" label="Date d'acquisition" default=$info_immo.date_achat help="si différente de la date de l'écriture d'immobilisation"}} - {{:input type="date" name="date_mes" label="Date de mise en service" default=$info_immo.date_mes help="si différente de la date d'acquisition"}} - {{:input type="text" name="libelle" label="Libellé" default=$info_immo.label help="si différent du libellé de l'écriture d'immobilisation"}} + {{:input type="date" name="date_achat" label="Date d'acquisition" default=$date_achat_defaut help="si différente de la date de l'écriture d'immobilisation"}} + {{:input type="date" name="date_mes" label="Date de mise en service" default=$date_mes_defaut help="si différente de la date d'acquisition"}} + {{:input type="text" name="libelle" label="Libellé" default=$immo_label help="si différent du libellé de l'écriture d'immobilisation"}}

From 47a610db100dbda27c74376884e083cb5ab7bb09 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 29 Jun 2026 10:48:40 +0200 Subject: [PATCH 103/133] Correction erreur url immobilisation --- other_amortizations.html | 1 + 1 file changed, 1 insertion(+) diff --git a/other_amortizations.html b/other_amortizations.html index d606d87..5a69be2 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -60,6 +60,7 @@ +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}}

From f2d351d4bd31e9a89b5c3f43a1716c04a53fb765 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 29 Jun 2026 11:03:04 +0200 Subject: [PATCH 104/133] =?UTF-8?q?Correction=20valeurs=20immobilisation?= =?UTF-8?q?=20affich=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- other_amortizations.html | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/other_amortizations.html b/other_amortizations.html index 5a69be2..61f870f 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -11,10 +11,16 @@ {{:error message=$message}} {{/if}} +{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.amount}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} +{{:assign date_mes=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} + +{{* déduire le montant des écritures liées à l'immo courante au crédit du même compte *}} +{{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="linked_immos, total_credits"}} +{{:assign montant_immo="%d-%d"|math:$montant_immo:$total_credits}} {{if $_GET.filter}} {{* déterminer le compte d'amortissement en fonction du compte d'immobilisation *}} @@ -67,9 +73,9 @@
Immobilisation
#{{$ligne_immo.trans_id}} {{$label_immo}}
Montant
-
{{"%f"|math:$ligne_immo.amount|money_currency_html:false|raw}}
-
Date de l'immobilisation
-
{{$ligne_immo.date_achat|date_short}}
+
{{"%f"|math:$montant_immo|money_currency_html:false|raw}}
+
Début d'amortissement
+
{{$date_mes|date_short}}
From 8a4ecc50c2fd189abfd7911899a68d7c244f2d9e Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 29 Jun 2026 11:04:02 +0200 Subject: [PATCH 105/133] =?UTF-8?q?Suppression=20code=20erron=C3=A9=20et?= =?UTF-8?q?=20inutile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modify_infos.html | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/modify_infos.html b/modify_infos.html index 0378939..174d1a4 100644 --- a/modify_infos.html +++ b/modify_infos.html @@ -95,44 +95,6 @@ {{:assign status="managed"}} - {{* écritures de crédit *}} - {{#foreach from=$linked_immos item="line"}} - {{if ! $_POST.credit_id|has:$line.trans_id}} - {{:assign var="docs_to_remove." value=$line.doc}} - {{:assign var="links_to_remove." value=$line.trans_id}} - {{/if}} - {{/foreach}} - - {{if $docs_to_remove != null}} - {{:assign remove_set=$docs_to_remove|implode:","}} - {{:assign remove_set="("|cat:$remove_set|cat:")"}} - {{:delete where="id IN %s"|args:$remove_set}} - - {{* idem avec acc_transactions_links *}} - {{#select - CASE links.id_related = :immo_trans_id - WHEN true THEN links.id_transaction - WHEN false THEN links.id_related - END as linked_id - FROM acc_transactions_links as links - WHERE id_transaction = :immo_trans_id or id_related = :immo_trans_id; - :immo_trans_id = $ligne_immo.trans_id - }} - {{if ! $linked_id|in:$links_to_remove}} - {{:assign var="linked_transactions." value=$linked_id}} - {{/if}} - {{/select}} - - {{* Enregistrer les liaisons *}} - {{:api - method="POST" - path="accounting/transaction/%s/transactions"|args:$ligne_immo.trans_id - assign="result" - assign_code="result_code" - transactions=$linked_transactions - }} - {{/if}} - {{* enregistrer les infos de l'immobilisation *}} {{:save key=$info_immo.key @@ -150,7 +112,6 @@ {{:assign type_immo="managed"}} {{:redirect force="amortization.html?immo_doc_id=%s&type_immo=%s&ok=1&msg=modif"|args:$_GET.immo_doc_id:$type_immo}} - {{/form}} {{:admin_header title="Modifier l'immobilisation" custom_css="./style.css" current="module_amortization"}} From 6de2535aaa20180264698d1af1367ed86e8d6171 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 12:52:55 +0200 Subject: [PATCH 106/133] =?UTF-8?q?Correction=20libell=C3=A9=20onglet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- other_amortizations.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/other_amortizations.html b/other_amortizations.html index 61f870f..6626368 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -22,13 +22,13 @@ {{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="linked_immos, total_credits"}} {{:assign montant_immo="%d-%d"|math:$montant_immo:$total_credits}} +{{* déterminer le compte d'amortissement en fonction du compte d'immobilisation *}} +{{:include + file="./_get_amort_code.html" + code_immo=$ligne_immo.account_code + keep="code_amort" +}} {{if $_GET.filter}} - {{* déterminer le compte d'amortissement en fonction du compte d'immobilisation *}} - {{:include - file="./_get_amort_code.html" - code_immo=$ligne_immo.account_code - keep="code_amort" - }} {{:assign filter_condition="account.code = "|cat:$code_amort}} {{else}} {{:assign account_filter="28%"|quote_sql}} From b20b231ce03d6ed27ea99ec9765c1d31e81b8d6d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 12:55:25 +0200 Subject: [PATCH 107/133] =?UTF-8?q?Modification=20message=20enregistrement?= =?UTF-8?q?/suppression=20param=C3=A8tres?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index ad62fa4..9c88e25 100644 --- a/index.html +++ b/index.html @@ -25,9 +25,9 @@ {{if $_GET.msg|match:"immobilisation"}} {{:assign msg="Immobilisation enregistrée"}} {{elseif $_GET.msg|match:"suppr_infos"}} - {{:assign msg="Informations supprimées"}} + {{:assign msg="Paramètres supprimés"}} {{elseif $_GET.msg|match:"infos"}} - {{:assign msg="Informations enregistrées"}} + {{:assign msg="Paramètres enregistrés"}} {{/if}}

{{$msg}}

{{elseif $_GET.err}} From c6ef1955d6d20770ed958d28d6cd8ca6892d4950 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 13:00:14 +0200 Subject: [PATCH 108/133] =?UTF-8?q?Modification=20navigation=20;=20mise-?= =?UTF-8?q?=C3=A0-jour=20date=20mise=20en=20service=20si=20date=20achat=20?= =?UTF-8?q?modifi=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_asset.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/add_asset.html b/add_asset.html index 6c21221..3738fa3 100644 --- a/add_asset.html +++ b/add_asset.html @@ -161,7 +161,7 @@ {{:admin_header title="Ajout immobilisation" current="module_amortization"}} {{* barre de navigation *}} {{if ! $dialog}} - {{:include file="_nav.html" current="managed" subcurrent="add_asset"}} + {{:linkbutton href="index.html" label="Retour" shape="left"}} {{/if}} {{:form_errors}} @@ -224,7 +224,7 @@
{{: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"}} + {{:input type="date" name="date_mes" label="Date de mise en service" default=$now|date_short help="C'est la date de première utilisation ; à modifier si différente de la date d'acquisition"}}
@@ -245,5 +245,8 @@ function changeYear(evt, f_accounts = ['credit_account', 'debit_account'], f_yea (function () { document.getElementById('f_id_year').onchange = changeYear; + document.getElementById('f_date_achat').addEventListener("change", (e) => { + document.getElementById('f_date_mes').value = document.getElementById('f_date_achat').value; + }); })(); From 1447883f5d2f4236f1c7063efa42d0c3fb7509ae Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 13:01:50 +0200 Subject: [PATCH 109/133] =?UTF-8?q?Modification=20ordre=20champs=20;=20mis?= =?UTF-8?q?e-=C3=A0-jour=20date=20mise=20en=20service=20si=20date=20achat?= =?UTF-8?q?=20modifi=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- add_infos.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/add_infos.html b/add_infos.html index 6e5fe46..9a45878 100644 --- a/add_infos.html +++ b/add_infos.html @@ -200,9 +200,9 @@ Classement
(obligatoire)
- {{:input type="radio-btn" name="classify" value="managed" label="Immobilisation à amortir" help="L'immobilisation sera classée parmi les immobilisations amortissables" default=$choix_defaut}} + {{:input type="radio-btn" name="classify" value="managed" label="Immobilisation à amortir" default=$choix_defaut}} {{if $ligne_immo.date_achat > $first_date}} - {{:input type="radio-btn" name="classify" value="archived" label="Immobilisation sortie du bilan" help="L'immobilisation sera classée parmi les immobilisations sorties du bilan" default=$choix_defaut}} + {{:input type="radio-btn" name="classify" value="archived" label="Immobilisation sortie du bilan" default=$choix_defaut}} {{/if}} {{:input type="radio-btn" name="classify" value="ignored" label="Immobilisation à ignorer" help="L'écriture n'apparaitra plus dans la liste des immobilisations" default=$choix_defaut}}
@@ -211,11 +211,11 @@
Informations
- {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 suffix="année(s)"}} - {{:input type="money" name="montant" label="Montant de l'immobilisation" required=true default=$reste help="à modifier si différent du montant de l'écriture d'immobilisation"}} {{:input type="date" name="date_achat" label="Date d'acquisition" default=$date_achat_defaut help="à modifier si nécessaire"}} - {{:input type="date" name="date_mes" label="Date de mise en service" default=$date_mes_defaut help="à modifier si différente de la date d'acquisition"}} {{:input type="text" name="libelle" label="Libellé" default=$immo_label help="à modifier si nécessaire"}} + {{:input type="money" name="montant" label="Montant de l'immobilisation" required=true default=$reste help="à modifier si différent du montant de l'écriture d'immobilisation"}} + {{:input type="number" name="duree" label="Durée d'amortissement" required=true min=1 suffix="année(s)"}} + {{:input type="date" name="date_mes" label="Date de mise en service" default=$date_mes_defaut help="à modifier si différente de la date d'acquisition"}}
@@ -236,7 +236,6 @@ function toggleInputs(event) { const managed = classement_immo.querySelector('input[type=radio][value=managed]'); if (managed.checked) { g.toggle('.masquable', true); - document.getElementById('f_duree').focus(); } else { g.toggle('.masquable', false); } @@ -248,6 +247,9 @@ toggleInputs(); radios.forEach(radio => { radio.addEventListener("change", toggleInputs); }); + document.getElementById('f_date_achat').addEventListener("change", (e) => { + document.getElementById('f_date_mes').value = document.getElementById('f_date_achat').value; + }); })(); From ee0c0e304d758c611f4e710d907ccec3981fa71e Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 13:22:58 +0200 Subject: [PATCH 110/133] Ajout class="actions" dans plusieurs tables --- amortization.html | 4 ++-- config.html | 4 ++-- exit_step1.html | 4 ++-- exit_step2.html | 4 ++-- exit_step3.html | 4 ++-- exit_step4.html | 4 ++-- filters.html | 2 +- link_immo.html | 2 +- other_amortizations.html | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/amortization.html b/amortization.html index 085edd3..b23d236 100644 --- a/amortization.html +++ b/amortization.html @@ -174,7 +174,7 @@
- - - + @@ -206,7 +206,7 @@ - + diff --git a/exit_step1.html b/exit_step1.html index 1154fcb..216c6b7 100644 --- a/exit_step1.html +++ b/exit_step1.html @@ -185,7 +185,7 @@ - @@ -229,7 +229,7 @@ - diff --git a/exit_step2.html b/exit_step2.html index 8235a02..f74c412 100644 --- a/exit_step2.html +++ b/exit_step2.html @@ -164,7 +164,7 @@ - @@ -221,7 +221,7 @@ - diff --git a/exit_step3.html b/exit_step3.html index fca3fec..62f9433 100644 --- a/exit_step3.html +++ b/exit_step3.html @@ -173,7 +173,7 @@ - @@ -226,7 +226,7 @@ - diff --git a/exit_step4.html b/exit_step4.html index 7868913..433f4cc 100644 --- a/exit_step4.html +++ b/exit_step4.html @@ -253,7 +253,7 @@ - @@ -293,7 +293,7 @@ - diff --git a/filters.html b/filters.html index 7590c9e..e59478d 100644 --- a/filters.html +++ b/filters.html @@ -31,7 +31,7 @@ - + diff --git a/link_immo.html b/link_immo.html index 43be090..d1bd3bf 100644 --- a/link_immo.html +++ b/link_immo.html @@ -118,7 +118,7 @@ - diff --git a/other_amortizations.html b/other_amortizations.html index 6626368..f9dd9cb 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -112,7 +112,7 @@ - From 5db235669f9eaf0092b9ef033c045b760b22c8fc Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 3 Jul 2026 22:11:32 +0200 Subject: [PATCH 111/133] =?UTF-8?q?Enregistrement=20libell=C3=A9=20lignes?= =?UTF-8?q?=20immo=20transf=C3=A9r=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- transfer.html | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/transfer.html b/transfer.html index 6a491b1..ec9b1db 100644 --- a/transfer.html +++ b/transfer.html @@ -36,7 +36,7 @@ {{: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)"}} +{{*:assign condition=$condition|cat:" AND NOT (trans.status & 16)"*}} {{#select trans.id as trans_id, @@ -45,6 +45,7 @@ SUM(line.debit) AS line_debit, account.code AS account_code, account.label AS account_label, + line.label as line_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 @@ -56,6 +57,7 @@ }} {{:assign var="transactions.%s"|args:$trans_id amount=$line_debit + line_label=$line_label date=$trans_date code=$account_code label=$account_label @@ -255,17 +257,17 @@ - + From 05e56d901a66211b701fcefd1bc8d053e68b457d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Mon, 6 Jul 2026 18:52:50 +0200 Subject: [PATCH 115/133] =?UTF-8?q?Correction=20libell=C3=A9=20et=20montan?= =?UTF-8?q?t=20faux=20(immo=20import=C3=A9e=20de=20balance=20initiale)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- write_exit.html | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/write_exit.html b/write_exit.html index cfd4a3a..5860b7c 100644 --- a/write_exit.html +++ b/write_exit.html @@ -17,6 +17,20 @@ {{:error message=$message}} {{/if}} +{{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} +{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} + {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} +{{/if}} + +{{:assign date_achat=$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{if $info_immo.date_mes != null && $info_immo.date_mes != $date_achat}} + {{:assign date_mes=$info_immo.date_mes}} +{{/if}} + +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.amount" value=$info_immo.amount}} +{{/if}} + {{* déduire le montant des écritures liées à l'immo courante au crédit du même compte *}} {{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="total_credits"}} {{:assign var="ligne_immo.amount" value="%d-%d"|math:$ligne_immo.amount:$total_credits}} @@ -45,19 +59,8 @@ {{:assign vnc_code="652"}} {{:assign cession_code="757"}} -{{* TODO : faut-il forcer les 3 sélecteurs de compte d'amortissement à avoir toujours la même valeur ? *}} - {{* Traiter l'envoi du formulaire *}} {{#form on="save"}} -{{* - {{if $_POST.amort_comp_account != null} - {{:assign account=$_POST.amort_comp_account}} - {{elseif $_POST.amort_except_account != null} - {{:assign account=$_POST.amort_except_account}} - {{elseif $_POST.amort_sortie_account != null} - {{:assign account=$_POST.amort_sortie_account}} - {{/if}} -*}} {{:assign account=$_POST.amort_sortie_account}} {{:include @@ -78,7 +81,7 @@ }} {{:assign comp_account_code=$account_code|keys|value:0}} - {{:assign libelle="Amortissement complémentaire "|cat:$ligne_immo.trans_label}} + {{:assign libelle="Amortissement complémentaire "|cat:$label_immo}} {{:assign var="lines." debit="%f/100"|math:$amort_comp @@ -103,7 +106,7 @@ keep="account_code" }} {{:assign except_account_code=$account_code|keys|value:0}} - {{:assign libelle="Amortissement exceptionnel "|cat:$ligne_immo.trans_label}} + {{:assign libelle="Amortissement exceptionnel "|cat:$label_immo}} {{:assign var="lines." debit="%f/100"|math:$amort_except @@ -129,7 +132,7 @@ id_year=$_GET.year type="advanced" date=$_GET.exit_date - label="Amortissement final "|cat:$ligne_immo.trans_label + label="Amortissement final "|cat:$label_immo lines=$lines linked_transactions=$ligne_immo.trans_id }} @@ -156,7 +159,7 @@ keep="account_code" }} {{:assign immo_account_code=$account_code|keys|value:0}} - {{:assign libelle="Sortie du bilan de "|cat:$ligne_immo.trans_label}} + {{:assign libelle="Sortie du bilan de "|cat:$label_immo}} {{:assign var="lines." account=$immo_account_code @@ -216,7 +219,7 @@ {{if $montant_cession > 0}} {{* Cession de l'immobilisation *}} - {{:assign libelle="Produit cession "|cat:$ligne_immo.trans_label}} + {{:assign libelle="Produit cession "|cat:$label_immo}} {{:include file="_get_codes.html" account=$_POST.creance_account @@ -333,7 +336,7 @@ {{/foreach}} {{:assign patterns=$pattern_array|implode:"|"}} -

Sortir l'immobilisation « {{$ligne_immo.trans_label}} » du bilan

+

Sortir l'immobilisation « {{$label_immo}} » du bilan

From afb88b8a012f6d53319d90f204eaf360029702fe Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 7 Jul 2026 15:55:08 +0200 Subject: [PATCH 116/133] =?UTF-8?q?Am=C3=A9lioration=20pr=C3=A9sentation?= =?UTF-8?q?=20titres=20tables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exit_step1.html | 2 +- exit_step2.html | 2 +- exit_step3.html | 4 ++-- exit_step4.html | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/exit_step1.html b/exit_step1.html index 216c6b7..83b6752 100644 --- a/exit_step1.html +++ b/exit_step1.html @@ -162,8 +162,8 @@
+

Écritures d'avoir attachées à l'immobilisation

{{if $linked_immos != null}} -

Écritures d'avoir attachées à l'immobilisation

{{$line.date|date_short}} {{$line.label}} {{"%f"|math:$line.amount|money_currency_html:false|raw}} + {{if $total_amort == 0}} {{:linkbutton label="Détacher" href="detach_credit.html?immo_doc_id=%s&credit_line_id=%s"|args:$_GET.immo_doc_id:$line.credit_line_id shape="minus"}} {{/if}} @@ -239,7 +239,7 @@ {{"%f"|math:$solde|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{if ! $created_amort}} {{:linkbutton label="Détacher" href="detach_amort.html?immo_doc_id=%s&amort_line_id=%s"|args:$_GET.immo_doc_id:$line.line_id shape="minus"}} {{/if}} diff --git a/config.html b/config.html index ec47093..a91e9d7 100644 --- a/config.html +++ b/config.html @@ -160,7 +160,7 @@
Compte
Compte
{{"%f"|math:$line.amount|money_currency_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Détacher" href="detach_credit.html?immo_doc_id=%s&credit_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.credit_line_id shape="minus"}}
{{$amount|money_html|raw}} {{$account_code}} {{$account_label}} + {{:linkbutton label="Attacher" href="attach_credit.html?immo_doc_id=%s&credit_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$credit_line_id shape="plus" target="_dialog"}}
{{"%f"|math:$line.amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Détacher" href="detach_amort.html?immo_doc_id=%s&amort_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.line_id shape="minus"}}
{{"%f"|math:$line.amort_amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_amort.html?immo_doc_id=%s&amort_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.amort_line_id shape="plus" target="_dialog"}}
{{"%f"|math:$line.amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Détacher" href="detach_cession.html?immo_doc_id=%s&cession_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.line_id shape="minus"}}
{{"%f"|math:$line.amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_cession.html?immo_doc_id=%s&cession_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.line_id shape="plus"}}
{{"%f"|math:$exit_line.amount|money_html:false|raw}} {{$exit_line.account_code}} {{$exit_line.account_label}} + {{:linkbutton label="Détacher" href="detach_exit.html?immo_doc_id=%s&exit_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$exit_line.line_id shape="minus"}}
{{"%f"|math:$line.amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_exit.html?immo_doc_id=%s&exit_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.credit_line_id shape="plus"}}
Libellé
{{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_credit.html?credit_line_id=%d&immo_doc_id=%s"|args:$line.credit_line_id:$_GET.immo_doc_id shape="plus"}}
{{"%f"|math:$line.amount|money_html:false|raw}} {{$line.account_code}} {{$line.account_label}} + {{:linkbutton label="Attacher" href="attach_amort.html?immo_doc_id=%s&amort_line_id=%s"|args:$_GET.immo_doc_id:$line.line_id shape="plus"}}
{{:input - type="list" - name="credit_accounts[]" - required=true - readonly=true - target="!acc/charts/accounts/selector.php?codes=%s&id_year=%d"|args:$code:$selected_year - default=$current_account + type="list" + name="credit_accounts[]" + required=true + readonly=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"}}{{:input type="text" name="line_labels[]" size="40" default=$line_label}} {{if $projects != null}} {{:input type="select" name="id_project" options=$projects default_empty="— Aucun —"}} From f74590b117d9d6fe3dc3bc8a087186ea431e8f6c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 4 Jul 2026 18:11:39 +0200 Subject: [PATCH 112/133] =?UTF-8?q?Simplification=20processus=20mise-?= =?UTF-8?q?=C3=A0-niveau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.html | 21 --------------------- index.html | 33 ++++++++++++++++++--------------- upgrade.html | 5 ----- 3 files changed, 18 insertions(+), 41 deletions(-) diff --git a/config.html b/config.html index a91e9d7..a8c91c9 100644 --- a/config.html +++ b/config.html @@ -129,27 +129,6 @@ {{/if}} - {{* Nouvelle version ? *}} - {{:include file="_get_module_version.tpl" keep="module_version"}} - {{:include file="_compare_version.tpl" nv1=$module_version nv2=$module.config.version keep="comp"}} - - {{if $comp > 0}} -
- Mettre à niveau le module -

- Une nouvelle version du module {{$module.label}} - est disponible ; veuillez cliquer sur le buton - « Mettre à niveau le module » pour effectuer la - mise à niveau -

- {{:linkbutton - label="Mettre à niveau le module" - href="upgrade.html" - shape="reset" - class="main" - }} -
- {{/if}}

Comptes d'immobilisation amortissables

diff --git a/index.html b/index.html index 9c88e25..e0018df 100644 --- a/index.html +++ b/index.html @@ -7,20 +7,26 @@ {{:assign type_immo=$_GET.type_immo}} {{/if}} - {{if $type_immo == "managed"}} - {{:admin_header title="Immobilisations en cours d'amortissement" custom_css="./style.css" current="module_amortization"}} - {{elseif $type_immo == "amortized"}} - {{:admin_header title="Immobilisations amorties" custom_css="./style.css" current="module_amortization"}} - {{elseif $type_immo == "archived"}} - {{:admin_header title="Immobilisations archivées" custom_css="./style.css" current="module_amortization"}} - {{elseif $type_immo == "other"}} - {{:admin_header title="Immobilisations à classer" custom_css="./style.css" current="module_amortization"}} - {{elseif $type_immo == "unfinished"}} - {{:admin_header title="Immobilisations en cours de constitution" custom_css="./style.css" current="module_amortization" subcurrent="unfinished"}} - {{/if}} - +{{if $type_immo == "managed"}} + {{:admin_header title="Immobilisations en cours d'amortissement" custom_css="./style.css" current="module_amortization"}} +{{elseif $type_immo == "amortized"}} + {{:admin_header title="Immobilisations amorties" custom_css="./style.css" current="module_amortization"}} +{{elseif $type_immo == "archived"}} + {{:admin_header title="Immobilisations archivées" custom_css="./style.css" current="module_amortization"}} +{{elseif $type_immo == "other"}} + {{:admin_header title="Immobilisations à classer" custom_css="./style.css" current="module_amortization"}} +{{elseif $type_immo == "unfinished"}} + {{:admin_header title="Immobilisations en cours de constitution" custom_css="./style.css" current="module_amortization" subcurrent="unfinished"}} +{{/if}} {{:include file="_nav.html" current=$type_immo}} +{{* Mise à niveau *}} +{{:assign module_version="0.33"}} +{{:include file="upgrade.html" module_version=$module_version}} + +{{* supprimer les documents sans écriture associée *}} +{{:include file="_remove_orphan_docs.tpl"}} + {{if $_GET.ok}} {{if $_GET.msg|match:"immobilisation"}} {{:assign msg="Immobilisation enregistrée"}} @@ -34,9 +40,6 @@

Échec enregistrement immobilisation

{{/if}} -{{* supprimer les documents sans écriture associée *}} -{{:include file="_remove_orphan_docs.tpl"}} - {{if $type_immo == "other"}} {{:include file="_immobilisations_autres.html"}} {{elseif $type_immo == "archived"}} diff --git a/upgrade.html b/upgrade.html index 8ecfe75..517eebe 100644 --- a/upgrade.html +++ b/upgrade.html @@ -4,11 +4,6 @@ mise à niveau des documents selon version *}} -{{:admin_header title="Mise à niveau" custom_css="./style.css" current="module_amortization"}} - -{{* numéro de version du module *}} -{{:include file="_get_module_version.tpl" keep="module_version"}} - {{* version 0.31 *}} {{:assign tag="0.31"}} From 0302e457bd1b56f77275def39197ffc81fb97396 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 4 Jul 2026 18:39:35 +0200 Subject: [PATCH 113/133] Suppression code inutile --- transfer.html | 1 - 1 file changed, 1 deletion(-) diff --git a/transfer.html b/transfer.html index ec9b1db..9a979b1 100644 --- a/transfer.html +++ b/transfer.html @@ -36,7 +36,6 @@ {{: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, From 2de72ed22c4def36f3ee3e43802e34cc5d7e48f5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 4 Jul 2026 18:43:41 +0200 Subject: [PATCH 114/133] =?UTF-8?q?Masquer=20bouton=20D=C3=A9tacher=20seul?= =?UTF-8?q?ement=20s'il=20y=20a=20un=20amortissement=20cr=C3=A9=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amortization.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amortization.html b/amortization.html index b23d236..81d0cfc 100644 --- a/amortization.html +++ b/amortization.html @@ -175,7 +175,7 @@
{{$line.label}} {{"%f"|math:$line.amount|money_currency_html:false|raw}} - {{if $total_amort == 0}} + {{if ! $created_amort}} {{:linkbutton label="Détacher" href="detach_credit.html?immo_doc_id=%s&credit_line_id=%s"|args:$_GET.immo_doc_id:$line.credit_line_id shape="minus"}} {{/if}}
diff --git a/exit_step2.html b/exit_step2.html index f74c412..f5a7a40 100644 --- a/exit_step2.html +++ b/exit_step2.html @@ -129,8 +129,8 @@ +

Écritures d'amortissement attachées à l'immobilisation

{{if $linked_amort != null}} -

Écritures d'amortissement attachées à l'immobilisation

diff --git a/exit_step3.html b/exit_step3.html index 62f9433..b935642 100644 --- a/exit_step3.html +++ b/exit_step3.html @@ -138,8 +138,8 @@ +

Écriture de cession attachée à l'immobilisation

{{if $linked_cessions != null}} -

Écriture de cession attachée à l'immobilisation

@@ -186,7 +186,7 @@

{{else}}

- Aucune écriture de cession... que faire ? + Aucune écriture de cession

{{/if}} diff --git a/exit_step4.html b/exit_step4.html index 433f4cc..08e0cd4 100644 --- a/exit_step4.html +++ b/exit_step4.html @@ -225,8 +225,8 @@ +

Écriture de sortie du bilan attachée à l'immobilisation

{{if $exit_line != null}} -

Écriture de sortie du bilan attachée à l'immobilisation

From 6ffdfe1e6f99c84c47744c93550699f065e4e1ae Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Tue, 7 Jul 2026 16:27:51 +0200 Subject: [PATCH 117/133] Correction date achat fausse --- write_exit.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/write_exit.html b/write_exit.html index 5860b7c..dd00705 100644 --- a/write_exit.html +++ b/write_exit.html @@ -345,10 +345,10 @@
Montant
{{$ligne_immo.amount|money_currency_html:false|raw}}
Date d'acquisition
-
{{$ligne_immo.date_achat|date_short}}
- {{if $info_immo.date_mes != null && $info_immo.date_mes != $ligne_immo.date_achat}} +
{{$date_achat|date_short}}
+ {{if $date_mes != null}}
Date de mise en service
-
{{$info_immo.date_mes|date_short}}
+
{{$date_mes|date_short}}
{{/if}}
Durée de l'amortissement
{{$info_immo.duration}} ans
From 3c29faea6c5a7d5a89ecd5d536bb238447f22e3b Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 8 Jul 2026 15:41:18 +0200 Subject: [PATCH 118/133] =?UTF-8?q?Correction=20v=C3=A9rifications=20monta?= =?UTF-8?q?nt=20avoir=20saisi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- attach_credit.html | 84 ++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/attach_credit.html b/attach_credit.html index 276dc76..0652ce3 100644 --- a/attach_credit.html +++ b/attach_credit.html @@ -18,9 +18,18 @@ {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.amount" value=$info_immo.amount}} +{{/if}} + {{* déduire le montant des écritures liées à l'immo courante au crédit du même compte *}} {{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="total_credits"}} -{{:assign solde_immo="%d-%d"|math:$ligne_immo.amount:$total_credits}} +{{:assign valeur_residuelle="%d-%d"|math:$ligne_immo.amount:$total_credits}} + +{{* lister les amortissements liés à l'immobilisation *}} +{{:include file="./_get_amort_lines.html" immo_doc_id=$_GET.immo_doc_id keep="linked_amort, total_amort, created_amort"}} +{{:assign valeur_residuelle="%d-%d"|math:$valeur_residuelle:$total_amort}} + {{* chercher l'écriture au crédit du compte d'immobilisation *}} {{#select @@ -62,53 +71,46 @@ {{/if}} {{else}} {{:assign montant_credit=$_POST.montant|money_int}} - {{* vérifier que le montant saisi est inférieur au solde de l'écriture d'immobilisation *}} - {{if $montant_credit > $solde_immo}} - {{:assign solde_nb="%f"|math:$solde_immo|money_currency:false}} - {{:error message="Le montant de l'avoir ne peut être supérieur au montant de l'immobilisation (%s)"|args:$solde_nb}} - {{/if}} - {{* vérifier que le montant saisi est inférieur au reste de l'écriture de crédit *}} - {{if $montant_credit > $reste}} - {{:assign reste_nb="%f"|math:$reste|money_currency:false}} - {{:error message="Le montant de l'avoir ne peut être supérieur au reste (%s)"|args:$reste_nb}} - {{/if}} - {{if $montant_credit == $credit_line.amount}} - {{:assign saved_credit=null}} - {{else}} - {{:assign saved_credit=$montant_credit}} - {{/if}} + {{/if}} + + {{* vérifier que le montant saisi est inférieur à la valeur nette de l'écriture d'immobilisation *}} + {{if $montant_credit > $valeur_residuelle}} + {{:assign solde_nb="%f"|math:$valeur_residuelle|money_currency:false}} + {{:error message="Le montant de l'avoir ne peut être supérieur à la valeur nette de l'immobilisation (%s)"|args:$solde_nb}} + {{/if}} + + {{* vérifier que le montant saisi est inférieur au reste de l'écriture de crédit *}} + {{if $montant_credit > $reste}} + {{:assign reste_nb="%f"|math:$reste|money_currency:false}} + {{:error message="Le montant de l'avoir ne peut être supérieur au reste (%s)"|args:$reste_nb}} + {{/if}} + {{if $montant_credit == $credit_line.amount}} + {{:assign saved_credit=null}} + {{else}} + {{:assign saved_credit=$montant_credit}} {{/if}} {{* Lier l'écriture de crédit à l'écriture d'immobilisation *}} {{:include file="_common_attach.html" immo_doc_id=$_GET.immo_doc_id trans_id=$credit_line.trans_id}} -{{* - TODO ? vérifier le succès avant d'enregistrer le doc ? -*}} - -{{* enregistrer la liaison des lignes d'immo *}} -{{:save - key=""|uuid - type="credit_link" - immo_doc_id=$_GET.immo_doc_id|intval - credit_line_id=$_GET.credit_line_id|intval - amount=$saved_credit -}} - {{* -{{if $montant_credit == $solde_immo}} - {{:save - id=$_GET.immo_doc_id - status="archived" - }} -{{/if}} -*}} + TODO ? vérifier le succès avant d'enregistrer le doc ? + *}} -{{if $_GET.from == "exit"}} - {{:redirect force="exit_step1.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} -{{else}} - {{:redirect force="amortization.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} -{{/if}} + {{* enregistrer la liaison des lignes d'immo *}} + {{:save + key=""|uuid + type="credit_link" + immo_doc_id=$_GET.immo_doc_id|intval + credit_line_id=$_GET.credit_line_id|intval + amount=$saved_credit + }} + + {{if $_GET.from == "exit"}} + {{:redirect force="exit_step1.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} + {{else}} + {{:redirect force="amortization.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} + {{/if}} {{/form}} {{:admin_header title="Écritures au crédit du compte d'immobilisation" custom_css="./style.css" current="module_amortization"}} From 64d4788e76874e6794f70717bf75d11f45afcab2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 8 Jul 2026 15:47:41 +0200 Subject: [PATCH 119/133] =?UTF-8?q?Avoirs=20:=20correction=20date=20et=20l?= =?UTF-8?q?ibell=C3=A9=20;=20s=C3=A9lection=20=C3=A9critures=20post=C3=A9r?= =?UTF-8?q?ieures=20date=20immo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- link_immo.html | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/link_immo.html b/link_immo.html index d1bd3bf..b8bf758 100644 --- a/link_immo.html +++ b/link_immo.html @@ -10,10 +10,15 @@ {{if $message != null}} {{:error message=$message}} {{/if}} -{{:assign label_immo=$ligne_immo.trans_label}} + +{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} +{{if $info_immo.amount != null}} + {{:assign var="ligne_immo.amount" value=$info_immo.amount}} +{{/if}} {{* lister les écritures au crédit du compte de l'immobilisation @@ -23,6 +28,8 @@ {{else}} {{:assign account_code=$ligne_immo.account_code|substr:0:2|cat:"%"}} {{/if}} +{{:assign date_immo=$info_immo.date_achat|or:$ligne_immo.date_achat}} + {{#select line.id as credit_line_id, line.id_transaction as credit_trans_id, @@ -40,6 +47,7 @@ INNER JOIN acc_accounts AS account ON account.id = line.id_account INNER JOIN acc_years AS y ON y.id = trans.id_year WHERE account.code LIKE :account_code AND credit > 0 + AND trans.date >= :date_immo AND credit_line_id NOT IN ( SELECT json_extract(link.document, '$.credit_line_id') AS credit_line_id FROM !table as link WHERE json_extract(link.document, '$.type') == "credit_link" @@ -48,7 +56,8 @@ WHERE json_extract(exit_link.document, '$.type') == "exit_link") ORDER BY trans.date, trans.label; :account_code = $account_code - !table =$module.table + !table = $module.table + :date_immo = $date_immo assign="other_immos." }} {{/select}} @@ -88,7 +97,7 @@
Montant
{{"%f"|math:$ligne_immo.amount|money_currency_html:false|raw}}
Date de l'immobilisation
-
{{$ligne_immo.date_achat|date_short}}
+
{{$date_debut|date_short}}
From 2b6ac366ec1dbbbb25b8898170e8a47eb54efc7e Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Wed, 8 Jul 2026 16:36:43 +0200 Subject: [PATCH 120/133] =?UTF-8?q?Ne=20pas=20lister=20amortissements=20an?= =?UTF-8?q?t=C3=A9rieurs=20mise=20en=20service=20immo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _get_free_amort.html | 6 +++--- amortization.html | 6 +++++- other_amortizations.html | 9 +++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/_get_free_amort.html b/_get_free_amort.html index 8a2649b..b3b142f 100644 --- a/_get_free_amort.html +++ b/_get_free_amort.html @@ -2,7 +2,7 @@ {{* lister les amortissement non rattachés à une immo - @param filter_condition + @param condition *}} {{#select line.id as line_id, @@ -18,9 +18,9 @@ FROM acc_transactions_lines AS line INNER JOIN acc_accounts AS account ON account.id = line.id_account INNER JOIN acc_transactions AS trans ON trans.id = line.id_transaction - WHERE credit > 0 AND (NOT trans.status & 16) AND !filter_condition + WHERE credit > 0 AND (NOT trans.status & 16) AND !condition ORDER BY trans.date, trans.label; - !filter_condition=$filter_condition + !condition=$condition assign="amort_line" }} {{* voir s'il existe des lignes d'immo liées à cette ligne d'amortissement *}} diff --git a/amortization.html b/amortization.html index 81d0cfc..cafea18 100644 --- a/amortization.html +++ b/amortization.html @@ -39,7 +39,11 @@ {{* lister les amortissements non attachés à une immo *}} {{:assign account_filter="28%"|quote_sql}} {{:assign filter_condition="account.code LIKE "|cat:$account_filter}} - {{:include file="./_get_free_amort.html" filter_condition=$filter_condition keep="free_amort_lines"}} + + {{:assign date_amort=$date_debut|quote_sql}} + {{:assign date_condition="trans.date >= "|cat:$date_amort}} + {{:assign condition=$date_condition|cat:" AND "|cat:$filter_condition}} + {{:include file="./_get_free_amort.html" condition=$condition keep="free_amort_lines"}} {{/if}} {{:admin_header title="Détails de l'immobilisation" custom_css="./style.css" current="module_amortization"}} diff --git a/other_amortizations.html b/other_amortizations.html index f9dd9cb..4c53fb2 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -29,14 +29,19 @@ keep="code_amort" }} {{if $_GET.filter}} - {{:assign filter_condition="account.code = "|cat:$code_amort}} + {{:assign amort_account=$code_amort|quote_sql}} + {{:assign filter_condition="account.code = "|cat:$amort_account}} {{else}} {{:assign account_filter="28%"|quote_sql}} {{:assign filter_condition="account.code LIKE "|cat:$account_filter}} {{/if}} +{{:assign date_amort=$date_mes|quote_sql}} +{{:assign date_condition="trans.date >= "|cat:$date_amort}} +{{:assign condition=$date_condition|cat:" AND "|cat:$filter_condition}} + {{* lister les amortissements non rattachés à une immo *}} -{{:include file="./_get_free_amort.html" filter_condition=$filter_condition keep="free_amort_lines"}} +{{:include file="./_get_free_amort.html" condition=$condition keep="free_amort_lines"}} {{:admin_header title="Amortissements non rattachés" custom_css="./style.css" current="module_amortization"}} From a256e90d096453e3ecfc3c4ccb90536657dcbe1a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 10 Jul 2026 09:39:26 +0200 Subject: [PATCH 121/133] Ajout liens vers immobilisation absents --- ignore.html | 1 + link_immo.html | 1 + 2 files changed, 2 insertions(+) diff --git a/ignore.html b/ignore.html index 4c1b760..a721759 100644 --- a/ignore.html +++ b/ignore.html @@ -21,6 +21,7 @@ {{:error message="Il n'y a aucune écriture avec le numéro de ligne %s !"|args:$_GET.immo_line_id}} {{/select}} {{#load type="immo" assign="info_immo" where="$$.line = :line_id" :line_id=$_GET.immo_line_id|intval}}{{/load}} +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} {{* Traiter l'envoi du formulaire *}} {{#form on="proceed"}} diff --git a/link_immo.html b/link_immo.html index b8bf758..c925988 100644 --- a/link_immo.html +++ b/link_immo.html @@ -11,6 +11,7 @@ {{:error message=$message}} {{/if}} +{{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} {{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} From 1439f0333d9904a36c78a5cc4408293b31633f50 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Fri, 10 Jul 2026 10:27:54 +0200 Subject: [PATCH 122/133] =?UTF-8?q?Correction=20statut=20lignes=20ignor?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations_autres.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_immobilisations_autres.html b/_immobilisations_autres.html index 7a4b04c..383ba12 100644 --- a/_immobilisations_autres.html +++ b/_immobilisations_autres.html @@ -149,6 +149,8 @@ {{#foreach from=$module.config.filters item="filter"}} {{if $trans_label|strpos:$filter !== false}} {{:assign status="ignored"}} + {{else}} + {{:assign status=""}} {{/if}} {{/foreach}} {{/if}} From 18e97956fed14a957555b34c4a57928591e00cc2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 11 Jul 2026 11:28:17 +0200 Subject: [PATCH 123/133] =?UTF-8?q?Am=C3=A9lioration=20affichage=20libell?= =?UTF-8?q?=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _immobilisations.html | 2 +- amortization.html | 2 +- attach_amort.html | 2 +- attach_credit.html | 2 +- balance_sheet_exit.html | 2 +- compute_exit_data.html | 2 +- exit_step1.html | 9 +++++---- exit_step2.html | 6 +++--- exit_step3.html | 6 +++--- exit_step4.html | 26 ++++++++++++++++++++------ link_immo.html | 2 +- other_amortizations.html | 2 +- write_exit.html | 2 +- 13 files changed, 40 insertions(+), 25 deletions(-) diff --git a/_immobilisations.html b/_immobilisations.html index ab4d4d6..93648ec 100644 --- a/_immobilisations.html +++ b/_immobilisations.html @@ -76,7 +76,7 @@ {{:assign montant_immo=$doc_amount|or:$debit}} {{:assign immo_date = $doc_date_achat|or:$trans_date}} {{:assign label_immo=$doc_label|or:$trans_label}} - {{if $line_label != null && $line_label != $label_immo}} + {{if $label_immo|strpos:$line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$line_label}} {{/if}} diff --git a/amortization.html b/amortization.html index cafea18..7d73749 100644 --- a/amortization.html +++ b/amortization.html @@ -15,7 +15,7 @@ {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} {{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{if $info_immo.amount != null}} diff --git a/attach_amort.html b/attach_amort.html index a6d05bb..95767e2 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -14,7 +14,7 @@ {{/if}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign montant_immo=$info_immo.amount|or:$ligne_immo.amount}} diff --git a/attach_credit.html b/attach_credit.html index 0652ce3..e081434 100644 --- a/attach_credit.html +++ b/attach_credit.html @@ -14,7 +14,7 @@ {{/if}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false }} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} diff --git a/balance_sheet_exit.html b/balance_sheet_exit.html index a561c80..f3c4ae0 100644 --- a/balance_sheet_exit.html +++ b/balance_sheet_exit.html @@ -18,7 +18,7 @@ *}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} diff --git a/compute_exit_data.html b/compute_exit_data.html index c824af5..f45a6fe 100644 --- a/compute_exit_data.html +++ b/compute_exit_data.html @@ -19,7 +19,7 @@ {{/if}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} diff --git a/exit_step1.html b/exit_step1.html index 83b6752..5744fb6 100644 --- a/exit_step1.html +++ b/exit_step1.html @@ -13,7 +13,7 @@ {{/if}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} @@ -123,12 +123,13 @@ {{/select}} {{:admin_header title="Immobilisation sortie du bilan" custom_css="./style.css" current="module_amortization"}} + {{if $_GET.from == "exit"}} {{:assign current="other"}} {{else}} {{:assign current="archived"}} {{/if}} -{{:include file="_nav.html" current=$current subcurrent="exit"}} +{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_avoir"}} @@ -146,7 +147,7 @@
Compte d'immobilisation
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
Montant de l'immobilisation
-
{{$ligne_immo.amount|money_html|raw}}
+
{{$montant_immo|money_currency_html:false|raw}}
{{if $total_credits > 0}}
Montant des avoirs
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
@@ -210,7 +211,7 @@
- + diff --git a/exit_step2.html b/exit_step2.html index f5a7a40..6c451fc 100644 --- a/exit_step2.html +++ b/exit_step2.html @@ -21,7 +21,7 @@ {{/form}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} @@ -95,7 +95,7 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{:include file="_nav.html" current=$current subcurrent="exit"}} +{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_amort"}} @@ -113,7 +113,7 @@
Compte d'immobilisation
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
Montant de l'immobilisation
-
{{$ligne_immo.amount|money_html|raw}}
+
{{$montant_immo|money_currency_html:false|raw}}
{{if $total_credits > 0}}
Montant des avoirs
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
diff --git a/exit_step3.html b/exit_step3.html index b935642..f55e5b5 100644 --- a/exit_step3.html +++ b/exit_step3.html @@ -21,7 +21,7 @@ {{/form}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} @@ -100,7 +100,7 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{:include file="_nav.html" current=$current subcurrent="exit"}} +{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_cession"}} @@ -118,7 +118,7 @@
Compte d'immobilisation
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
Montant de l'immobilisation
-
{{$ligne_immo.amount|money_html|raw}}
+
{{$montant_immo|money_currency_html:false|raw}}
{{if $total_credits > 0}}
Montant des avoirs
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
diff --git a/exit_step4.html b/exit_step4.html index 08e0cd4..5bc9f23 100644 --- a/exit_step4.html +++ b/exit_step4.html @@ -26,11 +26,11 @@ {{/form}} {{#form on="finish"}} - {{:redirect to="index.html?type_immo=managed"}} + {{:redirect to="index.html?type_immo=other"}} {{/form}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} @@ -187,7 +187,7 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{:include file="_nav.html" current=$current subcurrent="exit"}} +{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_exit"}} @@ -205,7 +205,7 @@
Compte d'immobilisation
{{$ligne_immo.account_code}} — {{$ligne_immo.account_label}}
Montant de l'immobilisation
-
{{$ligne_immo.amount|money_html|raw}}
+
{{$montant_immo|money_currency_html:false|raw}}
{{if $total_credits > 0}}
Montant des avoirs
{{"%f"|math:$total_credits|money_currency_html:false|raw}}
@@ -227,6 +227,7 @@

Écriture de sortie du bilan attachée à l'immobilisation

{{if $exit_line != null}} + {{:assign exit_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$exit_line.trans_id}}
Date LibelléMontantMontant N° compte Compte
@@ -241,7 +242,7 @@ - +
#{{$exit_line.trans_id}}#{{$exit_line.trans_id}} {{$exit_line.date|date_short}} {{if $exit_line.line_label != null}} @@ -301,7 +302,20 @@
{{elseif $exit_line == null}} -

Aucune écriture de sortie du bilan. Vérifiez l'attachement d'écriture d'avoir.

+

Aucune écriture de sortie du bilan avec un + montant de {{$solde|money_currency_html:false|raw}} au crédit du + compte {{$ligne_immo.account_code}} — {{$ligne_immo.account_label}} ; +
+ Vérifiez si vous avez correctement attaché les éventuelles écritures d'avoir. +
+ Si vous avez supprimé l'écriture de sortie de bilan, il faut + la recréer avant de pouvoir classer cette immobilisation + « Sortie du bilan » ! +

+ {{:save + key=$info_immo.key + status=null + }} {{/if}} diff --git a/link_immo.html b/link_immo.html index c925988..73e071b 100644 --- a/link_immo.html +++ b/link_immo.html @@ -14,7 +14,7 @@ {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} {{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label ===false }} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{if $info_immo.amount != null}} diff --git a/other_amortizations.html b/other_amortizations.html index 4c53fb2..d1b2909 100644 --- a/other_amortizations.html +++ b/other_amortizations.html @@ -13,7 +13,7 @@ {{:assign montant_immo=$info_immo.amount|or:$ligne_immo.amount}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} {{:assign date_mes=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} diff --git a/write_exit.html b/write_exit.html index dd00705..fa92190 100644 --- a/write_exit.html +++ b/write_exit.html @@ -18,7 +18,7 @@ {{/if}} {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} -{{if $ligne_immo.line_label != null && $ligne_immo.line_label != $label_immo}} +{{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} {{/if}} From 8810498843fb6c8f343609e46ee5859571d3fbac Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 11 Jul 2026 18:16:22 +0200 Subject: [PATCH 124/133] =?UTF-8?q?Am=C3=A9lioration=20d=C3=A9tection=20er?= =?UTF-8?q?reur=20classement=20sortie=20bilan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exit_step4.html | 71 +++++++++++++++++++++++++++++++++++++++++++++---- style.css | 9 +++++++ 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/exit_step4.html b/exit_step4.html index 5bc9f23..ed7be7a 100644 --- a/exit_step4.html +++ b/exit_step4.html @@ -84,6 +84,39 @@ assign="exit_line" }} {{/select}} + + {{* lignes de l'écriture de sortie *}} + {{#select + line.label as line_label, + line.credit, + line.debit, + acc.id as account_id, + acc.code as account_code, + acc.label as account_label + FROM acc_transactions AS trans + INNER JOIN acc_transactions_lines AS line ON line.id_transaction = trans.id + INNER JOIN acc_accounts AS acc ON line.id_account = acc.id + WHERE trans.id = :exit_trans_id; + :exit_trans_id = $exit_line.trans_id + assign="trans" + }} + {{:assign var="exit_trans.%s"|args:$account_code value=$trans}} + {{/select}} + + {{:assign acc_codes=$exit_trans|keys}} + {{#foreach from=$linked_amort}} + {{if $account_code|in:$acc_codes}} + {{:assign var="exit_amort" from="exit_trans.%s.debit"|args:$account_code}} + {{:break}} + {{/if}} + {{/foreach}} + + {{if $exit_amort != $total_amort}} + {{:assign exit_amort_display=$exit_amort|money_currency:false|replace:" ":" "}} + {{:assign total_amort_display=$total_amort|money_currency:false|replace:" ":" "}} + {{:assign erreur=1}} + {{:assign message="Le montant des amortissement dans l'écriture de sortie (%s) est différent du total des amortissements associés à l'immobilisation (%s)."|args:$exit_amort_display:$total_amort_display}} + {{/if}} {{/if}} {{* @@ -225,7 +258,35 @@
-

Écriture de sortie du bilan attachée à l'immobilisation

+{{if $erreur}} +

{{$message}}
Vérifiez si vous avez correctement attaché les écritures d'amortissement.

+ + + + + + + + + + + + + {{#foreach from=$exit_trans key="account_code" item="line"}} + {{:assign account_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.id_year}} + + + + + + + + {{/foreach}} + +
Détails de l'écriture de sortie de bilan
NuméroCompteDébitCréditLibellé
{{$line.account_code}}{{$line.account_label}}{{$line.debit|money_currency:false}}{{$line.credit|money_currency:false}}{{$line.line_label}}
+{{/if}} + +

Écriture de sortie de bilan attachée à l'immobilisation

{{if $exit_line != null}} {{:assign exit_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$exit_line.trans_id}} @@ -262,7 +323,7 @@
{{elseif $exit_lines}}

- Vous pouvez attacher une écriture de sortie du bilan à l'immobilisation + Vous pouvez attacher une écriture de sortie de bilan à l'immobilisation

{{/if}} @@ -302,7 +363,7 @@ {{elseif $exit_line == null}} -

Aucune écriture de sortie du bilan avec un +

Aucune écriture de sortie de bilan avec un montant de {{$solde|money_currency_html:false|raw}} au crédit du compte {{$ligne_immo.account_code}} — {{$ligne_immo.account_label}} ;
@@ -321,10 +382,10 @@

{{:button type="submit" name="backward" label="Revenir à l'étape précédente" shape="left" class="main"}} - {{if $exit_line}} + {{if $exit_line && ! $erreur}} {{:button type="submit" name="validate" label="Terminer" shape="check" class="main"}} {{else}} - {{:button type="submit" name="finish" label="Terminer" shape="export" class="main"}} + {{:button type="submit" name="finish" label="Annuler" shape="delete" class="main"}} {{/if}}

diff --git a/style.css b/style.css index 9811b17..c4b7591 100644 --- a/style.css +++ b/style.css @@ -74,6 +74,15 @@ table.list tbody tr.ignored:nth-child(even) { font-style: italic; background: rgba(255, 255, 200, 0.5); } + +table.error { + background-color: #fcc; +} +table.error tr, table.error td, table.error thead td { + background-image : none; + background-color: #fcc; +} + html.dark table.list tbody tr.ignored:nth-child(odd) { font-style: italic; background: rgba(100, 100, 0, 0.4); From 9e620c3efb752ad6e754d2eabc0b46214cb668fc Mon Sep 17 00:00:00 2001 From: Jean-Christophe Engel Date: Sat, 11 Jul 2026 18:17:05 +0200 Subject: [PATCH 125/133] Simplification explications aide --- doc/aide.html | 198 +++++++++++--------- doc/exemple_parametres_immobilisation-1.png | Bin 119274 -> 119944 bytes style_aide.css | 7 +- 3 files changed, 120 insertions(+), 85 deletions(-) diff --git a/doc/aide.html b/doc/aide.html index 6846953..005e29e 100644 --- a/doc/aide.html +++ b/doc/aide.html @@ -44,10 +44,10 @@ ultérieurement
  • Compte d’immobilisation
  • Projet
  • Durée d’amortissement en années
  • -
  • Date de mise en service : c’est la date à partir de laquelle -l’immobilisation peut être utilisée ; à renseigner uniquement si -différente de la date d’acquisition ; doit être postérieure ou égale à -la date d’acquisition.
  • +
  • Date de mise en service : c’est cette date qui est prise en +compte dans le calcul des amortissements. Il s’agit de la date à partir +de laquelle l’immobilisation peut commencer à être utilisée ; à modifier +uniquement si différente de la date d’acquisition.
  • Après création, l’immobilisation est classée dans l’onglet Amortissables.

    @@ -65,7 +65,7 @@ d’immobilisation.

    Pour cela, cliquer le bouton Détails en face de l’immobilisation concernée puis Attacher une écriture d’avoir ; s’il existe des écritures au crédit du compte de l’immobilisation, on -pourra en sélectionner une pour l’asocier à l’écriture +pourra en sélectionner une pour l’associer à l’écriture d’immobilisation ; son montant sera ensuite déduit du montant de l’immobilisaiton pour calculer le montant des amortissements.

    Si l’avoir a été reçu après la création du premier amortissement, il @@ -87,16 +87,23 @@ dehors du module) ; voir ci-dessous la rubrique Attacher un amortissement à une immobilisation.

    Cliquer le bouton Enregistrer un amortissement ; dans la -fenêtre de saisie, il faut renseigner les informations suivantes : - -Exercice : sélectionner l’exercice dans lequel enregistrer l’écriture - -Date de l’écriture : doit être située dans l’exercice sélectionné et -postérieure à la date de mise en service - Libellé - Montant : calculé -par le module ; il peut être modifié si nécessaire, par exemple pour -l’arrondir - Compte de débit : par défaut c’est le compte 6811 : -Dotation aux amortissements des immobilisations - Compte -d’amortissement : par défaut c’est le compte qui correspond au compte de -l’immobilisation, obtenu en intercalant le chiffre 8 après le premier -chiffre du compte d’immobilisation.

    +fenêtre de saisie, les informations sont calculées et pré-remplies par +le modules ; en général, il n’est pas nécessaire de les modifier :

    +
      +
    • Exercice : c’est l’exercice dans lequel enregistrer l’écriture
    • +
    • Date de l’écriture : doit être située dans l’exercice +sélectionné
    • +
    • Libellé
    • +
    • Montant : calculé par le module ; il peut être modifié si +nécessaire, par exemple pour l’arrondir
    • +
    • Compte de débit : par défaut c’est le compte 6811 : Dotation aux +amortissements des immobilisations
    • +
    • Compte d’amortissement : par défaut c’est le compte qui correspond +au compte de l’immobilisation, obtenu en intercalant le chiffre 8 après +le premier chiffre du compte d’immobilisation.
    • +
    +

    Après enregistrement, le nouvel amortissement apparaît dans la liste +des amortissements de l’immobilisation.

    Lorsqu’une immobilisation est totalement amortie, elle est classée dans l’onglet Amorties.

    Incorporer une écriture @@ -120,20 +127,21 @@ l’immobilisation :

  • Immobilisation à ignorer
  • Immobilisation à amortir

    -

    Saisir les informations :

    +

    Le seul paramètre obligatoire est la durée d’amortissement en +années ; les autres paramètres sont pré-remplis à partir de l’écriture +d’immobilisation ; dans la majorité des cas, il n’est pas nécessaire de +les modifier.

      -
    • Durée d’amortissement : (obligatoire) durée en années
    • -
    • Montant de l’immobilisation : (obligatoire) pré-rempli avec le -montant de l’écriture d’immobilisation
    • Date d’acquisition : (facultatif) à renseigner uniquement si elle diffère de la date de l’écriture d’immobilisation
    • -
    • Date de mise en service : (facultatif) c’est la date à laquelle -l’immobilisation est en état de fonctionner, qui peut être postérieure à -la date d’acquisition ; c’est cette date qui est prise en compte dans le -calcul des amortissements ; à renseigner uniquement si elle diffère de -la date d’acquisition.
    • Libellé : (facultatif) à renseigner uniquement s’il diffère du libellé de l’écriture d’immobilisation
    • +
    • Montant de l’immobilisation : (obligatoire) pré-rempli avec le +montant de l’écriture d’immobilisation
    • +
    • Durée d’amortissement : (obligatoire) durée en années
    • +
    • Date de mise en service : (facultatif) voir Créer une nouvelle +immobilisation.

    Après enregistrement, l’immobilisation est classée dans l’onglet Amortissables ; on peut vérifier et éventuellement modifier ses @@ -160,31 +168,42 @@ Paheko :

    Le module donne la possibilité de les attacher à l’immobilisation en plusieurs étapes :

      -
    1. S’il existe des écritures au crédit du compte de l’immobilisation, -il est possible d’en attacher une ou plusieurs à l’immobilisation, pour -tenir compte d’avoirs reçus après l’acquisition de -l’immobilisation.
    2. -
    3. Cette étape permet d’attacher une ou plusieurs écritures -d’amortissement à l’immobilisation
    4. -
    5. Cette étape permet d’attacher une écriture de cession à -l’immobilisation, le cas échéant
    6. -
    7. La dernière étape permet d’attacher une écriture de sortie du bilan -à l’immobilisation ; une fois cet attachement confirmé, l’immobilisation -sera classée dans l’onglet Sorties du bilan.
    8. +
    9. Attacher une ou plusieurs écritures d’avoir à l’immobilisation, le +cas échéant
    10. +
    11. Attacher une ou plusieurs écritures d’amortissement à +l’immobilisation
    12. +
    13. Attacher une écriture de cession à l’immobilisation, le cas +échéant
    14. +
    15. Attacher une écriture de sortie du bilan à l’immobilisation
    -

    En cas de besoin, il est possible de parcourir les différentes étapes -pour vérifier les attachements et éventuellement en modifier certains en -cliquant le bouton Modifier.

    +

    Une fois cette étape validée, l’immobilisation sera classée dans +l’onglet Sorties du bilan.

    Immobilisations créées dans une comptabilité antérieure à Paheko

    Les immobilisations et amortissements créés dans une comptabilité -antérieure à Paheko peuvent aussi être incorporés dans le module ; ces -immobilisations et amortissements se retrouvent dans la balance -d’ouverture du premier exercice créé dans Paheko ; cette balance inclut, -pour chaque compte d’immobilisation, le montant total des -immobilisations de ce compte. Il est donc nécessaire de répartir le -montant d’un compte entre les différentes immobilisations dont il est -composé. Il en est de même pour les amortissements.

    +antérieure à Paheko peuvent aussi être pris en charge par le module ; +ces immobilisations et amortissements figurent dans le bilan du +dernier exercice de l’ancienne comptabilité et doivent +obligatoirement se retrouver dans la balance d’ouverture du premier +exercice créé dans Paheko ; cette balance comporte, pour chaque +compte d’immobilisation, le montant total des immobilisations +de ce compte. Il va donc être nécessaire de répartir le montant d’un +compte entre les différentes immobilisations dont il est composé. Il en +est de même pour les amortissements.

    +

    Il faut donc obligatoirement disposer des informations ci-dessous +pour chaque immobilisation à incorporer :

    +
      +
    • montant amortissable de l’immobilisation, c’est-à-dire la différence +entre le montant d’acquisition et le montant des éventuelles ristournes +sous forme d’écritures d’avoir au crédit du compte d’immobilisation
    • +
    • montant total des amortissements
    • +
    • durée d’amortissement
    • +
    • date d’acquisition de l’immobilisation
      +ou
    • +
    • date de mise en service de l’immobilisation ; voir Créer une nouvelle +immobilisation.
    • +

    Remarque : les immobilisations créées et sorties du bilan dans une comptabilité antérieure à Paheko ne figurent plus au bilan (!) et n’apparaissent donc pas dans la balance d’ouverture du @@ -217,18 +236,14 @@ amortissements des deux immobilisations du compte amortissements des trois immobilisations du compte 2185 -

    Pour incorporer ces immobilisations dans Paheko, il va falloir -procéder comme pour les immobilisations créées dans paheko -avant la mise en service du module et ajouter les données propres à -chaque immobilisation.

    Dans l’onglet À classer on trouve les immobilisations de la balance d’ouverture :

    - +title="Immobilisations de la balance initiale à incorporer dans Paheko" +alt="Immobilisations de la balance initiale à incorporer dans Paheko" /> +
    • la colonne Date donne la date de la balance @@ -243,31 +258,33 @@ attribué
    • Pour saisir les paramètres de la première immobilisation du compte 2181, cliquer le bouton Paramètres, puis cocher le choix « Immobilisation à amortir ».

      +

      Les paramètres sont pré-remplis à partir des données de l’écriture de +la balance d’ouverture et seront donc à modifier en fonction des données +de l’immobilisation concernée.

      +title="Paramètres a renseigner" alt="Paramètres a renseigner" />
        -
      • Durée d’amortissement : rien de nouveau
      • -
      • Montant de l’immobilisation : (obligatoire) pré-rempli avec le -montant de l’écriture d’immobilisation ; à modifier +
      • Date d’acquisition de l’immobilisation
      • +
      • Libellé de l’immobilisation
      • +
      • Montant de l’immobilisation : (obligatoire) à modifier obligatoirement en indiquant le montant réel de l’immobilisation.
        Si une immobilisation a fait l’objet d’un avoir, il faut déduire ce montant de celui de l’immobilisation : le montant à indiquer est le montant à amortir.
      • -
      • Date d’acquisition : c’est la date d’acquisition de l’immobilisation -qui est forcément antérieure à la date de l’écriture qui est celle du -bilan d’ouverture
      • -
      • Date de mise en service : rien de nouveau
      • -
      • Libellé : c’est le libellé de l’écriture d’immobilisation qui -diffère forcément de celui de la balance d’ouverture
      • +
      • Durée d’amortissement : (obligatoire) durée en années
      • +
      • Date de mise en service : (facultatif) ; voir Créer une nouvelle +immobilisation.

      Après validation, cette immobilisation se retrouve classée dans les immobilisations amortissables :

      Immobilisations amortissables @@ -276,6 +293,7 @@ amortissables première immobilisation.

      Immobilisations à incorporer dans Paheko @@ -284,6 +302,7 @@ Paheko pour les trois immobilisations du compte 2185 et on obtient :

      Immobilisations amortissables @@ -293,7 +312,7 @@ amortissables immobilisations avant la mise en service du module, on pourra les attacher à leur immobilisation : voir ci-dessous la rubrique Attacher un amortissement à une -immobilisation)

      +immobilisation.

      Attacher un amortissement à une immobilisation

      Si des écritures d’amortissement ont été saisies avec Paheko @@ -311,14 +330,14 @@ immobilisation. »

      est présente, c’est qu’il existe des écritures d’amortissement saisies avec Paheko avant la mise en service du module.

      +

      Cas des amortissements +créés avec Paheko

      • cliquer le bouton Attacher un amortissement pour en afficher la liste
      • le cas échéant, cliquer Attacher en face de l’écriture à attacher.
      -

      Cas des amortissements -créés avec Paheko

      Le montant affiché est celui de l’écriture d’amortissement ; il suffit de valider.

      Cas des amortissements @@ -326,16 +345,21 @@ créés hors Paheko

      Rappel : ces amortissements sont présents dans la balance d’ouverture du premier exercice créé dans Paheko ; cette balance inclut, pour chaque compte d’amortissement, le montant total des -amortissements de ce compte qu’il va falloir répartir entre les -différentes immobilisations concernées.

      -

      Exemple : le montant des amortissements du Saxophone -au 01/01/2023 est de 1016,43€ ; dans la fenêtre de saisie il faut donc -remplacer le montant total des amortissements du compte 28185 (7058,06) -par 1016,43.

      +amortissements
      de ce compte à la date de fin du dernier exercice de +la comptabilité antérieure à Paheko ; ce montant devra donc être +réparti entre les différentes immobilisations concernées.

      +

      Exemple : le montant qui figure dans la balance +d’ouverture pour le compte 28185 est de 7058,06€ réparti ainsi :

      +
        +
      • montant des amortissements du Saxophone : 1016,43€
      • +
      • montant des amortissements du Piano numérique : 4102,39€
      • +
      • montant des amortissements de la Batterie : 1939,24€
      • +

      Voici la page des détails du Saxophone avant l’attachement des amortissements de la balance d’ouverture :

      Page de détails du saxophone
      @@ -343,6 +367,7 @@ alt="Page de détails du saxophone" /> amortissements du compte 28185 s’affiche :

      Amortissements du compte 28185 @@ -352,16 +377,17 @@ modifier le montant affiché (7058,06) en indiquant le montant des amortissements de l’immobilisation (1016,43).

      Saisie du montant de l’amortissement

      De retour sur la page des amortissements, on constate la présence de -l’écriture d’amortissement qu’on vient d’attacher ; on peut répéter le -processus plusieurs fois si nécessaire. On peut aussi détacher une +l’écriture d’amortissement qu’on vient d’attacher ; on peut détacher une écriture si on s’est trompé.

      Page de détails du saxophone
      @@ -370,13 +396,14 @@ immobilisations du compte 2185 (Batterie et Piano) puis pour celles du compte 2181 et l’on obtient :

      - +title="Immobilisations et amortissements après incorporation" +alt="Immobilisations et amortissements après incorporation" /> +

      Les immobilisations et amortissements de la balance d’ouverture -initiale ont été incorporés en totalité dans le module.
      -Par la suite, pour créer de nouveaux amortissements, il suffit de +initiale ont été incorporés en totalité dans le module.

      +

      Par la suite, pour créer de nouveaux amortissements, il suffit de procéder comme pour une immobilisation standard.

      Sortir une immobilisation du @@ -392,14 +419,14 @@ sortir du bilan, puis cliquer Sortir du bilan.

    • dans la première étape, il faut indiquer l’exercice et la date de sortie du bilan
    • dans la deuxième étape, il faut indiquer si la sortie de bilan -s’accompagne d’une cession (vente).
    • +s’accompagne d’une cession (vente) et dans ce cas, indiquer le montant +de la cession
    • la troisième étape indique l’ensemble des écritures avec :
        -
      • un amortissement complémentaire pour l’exercice en cours si -l’immobilisation n’est pas déjà totalement amortie
      • +
      • un amortissement complémentaire pour l’exercice à la date de sortie +si l’immobilisation n’est pas déjà totalement amortie
      • un amortissement exceptionnel s’il n’y a pas de cession et si l’immobilisation n’est pas déjà totalement amortie
      • -
      • l’écriture de sortie du bilan
      • une écriture de cession, le cas échéant ; cette écriture est une créance qu’il faudra solder lors de l’enregistrement du règlement de la cession
      • @@ -421,6 +448,7 @@ nouvelle immobilisation qui pourra être amortie.

        Transférer.

        Immobilisations en cours de constitutions @@ -429,7 +457,9 @@ constitutions immobilisation :

        • Exercice
        • -
        • Date de mise en service
        • +
        • Date de mise en service ; voir Créer une nouvelle +immobilisation.
        • Libellé
        • Compte dans lequel enregistrer l’écriture d’immobilisation
        • Durée d’amortissement
        • diff --git a/doc/exemple_parametres_immobilisation-1.png b/doc/exemple_parametres_immobilisation-1.png index e69edfa5a467a4aef45e88eedfad2414a39d87ce..a89169d5a372e29f68061c51806c043665523350 100644 GIT binary patch literal 119944 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�G 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 literal 119274 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%0DogwbWH z^Gma~R8qBc@;Z>~|f)o~^7K!Ep> zNf2R*xAARezaL;0pS+&uqqep*OuSeMtX=)@%;IM7ztLm*-XU3KOZj-e23P+fIj$gXi3NT#?5$1?HZ$=Y707S18raPbaD}rJ%dIx6Wan1~B#kY(f-6qqb9;m7 zx^rvo%;P;Wi&0&Qev1LRH5r!fzER~i(rcD)zX{6YIU7m zADhB%7?tfro6Qb!ll5zBU8{y!55fPPJggcGxJ0Z-wD`@*&ksMjZ3K8c>Zbg>)p$5< z#$%I1w_XjUe2s#gybc@YN)QO|W=*L1-z#H>yfea&kmy>?`qkfAq3@w^WLv0L+ci81 zA;~*8!>hvR_>$BnRc`6L4o~q8O}bx4bxNXp`adeCJj)?&zG|k}uRHeNv}|LK53Hg?c#o^^?p2%d#WYCrQji{CX_dEXDk#zQ( zI`?vD|C+IFD#%IT3ayWC*`On71)ncUwQuDq|9W$`==hEG$jMc@u?GE$k|C=hRo8Gy zn!iha4yVSVf1JnlRmX>OVBXyj@#p7yP|+cI(z(e0BuyX;cvK@hKt>)f92cJxb;H}3TTmHf2#leCW=Ai`^oPO{bI%pA^QwNhh{vtoi>{B5PCb<*sG73K4Y(L>OcEc zmXs%(m$Op^&<-aq*3{ z%~t(kMTPD7GXr}*wY0r0+1ll{31bwx$Y7{iHFD zo-h$Ry|Gw*Y|=eQtyZL2lz*`CBDSbuHJ@i_wA56IUedej)N8Ii%C_R!+Je4KPT98&?)iC!g)Otsn#}8h87hz(&AFafTFSn=1%B^W`AURc2rscnygfhO` zDQN^smY~m>2S#nx$(?(jY*hBMNS}*Jm)023OG)6n^Zx4jNorD`Y{@T=Z5g+nh`=J9 zax1s{AEVudc;tRL7PLx=S%q%c_V)^X);G=JG-`5CUDCN(WS#mm8#_db)d7gy>SAk! zpVLrYt9c(ER@719siq3r+GM``T`F~P#Abd;DN`Jder1{0 zq-TGHfrah3Tm8X$nC9CeorBe%)|vIDlSyM0ieFpe?={_t@?deZ-ngafC?3itD4=kCJKg?Lrxm| zgIS33RcikUD2fIFERUpe`>9FbhnPS5s8$XX`s#r^ayG@0)-cL+@}aj%Wct=c<}C^qddh(`7gfeO`0bg8nl4dD{*+q
          +F6Pc>y$&SO=l1mnuP6!EJ~cLA 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

          2e5s-T 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 Date: Mon, 13 Jul 2026 10:25:11 +0200 Subject: [PATCH 126/133] =?UTF-8?q?R=C3=A9organisation=20sortie=20bilan=20?= =?UTF-8?q?(onglets)=20+=20contr=C3=B4le=20coh=C3=A9rence=20montant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _archives.html | 2 +- attach_amort.html | 2 +- attach_cession.html | 2 +- attach_credit.html | 2 +- attach_exit.html | 2 +- detach_amort.html | 2 +- detach_cession.html | 2 +- detach_credit.html | 2 +- detach_exit.html | 2 +- exit_step1.html | 46 +++------------ exit_step2.html | 59 +++----------------- exit_step3.html | 56 +++---------------- exit_step4.html | 67 +++++++++++++++------- link_immo.html | 21 +++++-- list_cessions.html | 118 +++++++++++++++++++++++++++++++++++++++ list_exit.html | 108 +++++++++++++++++++++++++++++++++++ other_amortizations.html | 7 +-- 17 files changed, 327 insertions(+), 173 deletions(-) create mode 100644 list_cessions.html create mode 100644 list_exit.html diff --git a/_archives.html b/_archives.html index a4356d6..b5d2cc6 100644 --- a/_archives.html +++ b/_archives.html @@ -153,7 +153,7 @@ {{$account_code}} {{$account_label}} - {{:linkbutton label="Modifier" href="exit_step1.html?immo_doc_id=%s"|args:$info_immo.id shape="edit"}} + {{:linkbutton label="Modifier" href="exit_step1.html?immo_doc_id=%s&from=exit"|args:$info_immo.id shape="edit"}} {{/select}} diff --git a/attach_amort.html b/attach_amort.html index 95767e2..c03821b 100644 --- a/attach_amort.html +++ b/attach_amort.html @@ -130,7 +130,7 @@ {{/if}} {{if $_GET.from == "exit"}} - {{:redirect force="exit_step2.html?immo_doc_id=%s&ok=1&msg=attach_amort"|args:$_GET.immo_doc_id}} + {{:redirect force="exit_step2.html?immo_doc_id=%s&from=exit&ok=1&msg=attach_amort"|args:$_GET.immo_doc_id}} {{else}} {{:redirect force="amortization.html?immo_doc_id=%s&type_immo=%s&ok=1&msg=attach_amort"|args:$_GET.immo_doc_id:$status}} {{/if}} diff --git a/attach_cession.html b/attach_cession.html index 8ffe851..bd78460 100644 --- a/attach_cession.html +++ b/attach_cession.html @@ -36,4 +36,4 @@ cession_line_id=$_GET.cession_line_id|intval }} -{{:redirect force="exit_step3.html?immo_doc_id=%s&ok=1&msg=attach_cession"|args:$_GET.immo_doc_id}} +{{:redirect force="exit_step3.html?immo_doc_id=%s&from=exit&ok=1&msg=attach_cession"|args:$_GET.immo_doc_id}} diff --git a/attach_credit.html b/attach_credit.html index e081434..1c15ebd 100644 --- a/attach_credit.html +++ b/attach_credit.html @@ -107,7 +107,7 @@ }} {{if $_GET.from == "exit"}} - {{:redirect force="exit_step1.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} + {{:redirect force="exit_step1.html?immo_doc_id=%s&from=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id:$_GET.from}} {{else}} {{:redirect force="amortization.html?immo_doc_id=%s&ok=1&msg=attach_avoir"|args:$_GET.immo_doc_id}} {{/if}} diff --git a/attach_exit.html b/attach_exit.html index 2dda568..36cf6bf 100644 --- a/attach_exit.html +++ b/attach_exit.html @@ -36,4 +36,4 @@ exit_line_id=$_GET.exit_line_id|intval }} -{{:redirect to="exit_step4.html?immo_doc_id=%s&ok=1&msg=attach_exit"|args:$_GET.immo_doc_id}} +{{:redirect to="exit_step4.html?immo_doc_id=%s&from=exit&ok=1&msg=attach_exit"|args:$_GET.immo_doc_id}} diff --git a/detach_amort.html b/detach_amort.html index b058716..873c924 100644 --- a/detach_amort.html +++ b/detach_amort.html @@ -26,7 +26,7 @@ {{/if}} {{if $_GET.from == "exit"}} - {{:redirect force="exit_step2.html?immo_doc_id=%s&ok=1&msg=detach_amort"|args:$_GET.immo_doc_id}} + {{:redirect force="exit_step2.html?immo_doc_id=%s&from=exit&ok=1&msg=detach_amort"|args:$_GET.immo_doc_id}} {{else}} {{:redirect force="amortization.html?immo_doc_id=%s&ok=1&msg=detach_amort"|args:$_GET.immo_doc_id:}} {{/if}} diff --git a/detach_cession.html b/detach_cession.html index eab7863..2733fcc 100644 --- a/detach_cession.html +++ b/detach_cession.html @@ -18,4 +18,4 @@ {{:delete id=$id}} {{/load}} -{{:redirect to="exit_step3.html?immo_doc_id=%s&ok=1&msg=detach_cession"|args:$_GET.immo_doc_id}} +{{:redirect to="exit_step3.html?immo_doc_id=%s&from=exit&ok=1&msg=detach_cession"|args:$_GET.immo_doc_id}} diff --git a/detach_credit.html b/detach_credit.html index 9665e85..9b7da0e 100644 --- a/detach_credit.html +++ b/detach_credit.html @@ -19,7 +19,7 @@ {{/load}} {{if $_GET.from == "exit"}} - {{:redirect force="exit_step1.html?immo_doc_id=%s&ok=1&msg=detach_avoir"|args:$_GET.immo_doc_id}} + {{:redirect force="exit_step1.html?immo_doc_id=%s&from=%s&ok=1&msg=detach_avoir"|args:$_GET.immo_doc_id:$_GET.from}} {{else}} {{:redirect force="amortization.html?immo_doc_id=%s&ok=1&msg=detach_avoir"|args:$_GET.immo_doc_id}} {{/if}} diff --git a/detach_exit.html b/detach_exit.html index 1a71701..094bd88 100644 --- a/detach_exit.html +++ b/detach_exit.html @@ -18,4 +18,4 @@ {{:delete id=$id}} {{/load}} -{{:redirect to="exit_step4.html?immo_doc_id=%s&ok=1&msg=detach_exit"|args:$_GET.immo_doc_id}} +{{:redirect to="exit_step4.html?immo_doc_id=%s&from=exit&ok=1&msg=detach_exit"|args:$_GET.immo_doc_id}} diff --git a/exit_step1.html b/exit_step1.html index 5744fb6..3ffa2cd 100644 --- a/exit_step1.html +++ b/exit_step1.html @@ -129,7 +129,6 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_avoir"}} @@ -163,6 +162,15 @@ +{{if $credit_lines}} +

          +{{/if}} +

          Écritures d'avoir attachées à l'immobilisation

          {{if $linked_immos != null}} @@ -203,42 +211,6 @@

          {{/if}} -{{if $credit_lines}} -

          Autres écritures au crédit du compte d'immobilisation

          -
          - - - - - - - - - - - - - {{#foreach from=$credit_lines}} - {{:assign credit_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$trans_id}} - {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$account_id:$year}} - - - - - - - - - - {{/foreach}} - -
          DateLibelléMontantN° compteCompte
          #{{$trans_id}}{{$date|date_short}}{{$trans_label}} - {{if $line_label != null && $line_label != $trans_label}} — {{$line_label}}{{/if}} - {{$amount|money_html|raw}}{{$account_code}}{{$account_label}} - {{:linkbutton label="Attacher" href="attach_credit.html?immo_doc_id=%s&credit_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$credit_line_id shape="plus" target="_dialog"}} -
          -{{/if}} -

          {{:button type="submit" name="proceed" label="Poursuivre" shape="right" class="main"}} diff --git a/exit_step2.html b/exit_step2.html index 6c451fc..acf7cc0 100644 --- a/exit_step2.html +++ b/exit_step2.html @@ -95,7 +95,6 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_amort"}} @@ -129,6 +128,15 @@ +{{if $free_amort_lines}} +

          +{{/if}} +

          Écritures d'amortissement attachées à l'immobilisation

          {{if $linked_amort != null}} @@ -181,55 +189,6 @@

          {{/if}} - -{{if $free_amort_lines}} -

          Autres écritures d'amortissements

          -
          - - - - - - - - - - - - - - {{#foreach from=$free_amort_lines item="line"}} - {{:assign amort_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.amort_trans_id}} - {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.year}} - - - - - - - - - - {{/foreach}} - -
          DateLibelléMontantN° compteCompte
          #{{$line.amort_trans_id}}{{$line.date|date_short}} - {{if $line.line_label != null}} - {{$line.line_label}} - {{if $line.trans_label != $line.line_label}} - — {{$line.trans_label}} - {{/if}} - {{else}} - {{$line.trans_label}} - {{/if}} -{{* - {{$line.trans_label}} - {{if $line.line_label != null && $line.line_label != $line.trans_label}} — {{$line.line_label}}{{/if}} -*}} - {{"%f"|math:$line.amort_amount|money_html:false|raw}}{{$line.account_code}}{{$line.account_label}} - {{:linkbutton label="Attacher" href="attach_amort.html?immo_doc_id=%s&amort_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.amort_line_id shape="plus" target="_dialog"}} -
          -{{/if}} -

          {{:button type="submit" name="backward" label="Revenir à l'étape précédente" shape="left" class="main"}} diff --git a/exit_step3.html b/exit_step3.html index f55e5b5..365d817 100644 --- a/exit_step3.html +++ b/exit_step3.html @@ -92,7 +92,6 @@ {{:assign var="free_cessions." value=$line}} {{/select}} {{/select}} -{{*:debug linked_cessions=$linked_cessions free_cessions=$free_cessions total_cession=$total_cession*}} {{:admin_header title="Immobilisation sortie du bilan" custom_css="./style.css" current="module_amortization"}} {{if $_GET.from == "exit"}} @@ -100,7 +99,6 @@ {{else}} {{:assign current="archived"}} {{/if}} -{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_cession"}} @@ -138,6 +136,15 @@ +{{if $linked_cessions == null && $free_cessions != null}} +

          +{{/if}} +

          Écriture de cession attachée à l'immobilisation

          {{if $linked_cessions != null}} @@ -190,51 +197,6 @@

          {{/if}} - -{{if $free_cessions}} -

          Autres écritures de cession

          -
          - - - - - - - - - - - - - - {{#foreach from=$free_cessions item="line"}} - {{:assign cession_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$line.trans_id}} - {{:assign compte_url="%s/acc/accounts/journal.php?id=%s&year=%s"|args:$admin_url:$line.account_id:$line.year}} - - - - - - - - - - {{/foreach}} - -
          DateLibelléMontantN° compteCompte
          #{{$line.trans_id}}{{$line.date|date_short}} - {{if $line.line_label != null}} - {{$line.line_label}} - {{if $line.trans_label != $line.line_label}} - — {{$line.trans_label}} - {{/if}} - {{else}} - {{$line.trans_label}} - {{/if}} - {{"%f"|math:$line.amount|money_html:false|raw}}{{$line.account_code}}{{$line.account_label}} - {{:linkbutton label="Attacher" href="attach_cession.html?immo_doc_id=%s&cession_line_id=%s&from=exit"|args:$_GET.immo_doc_id:$line.line_id shape="plus"}} -
          -{{/if}} -

          {{:button type="submit" name="backward" label="Revenir à l'étape précédente" shape="left" class="main"}} diff --git a/exit_step4.html b/exit_step4.html index ed7be7a..ba6344a 100644 --- a/exit_step4.html +++ b/exit_step4.html @@ -12,23 +12,6 @@ {{:error message=$message}} {{/if}} -{{#form on="backward"}} - {{:redirect to="exit_step3.html?immo_doc_id=%s&from=%s"|args:$_GET.immo_doc_id:$_GET.from}} -{{/form}} - -{{#form on="validate"}} - {{* mettre à jour l'état de l'immobilisation *}} - {{:save - key=$info_immo.key - status="archived" - }} - {{:redirect to="index.html?type_immo=archived"}} -{{/form}} - -{{#form on="finish"}} - {{:redirect to="index.html?type_immo=other"}} -{{/form}} - {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $label_immo|strpos:$ligne_immo.line_label === false}} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} @@ -60,6 +43,7 @@ {{else}} {{:assign montant_cession=$amount}} {{/if}} + {{:assign cession_doc_id=$id}} {{/load}} {{* chercher une écriture de sortie de bilan associée *}} @@ -117,6 +101,13 @@ {{:assign erreur=1}} {{:assign message="Le montant des amortissement dans l'écriture de sortie (%s) est différent du total des amortissements associés à l'immobilisation (%s)."|args:$exit_amort_display:$total_amort_display}} {{/if}} + + {{if $exit_line.amount != $solde}} + {{:assign erreur=2}} + {{:assign exit_line_amount=$exit_line.amount|money_currency:false|replace:" ":" "}} + {{:assign solde_immo=$solde|money_currency:false|replace:" ":" "}} + {{:assign message="Le montant de de l'immobilisation dans l'écriture de sortie (%s) est différent du montant à amortir (%s)."|args:$exit_line_amount:$solde_immo}} + {{/if}} {{/if}} {{* @@ -214,13 +205,32 @@ {{/if}} {{/select}} +{{#form on="backward"}} + {{:redirect to="exit_step3.html?immo_doc_id=%s&from=%s"|args:$_GET.immo_doc_id:$_GET.from}} +{{/form}} + +{{#form on="validate"}} + {{* mettre à jour l'état de l'immobilisation *}} + {{:save + key=$info_immo.key + status="archived" + }} + {{:redirect to="index.html?type_immo=archived"}} +{{/form}} + +{{#form on="cancel"}} + {{* supprimer les docs de cession et de sortie *}} + {{if $cession_doc_id != null}}{{:delete id=$cession_doc_id}}{{/if}} + {{if $exit_info != null}}{{:delete id=$exit_info.id}}{{/if}} + {{:redirect to="index.html?type_immo=other"}} +{{/form}} + {{:admin_header title="Immobilisation sortie du bilan" custom_css="./style.css" current="module_amortization"}} {{if $_GET.from == "exit"}} {{:assign current="other"}} {{else}} {{:assign current="archived"}} {{/if}} -{{*:include file="_nav.html" current=$current subcurrent="exit"*}} {{if $_GET.ok}} {{if $_GET.msg|match:"attach_exit"}} @@ -259,7 +269,13 @@ {{if $erreur}} -

          {{$message}}
          Vérifiez si vous avez correctement attaché les écritures d'amortissement.

          +

          {{$message}}
          + {{if $erreur == 1}} + Vérifiez si vous avez correctement attaché les écritures d'amortissement. + {{elseif $erreur == 2}} + Vérifiez si vous avez correctement attaché les éventuelles écritures d'avoir. + {{/if}} +

          @@ -286,6 +302,15 @@
          Détails de l'écriture de sortie de bilan
          {{/if}} +{{if $exit_lines}} + +{{/if}} +

          Écriture de sortie de bilan attachée à l'immobilisation

          {{if $exit_line != null}} {{:assign exit_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$exit_line.trans_id}} @@ -328,6 +353,7 @@ {{/if}} {{if $exit_lines}} +{{*

          Écritures non rattachées

          @@ -362,6 +388,7 @@ {{/foreach}}
          +*}} {{elseif $exit_line == null}}

          Aucune écriture de sortie de bilan avec un montant de {{$solde|money_currency_html:false|raw}} au crédit du @@ -385,7 +412,7 @@ {{if $exit_line && ! $erreur}} {{:button type="submit" name="validate" label="Terminer" shape="check" class="main"}} {{else}} - {{:button type="submit" name="finish" label="Annuler" shape="delete" class="main"}} + {{:button type="submit" name="cancel" label="Annuler" shape="delete" class="main"}} {{/if}}

          diff --git a/link_immo.html b/link_immo.html index 73e071b..2a049dc 100644 --- a/link_immo.html +++ b/link_immo.html @@ -12,7 +12,9 @@ {{/if}} {{:assign trans_url="%s/acc/transactions/details.php?id=%s"|args:$admin_url:$ligne_immo.trans_id}} -{{:assign date_debut=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{:assign date_immo=$info_immo.date_mes|or:$info_immo.date_achat|or:$ligne_immo.date_achat}} +{{:assign montant_immo=$info_immo.amount|or:$ligne_immo.amount}} + {{:assign label_immo=$info_immo.label|or:$ligne_immo.trans_label}} {{if $label_immo|strpos:$ligne_immo.line_label ===false }} {{:assign label_immo=$label_immo|cat:" — "|cat:$ligne_immo.line_label}} @@ -21,6 +23,10 @@ {{:assign var="ligne_immo.amount" value=$info_immo.amount}} {{/if}} +{{* déduire le montant des écritures liées à l'immo courante au crédit du même compte *}} +{{:include file="_get_credit_lines.html" immo_doc_id=$_GET.immo_doc_id keep="linked_immos, total_credits"}} +{{:assign solde="%d-%d"|math:$montant_immo:$total_credits}} + {{* lister les écritures au crédit du compte de l'immobilisation *}} @@ -59,8 +65,11 @@ :account_code = $account_code !table = $module.table :date_immo = $date_immo - assign="other_immos." + assign="credit_line" }} + {{if $credit_line.credit_amount < $solde}} + {{:assign var="other_immos." value=$credit_line}} + {{/if}} {{/select}} {{:admin_header title="Écritures au crédit du compte d'immobilisation" custom_css="./style.css" current="module_amortization"}} @@ -78,12 +87,12 @@