Skip to content

data-centralization.md

ISSUE #2 : CENTRALISATION DES DONNÉES MULTI-SOURCES

🎯 OBJECTIF

Importer et centraliser les données de 5 sources externes (FNE, e-impots, CNPS, Douanes, Banques) dans la base SmartAudit.

📖 CONTEXTE DU PROJET

SmartAudit centralise les données fiscales de multiples sources pour permettre des croisements et détections d'anomalies. Chaque source a sa propre structure et format de données.

Sources de Données

  1. RNE (Registre National des Entreprises) : Données entreprises
  2. FNE (Facturation Numérique Électronique) : Factures certifiées
  3. e-impots : Déclarations fiscales (TVA, IS, DISA)
  4. CNPS : Cotisations sociales
  5. Douanes : Déclarations import/export
  6. Banques : Transactions bancaires

Architecture des Données

  • Company : Données RNE (ifu, rccm, nom, secteur, adresse)
  • Declaration : Déclarations e-impots (TVA, IS, DISA)
  • Invoice : Factures FNE (numéro, montant, TVA, client)
  • Transaction : Transactions bancaires (crédits, débits)
  • District : Géolocalisation (14 districts CI)

🛠️ TÂCHES À IMPLÉMENTER

1. Repositories JPA

// Fichier : repository/DeclarationRepository.java
@Repository
public interface DeclarationRepository extends JpaRepository<Declaration, Long> {
    List<Declaration> findByCompany(Company company);
    List<Declaration> findByCompanyAndType(Company company, DeclarationType type);
    List<Declaration> findByPeriod(String period);
    List<Declaration> findByStatus(DeclarationStatus status);
    Optional<Declaration> findByCompanyAndTypeAndPeriod(Company company, DeclarationType type, String period);
}

// Fichier : repository/InvoiceRepository.java
@Repository
public interface InvoiceRepository extends JpaRepository<Invoice, Long> {
    List<Invoice> findByCompany(Company company);
    List<Invoice> findByCompanyAndStatus(Company company, InvoiceStatus status);
    List<Invoice> findByIssuedDateBetween(LocalDate startDate, LocalDate endDate);
    BigDecimal sumAmountByCompanyAndStatus(Company company, InvoiceStatus status);
}

// Fichier : repository/TransactionRepository.java
@Repository
public interface TransactionRepository extends JpaRepository<Transaction, Long> {
    List<Transaction> findByCompany(Company company);
    List<Transaction> findByCompanyAndType(Company company, TransactionType type);
    List<Transaction> findByTransactionDateBetween(LocalDate startDate, LocalDate endDate);
    BigDecimal sumAmountByCompanyAndType(Company company, TransactionType type);
}

2. Services de Données

// Fichier : service/DataImportService.java
@Service
@Transactional
public class DataImportService {
    
    @Autowired
    private CompanyRepository companyRepository;
    
    @Autowired
    private DeclarationRepository declarationRepository;
    
    public void importCompaniesFromCSV(String csvFilePath) {
        // 1. Lire fichier CSV entreprises
        // 2. Valider données (IFU, RCCM)
        // 3. Créer/MAJ entreprises
        // 4. Logger résultats import
    }
    
    public void importDeclarationsFromCSV(String csvFilePath) {
        // 1. Lire fichier CSV déclarations
        // 2. Associer à entreprises existantes
        // 3. Valider cohérence données
        // 4. Sauvegarder déclarations
    }
    
    public void importInvoicesFromCSV(String csvFilePath) {
        // 1. Lire fichier CSV factures FNE
        // 2. Valider numéros FNE
        // 3. Calculer TVA automatiquement
        // 4. Associer aux entreprises
    }
    
    public void importTransactionsFromCSV(String csvFilePath) {
        // 1. Lire fichier CSV transactions
        // 2. Valider montants et dates
        // 3. Associer aux entreprises
        // 4. Calculer totaux par période
    }
}

3. DataInitializer

// Fichier : config/DataInitializer.java
@Component
@Slf4j
public class DataInitializer implements CommandLineRunner {
    
    @Autowired
    private DataImportService dataImportService;
    
    @Autowired
    private DistrictService districtService;
    
