Aller au contenu

app.mouvement

Mouvement de matière, en ajout seul. Se compose de lignes signées dont la somme est nulle. Toute correction passe par une contre-passation.

Name Type Default Nullable Children Parents Comment
id uuid app.uuid_v7() false app.mouvement app.mouvement_ligne app.lot app.sortie_etape app.expedition app.registre_annulation Identifiant du mouvement (UUID v7).
organisation_id uuid false app.mouvement app.mouvement_ligne app.lot app.sortie_etape app.expedition app.registre_annulation app.organisation app.utilisateur app.mouvement app.etape_realisee Organisation propriétaire de la ligne. Sert à l’isolation par RLS (EC-032) et au filtrage de la synchronisation.
nature text false Nature : reception, transfert, transformation, expedition, perte, inventaire ou contrepassation.
date_operation timestamp with time zone false Date de l’opération sur le terrain ou à la balance.
contrepasse_mouvement_id uuid true app.mouvement Mouvement annulé par cette contre-passation. Un mouvement n’est contre-passé qu’une fois.
motif text true Motif, obligatoire pour une contre-passation.
commande_id uuid true Commande de synchronisation à l’origine du mouvement.
cree_par uuid false app.utilisateur Utilisateur auteur du mouvement.
cree_le timestamp with time zone now() false Date de création de la ligne.
etape_realisee_id uuid true app.etape_realisee Étape réalisée à laquelle se rattache un mouvement de transformation (AM-12) ; obligatoire pour ce type de mouvement, vide pour les autres.
Name Type Definition
mouvement_check CHECK CHECK (((nature = ‘contrepassation’::text) = (contrepasse_mouvement_id IS NOT NULL)))
mouvement_check1 CHECK CHECK (((nature <> ‘contrepassation’::text) OR (motif IS NOT NULL)))
mouvement_equilibre TRIGGER CREATE CONSTRAINT TRIGGER mouvement_equilibre AFTER INSERT ON app.mouvement DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION app.tg_mouvement_equilibre()
mouvement_etape_seulement_transformation CHECK CHECK (((etape_realisee_id IS NULL) OR (nature = ‘transformation’::text)))
mouvement_nature_check CHECK CHECK ((nature = ANY (ARRAY[‘reception’::text, ‘transfert’::text, ‘transformation’::text, ‘expedition’::text, ‘perte’::text, ‘inventaire’::text, ‘contrepassation’::text])))
mouvement_organisation_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)
mouvement_organisation_id_cree_par_fkey FOREIGN KEY FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)
mouvement_pkey PRIMARY KEY PRIMARY KEY (id)
mouvement_contrepasse_mouvement_id_key UNIQUE UNIQUE (contrepasse_mouvement_id)
mouvement_organisation_id_contrepasse_mouvement_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, contrepasse_mouvement_id) REFERENCES app.mouvement(organisation_id, id)
mouvement_organisation_id_id_key UNIQUE UNIQUE (organisation_id, id)
mouvement_organisation_id_etape_realisee_id_fkey FOREIGN KEY FOREIGN KEY (organisation_id, etape_realisee_id) REFERENCES app.etape_realisee(organisation_id, id)
Name Definition
mouvement_pkey CREATE UNIQUE INDEX mouvement_pkey ON app.mouvement USING btree (id)
mouvement_contrepasse_mouvement_id_key CREATE UNIQUE INDEX mouvement_contrepasse_mouvement_id_key ON app.mouvement USING btree (contrepasse_mouvement_id)
mouvement_organisation_id_id_key CREATE UNIQUE INDEX mouvement_organisation_id_id_key ON app.mouvement USING btree (organisation_id, id)
mouvement_etape_idx CREATE INDEX mouvement_etape_idx ON app.mouvement USING btree (organisation_id, etape_realisee_id) WHERE (etape_realisee_id IS NOT NULL)
Name Definition
journal CREATE TRIGGER journal AFTER INSERT OR DELETE OR UPDATE ON app.mouvement FOR EACH ROW EXECUTE FUNCTION journal.tg_journaliser()
ajout_seul CREATE TRIGGER ajout_seul BEFORE DELETE OR UPDATE ON app.mouvement FOR EACH ROW EXECUTE FUNCTION app.tg_ajout_seul()
mouvement_equilibre CREATE CONSTRAINT TRIGGER mouvement_equilibre AFTER INSERT ON app.mouvement DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION app.tg_mouvement_equilibre()
mouvement_etape_controle CREATE TRIGGER mouvement_etape_controle BEFORE INSERT ON app.mouvement FOR EACH ROW EXECUTE FUNCTION app.tg_mouvement_etape_controle()
erDiagram

