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::{FromDispatch, FromDispatchNew, SafeDispatch, SafeVariant};
use crate::errors::SageResult;
use windows::Win32::System::Com::IDispatch;

/// Wrapper pour l'objet Famille de Sage 100c (IBOFamille)
///
/// Représente une famille d'articles permettant de classifier et organiser
/// le catalogue produits de manière hiérarchique.
///
/// # Exemples
///
/// ```no_run
/// # use objets_metier_rs::wrappers::cial::CialApplication;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let cial = CialApplication::new("Objets100c.CIAL")?;
/// # cial.set_name("D:\\Sage\\BIJOU.MAE")?;
/// # cial.open()?;
/// let factory = cial.factory_famille()?;
/// let famille = factory.read_intitule("Informatique")?;
/// println!("Famille : {}", famille.fa_intitule()?);
/// println!("Code : {}", famille.fa_code_famille()?);
/// # Ok(())
/// # }
/// ```
pub struct Famille {
    pub(crate) dispatch: IDispatch,
}

impl Famille {
    /// Crée un SafeDispatch temporaire pour les appels
    fn dispatch(&self) -> SafeDispatch<'_> {
        SafeDispatch::new(&self.dispatch)
    }

    // ==================== IDENTIFICATION ====================

    /// Obtient l'intitulé de la famille
    pub fn fa_intitule(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_Intitule", &[])?
            .to_string()
    }

    /// Définit l'intitulé de la famille
    pub fn set_fa_intitule(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch().call_property_put("FA_Intitule", &[param])?;
        Ok(())
    }

    /// Obtient le code de la famille
    pub fn fa_code_famille(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_CodeFamille", &[])?
            .to_string()
    }

    /// Définit le code de la famille
    pub fn set_fa_code_famille(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("FA_CodeFamille", &[param])?;
        Ok(())
    }

    /// Obtient le compteur interne de la famille
    pub fn cbmarq(&self) -> SageResult<i32> {
        self.dispatch().call_method_by_name("cbMarq", &[])?.to_i32()
    }

    // ==================== HIÉRARCHIE ====================

    /// Obtient le code de la famille parente (pour hiérarchie)
    pub fn fa_code_famille_parent(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_CodeFamilleParent", &[])?
            .to_string()
    }

    /// Définit le code de la famille parente
    pub fn set_fa_code_famille_parent(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("FA_CodeFamilleParent", &[param])?;
        Ok(())
    }

    /// Obtient le niveau hiérarchique de la famille (0=racine, 1=niveau 1, etc.)
    pub fn fa_niveau(&self) -> SageResult<i32> {
        self.dispatch()
            .call_method_by_name("FA_Niveau", &[])?
            .to_i32()
    }

    /// Définit le niveau hiérarchique de la famille
    pub fn set_fa_niveau(&self, value: i32) -> SageResult<()> {
        let param = SafeVariant::from_i32(value);
        self.dispatch().call_property_put("FA_Niveau", &[param])?;
        Ok(())
    }

    // ==================== CATÉGORIES COMPTABLES ====================

    /// Obtient la catégorie comptable vente
    pub fn fa_cat_compta_vte(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_CatComptaVte", &[])?
            .to_string()
    }

    /// Définit la catégorie comptable vente
    pub fn set_fa_cat_compta_vte(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("FA_CatComptaVte", &[param])?;
        Ok(())
    }

    /// Obtient la catégorie comptable achat
    pub fn fa_cat_compta_ach(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_CatComptaAch", &[])?
            .to_string()
    }

    /// Définit la catégorie comptable achat
    pub fn set_fa_cat_compta_ach(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("FA_CatComptaAch", &[param])?;
        Ok(())
    }

    /// Obtient la catégorie comptable stock
    pub fn fa_cat_compta_stk(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_CatComptaStk", &[])?
            .to_string()
    }

    /// Définit la catégorie comptable stock
    pub fn set_fa_cat_compta_stk(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("FA_CatComptaStk", &[param])?;
        Ok(())
    }

    // ==================== STATISTIQUES ====================

    /// Obtient le code statistique de la famille
    pub fn fa_stat_01(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("FA_Stat01", &[])?
            .to_string()
    }

    /// Définit le code statistique de la famille
    pub fn set_fa_stat_01(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch().call_property_put("FA_Stat01", &[param])?;
        Ok(())
    }

    // ==================== OPTIONS ====================

    /// Obtient le type de famille (0=Achetée, 1=Fabriquée, 2=Autre)
    pub fn fa_type(&self) -> SageResult<i32> {
        self.dispatch()
            .call_method_by_name("FA_Type", &[])?
            .to_i32()
    }

    /// Définit le type de famille
    pub fn set_fa_type(&self, value: i32) -> SageResult<()> {
        let param = SafeVariant::from_i32(value);
        self.dispatch().call_property_put("FA_Type", &[param])?;
        Ok(())
    }

    /// Indique si la famille est cachée
    pub fn fa_cachee(&self) -> SageResult<bool> {
        self.dispatch()
            .call_method_by_name("FA_Cachee", &[])?
            .to_bool()
    }

    /// Définit si la famille est cachée
    pub fn set_fa_cachee(&self, value: bool) -> SageResult<()> {
        let param = SafeVariant::from_bool(value);
        self.dispatch().call_property_put("FA_Cachee", &[param])?;
        Ok(())
    }

    // ==================== MÉTHODES D'ÉCRITURE ====================

    /// Enregistre les modifications de la famille dans la base de données
    ///
    /// # Exemples
    ///
    /// ```no_run
    /// # use objets_metier_rs::wrappers::cial::objects::Famille;
    /// # fn example(famille: &Famille) -> Result<(), Box<dyn std::error::Error>> {
    /// famille.set_fa_intitule("Nouvelle catégorie")?;
    /// famille.set_fa_type(0)?;
    /// famille.write()?;
    /// # Ok(())
    /// # }
    /// ```
    pub fn write(&self) -> SageResult<()> {
        self.dispatch().call_method_by_name("Write", &[])?;
        Ok(())
    }

    /// Supprime la famille de la base de données
    ///
    /// ⚠️ Attention : Cette opération est irréversible
    pub fn remove(&self) -> SageResult<()> {
        self.dispatch().call_method_by_name("Remove", &[])?;
        Ok(())
    }
}

impl FromDispatch for Famille {
    fn from_dispatch(dispatch: IDispatch) -> SageResult<Self> {
        Ok(Famille { dispatch })
    }
}

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

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_famille_structure() {
        // Test de documentation vérifiant que la structure compile
        // Ne s'exécute pas réellement car nécessite une connexion Sage
    }
}