sglab02_lib/web/
wk5t1.rs

1use crate::sg::{dcl, dcl::DaVa, /*ldp*/ ldp::base, uty::NumForm, wk5};
2use askama::Template;
3//use askama_axum;
4//use axum::extract::{Path, Query};
5use regex::Regex;
6use serde::{Deserialize, Serialize};
7use std::cmp::{/*Eq, Ord, PartialEq,*/ PartialOrd};
8//use std::collections::{HashMap, HashSet};
9use std::sync::Arc;
10//use thousands::Separable;
11use tokio::sync::RwLock;
12use tokio::sync::{OwnedRwLockReadGuard, /*RwLockReadGuard*/};
13
14#[derive(Template, Debug)]
15#[template(path = "pg2/wk5f.html", escape = "none")]
16pub struct ReportTemp {
17    pub title: String,
18    pub wk: OwnedRwLockReadGuard<wk5::Wk5Proc>,
19}
20
21fn rp(wk5prc: &wk5::Wk5Proc) -> &Report {
22    &wk5prc.wk5t1
23}
24fn sp(wk5prc: &mut wk5::Wk5Proc, rp: Report) {
25    wk5prc.wk5t1 = rp;
26}
27
28impl ReportTemp {
29    pub fn repo(&self) -> &Report {
30        &self.wk.wk5t1
31    }
32    async fn new(wk5prc: Arc<RwLock<wk5::Wk5Proc>>) -> Self {
33        let wk = wk5prc.read_owned().await;
34        let title = "ECONOMIC BENEFIT PROJECTION : WK5T";
35        let title = title.to_string();
36
37        ReportTemp { wk, title }
38    }
39    pub fn sum(&self, c: &usize) -> String {
40        if *c == 0 {
41            return format!("");
42        }
43        match rp(&self.wk).sums[*c] {
44            DaVa::F32(v) => v.form(),
45            DaVa::F64(v) => v.form(),
46            DaVa::USZ(v) => v.form(),
47            DaVa::I32(v) => v.form(),
48            DaVa::I64(v) => v.form(),
49            _ => format!(""),
50        }
51    }
52    pub fn cell(&self, r: &usize, c: &usize) -> String {
53        let mut ce = rp(&self.wk).dava(&self.wk.ssv, *r, *c);
54        if *c == 5 {
55            if let DaVa::F32(v) = ce {
56                let s = rp(&self.wk).rows[*r].s;
57                let f = rp(&self.wk).rows[*r].f;
58                let ss = &self.wk.ssv[s].ssid;
59                let fd = &self.wk.ssv[s].feeders[f].fdid;
60                ce = DaVa::Text(format!(
61                    "<a href='/feeder_yrpw01/{}/{}'>{}</a>",
62                    ss,
63                    fd,
64                    v.form()
65                ));
66            }
67        }
68        match ce {
69            DaVa::Text(s) => s,
70            DaVa::F32(f) => f.form(),
71            DaVa::F64(f) => f.form(),
72            DaVa::USZ(u) => format!("{}", u),
73            d => format!("{:?}", d),
74        }
75    }
76}
77
78#[derive(Serialize, Deserialize, Debug, Clone, Default)]
79pub struct Report {
80    pub rows: Vec<RepoRow1>,
81    pub cols: Vec<String>,
82    pub sums: Vec<DaVa>,
83}
84
85#[derive(Serialize, Deserialize, Debug, Clone, Default)]
86pub struct RepoRow1 {
87    pub s: usize, // substation
88    pub f: usize, // feeder
89}
90
91const TT: [&str; 4] = ["NO", "PROV", "FDID", "TOTAL"];
92
93pub async fn make_repo(wk5prc: &mut wk5::Wk5Proc, _acfg: Arc<RwLock<dcl::Config>>) {
94    let mut repo = rp(wk5prc).clone();
95
96    //let cfg = acfg.read().await;
97    for t in TT {
98        repo.cols.push(t.to_string());
99        repo.sums.push(DaVa::None);
100    }
101    let cfg = base().config.read().await;
102    let syf = cfg.criteria.start_year_from_2022;
103    let imy = cfg.criteria.implement_year;
104    let opy = cfg.criteria.operate_year;
105    let yrl = syf + imy + opy;
106    let yrl = yrl as usize;
107    for i in 0..yrl {
108        let yr = 2022 + i + 1;
109        repo.cols.push(format!("{}:B", yr));
110        repo.sums.push(DaVa::None);
111    }
112    //let re = Regex::new(r"[A-Z]{3}_[0-9][0-9][VY].*").unwrap();
113    //let re = Regex::new(r"[A-Z]{3}_[0-9][0-9][VY].*").unwrap();
114    let re = Regex::new(r"..._[0-9][0-9].+").unwrap();
115    for s in 0..wk5prc.ssv.len() {
116        for f in 0..wk5prc.ssv[s].feeders.len() {
117            let mut rw = RepoRow1::default();
118            rw.s = s;
119            rw.f = f;
120            let fd = &wk5prc.ssv[s].feeders[f];
121            if re.is_match(fd.fdid.as_str()) {
122                //if &fd.fdid[5..6] == "V" {
123                if fd.ev.ev_ds > 0.0 && fd.tx.tx_no > 0 {
124                    repo.rows.push(rw);
125                }
126            }
127        }
128    }
129    repo.rows.sort_by(|a, b| {
130        let a0 = &wk5prc.ssv[a.s].prov;
131        let a1 = &wk5prc.ssv[a.s].ssid;
132        let a2 = &wk5prc.ssv[a.s].feeders[a.f].fdid;
133        let b0 = &wk5prc.ssv[b.s].prov;
134        let b1 = &wk5prc.ssv[b.s].ssid;
135        let b2 = &wk5prc.ssv[b.s].feeders[b.f].fdid;
136		if a0!=b0 {
137			a0.partial_cmp(b0).unwrap()
138		} else {
139			if a1!=b1 {
140				a1.partial_cmp(b1).unwrap()
141			} else {
142				a2.partial_cmp(b2).unwrap()
143			}
144		}
145		/*
146        let a1 = &wk5prc.ssv[a.s].feeders[a.f].ev.ev_ds;
147        let b1 = &wk5prc.ssv[b.s].feeders[b.f].ev.ev_ds;
148        b1.partial_cmp(a1).unwrap()
149		*/
150    });
151
152    sum(&mut repo, &wk5prc.ssv);
153
154    sp(wk5prc, repo);
155}
156
157impl Report {
158    pub fn dava(&self, ssv: &Vec<wk5::Substation>, r: usize, c: usize) -> dcl::DaVa {
159        let s = self.rows[r].s;
160        let f = self.rows[r].f;
161        let ss = &ssv[s];
162        let fd = &ssv[s].feeders[f];
163        match c {
164            0 => DaVa::USZ(r + 1),
165            1 => DaVa::Text(ss.prov.to_string()),
166            2 => DaVa::Text(fd.fdid5.to_string()),
167            3 => DaVa::F32(fd.economic_benefit),
168            // ========
169            n => DaVa::F32(fd.economic_benefit_series[n - 4]),
170        }
171    }
172}
173
174pub async fn handler() -> ReportTemp {
175    ReportTemp::new(base().wk5prc.clone()).await
176}
177
178fn sum(repo: &mut Report, ssv: &Vec<wk5::Substation>) {
179    if repo.rows.len() > 0 {
180        repo.sums[0] = DaVa::None;
181        for ci in 1..repo.cols.len() {
182            repo.sums[ci] = match repo.dava(ssv, 0, ci) {
183                DaVa::F32(_) => DaVa::F32(0.0),
184                DaVa::F64(_) => DaVa::F64(0.0),
185                DaVa::I32(_) => DaVa::I32(0),
186                DaVa::I64(_) => DaVa::I64(0),
187                DaVa::USZ(_) => DaVa::USZ(0),
188                _ => DaVa::None,
189            };
190        }
191        //let mut txno = 0;
192        for (ri, _rr) in repo.rows.iter().enumerate() {
193            if let DaVa::USZ(_v) = repo.dava(ssv, ri, 5) {
194                //txno += v;
195            }
196
197            for ci in 0..repo.cols.len() {
198                repo.sums[ci] = match repo.dava(ssv, ri, ci) {
199                    DaVa::F32(v1) => {
200                        if let DaVa::F32(v2) = repo.sums[ci] {
201                            DaVa::F32(v1 + v2)
202                        } else {
203                            DaVa::F32(0.0)
204                        }
205                    }
206                    DaVa::F64(v1) => {
207                        if let DaVa::F64(v2) = repo.sums[ci] {
208                            DaVa::F64(v1 + v2)
209                        } else {
210                            DaVa::F64(0.0)
211                        }
212                    }
213                    DaVa::I32(v1) => {
214                        if let DaVa::I32(v2) = repo.sums[ci] {
215                            DaVa::I32(v1 + v2)
216                        } else {
217                            DaVa::I32(0)
218                        }
219                    }
220                    DaVa::I64(v1) => {
221                        if let DaVa::I64(v2) = repo.sums[ci] {
222                            DaVa::I64(v1 + v2)
223                        } else {
224                            DaVa::I64(0)
225                        }
226                    }
227                    DaVa::USZ(v1) => {
228                        if let DaVa::USZ(v2) = repo.sums[ci] {
229                            DaVa::USZ(v1 + v2)
230                        } else {
231                            DaVa::USZ(0)
232                        }
233                    }
234                    _ => DaVa::None,
235                };
236            }
237        }
238    }
239}