Client autocomplete, drill down from versements, multi-entrée linking
Three related changes to the /lignes table:
1. The "Client" filter is now a text input with a <datalist> instead
of a <select> -- 50+ clients made the dropdown unwieldy. v-model.lazy
(not the default per-keystroke binding) since a change here triggers
ensureScrollable() and a hash rewrite, which shouldn't fire on every
character typed.
2. Clicking a "versement freelance" row's own status badge (Non liée /
Reste à verser / Sur-versé) now drills down the same way an entrée's
"N sorties liées" badge already did, instead of only being clickable
from the entrée side.
3. field_entree_liee is now multi-value (cardinality unlimited) --
sometimes one payment covers several client invoices at once.
LinkEntreeForm uses #tags => TRUE (a single comma-separated
autocomplete field, Drupal's field-API-native multi-value shape on
submit, no manual tag parsing needed). This is the deeper change and
touches most of the reconciliation logic in home.js:
- buildRows() reads field_entree_liee as an array
(entreeLieeIds/entreeLieeLabels) -- JSON:API always returns a list
for a multi-cardinality relationship now, even with 0 or 1 items.
- sortiesByEntree indexes a sortie under every entrée it links to.
- reconciliationByEntree splits a multi-linked sortie's répartition
equally across its linked entrées -- there's no per-link amount to
divide by, so equal split is the least-wrong assumption available
rather than counting the sortie's full amount against every linked
entrée (which would double-count the same money).
- versementStatus() sums residuals across all of a versement's linked
entrées for its own compte(s), skipping any not in the currently
loaded window (same accepted trade-off reconciliationByEntree
already had).
- The drill-down (filterEntreeId) is now filterEntreeGroup, a
transitive closure over shared entrée<->sortie links -- clicking
one entrée (or, per #2, one versement) surfaces every other entrée
it's connected to through a shared sortie, and every sortie linked
to any of them, not just the originally-clicked one's direct links.
Verified end-to-end: linked a real unlinked versement to two entrées
for the same client via the actual form submission (no manual DB
edit), confirmed both persisted, confirmed the link button's tooltip
lists both, and confirmed clicking either the versement's or an
entrée's badge produces the same 3-row connected group with correct
drill-down footer totals. Reverted the test link afterward.
This commit is contained in:
@@ -13,7 +13,11 @@ use Drupal\node\NodeInterface;
|
||||
* Quick-link form: sets field_entree_liee on a single sortie line without
|
||||
* opening the full ligne_comptable edit form -- the associates only ever
|
||||
* need to touch this one field to link a versement/achat/hébergement to
|
||||
* the entrée client it pays out against.
|
||||
* the entrée client(s) it pays out against. field_entree_liee is
|
||||
* multi-value (cardinality unlimited) since one payment sometimes covers
|
||||
* several client invoices at once; #tags renders that as a single
|
||||
* comma-separated autocomplete field instead of a Drupal "add another
|
||||
* item" widget.
|
||||
*/
|
||||
class LinkEntreeForm extends FormBase {
|
||||
|
||||
@@ -32,8 +36,9 @@ class LinkEntreeForm extends FormBase {
|
||||
|
||||
$form['field_entree_liee'] = [
|
||||
'#type' => 'entity_autocomplete',
|
||||
'#title' => $this->t('Entrée client liée'),
|
||||
'#title' => $this->t('Entrées clients liées'),
|
||||
'#target_type' => 'node',
|
||||
'#tags' => TRUE,
|
||||
'#selection_handler' => 'figli_compta_ledger:entree_client',
|
||||
'#selection_settings' => [
|
||||
'target_bundles' => ['ligne_comptable' => 'ligne_comptable'],
|
||||
@@ -41,8 +46,8 @@ class LinkEntreeForm extends FormBase {
|
||||
// read by EntreeClientSelection::buildEntityQuery().
|
||||
'entity' => $node,
|
||||
],
|
||||
'#default_value' => $node->get('field_entree_liee')->entity,
|
||||
'#description' => $this->t('Laisser vide pour retirer le lien.'),
|
||||
'#default_value' => $node->get('field_entree_liee')->referencedEntities(),
|
||||
'#description' => $this->t('Laisser vide pour retirer tous les liens. Plusieurs entrées possibles (paiement en plusieurs fois) : séparez-les par une virgule.'),
|
||||
];
|
||||
|
||||
$form['actions'] = ['#type' => 'actions'];
|
||||
@@ -63,7 +68,12 @@ class LinkEntreeForm extends FormBase {
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$node = $form_state->get('node');
|
||||
$node->set('field_entree_liee', $form_state->getValue('field_entree_liee') ?: NULL);
|
||||
// #tags => TRUE normalizes the submitted value to the field API's own
|
||||
// multi-value shape (an array of ['target_id' => ..., ...] items, one
|
||||
// per comma-separated entry), so this is just field-API assignment,
|
||||
// no manual tag-string parsing needed.
|
||||
$values = $form_state->getValue('field_entree_liee') ?: [];
|
||||
$node->set('field_entree_liee', $values);
|
||||
$node->save();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user