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 Pays de Sage 100c (IBOPays3)
///
/// Représente un pays avec ses codes ISO, devise et informations internationales.
/// Utilisé pour la gestion multidevise et les échanges internationaux.
pub struct Pays {
    pub dispatch: IDispatch,
}

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

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

    /// Obtient l'intitulé du pays
    pub fn pa_intitule(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("PA_Intitule", &[])?
            .to_string()
    }

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

    // ==================== CODES ISO ====================

    /// Obtient le code ISO 2 lettres (ex: FR, US, DE)
    pub fn pa_code_iso2(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("PA_CodeISO2", &[])?
            .to_string()
    }

    /// Définit le code ISO 2 lettres
    pub fn set_pa_code_iso2(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch().call_property_put("PA_CodeISO2", &[param])?;
        Ok(())
    }

    /// Obtient le code ISO 3 lettres (ex: FRA, USA, DEU)
    pub fn pa_code_iso3(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("PA_CodeISO3", &[])?
            .to_string()
    }

    /// Définit le code ISO 3 lettres
    pub fn set_pa_code_iso3(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch().call_property_put("PA_CodeISO3", &[param])?;
        Ok(())
    }

    /// Obtient le code numérique ISO (ex: 250 pour France)
    pub fn pa_code_numerique(&self) -> SageResult<i32> {
        self.dispatch()
            .call_method_by_name("PA_CodeNumerique", &[])?
            .to_i32()
    }

    /// Définit le code numérique ISO
    pub fn set_pa_code_numerique(&self, value: i32) -> SageResult<()> {
        let param = SafeVariant::from_i32(value);
        self.dispatch()
            .call_property_put("PA_CodeNumerique", &[param])?;
        Ok(())
    }

    // ==================== UNION EUROPÉENNE ====================

    /// Indique si le pays fait partie de l'Union Européenne
    pub fn pa_ue(&self) -> SageResult<bool> {
        self.dispatch().call_method_by_name("PA_UE", &[])?.to_bool()
    }

    /// Définit si le pays fait partie de l'UE
    pub fn set_pa_ue(&self, value: bool) -> SageResult<()> {
        let param = SafeVariant::from_bool(value);
        self.dispatch().call_property_put("PA_UE", &[param])?;
        Ok(())
    }

    // ==================== DEVISE ====================

    /// Obtient le code devise du pays (ex: EUR, USD, GBP)
    pub fn pa_devise(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("PA_Devise", &[])?
            .to_string()
    }

    /// Définit le code devise du pays
    pub fn set_pa_devise(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch().call_property_put("PA_Devise", &[param])?;
        Ok(())
    }

    // ==================== TÉLÉPHONIE ====================

    /// Obtient le préfixe téléphonique international (ex: 33 pour France)
    pub fn pa_prefixe_tel(&self) -> SageResult<String> {
        self.dispatch()
            .call_method_by_name("PA_PrefixeTel", &[])?
            .to_string()
    }

    /// Définit le préfixe téléphonique
    pub fn set_pa_prefixe_tel(&self, value: &str) -> SageResult<()> {
        let param = SafeVariant::from_string(value);
        self.dispatch()
            .call_property_put("PA_PrefixeTel", &[param])?;
        Ok(())
    }

    // ==================== MÉTHODES IBIPersistObject ====================

    /// Enregistre l'objet dans la base de données
    pub fn write(&self) -> SageResult<()> {
        self.dispatch().call_method_by_name("Write", &[])?;
        Ok(())
    }

    /// Lit l'objet depuis la base de données
    pub fn read(&self) -> SageResult<SafeVariant> {
        self.dispatch().call_method_by_name("Read", &[])
    }

    /// Supprime l'objet de la base de données
    pub fn remove(&self) -> SageResult<()> {
        self.dispatch().call_method_by_name("Remove", &[])?;
        Ok(())
    }

    // ==================== MÉTHODES UTILITAIRES ====================

    /// Retourne une description formatée du pays
    /// Format: "Pays [Intitulé] (ISO2: [Code], Devise: [Devise])"
    pub fn description(&self) -> SageResult<String> {
        let intitule = self.pa_intitule()?;
        let iso2 = self.pa_code_iso2()?;
        let devise = self.pa_devise().unwrap_or_else(|_| "N/A".to_string());

        Ok(format!(
            "Pays {} (ISO2: {}, Devise: {})",
            intitule, iso2, devise
        ))
    }

    /// Retourne les codes ISO complets
    /// Format: "ISO2: FR, ISO3: FRA, Num: 250"
    pub fn codes_iso(&self) -> SageResult<String> {
        let iso2 = self.pa_code_iso2()?;
        let iso3 = self.pa_code_iso3()?;
        let num = self.pa_code_numerique()?;

        Ok(format!("ISO2: {}, ISO3: {}, Num: {}", iso2, iso3, num))
    }

    /// Retourne l'appartenance UE
    pub fn zone(&self) -> SageResult<String> {
        let ue = self.pa_ue()?;
        Ok(if ue {
            "Union Européenne".to_string()
        } else {
            "Hors UE".to_string()
        })
    }
}

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

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

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

        // Utilisation typique :
        // let factory = app.factory_pays()?;
        // let pays = factory.read_intitule("France")?;
        //
        // println!("Pays: {}", pays.pa_intitule()?);
        // println!("Codes: {}", pays.codes_iso()?);
        // println!("Devise: {}", pays.pa_devise()?);
        // println!("Zone: {}", pays.zone()?);
        // println!("Préfixe: +{}", pays.pa_prefixe_tel()?);
        //
        // // Création d'un nouveau pays
        // let nouveau = factory.create()?;
        // nouveau.set_pa_intitule("Suisse")?;
        // nouveau.set_pa_code_iso2("CH")?;
        // nouveau.set_pa_code_iso3("CHE")?;
        // nouveau.set_pa_code_numerique(756)?;
        // nouveau.set_pa_ue(false)?;
        // nouveau.set_pa_devise("CHF")?;
        // nouveau.set_pa_prefixe_tel("41")?;
        // nouveau.write()?;
    }
}