cpro-client 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f1452657739318ca5d2a71a6673d046dea03e4f5e3b00befc41ae210fcf3ee4
4
- data.tar.gz: b36804bf664635e9d5f510fe8a8ed2e52a6aeb1753b9de3bc3b919475d3e51cb
3
+ metadata.gz: 56e12349c80b29ebc7190354cefea789a6a9114d42260bc40e2851529255a043
4
+ data.tar.gz: 35ec2d79aace35593b9493dd6e07b3ede842726ba9b2cc9b63491ca269844272
5
5
  SHA512:
6
- metadata.gz: 918adeba480ffaaec7508e21e68c31799708e568fb4dc5f2678072ab9f10971f31a03c8af893e57548cce0d5c93b9ad2b9d5387a50a7d629f40f945dfb16b93a
7
- data.tar.gz: 299ffdbbc8b8c9f25b24c09d1577fdd4e0d1f3b9bc9f3b0eed7c6d607f428e86e87d1a1978bb55c10ab6e450bdb24c996b5909673113031cfb375bb65ab30255
6
+ metadata.gz: e3372fac6b533cb8b24b08dbae14c2dce8f495a93d4b53161d553b874ab208bee3099f53efa0af7159e4690cd5aea8414c9da2fef33a38c8cd875796aff99d60
7
+ data.tar.gz: fae64931447cd4708e173bca2790890bad33ed65bbc370ad49dc40e60a1f12185af579d947eec2a766fbb79f1dd5da07f77e1c99d18a54678532866b664ae206
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
1
  ## [Unreleased]
2
2
 
3
3
 
4
+ ## [0.2.7] - 2026-09-07
5
+
6
+ ### Ajouté
7
+ - `Cpro::Suivi#orientation` nomme la situation d'un dépôt en une valeur sur laquelle brancher —
8
+ `:en_attente`, `:enveloppe_irrecevable`, `:facture_introuvable`, `:en_cours`, `:rejetee`,
9
+ `:non_transmise`, `:erreur_routage`, `:transmise` — en aplatissant l'étape du suivi et l'état de
10
+ la facture. Ne repose que sur des codes : statut, code motif, étape. Un statut d'acheminement
11
+ l'emporte sur un `NON_TRANSMISE` devenu caduc, et c'est l'incident courant qui décide.
12
+
13
+ Deux distinctions restent à l'appelant : séparer les deux `NON_TRANSMISE` supposerait de lire le
14
+ texte d'une note rédigée par l'AIFE, et séparer un rejet corrigeable d'un rejet définitif repose
15
+ sur une lecture de la spécification que nous n'avons pas mesurée.
16
+ - `CHORUS_PRO.md` — les séquences de statuts et de motifs renvoyées par la plateforme, scénario par
17
+ scénario, en distinguant les relevés sandbox des comportements seulement documentés.
18
+
19
+
4
20
  ## [0.2.6] - 2026-09-05
5
21
 