    @Override
    public void run(String... args) throws Exception {
        log.info("Initialisation des données SmartAudit...");
        
        // 1. Créer les 14 districts CI
        createDistricts();
        
        // 2. Importer entreprises RNE
        dataImportService.importCompaniesFromCSV("datasets/rne_companies.csv");
        
        // 3. Importer déclarations e-impots
        dataImportService.importDeclarationsFromCSV("datasets/eimpots_declarations.csv");
        
        // 4. Importer factures FNE
        dataImportService.importInvoicesFromCSV("datasets/fne_invoices.csv");
        
        // 5. Importer transactions bancaires
        dataImportService.importTransactionsFromCSV("datasets/bank_transactions.csv");
        
        log.info("Initialisation terminée avec succès !");
    }
    
    private void createDistricts() {
        // Créer les 14 districts de Côte d'Ivoire
        List<District> districts = Arrays.asList(
            new District("ABJ", "Abidjan", "District économique principal"),
            new District("YAM", "Yamoussoukro", "Capitale politique"),
            new District("BOU", "Bouaké", "Centre du pays"),
            // ... 11 autres districts
        );
        districtService.saveAll(districts);
    }
}

4. Controllers REST

// Fichier : controller/DataController.java
@RestController
@RequestMapping("/api/data")
@PreAuthorize("hasAnyRole('ADMIN', 'AGENT')")
public class DataController {
    
    @GetMapping("/companies")
    public ResponseEntity<List<CompanyDTO>> getAllCompanies() {
        // Retourner toutes les entreprises
    }
    
    @GetMapping("/companies/{ifu}/declarations")
    public ResponseEntity<List<DeclarationDTO>> getCompanyDeclarations(@PathVariable String ifu) {
        // Déclarations d'une entreprise
    }
    
    @GetMapping("/companies/{ifu}/invoices")
    public ResponseEntity<List<InvoiceDTO>> getCompanyInvoices(@PathVariable String ifu) {
        // Factures d'une entreprise
    }
    
    @GetMapping("/companies/{ifu}/transactions")
    public ResponseEntity<List<TransactionDTO>> getCompanyTransactions(@PathVariable String ifu) {
        // Transactions d'une entreprise
    }
    
    @PostMapping("/import")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<String> importData(@RequestParam String source) {
        // Import manuel de données
    }
}

5. DTOs

// Fichier : dto/CompanyDTO.java
public class CompanyDTO {
    private String ifu;
    private String rccm;
    private String companyName;
    private LegalForm legalForm;
    private Sector sector;
    private String address;
    private String districtName;
    private LocalDate registrationDate;
    private Integer employeeCount;
    private BigDecimal annualRevenue;
    private CompanyStatus status;
    private BigDecimal complianceScore;
    private RiskLevel riskLevel;
}

// Fichier : dto/DeclarationDTO.java
public class DeclarationDTO {
    private DeclarationType type;
    private String period;
    private LocalDate submittedDate;
    private BigDecimal declaredRevenue;
    private BigDecimal declaredTVA;
    private BigDecimal declaredIS;
    private DeclarationStatus status;
    private String referenceNumber;
}

🔧 OUTILS & TECHNOLOGIES

Spring Boot

  • Spring Data JPA : Repositories et requêtes
  • @Transactional : Gestion des transactions
  • CommandLineRunner : Initialisation au démarrage
  • CSV Parser : Apache Commons CSV

Dépendances Maven

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

📊 FICHIERS CSV À CRÉER

1. rne_companies.csv (100 lignes)

ifu,rccm,name,legalForm,sector,address,districtCode,registrationDate,employeeCount,annualRevenue,capitalSocial,phoneNumber,email
1234567890,CI-ABJ-2020-A-5678,SMART TECH CI,SARL,NUMERIQUE,"Cocody Angré 7ème tranche",ABJ,2020-03-15,45,250000000,10000000,+2250709123456,contact@smarttech.ci
1234567891,CI-YAM-2019-B-1234,BATIMEX SA,SA,BTP,"Zone industrielle Yamoussoukro",YAM,2019-06-20,120,850000000,50000000,+2250759876543,info@batimex.ci

2. fne_invoices.csv (1000 lignes)

companyIfu,fneNumber,amount,tvaAmount,issuedDate,clientName,status
1234567890,FNE2024ABJ000001,5000000,900000,2024-01-15,CLIENT ABC SARL,VALID
1234567890,FNE2024ABJ000002,3200000,576000,2024-01-22,ENTREPRISE XYZ,VALID

3. eimpots_declarations.csv (700 lignes)

