diff --git a/web/modules/custom/figli_compta_ledger/figli_compta_ledger.install b/web/modules/custom/figli_compta_ledger/figli_compta_ledger.install index 0ad9db4..1dd6f1e 100644 --- a/web/modules/custom/figli_compta_ledger/figli_compta_ledger.install +++ b/web/modules/custom/figli_compta_ledger/figli_compta_ledger.install @@ -685,3 +685,41 @@ function figli_compta_ledger_update_8007() { return "Cotisation/TVA : $corrected lignes corrigées (cotisation active), $alreadyOfficial déjà correctes (cotisation inactive), $stillAmbiguous laissées telles quelles (taux non standard des deux façons), $noData sans HT/TTC, $skipped2021 lignes 2021 ignorées."; } + +/** + * Corrects what field_cotisation_urssaf stores for the lines + * figli_compta_ledger_update_8007() marked cotisation-active: that + * migration (and figli_compta_ledger_node_presave() as first written) + * stored Montant HT + 1,1% there, but "1,1%" as a field/column label + * means just the 1,1% itself -- the delta, not the augmented total. + * TVA still applies to the augmented base (Montant HT + this field), so + * Montant TTC is untouched by this correction; only + * field_cotisation_urssaf's own value changes, from round(HT * 1.011, 2) + * to round(HT * 0.011, 2). Safe to run unconditionally on every + * cotisation-active line -- this is a bug in code from earlier the same + * day, not a judgment call about ambiguous historical data like + * figli_compta_ledger_update_8007()'s. + */ +function figli_compta_ledger_update_8008() { + $storage = \Drupal::entityTypeManager()->getStorage('node'); + $nids = $storage->getQuery() + ->accessCheck(FALSE) + ->condition('type', 'ligne_comptable') + ->condition('field_cotisation_active', 1) + ->execute(); + + $fixed = 0; + \Drupal::state()->set('figli_compta_ledger.skip_validation', TRUE); + foreach ($storage->loadMultiple($nids) as $node) { + if (!$node->hasField('field_montant_ht') || $node->get('field_montant_ht')->isEmpty()) { + continue; + } + $ht = (float) $node->get('field_montant_ht')->value; + $node->set('field_cotisation_urssaf', round($ht * 0.011, 2)); + $node->save(); + $fixed++; + } + \Drupal::state()->delete('figli_compta_ledger.skip_validation'); + + return "field_cotisation_urssaf corrigé (delta seul, pas HT + delta) pour $fixed lignes."; +} diff --git a/web/modules/custom/figli_compta_ledger/figli_compta_ledger.module b/web/modules/custom/figli_compta_ledger/figli_compta_ledger.module index c7ca4e4..77d09c3 100644 --- a/web/modules/custom/figli_compta_ledger/figli_compta_ledger.module +++ b/web/modules/custom/figli_compta_ledger/figli_compta_ledger.module @@ -137,7 +137,7 @@ function figli_compta_ledger_form_alter(&$form, FormStateInterface $form_state, 'visible' => [':input[name="field_type_ligne"]' => ['value' => 'entree']], ]; $form['field_cotisation_urssaf']['widget'][0]['value']['#disabled'] = TRUE; - $form['field_cotisation_urssaf']['widget'][0]['value']['#description'] = t('Calculé automatiquement (Montant HT + 1,1%) si la cotisation ci-dessus est cochée.'); + $form['field_cotisation_urssaf']['widget'][0]['value']['#description'] = t('Calculé automatiquement (1,1% du montant HT) si la cotisation ci-dessus est cochée. La TVA est ensuite appliquée sur Montant HT + ce montant.'); } // TVA: a select of the official French rates covers the overwhelming @@ -398,9 +398,15 @@ function figli_compta_ledger_node_presave(NodeInterface $node) { } if ($inputs_changed) { if ($cotisation_applies) { - $base = round($montant_ht * 1.011, 2); + // field_cotisation_urssaf stores just the 1,1% itself (the + // delta), not Montant HT + 1,1% -- that's what "1,1%" as a + // column/field label means. TVA still applies to the augmented + // base though, so $base (used for Montant TTC just below) stays + // HT + delta; only what gets *written* to the field changes. + $delta = round($montant_ht * 0.011, 2); + $base = $montant_ht + $delta; if ($node->hasField('field_cotisation_urssaf')) { - $node->set('field_cotisation_urssaf', $base); + $node->set('field_cotisation_urssaf', $delta); } } else { diff --git a/web/modules/custom/figli_compta_ledger/js/ledger-form.js b/web/modules/custom/figli_compta_ledger/js/ledger-form.js index cfc3d1b..c29bd69 100644 --- a/web/modules/custom/figli_compta_ledger/js/ledger-form.js +++ b/web/modules/custom/figli_compta_ledger/js/ledger-form.js @@ -63,9 +63,14 @@ } var base = htValue; if (cotisationApplies()) { - base = Math.round(htValue * 1.011 * 100) / 100; + // Displayed/stored value is just the 1,1% itself (the + // delta), not HT + 1,1% -- but TVA still applies to the + // augmented base, so $base for the TTC calc below stays + // htValue + delta regardless. + var delta = Math.round(htValue * 0.011 * 100) / 100; + base = htValue + delta; if (cotisationAmount) { - cotisationAmount.value = base.toFixed(2); + cotisationAmount.value = delta.toFixed(2); } } else if (cotisationAmount) { diff --git a/web/modules/custom/figli_compta_ledger/src/Controller/LedgerStatsController.php b/web/modules/custom/figli_compta_ledger/src/Controller/LedgerStatsController.php index d5c2cc7..ea16f69 100644 --- a/web/modules/custom/figli_compta_ledger/src/Controller/LedgerStatsController.php +++ b/web/modules/custom/figli_compta_ledger/src/Controller/LedgerStatsController.php @@ -43,6 +43,7 @@ class LedgerStatsController extends ControllerBase { $par_compte = []; $montant_ht = 0.0; + $cotisation = 0.0; $montant_ttc = 0.0; $ecart = 0.0; foreach ($storage->loadMultiple($nids) as $node) { @@ -52,6 +53,13 @@ class LedgerStatsController extends ControllerBase { ? (float) $node->get('field_montant_ttc')->value : 0.0; $montant_ht += $ht; $montant_ttc += $ttc; + // Blank (never 0) for most lines -- only "Entrée client" lines + // with the cotisation checkbox on ever have this field set (see + // figli_compta_ledger_node_presave()) -- but summing a blank + // value as 0 here is exactly right for a total. + if ($node->hasField('field_cotisation_urssaf') && !$node->get('field_cotisation_urssaf')->isEmpty()) { + $cotisation += (float) $node->get('field_cotisation_urssaf')->value; + } $somme = 0.0; foreach ($node->get('field_repartition')->referencedEntities() as $paragraph) { @@ -71,6 +79,7 @@ class LedgerStatsController extends ControllerBase { return new JsonResponse([ 'annee' => $annee, 'montant_ht' => round($montant_ht, 2), + 'cotisation' => round($cotisation, 2), 'montant_ttc' => round($montant_ttc, 2), 'ecart' => round($ecart, 2), 'par_compte' => array_map(fn ($v) => round($v, 2), $par_compte), diff --git a/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig b/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig index 50468bc..b156778 100644 --- a/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig +++ b/web/modules/custom/figli_compta_ledger/templates/figli-compta-home.html.twig @@ -263,7 +263,7 @@ chargement… {{ currentYearTotals ? formatEur(currentYearTotals.montant_ht) : '' }} - + {{ currentYearTotals ? formatEur(currentYearTotals.cotisation) : '' }} {{ currentYearTotals ? formatEur(currentYearTotals.montant_ttc) : '' }} {{ currentYearTotals && currentYearTotals.par_compte[c] !== undefined ? formatEur(currentYearTotals.par_compte[c]) : '' }}