6
22
  ### Modifié
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpro-client (0.2.6)
4
+ cpro-client (0.2.7)
5
5
  faraday (>= 0.9, < 3.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -283,6 +283,24 @@ suivi.facture # la facture et son historique, à l'étape :facture_connue
283
283
  suivi.statut_flux # le statut brut du flux, dès qu'il est connu
284
284
  ```
285
285
 
286
+ Pour brancher directement sans reconstruire le même `if` dans chaque application,
287
+ `orientation` aplatit l'étape et l'état de la facture en une valeur :
288
+
289
+ ```ruby
290
+ case suivi.orientation
291
+ when :en_attente, :en_cours, :facture_introuvable then reprogrammer_le_suivi
292
+ when :enveloppe_irrecevable, :rejetee then signaler(suivi.motifs)
293
+ when :non_transmise then preparer_un_duplicata
294
+ when :erreur_routage then alerter
295
+ when :transmise then classer
296
+ end
297
+ ```
298
+
299
+ Elle ne repose que sur des codes — statut, code motif, étape — jamais sur le texte d'une note.
300
+ Deux distinctions restent donc à l'appelant, et [CHORUS_PRO.md](CHORUS_PRO.md) explique comment les
301
+ obtenir : séparer les deux causes de `:non_transmise`, et distinguer un rejet corrigeable d'un rejet
302
+ définitif.
303
+
286
304
  `motifs` cumule tout l'historique — un incident réglé y côtoie l'incident courant. Pour n'avoir que
287
305
  le plus récent, avec le statut qui le portait et sa date :
288
306
 
@@ -469,6 +487,12 @@ client.annuaire.find_by_siren("474775418").lignes_annuaire.map(&:identifiant_adr
469
487
  C'est cet identifiant qui doit alimenter BT-49 sur la facture et MDT-73 sur le cycle de vie.
470
488
  Vérifiez `plateforme_active?` avant de compter sur un acheminement.
471
489
 
490
+ ## Comportements de la plateforme
491
+
492
+ [CHORUS_PRO.md](CHORUS_PRO.md) rassemble, scénario par scénario, la séquence de statuts et de motifs
493
+ que renvoie réellement la plateforme — enveloppe irrecevable, adressage introuvable, destinataire
494
+ non raccordé, doublon — en distinguant ce qui a été mesuré en sandbox de ce qui n'est que documenté.
495
+
472
496
  ## Licence
473
497
 
474
498
  Disponible en open source sous les termes de la [licence MIT](https://opensource.org/licenses/MIT).
data/lib/cpro/suivi.rb CHANGED
@@ -10,6 +10,24 @@ module Cpro
10
10
  class Suivi
11
11
  ETAPES = %i[flux_en_attente flux_irrecevable facture_introuvable facture_connue].freeze
12
12
 
13
+ ORIENTATIONS = %i[en_attente enveloppe_irrecevable facture_introuvable en_cours
14
+ rejetee non_transmise erreur_routage transmise].freeze
15
+
16
+ # Statuts qui prouvent que la facture a quitté Chorus Pro : d'après la colonne « Sens flux »
17
+ # de l'annexe des statuts, ils proviennent de la plateforme du destinataire ou constatent
18
+ # l'émission par la plateforme.
19
+ #
20
+ # `APPROUVEE`, `REFUSEE` et `VISEE` circulent dans les deux sens. Ils figurent ici parce que
21
+ # les recevoir est le cas courant, et que les omettre ferait passer une facture refusée par
22
+ # l'acheteur pour une facture encore en cours. Une application qui les émet elle-même le sait.
23
+ STATUTS_TRANSMISE = %w[
24
+ EMISE_PAR_LA_PLATEFORME RECUE_DE_LA_PLATEFORME MISE_A_DISPOSITION PRISE_EN_CHARGE
25
+ APPROUVEE APPROUVEE_PARTIELLEMENT EN_LITIGE SUSPENDUE PAIEMENT_TRANSMIS REFUSEE VISEE
26
+ ].freeze
27
+
28
+ MOTIF_NON_TRANSMISE = "NON_TRANSMISE"
29
+ STATUT_ERREUR_ROUTAGE = "ERREUR_ROUTAGE"
30
+
13
31
  attr_reader :etape, :statut_flux, :facture
14
32
 
15
33
  # Un 404 sur le flux et une recherche vide sont des états du parcours, pas des erreurs : ils
@@ -80,6 +98,30 @@ module Cpro
80
98
  facture&.dernier_incident
81
99
  end
82
100
 
101
+ # Nomme la situation en une valeur sur laquelle brancher, l'étape du suivi et l'état de la
102
+ # facture étant aplatis ensemble. Ne repose que sur des codes — statut, code motif, étape.
103
+ #
104
+ # Deux distinctions sont délibérément laissées à l'appelant, parce que les porter ici serait
105
+ # fragile :
106
+ #
107
+ # - séparer les deux `NON_TRANSMISE` — destinataire sans plateforme, qui ne recevra jamais, ou
108
+ # plateforme non encore raccordée, qui recevra plus tard — suppose de lire le texte d'une
109
+ # note rédigée par l'AIFE. L'annuaire le dit plus sûrement avant le dépôt, par
110
+ # `Annuaire#find_identifiant_adressage(siret).statut_plateforme` ;
111
+ # - séparer un rejet corrigeable d'un rejet définitif repose sur l'idée qu'un rejet de
112
+ # conformité n'intègre pas la facture et ne consomme donc pas son numéro. La spécification
113
+ # le laisse entendre, nous ne l'avons pas mesuré.
114
+ #
115
+ # `motifs` et `dernier_incident` restent disponibles pour qui veut trancher lui-même.
116
+ def orientation
117
+ case etape
118
+ when :flux_en_attente then :en_attente
119
+ when :flux_irrecevable then :enveloppe_irrecevable
120
+ when :facture_introuvable then :facture_introuvable
121
+ else orientation_facture
122
+ end
123
+ end
124
+
83
125
  def nom_flux
84
126
  statut_flux&.nom_flux
85
127
  end
@@ -88,5 +130,22 @@ module Cpro
88
130
  [etape, facture&.statut, motifs.map(&:code).join(", ")].reject { |v| v.nil? || v.to_s.empty? }
89
131
  .join(" — ")
90
132
  end
133
+
134
+ private
135
+
136
+ # L'ordre compte : un statut d'acheminement l'emporte sur un NON_TRANSMISE devenu caduc, et
137
+ # c'est l'incident courant — non le cumul de l'historique — qui décrit la situation présente.
138
+ def orientation_facture
139
+ return :erreur_routage if facture.statut == STATUT_ERREUR_ROUTAGE
140
+ return :rejetee if facture.rejetee?
141
+ return :transmise if STATUTS_TRANSMISE.include?(facture.statut)
142
+ return :non_transmise if non_transmise?
143
+
144
+ :en_cours
145
+ end
146
+
147
+ def non_transmise?
148
+ dernier_incident&.motifs_rejet.to_a.any? { |motif| motif.code == MOTIF_NON_TRANSMISE }
149
+ end
91
150
  end
92
151
  end
data/lib/cpro/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpro
4
- VERSION = "0.2.6"
4
+ VERSION = "0.2.7"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpro-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hôtentic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-05 00:00:00.000000000 Z
11
+ date: 2026-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday