objets_metier_rs 1.0.2

Bibliothèque Rust moderne et sûre pour l'API COM Objets Métier Sage 100c - Production Ready
use crate::com::FromDispatchNew;
use crate::errors::SageResult;
use crate::wrappers::cpta::objects::Tiers;
use std::ops::Deref;
use windows::Win32::System::Com::IDispatch;

/// Fournisseur - Spécialisation de Tiers avec CT_Type = 1
///
/// Un fournisseur est un tiers de type 1 dans Sage 100c.
/// Cette structure encapsule un objet Tiers et expose toutes ses méthodes
/// via le trait Deref, tout en permettant d'ajouter des méthodes spécifiques aux fournisseurs.
#[derive(Debug)]
pub struct Fournisseur {
    tiers: Tiers,
}

impl Fournisseur {
    /// Crée un Fournisseur à partir d'un Tiers existant
    ///
    /// # Arguments
    /// * `tiers` - L'objet Tiers sous-jacent
    ///
    /// # Note
    /// Cette fonction ne vérifie pas que le tiers est bien de type Fournisseur (CT_Type = 1).
    /// Il est de la responsabilité de l'appelant de s'assurer de la cohérence.
    pub fn from_tiers(tiers: Tiers) -> Self {
        Self { tiers }
    }

    /// Accède au Tiers sous-jacent (consomme le Fournisseur)
    pub fn into_tiers(self) -> Tiers {
        self.tiers
    }

    /// Référence immutable au Tiers sous-jacent
    pub fn as_tiers(&self) -> &Tiers {
        &self.tiers
    }

    /// Référence mutable au Tiers sous-jacent
    pub fn as_tiers_mut(&mut self) -> &mut Tiers {
        &mut self.tiers
    }

    /// Méthode utilitaire spécifique aux fournisseurs
    /// Retourne une description formatée du fournisseur
    pub fn description(&self) -> SageResult<String> {
        let numero = self.tiers.ct_num()?;
        let intitule = self.tiers.ct_intitule()?;
        Ok(format!("Fournisseur {} - {}", numero, intitule))
    }

    /// Vérifie que le tiers est bien de type Fournisseur (CT_Type = 1)
    pub fn verify_type(&self) -> SageResult<bool> {
        let type_tiers = self.tiers.ct_type()?;
        Ok(type_tiers == 1)
    }
}

// Implémentation de Deref pour accéder directement aux méthodes de Tiers
// Cela permet d'écrire : fournisseur.ct_num() au lieu de fournisseur.tiers.ct_num()
impl Deref for Fournisseur {
    type Target = Tiers;

    fn deref(&self) -> &Self::Target {
        &self.tiers
    }
}

// Implémentation de Clone
impl Clone for Fournisseur {
    fn clone(&self) -> Self {
        Self {
            tiers: self.tiers.clone(),
        }
    }
}

// Implémentation de PartialEq basée sur le numéro de tiers
impl PartialEq for Fournisseur {
    fn eq(&self, other: &Self) -> bool {
        self.tiers == other.tiers
    }
}

impl FromDispatchNew for Fournisseur {
    fn from_dispatch_new(dispatch: IDispatch) -> SageResult<Self> {
        Ok(Self::from_tiers(Tiers { dispatch }))
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_fournisseur_documentation() {
        // Test de documentation - nécessite un environnement Sage pour s'exécuter

        // Utilisation typique :
        // let factory = app.factory_fournisseur()?;
        // let fournisseur = factory.read_by_code("FOURNISSEUR01")?;
        //
        // // Accès direct aux méthodes Tiers via Deref
        // let numero = fournisseur.ct_num()?;
        // let intitule = fournisseur.ct_intitule()?;
        // let solde = fournisseur.ct_solde()?;
        //
        // // Méthode spécifique Fournisseur
        // let description = fournisseur.description()?;
        // assert_eq!(description, format!("Fournisseur {} - {}", numero, intitule));
    }
}