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;

/// Client - Spécialisation de Tiers avec CT_Type = 0
///
/// Un client est un tiers de type 0 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 clients.
#[derive(Debug)]
pub struct Client {
    tiers: Tiers,
}

impl Client {
    /// Crée un Client à 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 Client (CT_Type = 0).
    /// 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 Client)
    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 clients
    /// Retourne une description formatée du client
    pub fn description(&self) -> SageResult<String> {
        let numero = self.tiers.ct_num()?;
        let intitule = self.tiers.ct_intitule()?;
        Ok(format!("Client {} - {}", numero, intitule))
    }

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

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

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

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

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

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

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

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