Pipeline des Bills — architecture et ajout d’un nouveau type
Architectre des Bills
Le système de bills traverse la configuration, le backend Node.js/BrainCloud, la sérialisation, les données Unity et l'UI. Ajouter un nouveau bill seulement dans un de ces endroits produit typiquement un bill qui n'est jamais généré, qui ne peut pas être désérialisé, ou qui s'affiche avec le mauvais template.
Cette page décrit le pipeline complet et sert surtout de checklist lorsqu'un nouveau type de bill est ajouté.
1. Architecture complète
flowchart LR
DEF[bills_settings_definitions.json] --> WIZ[Configuration module / wizard]
MOD[modules_settings_definitions.json] --> WIZ
WIZ --> CFG[bills_type_data + bills_category_settings]
CFG --> CREATE[createBills()]
CREATE --> CTX[BillCreationContext]
CTX --> FACTORY[BillFactory.BILL_MAPPING]
FACTORY --> CLASS[Classe Bill JS concrète]
CLASS --> BCTX[BillContext]
BCTX --> SERIAL[Serialized billsData + billsOrder + partners]
SERIAL --> TMTD[Unity TeamModuleTypeData]
TMTD --> BILL[Bill.cs]
BILL --> DATA[BillDataBase.CreateBillData]
DATA --> WINDOW[BillWindowControl]
WINDOW --> TEMPLATE[BillTemplateType / BillControlBase]
TEMPLATE --> USER[Bill affiché à l'utilisateur]
2. Phase A — configuration
La configuration d'un bill commence dans bills_settings_definitions.json. Chaque clé représente un bill configurable et décrit notamment son category, son num_bills, ses conditions de visibilité et ses champs supplémentaires.
modules_settings_definitions.json choisit ensuite quelles definitions de bills sont disponibles pour chaque type de module. Les valeurs réellement choisies finissent dans les settings du module sous bills_type_data. Les options communes à une famille sont dans bills_category_settings.
flowchart TD
BSD[bills_settings_definitions.json] --> BILLDEF[Definition du type]
MSD[modules_settings_definitions.json] --> EXPOSE[Expose le type dans le module]
BILLDEF --> WIZ[BillsDataWizardPageControl]
EXPOSE --> WIZ
WIZ --> BTD[bills_type_data]
WIZ --> BCS[bills_category_settings]
BTD --> SERVER[Backend de génération]
BCS --> SERVER
3. Phase B — génération backend
Le point de départ serveur est createBills() dans byModule_utils_create_module_type_data_functions.js. Il initialise BillCreationContext, regroupe la configuration par type, applique les catégories aléatoires, puis génère les types dans un ordre déterministe.
Ordre de calcul
BillCreationContext._billTypeComputingOrder n'est pas décoratif. Plusieurs bills dépendent de bills créés avant eux : checks, credit notes, reports, notes receivable, régularisations, etc. Un nouveau type qui dépend d'un autre doit donc être placé après sa dépendance.
sequenceDiagram
participant C as createBills()
participant BC as BillCreationContext
participant F as BillFactory
participant B as Classe Bill
participant X as BillContext
C->>BC: init(random, settings, context, dates)
C->>C: groupe bills_type_data par type
loop _billTypeComputingOrder
C->>F: createBills(billTypeData)
F->>F: BILL_MAPPING[type]
F->>B: new ConcreteBill(...)
B-->>BC: addBill(uid, bill)
end
C->>X: init(... bills générés ...)
X->>X: post-processing / tri / sérialisation
X-->>C: billsData + billsOrder + partners + taxes
Factory backend
BillFactory.BILL_MAPPING est le dispatch principal string type → fonction de création. Une entrée peut pointer directement vers une fonction ou passer par conditionallyCreateBills(...) pour respecter une feature flag/préférence comme employés, taxes, banking, immobilisations ou forme juridique.
Les fonctions de création choisissent les partenaires, dates, produits/services, montants et objets dépendants, construisent la classe de bill puis appellent BillCreationContext.addBill().
4. Phase C — classes et sérialisation serveur
Les classes serveur se trouvent sous :
master/node.js/backend/braincloud/server_scripts/_utils/by_module/classes/bills/
Il existe des classes de base et des familles spécialisées : checks, reports, contracts, immobilizations, etc. Une classe concrète est nécessaire lorsqu'un type possède une structure, un calcul ou des références spécifiques qui ne peuvent pas être représentés par une classe existante.
flowchart TD
BASE[BillBase JS] --> EXIST{Structure existante suffisante ?}
EXIST -->|Oui| REUSE[Réutiliser classe existante]
EXIST -->|Non| NEW[Créer ConcreteBill.js]
NEW --> SER[serialize()]
NEW --> DES[deserialize()]
NEW --> CALC[calculs / références spécifiques]
REUSE --> CTX[BillContext]
SER --> CTX
CTX --> JSON[bills.billsData]
BillContext._deserializeBills() utilise utilsByModule.getBillClassFromType() pour reconstruire les bonnes classes à partir de JSON déjà sérialisé. C'est donc un deuxième mapping backend à ne pas oublier lorsqu'un nouveau type nécessite une classe.
5. Phase D — chargement dans Unity
TeamModuleTypeData.Deserialize() charge d'abord les partenaires, services, dépenses, contrats, immobilisations, taxes et autres dépendances. Ensuite il parcourt bills.billsData et construit chaque Bill.
Bill.Deserialize() lit le billType, puis appelle BillDataBase.CreateBillData(billType) afin de créer la bonne structure de données Unity avant de désérialiser billData.
sequenceDiagram
participant JSON as Team module JSON
participant T as TeamModuleTypeData
participant B as Bill
participant F as BillDataBase.CreateBillData
participant D as Concrete BillData
JSON->>T: billsData + partners + dépendances
T->>B: new Bill + Deserialize(...)
B->>B: BillBase.Deserialize billType
B->>F: CreateBillData(billType)
F-->>B: instance Concrete BillData
B->>D: Deserialize(billData, dependencies...)
B-->>T: Bill complet
T->>T: bills[uid] + billsOrder
6. Phase E — affichage Unity
BillWindowControl.GetBillTemplateTypeFromBillType() choisit le template UI à utiliser. Plusieurs types partagent le même template : Sales, Check, OperatingCost, Memo, Letter, Payslip, CreditNote, etc.
Le template est ensuite alloué depuis un pool et reçoit le bill via BillControlBase.SetData(). Les contrôles spécialisés castent le billData lorsque des champs spécifiques doivent être affichés.
flowchart LR
B[Bill + BillData] --> MAP[BillWindowControl.GetBillTemplateTypeFromBillType]
MAP --> SALES[Sales]
MAP --> CHECK[Check]
MAP --> OP[OperatingCost]
MAP --> LETTER[Letter]
MAP --> MEMO[Memo]
MAP --> REPORT[Report spécialisé]
SALES --> SET[BillControlBase.SetData]
CHECK --> SET
OP --> SET
LETTER --> SET
MEMO --> SET
REPORT --> SET
SET --> UI[UI finale]
7. État « finished »
Le fait qu'un étudiant ait terminé de traiter un bill est séparé du bill lui-même. Unity conserve finishedBills dans TeamModuleTypeData. BillWindowControl permet de modifier l'état et le backend persiste la liste via la custom command gérée par saveTeamModuleFinishedBills().
8. Ajouter un nouveau type de bill — checklist obligatoire
Exemple : ajout d'un type serveur new_bill.
| # | Fichier / zone | Modification | Obligatoire ? |
|---|---|---|---|
| 1 | Assets/.../data_byModule/bills_settings_definitions.json |
Créer la definition new_bill avec category, num_bills, visibilité et champs nécessaires. |
Oui si le bill est configurable/généré par settings. |
| 2 | modules_settings_definitions.json |
Ajouter new_bill dans la liste bills des types de modules qui doivent pouvoir le configurer. |
Oui pour l'exposer dans le wizard concerné. |
| 3 | BillCreationContext.js |
Ajouter new_bill dans _billTypeComputingOrder, à l'endroit correct selon ses dépendances. |
Oui pour un bill généré par le pipeline standard. |
| 4 | BillFactory.js |
Ajouter BILL_MAPPING["new_bill"] et implémenter/réutiliser la fonction de création. |
Oui. |
| 5 | classes/bills/.../*.js |
Créer une classe JS si le bill ne peut pas réutiliser une classe existante; implémenter sérialisation/désérialisation et logique spécifique. | Conditionnel. |
| 6 | BillFactory.js includes |
Inclure la nouvelle classe serveur si une nouvelle classe est créée. | Conditionnel. |
| 7 | byModule_utils.js → getBillClassFromType() |
Mapper new_bill vers la classe JS utilisée pour désérialiser les bills existants/contextes. |
Oui si nouvelle classe/type sérialisé. |
| 8 | Assets/Src/Game/Data/ByModule/BillBase.cs |
Ajouter le nom string, l'enum BillType, GetBillNameFromType(), GetBillTypeFromName() et vérifier les switches de taxes/partenaires/type simplifié. |
Oui. |
| 9 | Assets/Src/UI/SimByModule/Data/Runtime/BillDataBase.cs |
Ajouter le mapping dans CreateBillData() vers une classe existante ou une nouvelle classe BillData.... |
Oui. |
| 10 | Assets/Src/UI/SimByModule/Data/Runtime/BillData*.cs |
Créer la classe data Unity si le JSON billData a une forme ou des calculs propres. |
Conditionnel. |
| 11 | Assets/Src/UI/SimByModule/UI/BillWindowControl.cs |
Mapper le nouveau BillType vers le bon BillTemplateType. |
Oui. |
| 12 | BillControlBase.cs / contrôle spécialisé |
Vérifier titre, sender/receiver, taxes, total et raw data. Créer/modifier un contrôle si le template existant ne suffit pas. | Conditionnel mais à vérifier systématiquement. |
| 13 | Prefab/template Unity du bill | Créer ou brancher un prefab si un nouveau BillTemplateType ou une mise en page spécifique est nécessaire. |
Conditionnel. |
| 14 | Textes/localisation | Ajouter les clés utilisées par GetSimplifiedBillTypeName(), titre, memo, descriptions ou labels spécialisés. |
Selon UI. |
| 15 | Accounting switches / Utils | Rechercher le nouveau type dans les règles de taxes, partenaires, journaux, inventory, regularizations, reports et autres traitements. | À auditer systématiquement. |
9. Fichiers critiques — ne pas oublier
Backend Node.js / BrainCloud
backend/braincloud/server_scripts/_utils/by_module/functions/byModule_utils_create_module_type_data_functions.js— orchestrationcreateBills().backend/braincloud/server_scripts/_utils/by_module/contexts/BillCreationContext.js— contexte global, ordre de calcul, partenaires/dates/dépendances.backend/braincloud/server_scripts/_utils/by_module/factories/BillFactory.js— mapping type → création et includes des classes.backend/braincloud/server_scripts/_utils/by_module/contexts/BillContext.js— post-processing, désérialisation, ordre et sérialisation finale.backend/braincloud/server_scripts/_utils/by_module/byModule_utils.js—getBillClassFromType()et plusieurs règles Accounting transversales.backend/braincloud/server_scripts/_utils/by_module/classes/bills/— implémentations concrètes.backend/braincloud/server_scripts/_utils/command/utils_custom_command_by_module.js— actions runtime persistées, notammentfinishedBillset autres mutations de module.
Unity / Game
Assets/Src/Game/Data/ByModule/BillBase.cs— enum et conversion string/type, taxes et helpers communs.Assets/Src/Game/Data/ByModule/TeamModuleTypeData.cs— désérialisation du payload complet de bills.Assets/Src/UI/SimByModule/Data/Runtime/Bill.cs— objet runtime principal.Assets/Src/UI/SimByModule/Data/Runtime/BillDataBase.cs— factory dubillData.Assets/Src/UI/SimByModule/Data/Runtime/BillData*.cs— structures spécifiques.Assets/Src/UI/SimByModule/UI/BillWindowControl.cs— sélection du template et affichage/finalisation.Assets/Src/UI/SimByModule/UI/BillControlBase.cs— affichage commun, taxes/total, titres et raw data.Assets/Src/UI/SimByModule/UI/*BillControl.cs— contrôles spécialisés.Assets/Src/Game/Data/ByModule/ModuleSettingsBase.cs— settings runtime des bills.Assets/Src/UI/SimByModule/Data/BillsDataWizardPageControl.cs— configuration dans l'éditeur.
Configuration
Assets/GameSpecific/byModule/Resources/data_byModule/bills_settings_definitions.jsonAssets/GameSpecific/byModule/Resources/data_byModule/bills_category_settings_definitions.jsonAssets/GameSpecific/byModule/Resources/data_byModule/modules_settings_definitions.jsonAssets/GameSpecific/byModule/Resources/data_byModule/modules_settings.jsonpour les defaults applicables.accounts.json,taxes.json,interests.json,immobilizations.json,contract_regularizations.jsonlorsque le nouveau bill dépend de ces domaines.
10. Audit obligatoire après ajout
Après avoir ajouté le string du nouveau type, faire une recherche globale sur les endroits qui switchent sur les bill types. Le code actuel contient plusieurs décisions distribuées qui ne passent pas toutes par une factory unique.
git grep -n "new_bill" master/game master/node.js
git grep -n "BillType.eNewBill" master/game
git grep -n "switch.*billType|switch.*bill.billType" master/game master/node.js
Les hotspots les plus importants sont : taxes, sélection du partenaire fiscal, type simplifié/titre, mapping du template, génération d'entrées comptables, stock/inventaire, reports/régularisations et dépendances entre bills.
11. Test mental minimal d’un nouveau bill
flowchart TD
CFG[Le wizard peut le configurer ?] --> GEN[Le serveur le génère ?]
GEN --> SER[Il se serialize puis se deserialize ?]
SER --> UNITY[Unity reconnait son BillType ?]
UNITY --> DATA[CreateBillData retourne le bon data ?]
DATA --> UI[BillWindow choisit le bon template ?]
UI --> NUM[Totaux/taxes/entries corrects ?]
NUM --> STATE[Finished state et reload corrects ?]
STATE --> MULTI[Reload / autre client / contexte précédent correct ?]
Si une seule étape échoue, le nouveau bill n'est pas réellement intégré de bout en bout.