"app.mouvement" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, contrepasse_mouvement_id) REFERENCES app.mouvement(organisation_id, id)"
"app.mouvement_ligne" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, mouvement_id) REFERENCES app.mouvement(organisation_id, id)"
"app.lot" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, mouvement_creation_id) REFERENCES app.mouvement(organisation_id, id)"
"app.sortie_etape" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, mouvement_id) REFERENCES app.mouvement(organisation_id, id)"
"app.expedition" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, mouvement_id) REFERENCES app.mouvement(organisation_id, id)"
"app.registre_annulation" }o--|| "app.mouvement" : "FOREIGN KEY (organisation_id, mouvement_id) REFERENCES app.mouvement(organisation_id, id)"
"app.mouvement" }o--|| "app.organisation" : "FOREIGN KEY (organisation_id) REFERENCES app.organisation(id)"
"app.mouvement" }o--|| "app.utilisateur" : "FOREIGN KEY (organisation_id, cree_par) REFERENCES app.utilisateur(organisation_id, id)"
"app.mouvement" }o--|| "app.etape_realisee" : "FOREIGN KEY (organisation_id, etape_realisee_id) REFERENCES app.etape_realisee(organisation_id, id)"

"app.mouvement" {
  uuid id "Identifiant du mouvement (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  text nature "Nature : reception, transfert, transformation, expedition, perte, inventaire ou contrepassation."
  timestamp_with_time_zone date_operation "Date de l'opération sur le terrain ou à la balance."
  uuid contrepasse_mouvement_id FK "Mouvement annulé par cette contre-passation. Un mouvement n'est contre-passé qu'une fois."
  text motif "Motif, obligatoire pour une contre-passation."
  uuid commande_id "Commande de synchronisation à l'origine du mouvement."
  uuid cree_par FK "Utilisateur auteur du mouvement."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  uuid etape_realisee_id FK "Étape réalisée à laquelle se rattache un mouvement de transformation (AM-12) ; obligatoire pour ce type de mouvement, vide pour les autres."
}
"app.mouvement_ligne" {
  uuid id "Identifiant de la ligne (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  uuid mouvement_id FK "Mouvement auquel appartient la ligne."
  uuid compte_matiere_id FK "Compte débité ou crédité."
  uuid produit_id FK "Produit concerné, de la même organisation (clé étrangère posée au Lot 1, séquence A2)."
  bigint quantite_g "Quantité en grammes, signée et non nulle."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
}
"app.lot" {
  uuid id "Identifiant du lot (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
  uuid campagne_id FK "Campagne du lot."
  text reference_provisoire "Référence provisoire, tant que le lot n'est pas validé (BR-AAAA-MM-JJ-NNNN dans le cahier)."
  bigint numero "Rang du numéro officiel, pris par app.attribuer_numero à la validation, jamais réutilisé (I3). Vide avant la validation."
  text nature "Nature de la séquence de numérotation : MP matière première, REC réception, NET nettoyé, PF produit fini (EC-068)."
  uuid produit_id FK "Produit du lot."
  text qualite "Catégorie d'affichage du lot (EC-090) : saisie à la réception, calculée par le mélange (la plus basse catégorie des entrées et des états du résultat, EC-120). La qualité par référentiel est dans app.lot_qualite."
  text statut "Statut : brouillon, en_attente, valide, rejete, annule, consomme, quarantaine, archive. Transitions contrôlées par app.tg_lot_controle."
  uuid compte_matiere_id FK "Compte de matière du lot (nature lot) : son solde est la quantité du lot."
  uuid mouvement_creation_id FK "Mouvement qui crée le lot (I4) : il crédite le compte du lot et n'est pas une contre-passation."
  timestamp_with_time_zone date_operation "Date de l'opération qui crée le lot, saisie sur le terrain."
  text motif_annulation "Motif de l'annulation ; renseigné si et seulement si le statut est annule."
  uuid annule_par FK "Utilisateur qui a annulé le lot."
  timestamp_with_time_zone date_annulation "Date de l'annulation."
  uuid cree_par FK "Utilisateur qui a créé le lot."
  timestamp_with_time_zone cree_le "Date d'enregistrement du lot."
  timestamp_with_time_zone modifie_le "Date de la dernière modification (statut ou numéro)."
}
"app.sortie_etape" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
  uuid etape_realisee_id FK "Étape qui produit la sortie ; elle doit être en cours ou réalisée, pas encore validée."
  text nature "produit_principal (au plus un par étape), coproduit, sous_produit, rebut ou perte."
  uuid produit_id FK "Produit de la sortie."
  bigint quantite_g "Quantité en grammes, strictement positive."
  uuid lot_id FK "Lot créé par un mouvement de l'étape, pour la même quantité ; vide pour un rebut ou une perte, qui ne deviennent jamais un lot."
  text destination "Destination du rebut (obligatoire pour un rebut)."
  text motif "Motif de la perte déclarée (obligatoire pour une perte)."
  uuid cree_par FK "Utilisateur qui a déclaré la sortie."
  timestamp_with_time_zone cree_le "Date de la déclaration."
  boolean reintegre_flux_bio "Vrai si l'opérateur déclare que ce rebut réintègre un flux biologique (EC-120) ; réservé à la nature rebut. Lu par la variable etape.rebut_reintegre_flux_bio des normes."
  uuid mouvement_id FK "Mouvement de transformation qui a produit la sortie. Une sortie dont le mouvement est contre-passé (étape dévalidée) ne compte plus dans le bilan ; vide pour les sorties antérieures à L2-6 sans mouvement retrouvé."
}
"app.expedition" {
  uuid id "Identifiant de l'expédition (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
  uuid vente_id FK "Vente validée qui donne lieu à l'expédition ; une vente en a une ou plusieurs."
  uuid vehicule_id FK "Véhicule qui charge la matière."
  uuid pv_nettoyage_id FK "PV de nettoyage du véhicule avant chargement ; il doit être valable à la date de l'expédition."
  timestamp_with_time_zone date_operation "Date de l'expédition : c'est elle qui sert à apprécier les certificats de la chaîne (AV1-03)."
  text conteneur "Numéro du conteneur ; vide hors transport conteneurisé."
  text__ scelles "Numéros des scellés posés."
  text destination "Destination de l'expédition."
  text coi_reference "Référence du certificat d'inspection (COI) ; facultative, donnée seulement tant qu'aucun module documents n'existe."
  text nop_import_certificate "Référence du NOP Import Certificate ; facultative."
  text eudr_reference "Référence de la déclaration EUDR ; facultative."
  text statut "Statut : brouillon, validee ou annulee. Ne revient jamais en arrière."
  uuid mouvement_id FK "Mouvement de matière (nature expedition) écrit à la validation : débit des lots, crédit du compte technique d'expédition. Vide hors expédition validée."
  uuid decide_par FK "Utilisateur qui a validé ou annulé l'expédition."
  timestamp_with_time_zone decide_le "Date de la décision."
  uuid cree_par FK "Utilisateur qui a saisi l'expédition."
  timestamp_with_time_zone cree_le "Date de saisie de l'expédition."
  timestamp_with_time_zone modifie_le "Date de la dernière modification de l'expédition."
}
"app.registre_annulation" {
  uuid id "Identifiant de la ligne du registre (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
  text objet_type "Type d'objet défait : reception, etape_realisee, expedition, vente ou lot."
  uuid objet_id "Identifiant de l'objet défait."
  text nature "devalidation (retour à l'état précédent : réception, étape, expédition) ou annulation (clôture : vente, lot). Deux mécanismes distincts (EC-008)."
  text motif "Justification écrite, obligatoire."
  uuid lot_id FK "Lot annulé, avec son numéro conservé (RG-143) ; pour une dévalidation de réception, le lot d'origine annulé. Vide pour une vente, une étape ou une expédition."
  uuid campagne_id FK "Campagne concernée, pour l'édition du registre par campagne (RG-144) ; vide pour une vente ou une expédition."
  uuid mouvement_id FK "Mouvement de contre-passation écrit ; vide pour l'annulation d'une vente, qui n'a pas encore bougé la matière."
  uuid constat_id FK "Constat consigné pour la dévalidation (AM-15) ; vide pour une annulation."
  uuid cree_par FK "Utilisateur qui défait l'objet (direction)."
  timestamp_with_time_zone cree_le "Date de la dévalidation ou de l'annulation."
}
"app.organisation" {
  uuid id "Identifiant de l'organisation (UUID v7)."
  text code "Code court en majuscules. Immuable : il figure dans les identifiants Keycloak (coopa.agent01). « EXT » est réservé."
  text nom "Nom de l'organisation."
  text pays "Pays, code ISO 3166-1 alpha-2."
  text langue "Langue de l'organisation : fr ou en."
  text fuseau_horaire "Fuseau horaire IANA utilisé pour l'affichage des dates."
  text devise_defaut "Devise par défaut des montants, code ISO 4217."
  text keycloak_organisation_id "Identifiant de l'organisation dans Keycloak."
  text organisme_certificateur "Organisme de certification de l'organisation. Aucun contrôle de format (EC-027)."
  text code_operateur "Code d'opérateur attribué par l'organisme certificateur."
  uuid logo_fichier_id FK "Fichier du logo (EC-029)."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de la dernière modification, tenue par un déclencheur."
  text source_conformite "Source des décisions de conformité : `interne` (contrôle interne de BioTrace) ou `externe` (outil tiers). Une seule source active à la fois ; app.statut_conformite.source doit lui être égale."
  text statut "État du compte client : `active` ou `suspendue`. Une organisation suspendue est refusée par la garde d'authentification (`organisation_suspendue`) ; ses données et ses comptes sont conservés. Décidé par l'équipe de l'éditeur (EC-126)."
  timestamp_with_time_zone suspendue_le "Date de la suspension en cours ; nulle tant que l'organisation est active."
}
"app.utilisateur" {
  uuid id "Identifiant de l'utilisateur (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire de la ligne. Sert à l'isolation par RLS (EC-032) et au filtrage de la synchronisation."
  uuid keycloak_sub "Identifiant du compte Keycloak (revendication sub). Identique d'une organisation à l'autre pour un compte externe."
  text identifiant "Identifiant local de connexion, sans le code de l'organisation : 3 à 32 caractères parmi a-z, 0-9, _ et -. Unique dans l'organisation."
  text nom_affiche "Nom affiché dans l'application."
  text telephone "Numéro de téléphone. Attribut du compte, jamais son identifiant."
  text statut "Statut du compte : actif, suspendu ou desactive."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de la dernière modification, tenue par un déclencheur."
}
"app.etape_realisee" {
  uuid id "Identifiant stable (UUID v7)."
  uuid organisation_id FK "Organisation propriétaire (isolation par ligne)."
  uuid ordre_id FK "Ordre de transformation concerné."
  uuid noeud_etape_id FK "Étape du procédé (nœud enfant du procédé). Vide pour la saisie qui couvre tout le procédé en suivi global."
  text statut "a_faire, en_cours, realisee ou validee ; une seule marche à la fois."
  jsonb mesures "Mesures saisies à l'étape (objet JSON) ; modifiables tant que l'étape n'est pas validée."
  timestamp_with_time_zone debut_le "Début de l'étape."
  timestamp_with_time_zone fin_le "Fin de l'étape ; jamais avant le début."
  uuid cree_par FK "Utilisateur qui a ouvert l'étape."
  uuid valide_par FK "Utilisateur qui a validé l'étape ; renseigné si et seulement si elle est validée."
  timestamp_with_time_zone valide_le "Date de validation de l'étape."
  timestamp_with_time_zone cree_le "Date de création de la ligne."
  timestamp_with_time_zone modifie_le "Date de dernière modification."
}

Generated by tbls