1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
use crate::com::{FromDispatch, FromDispatchNew, SafeDispatch, SafeVariant};
use crate::errors::SageResult;
use windows::Win32::System::Com::IDispatch;
/// Wrapper pour l'objet Analytique de Sage 100c (IBOAnalytique3)
///
/// Représente une section analytique (axe d'analyse) permettant de ventiler
/// les écritures comptables selon différents critères (projets, services, etc.)
pub struct Analytique {
pub dispatch: IDispatch,
}
impl Analytique {
/// Crée un SafeDispatch temporaire pour les appels
fn dispatch(&self) -> SafeDispatch<'_> {
SafeDispatch::new(&self.dispatch)
}
// ==================== IDENTIFICATION ====================
/// Obtient le numéro de la section analytique
pub fn a_numero(&self) -> SageResult<String> {
self.dispatch()
.call_method_by_name("A_Numero", &[])?
.to_string()
}
/// Définit le numéro de la section analytique
pub fn set_a_numero(&self, value: &str) -> SageResult<()> {
let param = SafeVariant::from_string(value);
self.dispatch().call_property_put("A_Numero", &[param])?;
Ok(())
}
/// Obtient l'intitulé de la section analytique
pub fn a_intitule(&self) -> SageResult<String> {
self.dispatch()
.call_method_by_name("A_Intitule", &[])?
.to_string()
}
/// Définit l'intitulé de la section analytique
pub fn set_a_intitule(&self, value: &str) -> SageResult<()> {
let param = SafeVariant::from_string(value);
self.dispatch().call_property_put("A_Intitule", &[param])?;
Ok(())
}
// ==================== CLASSIFICATION ====================
/// Obtient le type de section analytique
/// 0 = Détail, 1 = Total
pub fn a_type(&self) -> SageResult<i32> {
self.dispatch().call_method_by_name("A_Type", &[])?.to_i32()
}
/// Définit le type de section analytique
/// 0 = Détail, 1 = Total
pub fn set_a_type(&self, value: i32) -> SageResult<()> {
let param = SafeVariant::from_i32(value);
self.dispatch().call_property_put("A_Type", &[param])?;
Ok(())
}
/// Obtient le niveau hiérarchique de la section (0-9)
pub fn a_niveau(&self) -> SageResult<i32> {
self.dispatch()
.call_method_by_name("A_Niveau", &[])?
.to_i32()
}
/// Définit le niveau hiérarchique de la section
pub fn set_a_niveau(&self, value: i32) -> SageResult<()> {
let param = SafeVariant::from_i32(value);
self.dispatch().call_property_put("A_Niveau", &[param])?;
Ok(())
}
// ==================== COMPTE DE RATTACHEMENT ====================
/// Obtient le compte général de rattachement
pub fn a_compte_rattachement(&self) -> SageResult<String> {
self.dispatch()
.call_method_by_name("A_CompteRattachement", &[])?
.to_string()
}
/// Définit le compte général de rattachement
pub fn set_a_compte_rattachement(&self, value: &str) -> SageResult<()> {
let param = SafeVariant::from_string(value);
self.dispatch()
.call_property_put("A_CompteRattachement", &[param])?;
Ok(())
}
// ==================== ÉTAT ====================
/// Indique si la section analytique est active
pub fn a_actif(&self) -> SageResult<bool> {
self.dispatch()
.call_method_by_name("A_Actif", &[])?
.to_bool()
}
/// Définit si la section analytique est active
pub fn set_a_actif(&self, value: bool) -> SageResult<()> {
let param = SafeVariant::from_bool(value);
self.dispatch().call_property_put("A_Actif", &[param])?;
Ok(())
}
// ==================== PLAN ANALYTIQUE ====================
/// Obtient le numéro du plan analytique (1-10)
pub fn a_plan(&self) -> SageResult<i32> {
self.dispatch().call_method_by_name("A_Plan", &[])?.to_i32()
}
/// Définit le numéro du plan analytique
pub fn set_a_plan(&self, value: i32) -> SageResult<()> {
let param = SafeVariant::from_i32(value);
self.dispatch().call_property_put("A_Plan", &[param])?;
Ok(())
}
// ==================== RUPTURE ET SAUT ====================
/// Obtient le niveau de rupture
pub fn a_rupture(&self) -> SageResult<i32> {
self.dispatch()
.call_method_by_name("A_Rupture", &[])?
.to_i32()
}
/// Définit le niveau de rupture
pub fn set_a_rupture(&self, value: i32) -> SageResult<()> {
let param = SafeVariant::from_i32(value);
self.dispatch().call_property_put("A_Rupture", &[param])?;
Ok(())
}
/// Obtient le saut de ligne pour l'impression
pub fn a_saut(&self) -> SageResult<i32> {
self.dispatch().call_method_by_name("A_Saut", &[])?.to_i32()
}
/// Définit le saut de ligne pour l'impression
pub fn set_a_saut(&self, value: i32) -> SageResult<()> {
let param = SafeVariant::from_i32(value);
self.dispatch().call_property_put("A_Saut", &[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 de la section analytique
/// Format: "Analytique [Numéro] - [Intitulé] (Type: [Type], Niveau: [Niveau])"
pub fn description(&self) -> SageResult<String> {
let numero = self.a_numero()?;
let intitule = self.a_intitule()?;
let type_val = self.a_type()?;
let niveau = self.a_niveau()?;
let type_str = match type_val {
0 => "Détail",
1 => "Total",
_ => "Inconnu",
};
Ok(format!(
"Analytique {} - {} (Type: {}, Niveau: {})",
numero, intitule, type_str, niveau
))
}
/// Retourne l'état de la section (Active/Inactive)
pub fn etat(&self) -> SageResult<String> {
let actif = self.a_actif()?;
Ok(if actif {
"Active".to_string()
} else {
"Inactive".to_string()
})
}
}
impl FromDispatch for Analytique {
fn from_dispatch(dispatch: IDispatch) -> SageResult<Self> {
Ok(Analytique { dispatch })
}
}
impl FromDispatchNew for Analytique {
fn from_dispatch_new(dispatch: IDispatch) -> SageResult<Self> {
Ok(Self { dispatch })
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_analytique_documentation() {
// Test de documentation - nécessite un environnement Sage pour s'exécuter
// Utilisation typique :
// let factory = app.factory_analytique()?;
// let section = factory.read_numero("PRJ001")?;
//
// println!("Section: {}", section.a_intitule()?);
// println!("Type: {}", section.a_type()?);
// println!("Niveau: {}", section.a_niveau()?);
// println!("Compte rattachement: {}", section.a_compte_rattachement()?);
// println!("État: {}", section.etat()?);
//
// // Création d'une nouvelle section
// let nouvelle = factory.create()?;
// nouvelle.set_a_numero("SRV001")?;
// nouvelle.set_a_intitule("Service Commercial")?;
// nouvelle.set_a_type(0)?; // Détail
// nouvelle.set_a_niveau(1)?;
// nouvelle.set_a_plan(1)?;
// nouvelle.set_a_actif(true)?;
// nouvelle.write()?;
}
}