companyIfu,declarationType,period,submittedDate,declaredRevenue,declaredTVA,declaredIS,status
1234567890,TVA,2024-01,2024-02-15,42000000,7560000,0,VALIDATED
1234567890,TVA,2024-02,2024-03-18,38000000,6840000,0,VALIDATED

4. bank_transactions.csv (2000 lignes)

companyIfu,transactionDate,amount,type,description
1234567890,2024-01-10,5500000,CREDIT,Virement CLIENT ABC
1234567890,2024-01-15,3800000,CREDIT,Virement ENTREPRISE XYZ

🎯 CRITÈRES D'ACCEPTATION

Import de Données

  • 100 entreprises importées depuis RNE
  • 1000 factures FNE avec numéros valides
  • 700 déclarations e-impots (TVA, IS, DISA)
  • 2000 transactions bancaires réalistes
  • 14 districts CI avec coordonnées

Validation des Données

  • IFU validation : Format 10 chiffres
  • RCCM validation : Format CI-CODE-ANNEE-LETTRE-NUMERO
  • Montants cohérents : TVA 18%, totaux corrects
  • Dates logiques : Pas de dates futures
  • Associations correctes : Entreprises liées aux données

API REST

  • Endpoints consultation : Par IFU, par période
  • Filtres avancés : Par secteur, district, statut
  • Pagination : Pour gros volumes
  • Performance : < 500ms pour requêtes complexes

📁 STRUCTURE DES FICHIERS

src/main/java/ci/dgi/smartaudit/
├── repository/
│   ├── DeclarationRepository.java
│   ├── InvoiceRepository.java
│   ├── TransactionRepository.java
│   └── CompanyRepository.java
├── service/
│   ├── DataImportService.java
│   ├── DeclarationService.java
│   ├── InvoiceService.java
│   └── TransactionService.java
├── controller/
│   └── DataController.java
├── dto/
│   ├── CompanyDTO.java
│   ├── DeclarationDTO.java
│   ├── InvoiceDTO.java
│   └── TransactionDTO.java
└── config/
    └── DataInitializer.java

src/main/resources/
├── datasets/
│   ├── rne_companies.csv
│   ├── fne_invoices.csv
│   ├── eimpots_declarations.csv
│   ├── bank_transactions.csv
│   ├── cnps_contributions.csv
│   └── customs_declarations.csv

🧪 TESTS À IMPLÉMENTER

Tests Unitaires

@ExtendWith(MockitoExtension.class)
class DataImportServiceTest {
    
    @Test
    void importCompanies_WithValidCSV_ShouldCreateCompanies() {
        // Test import entreprises
    }
    
    @Test
    void importDeclarations_WithInvalidIFU_ShouldSkipRecord() {
        // Test validation IFU
    }
    
    @Test
    void calculateTVA_WithValidAmount_ShouldReturnCorrectTVA() {
        // Test calcul TVA 18%
    }
}

Tests d'Intégration

@SpringBootTest
@AutoConfigureTestDatabase
class DataInitializerIntegrationTest {
    
    @Test
    void dataInitializer_ShouldImportAllData() {
        // Test import complet
    }
}

🚀 DÉMARRAGE RAPIDE

1. Configuration Base

# application.yml
spring:
  sql:
    init:
      mode: always
  jpa:
    hibernate:
      ddl-auto: update

2. Commandes de Test

# Lancer l'application avec import
mvn spring-boot:run

# Vérifier les données importées
curl http://localhost:8080/api/data/companies

📊 MÉTRIQUES DE SUCCÈS

  • Volume données : 100+ entreprises, 1000+ factures
  • Performance import : < 30 secondes pour tout
  • Cohérence données : 0 erreur de validation
  • API response time : < 500ms

🔗 INTÉGRATIONS

Avec Issue #1

  • Validation IFU : Vérification existence dans RNE
  • Création comptes : Entreprises PENDING

Avec Issue #3

  • Données pour IA : Croisement multi-sources
  • Détection anomalies : Écarts entre sources

Avec Issue #2

  • Géolocalisation : Districts avec coordonnées
  • Carte Fiscométéo : Données par district

⚠️ POINTS D'ATTENTION

  1. Performance : Import en batch pour gros volumes
  2. Validation : Vérifier cohérence entre sources
  3. Erreurs : Logger et gérer les échecs d'import
  4. Données sensibles : Anonymiser si nécessaire

ESTIMATION : 2 jours
DIFFICULTÉ : Moyenne
PRIORITÉ : Critique (base pour détection IA)