sz_configtool_lib/
generic_plans.rs1use crate::error::{Result, SzConfigError};
7use crate::helpers;
8use serde_json::{Value, json};
9
10pub fn clone_generic_plan(
32 config_json: &str,
33 source_gplan_code: &str,
34 new_gplan_code: &str,
35 new_gplan_desc: Option<&str>,
36) -> Result<(String, i64)> {
37 let source_code = source_gplan_code.to_uppercase();
38 let new_code = new_gplan_code.to_uppercase();
39 let new_desc = new_gplan_desc.unwrap_or(&new_code);
40
41 let source_plan =
43 helpers::find_in_config_array(config_json, "CFG_GPLAN", "GPLAN_CODE", &source_code)?
44 .ok_or_else(|| {
45 SzConfigError::NotFound(format!("Source generic plan not found: {source_code}"))
46 })?;
47
48 let source_gplan_id = source_plan
49 .get("GPLAN_ID")
50 .and_then(|v| v.as_i64())
51 .ok_or_else(|| {
52 SzConfigError::InvalidConfig("Invalid GPLAN_ID in source plan".to_string())
53 })?;
54
55 if helpers::find_in_config_array(config_json, "CFG_GPLAN", "GPLAN_CODE", &new_code)?.is_some() {
57 return Err(SzConfigError::AlreadyExists(format!(
58 "Generic plan already exists: {new_code}"
59 )));
60 }
61
62 let config_data: Value = serde_json::from_str(config_json)?;
64 let max_gplan_id = config_data
65 .get("G2_CONFIG")
66 .and_then(|g| g.get("CFG_GPLAN"))
67 .and_then(|v| v.as_array())
68 .map(|arr| {
69 arr.iter()
70 .filter_map(|item| item.get("GPLAN_ID").and_then(|v| v.as_i64()))
71 .max()
72 .unwrap_or(0)
73 })
74 .unwrap_or(0);
75
76 let new_gplan_id = max_gplan_id + 1;
77
78 let new_plan = json!({
80 "GPLAN_ID": new_gplan_id,
81 "GPLAN_CODE": new_code,
82 "GPLAN_DESC": new_desc
83 });
84
85 let mut modified_json = helpers::add_to_config_array(config_json, "CFG_GPLAN", new_plan)?;
86
87 let config_data: Value = serde_json::from_str(&modified_json)?;
89 if let Some(gthresh_array) = config_data
90 .get("G2_CONFIG")
91 .and_then(|g| g.get("CFG_GENERIC_THRESHOLD"))
92 .and_then(|v| v.as_array())
93 {
94 let mut cloned_thresholds = Vec::new();
95 for item in gthresh_array {
96 if item.get("GPLAN_ID").and_then(|v| v.as_i64()) == Some(source_gplan_id) {
97 let mut cloned = item.clone();
98 if let Some(obj) = cloned.as_object_mut() {
99 obj.insert("GPLAN_ID".to_string(), json!(new_gplan_id));
100 }
101 cloned_thresholds.push(cloned);
102 }
103 }
104
105 for threshold in cloned_thresholds {
107 modified_json =
108 helpers::add_to_config_array(&modified_json, "CFG_GENERIC_THRESHOLD", threshold)?;
109 }
110 }
111
112 Ok((modified_json, new_gplan_id))
113}
114
115pub fn delete_generic_plan(config_json: &str, gplan_code: &str) -> Result<String> {
136 let gplan_code = gplan_code.to_uppercase();
137
138 let plan = helpers::find_in_config_array(config_json, "CFG_GPLAN", "GPLAN_CODE", &gplan_code)?
140 .ok_or_else(|| SzConfigError::NotFound(format!("Generic plan not found: {gplan_code}")))?;
141
142 let gplan_id = plan
143 .get("GPLAN_ID")
144 .and_then(|v| v.as_i64())
145 .ok_or_else(|| SzConfigError::InvalidConfig("Invalid GPLAN_ID".to_string()))?;
146
147 if gplan_id <= 2 {
149 return Err(SzConfigError::InvalidInput(format!(
150 "The {gplan_code} plan cannot be deleted"
151 )));
152 }
153
154 let mut config_data: Value = serde_json::from_str(config_json)?;
156
157 if let Some(g2_config) = config_data.get_mut("G2_CONFIG") {
159 if let Some(gplan_array) = g2_config
160 .get_mut("CFG_GPLAN")
161 .and_then(|v| v.as_array_mut())
162 {
163 gplan_array
164 .retain(|item| item.get("GPLAN_ID").and_then(|v| v.as_i64()) != Some(gplan_id));
165 }
166
167 if let Some(gthresh_array) = g2_config
169 .get_mut("CFG_GENERIC_THRESHOLD")
170 .and_then(|v| v.as_array_mut())
171 {
172 gthresh_array
173 .retain(|item| item.get("GPLAN_ID").and_then(|v| v.as_i64()) != Some(gplan_id));
174 }
175 }
176
177 Ok(serde_json::to_string(&config_data)?)
178}
179
180pub fn list_generic_plans(config_json: &str, filter: Option<&str>) -> Result<Vec<Value>> {
201 let items = helpers::list_from_config_array(config_json, "CFG_GPLAN")?;
203
204 let mut result: Vec<Value> = items
206 .into_iter()
207 .filter(|item| {
208 if let Some(f) = filter {
209 let item_str = item.to_string().to_lowercase();
211 item_str.contains(&f.to_lowercase())
212 } else {
213 true
214 }
215 })
216 .map(|item| {
217 json!({
218 "id": item.get("GPLAN_ID").and_then(|v| v.as_i64()).unwrap_or(0),
219 "plan": item.get("GPLAN_CODE").and_then(|v| v.as_str()).unwrap_or(""),
220 "description": item.get("GPLAN_DESC").and_then(|v| v.as_str()).unwrap_or("")
221 })
222 })
223 .collect();
224
225 result.sort_by_key(|item| item.get("id").and_then(|v| v.as_i64()).unwrap_or(0));
227
228 Ok(result)
229}
230
231pub fn set_generic_plan(
253 config_json: &str,
254 gplan_code: &str,
255 gplan_desc: &str,
256) -> Result<(String, i64, bool)> {
257 let code = gplan_code.to_uppercase();
258
259 if let Some(existing) =
261 helpers::find_in_config_array(config_json, "CFG_GPLAN", "GPLAN_CODE", &code)?
262 {
263 let plan_id = existing
265 .get("GPLAN_ID")
266 .and_then(|v| v.as_i64())
267 .unwrap_or(0);
268 let mut updated = existing.clone();
269 if let Some(obj) = updated.as_object_mut() {
270 obj.insert("GPLAN_DESC".to_string(), json!(gplan_desc));
271 }
272 let modified = helpers::update_in_config_array(
273 config_json,
274 "CFG_GPLAN",
275 "GPLAN_CODE",
276 &code,
277 updated,
278 )?;
279 Ok((modified, plan_id, false))
280 } else {
281 let config_data: Value = serde_json::from_str(config_json)?;
283 let max_id = config_data
284 .get("G2_CONFIG")
285 .and_then(|g| g.get("CFG_GPLAN"))
286 .and_then(|v| v.as_array())
287 .map(|arr| {
288 arr.iter()
289 .filter_map(|item| item.get("GPLAN_ID").and_then(|v| v.as_i64()))
290 .max()
291 .unwrap_or(0)
292 })
293 .unwrap_or(0);
294
295 let new_id = max_id + 1;
296 let new_plan = json!({
297 "GPLAN_ID": new_id,
298 "GPLAN_CODE": code,
299 "GPLAN_DESC": gplan_desc
300 });
301
302 let modified = helpers::add_to_config_array(config_json, "CFG_GPLAN", new_plan)?;
303 Ok((modified, new_id, true))
304 }
305}