advotracker-client: more twine adaptions

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2021-03-22 23:50:15 +01:00
parent dd5d361116
commit 9ed395d04b
9 changed files with 677 additions and 678 deletions

View File

@@ -39,7 +39,8 @@ viperus = { git = "https://github.com/maurocordioli/viperus", features = ["cach
[build-dependencies] [build-dependencies]
winres = { version = "0.1.11" } winres = { version = "0.1.11" }
twine = { version = "~0.3.8", features = ["serde"] } #twine = { version = "0.3.8" }
twine = { path = "../../../twine", features = ["serde"] }
[features] [features]
default = [] default = []

View File

@@ -7,11 +7,11 @@
extern crate winres; extern crate winres;
use twine; use twine::build_translations;
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
twine::build_translations(&["./src/i18n/localization.ini"], "i18n.rs").unwrap(); build_translations(&["./src/i18n/localization.ini"], "i18n.rs").unwrap();
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
let mut res = winres::WindowsResource::new(); let mut res = winres::WindowsResource::new();

View File

@@ -26,6 +26,9 @@
//! WIP: provide a workflow image //! WIP: provide a workflow image
//! //!
// i18n: get the macro (t!) accessing translated strings
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));
// /// The client specific services // /// The client specific services
// pub mod clients; // pub mod clients;

View File

@@ -16,7 +16,6 @@ use std::env;
//use std::process; //use std::process;
use substring::Substring; use substring::Substring;
use tracing::{info, trace, Level}; use tracing::{info, trace, Level};
use twine::t;
use orbtk::{ use orbtk::{
prelude::*, prelude::*,
@@ -30,6 +29,9 @@ use orbtk::theme_fluent::{THEME_FLUENT, THEME_FLUENT_COLORS_DARK, THEME_FLUENT_F
// The Main view // The Main view
use advotracker_client::widgets::main_view; use advotracker_client::widgets::main_view;
// get the macro (t!) accessing the internationalization strings
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));
mod parse_args; mod parse_args;
/// define valid environment variables provided via .env files /// define valid environment variables provided via .env files
@@ -37,7 +39,7 @@ mod parse_args;
/// this is primarily used in testing scenarios (eg. debugging) /// this is primarily used in testing scenarios (eg. debugging)
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct Environment { struct Environment {
lang: String, lang: Lang,
test_lang: String, test_lang: String,
rust_log: String, rust_log: String,
} }
@@ -46,8 +48,8 @@ struct Environment {
static DEFAULT_DARK_EXT: &str = include_str!("../assets/advotracker/default_dark.ron"); static DEFAULT_DARK_EXT: &str = include_str!("../assets/advotracker/default_dark.ron");
cfg_if! { cfg_if! {
if #[cfg(windows)] { if #[cfg(windows)] {
static FLUENT_DARK_EXT: &str = include_str!("../assets/advotracker/fluent_dark.ron"); static FLUENT_DARK_EXT: &str = include_str!("../assets/advotracker/fluent_dark.ron");
static FLUENT_LIGHT_EXT: &str = include_str!("../assets/advotracker/fluent_light.ron"); static FLUENT_LIGHT_EXT: &str = include_str!("../assets/advotracker/fluent_light.ron");
} }
} }
@@ -64,10 +66,10 @@ fn get_lang() -> String {
// testing environment: read from .env file // testing environment: read from .env file
dotenv().ok(); dotenv().ok();
match envy::from_env::<Environment>() { match envy::from_env::<Environment>() {
Ok(environment) => { Ok(environment) => {
if environment.test_lang != lang { lang = environment.test_lang; } if environment.test_lang != lang { lang = environment.test_lang; }
}, },
Err(e) => { info!(target: "advotracker", "{}", e) } Err(e) => { info!(target: "advotracker", "{}", e) }
} }
trace!(target: "advotracker", lang = ?lang); trace!(target: "advotracker", lang = ?lang);
@@ -77,38 +79,38 @@ fn get_lang() -> String {
cfg_if! { cfg_if! {
if #[cfg(windows)] { if #[cfg(windows)] {
/// Extend and register theme assets. /// Extend and register theme assets.
fn theme() -> Theme { fn theme() -> Theme {
register_default_fonts(Theme::from_config( register_default_fonts(Theme::from_config(
ThemeConfig::from(DEFAULT_DARK_EXT) ThemeConfig::from(DEFAULT_DARK_EXT)
.extend(ThemeConfig::from(THEME_DEFAULT)) .extend(ThemeConfig::from(THEME_DEFAULT))
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK)) .extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)), .extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
)) ))
} }
fn theme_fluent() -> Theme { fn theme_fluent() -> Theme {
register_fluent_fonts(Theme::from_config( register_fluent_fonts(Theme::from_config(
ThemeConfig::from(FLUENT_DARK_EXT) ThemeConfig::from(FLUENT_DARK_EXT)
.extend(ThemeConfig::from(THEME_FLUENT)) .extend(ThemeConfig::from(THEME_FLUENT))
.extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK)) .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_FLUENT_FONTS)), .extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
)) ))
// register_fluent_fonts(Theme::from_config( // register_fluent_fonts(Theme::from_config(
// ThemeConfig::from(FLUENT_LIGHT_EXT) // ThemeConfig::from(FLUENT_LIGHT_EXT)
// .extend(ThemeConfig::from(THEME_FLUENT)) // .extend(ThemeConfig::from(THEME_FLUENT))
// .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK)) // .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
// .extend(ThemeConfig::from(THEME_FLUENT_FONTS)), // .extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
} }
} else { } else {
/// Extend and register theme assets. /// Extend and register theme assets.
fn theme() -> Theme { fn theme() -> Theme {
register_default_fonts(Theme::from_config( register_default_fonts(Theme::from_config(
ThemeConfig::from(DEFAULT_DARK_EXT) ThemeConfig::from(DEFAULT_DARK_EXT)
.extend(ThemeConfig::from(THEME_DEFAULT)) .extend(ThemeConfig::from(THEME_DEFAULT))
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK)) .extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)), .extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
)) ))
} }
} }
} }
@@ -118,11 +120,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
use viperus::Viperus; use viperus::Viperus;
let machine_kind = if cfg!(unix) { let machine_kind = if cfg!(unix) {
"unix" "unix"
} else if cfg!(windows) { } else if cfg!(windows) {
"windows" "windows"
} else { } else {
"unknown/unsupported" "unknown/unsupported"
}; };
// respect dotenv environment (e.g for testing) // respect dotenv environment (e.g for testing)
@@ -134,81 +136,79 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// reference: https://tokio.rs/blog/2019-08-tracing/ // reference: https://tokio.rs/blog/2019-08-tracing/
let span = tracing::span!(Level::TRACE, "advotracker"); let span = tracing::span!(Level::TRACE, "advotracker");
let _enter = span.enter(); let _enter = span.enter();
let subscriber = fmt::Subscriber::builder() let collector = fmt::Subscriber::builder()
.with_env_filter(&rust_log) .with_env_filter(&rust_log)
//.with_max_level(tracing::Level::DEBUG) //.with_max_level(tracing::Level::DEBUG)
.finish(); .finish();
tracing::subscriber::with_default(subscriber, || { tracing::subscriber::with_default(collector, || {
// get system environment // get system environment
let lang = get_lang(); //let lang = get_lang();
let lang = Lang::De("de");
// include localization strings let mut state = t!(state_started => lang);
include!(concat!(env!("OUTDIR"), "/i18n.rs")); let mut res = t!(parse_environment => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
trace!(target: "advotracker", environment = "system", lang = ?lang);
trace!(target: "advotracker", machine = ?&machine_kind);
let mut state = t!(state_started => lang); // how to handle unimplemented lang resources??
let mut res = t!(parse_environment => lang); res = t!(parse_environment => lang);
trace!(target: "advotracker", process = ?res, state = ?state); trace!(target: "advotracker", environment = "envy", lang = ?lang);
trace!(target: "advotracker", environment = "system", lang = ?lang); state = t!(state_finished => lang);
trace!(target: "advotracker", machine = ?&machine_kind); trace!(target: "advotracker", process = ?res, state = ?state);
// how to handle unimplemented lang resources?? // initialize viperus structure
res = t!(parse_environment => lang); let mut viperus = Viperus::new();
trace!(target: "advotracker", environment = "envy", lang = ?lang);
state = t!(state_finished => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// initialize viperus structure // parse commandline arguments
let mut viperus = Viperus::new(); res = t!(parse_arguments => lang);
state = t!(state_started => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// parse commandline arguments let _ = parse_args(&mut viperus);
res = t!(parse_arguments => lang); state = t!(state_finished => lang);
state = t!(state_started => lang); trace!(target: "advotracker", process = ?res, state = ?state);
trace!(target: "advotracker", process = ?res, state = ?state);
let _ = parse_args(&mut viperus); // type conversion (viperus String -> u64)
state = t!(state_finished => lang); let test_policy_number = viperus.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap();
trace!(target: "advotracker", process = ?res, state = ?state); trace!(target: "advotracker", test_policy_number = ?test_policy_number);
// type conversion (viperus String -> u64) // main tasks
let test_policy_number = viperus.get::<String>("test_policy_number").unwrap().parse::<u64>().unwrap(); res = t!(main_started => lang);
trace!(target: "advotracker", test_policy_number = ?test_policy_number); state = t!(state_started => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// main tasks // use this only if you want to run it as web application.
res = t!(main_started => lang); orbtk::initialize();
state = t!(state_started => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
// use this only if you want to run it as web application. // Preset localization and language from given environment.
orbtk::initialize(); // if no dictionary is set for the chosen default language
// the content of the text property will be drawn.
let localization = RonLocalization::create()
.language("de")
.dictionary("de_DE", ADVOTRACKER_DE_DE)
.build();
// Preset localization and language from given environment. Application::from_name("nwx.advotracker")
// if no dictionary is set for the chosen default language .localization(localization)
// the content of the text property will be drawn. .theme(theme())
let localization = RonLocalization::create() .window(|ctx| {
.language(&lang) Window::new()
.dictionary("de_DE", ADVOTRACKER_DE_DE) .title("AdvoTracker - DirectCall")
.build(); .position((500.0, 100.0))
.size(800.0, 620.0)
//.min_width(460.0)
//.min_height(380.0)
.resizeable(true)
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
Application::from_name("nwx.advotracker") state = t!(state_finished => lang);
.localization(localization) res = t!(main_finished => lang);
.theme(theme()) trace!(target: "advotracker", process = ?res, state = ?state);
.window(|ctx| {
Window::new()
.title("AdvoTracker - DirectCall")
.position((500.0, 100.0))
.size(800.0, 620.0)
//.min_width(460.0)
//.min_height(380.0)
.resizeable(true)
.child(main_view::MainView::new().build(ctx))
.build(ctx)
})
.run();
state = t!(state_finished => lang);
res = t!(main_finished => lang);
trace!(target: "advotracker", process = ?res, state = ?state);
}); });
Ok(()) Ok(())
@@ -218,6 +218,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
mod tests { mod tests {
#[test] #[test]
fn it_works() { fn it_works() {
assert_eq!(2 + 2, 4); assert_eq!(2 + 2, 4);
} }
} }

View File

@@ -6,21 +6,19 @@
*/ */
//use chrono::{Local, DateTime}; //use chrono::{Local, DateTime};
use locales::t;
use std::error::Error; use std::error::Error;
use tracing::trace; use tracing::trace;
use crate::Lang;
/// export as csv format /// export as csv format
/// https://docs.rs/csv/1.1.3/csv/cookbook/index.html /// https://docs.rs/csv/1.1.3/csv/cookbook/index.html
/// https://blog.burntsushi.net/csv/ /// https://blog.burntsushi.net/csv/
pub fn export(p: &mut String, lang: &str) -> Result<(), Box<dyn Error>> { pub fn export(p: &mut String, lang: &Lang) -> Result<(), Box<dyn Error>> {
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
//use std::ffi::OsStr; //use std::ffi::OsStr;
// include localization strings
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));
let mut res = t!(csv_export_started => lang); let mut res = t!(csv_export_started => lang);
let mut state = t!(state_started => lang); let mut state = t!(state_started => lang);
trace!(target: "csv-export", process = ?res, state = ?state); trace!(target: "csv-export", process = ?res, state = ?state);
@@ -33,7 +31,7 @@ pub fn export(p: &mut String, lang: &str) -> Result<(), Box<dyn Error>> {
trace!(target: "csv.export", extension = ?path.extension(), file = ?file); trace!(target: "csv.export", extension = ?path.extension(), file = ?file);
state = t!(state_finished => lang); state = t!(state_finished => lang);
res = t!(csv_export_finished", lang); res = t!(csv_export_finished => lang);
trace!(target: "csv-export", process = ?res, state = ?state); trace!(target: "csv-export", process = ?res, state = ?state);
Ok(()) Ok(())

View File

@@ -10,19 +10,18 @@ use lettre::{
Message, SmtpTransport, Transport, Message, SmtpTransport, Transport,
transport::smtp::authentication::Credentials, transport::smtp::authentication::Credentials,
}; };
use locales::t;
use maud::html; use maud::html;
use std::error::Error; use std::error::Error;
//use std::process; //use std::process;
use tracing::{info, trace}; use tracing::{info, trace};
use crate::data::structures::Email; use crate::{
data::structures::Email,
Lang,
};
/// send ticket data via eMail /// send ticket data via eMail
pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> { pub fn sendticketdata(email: &Email, lang: &Lang) -> Result<(), Box<dyn Error>> {
// include localization strings
include!(concat!(env!("OUT_DIR"), "/i18n.rs"));
let mut res = t!(sendticketdata_export_started => lang); let mut res = t!(sendticketdata_export_started => lang);
let mut state = t!(state_started =>lang); let mut state = t!(state_started =>lang);
trace!(target: "sendticketdata", process = ?res, state = ?state); trace!(target: "sendticketdata", process = ?res, state = ?state);
@@ -30,67 +29,67 @@ pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
// The html we want to send. // The html we want to send.
// It uses https://crates.io/crates/maud // It uses https://crates.io/crates/maud
let html = html! { let html = html! {
head { head {
title { (email.subject) " (" (email.policy_code) ")" } title { (email.subject) " (" (email.policy_code) ")" }
style type="text/css" { style type="text/css" {
"h2, h4 { font-family: Arial, Helvetica, sans-serif; }" "h2, h4 { font-family: Arial, Helvetica, sans-serif; }"
} }
} }
div style="display: flex; flex-direction: column; align-items: left;" { div style="display: flex; flex-direction: column; align-items: left;" {
// compose with variables and strings // compose with variables and strings
h2 { (email.subject) " (" (email.policy_code) ")" } h2 { (email.subject) " (" (email.policy_code) ")" }
p { "Vers.-Schein/Schadennummer: " (email.policy_code) } p { "Vers.-Schein/Schadennummer: " (email.policy_code) }
p { "Versicherungsnehmer: " (email.policy_holder) } p { "Versicherungsnehmer: " (email.policy_holder) }
p { "Selbstbehalt: " (email.deductible) } p { "Selbstbehalt: " (email.deductible) }
p { "Rückrufnummer: " (email.callback_number) } p { "Rückrufnummer: " (email.callback_number) }
p { "Erreichbarkeit: " (email.callback_date) } p { "Erreichbarkeit: " (email.callback_date) }
p { "Rechtsproblem: " (email.harm_type) } p { "Rechtsproblem: " (email.harm_type) }
p { "Rechtsrat: " (email.ivr_comment) } p { "Rechtsrat: " (email.ivr_comment) }
} }
}; };
let ascii_body = String::new() let ascii_body = String::new()
+ &"Vers.-Schein/Schadennummer".to_string() + &(email.policy_code) + &"\n" + &"Vers.-Schein/Schadennummer".to_string() + &(email.policy_code) + &"\n"
+ &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n" + &"Versicherungsnehmer: ".to_string() + &(email.policy_holder) + &"\n"
+ &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n" + &"Selbstbehalt: ".to_string() + &(email.deductible) + &"\n"
+ &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n" + &"Rückrufnummer: ".to_string()+ &(email.callback_number) + &"\n"
+ &"Erreichbarkeit: ".to_string() + &(email.callback_date) + &"\n" + &"Erreichbarkeit: ".to_string() + &(email.callback_date) + &"\n"
+ &"Rechtsproblem: ".to_string() + &(email.harm_type) + &"\n" + &"Rechtsproblem: ".to_string() + &(email.harm_type) + &"\n"
+ &"Rechtsrat: ".to_string() + &(email.ivr_comment) + &"\n"; + &"Rechtsrat: ".to_string() + &(email.ivr_comment) + &"\n";
info!("email body: {:?}", ascii_body); info!("email body: {:?}", ascii_body);
let message = Message::builder() let message = Message::builder()
.from((email.mail_from).parse().unwrap()) .from((email.mail_from).parse().unwrap())
.reply_to((email.mail_reply).parse().unwrap()) .reply_to((email.mail_reply).parse().unwrap())
.to((email.mail_to).parse().unwrap()) .to((email.mail_to).parse().unwrap())
.cc((email.mail_cc).parse().unwrap()) .cc((email.mail_cc).parse().unwrap())
// we do not use bcc yet // we do not use bcc yet
//.bcc((email.mail_bcc).parse().unwrap()) //.bcc((email.mail_bcc).parse().unwrap())
.subject(String::new() .subject(String::new()
+ &email.subject.to_string() + &email.subject.to_string()
+ &" (".to_string() + &" (".to_string()
+ &email.policy_code.to_string() + &email.policy_code.to_string()
+ &")".to_string() + &")".to_string()
) )
.multipart( .multipart(
MultiPart::alternative() // This is composed of two parts. MultiPart::alternative() // This is composed of two parts.
.singlepart( .singlepart(
SinglePart::builder() SinglePart::builder()
.header(header::ContentType( .header(header::ContentType(
"text/plain; charset=utf8".parse().unwrap(), "text/plain; charset=utf8".parse().unwrap(),
)) ))
.body(String::from(ascii_body)), .body(String::from(ascii_body)),
) )
.singlepart( .singlepart(
SinglePart::builder() SinglePart::builder()
.header(header::ContentType( .header(header::ContentType(
"text/html; charset=utf8".parse().unwrap(), "text/html; charset=utf8".parse().unwrap(),
)) ))
.body(html.into_string()), .body(html.into_string()),
), ),
) )
.expect("failed to build email"); .expect("failed to build email");
info!("message: {:?}", message); info!("message: {:?}", message);
@@ -108,9 +107,9 @@ pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
let relay = "smtp.strato.de"; let relay = "smtp.strato.de";
let mailer = SmtpTransport::relay(relay) let mailer = SmtpTransport::relay(relay)
.unwrap() .unwrap()
.credentials(credentials) .credentials(credentials)
.build(); .build();
trace!(target: "sendticketdata", email = ?email); trace!(target: "sendticketdata", email = ?email);

View File

@@ -6,34 +6,32 @@
*/ */
use chrono::{Local, DateTime}; use chrono::{Local, DateTime};
use locales::t;
use std::error::Error; use std::error::Error;
use std::collections::HashMap; use std::collections::HashMap;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use tracing::trace; use tracing::trace;
//use crate::db::redis; //use crate::db::redis;
use crate::data::structures::{PolicyCode, PolicyDataList, PolicyData}; use crate::{
//use crate::data::structures::PolicyDataList; data::structures::{PolicyCode, PolicyDataList, PolicyData},
Lang,
};
/// import AllianzDirectCall data from a csv delimeted file /// import AllianzDirectCall data from a csv delimeted file
/// save records to redis backend /// save records to redis backend
/// https://docs.rs/csv/1.1.3/csv/cookbook/index.html /// https://docs.rs/csv/1.1.3/csv/cookbook/index.html
/// https://blog.burntsushi.net/csv/ /// https://blog.burntsushi.net/csv/
pub fn import(p: &mut String, data_list: &mut PolicyDataList, pub fn import(p: &mut String, data_list: &mut PolicyDataList,
policy_numbers: &mut HashMap<u64, PolicyCode>, policy_numbers: &mut HashMap<u64, PolicyCode>,
policy_data_count: &mut u64, policy_data_count: &mut u64)
lang: &str) -> Result<(u64, Duration), Box<dyn Error>> {
-> Result<(u64, Duration), Box<dyn Error>> {
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use std::ffi::OsStr; use std::ffi::OsStr;
// include localization strings let lang = Lang::De("");
include!(concat!(env!("OUT_DIR"), "/i18n.rs")); let mut res = t!(csv_import_started => lang);
let mut state = t!(state_started => lang);
let mut res = t!("csv.import.started", lang);
let mut state = t!("state.started", lang);
let time_start = SystemTime::now(); let time_start = SystemTime::now();
let datetime: DateTime<Local> = time_start.into(); let datetime: DateTime<Local> = time_start.into();
@@ -56,45 +54,45 @@ pub fn import(p: &mut String, data_list: &mut PolicyDataList,
// Build the CSV reader // Build the CSV reader
let mut csv_reader = csv::ReaderBuilder::new() let mut csv_reader = csv::ReaderBuilder::new()
.has_headers(true) .has_headers(true)
.delimiter(b' ') .delimiter(b' ')
//.comment(Some(b'#')) //.comment(Some(b'#'))
//.flexible(true) //.flexible(true)
.from_reader(file); .from_reader(file);
{ {
// We nest this call in its own scope because of lifetimes. // We nest this call in its own scope because of lifetimes.
let headers = csv_reader.headers()?; let headers = csv_reader.headers()?;
trace!(target: "csv-import", header = ?headers); trace!(target: "csv-import", header = ?headers);
} }
// Iterate over each record, deserialize und write to our structures // Iterate over each record, deserialize und write to our structures
let mut count : u64 = 0; let mut count : u64 = 0;
for result in csv_reader.deserialize() { for result in csv_reader.deserialize() {
// The iterator yields Result<StringRecord, Error>, so we check the // The iterator yields Result<StringRecord, Error>, so we check the
// error here. // error here.
let record: PolicyData = result?; let record: PolicyData = result?;
//if verbose > 3 { //if verbose > 3 {
// println!("{:?}", record); // println!("{:?}", record);
//} //}
// WIP: write to redis backend // WIP: write to redis backend
// for now: append the policy_number to the HashMap // for now: append the policy_number to the HashMap
policy_numbers.insert(record.policy_number, record.policy_code); policy_numbers.insert(record.policy_number, record.policy_code);
// push record as new vector elements // push record as new vector elements
data_list.push(record); data_list.push(record);
count +=1; count +=1;
*policy_data_count = count; *policy_data_count = count;
}; };
let time_end = SystemTime::now(); let time_end = SystemTime::now();
let duration = time_end.duration_since(time_start) let duration = time_end.duration_since(time_start)
.expect("Clock may have gone backwards"); .expect("Clock may have gone backwards");
trace!(target: "csv-import", record_count = ?count, duration = ?duration); trace!(target: "csv-import", record_count = ?count, duration = ?duration);
state = t!("state.finished", lang); state = t!(state_finished => lang);
res = t!("csv.import.finished", lang); res = t!(csv_import_finished => lang);
let datetime: DateTime<Local> = time_end.into(); let datetime: DateTime<Local> = time_end.into();
trace!(target: "csv-import", process = ?res, state = ?state, date_stop = ?datetime.to_string()); trace!(target: "csv-import", process = ?res, state = ?state, date_stop = ?datetime.to_string());
@@ -114,23 +112,23 @@ fn test_import() {
let lang = "en".to_string(); let lang = "en".to_string();
match import(&mut csv_import_path, &mut policy_data, match import(&mut csv_import_path, &mut policy_data,
&mut policy_numbers, &mut policy_data_count, &mut policy_numbers, &mut policy_data_count,
&lang) { &lang) {
Ok((count, duration)) => { Ok((count, duration)) => {
println!("import {:?} records. Duration: {:?}", count, duration); println!("import {:?} records. Duration: {:?}", count, duration);
} }
Err(err) => { Err(err) => {
println!("error running CSV-Import: {}", err); println!("error running CSV-Import: {}", err);
} }
}; };
for p in &my_policy_numbers { for p in &my_policy_numbers {
match policy_numbers.get(&p) { match policy_numbers.get(&p) {
Some(policy_code) => { Some(policy_code) => {
println!("Test: Policy-Number {:?} => Policy-Type {:?}, as expected!", println!("Test: Policy-Number {:?} => Policy-Type {:?}, as expected!",
p, policy_code); p, policy_code);
}, },
_ => println!("Test: Policy-Number {:?} => not valid, can't dereference the Policy-Type as expected", p), _ => println!("Test: Policy-Number {:?} => not valid, can't dereference the Policy-Type as expected", p),
} }
} }
} }

View File

@@ -20,6 +20,7 @@ use crate::{
services::exports::send_ticketdata::sendticketdata, services::exports::send_ticketdata::sendticketdata,
widgets::ticketdata::ticketdata_view::TicketdataView, widgets::ticketdata::ticketdata_view::TicketdataView,
//widgets::policycheck::policycheck_state::PolicycheckAction, //widgets::policycheck::policycheck_state::PolicycheckAction,
Lang,
}; };
/// Valid `actions` that are handled as state changes in the `Ticketdata` widget. /// Valid `actions` that are handled as state changes in the `Ticketdata` widget.
@@ -47,7 +48,7 @@ struct Environment {
pub struct TicketdataState { pub struct TicketdataState {
actions: Vec<TicketdataAction>, actions: Vec<TicketdataAction>,
button_menu: Entity, button_menu: Entity,
lang: String, lang: Lang,
target: Entity target: Entity
} }
@@ -113,7 +114,7 @@ impl TicketdataState {
} }
} }
pub fn send_form(entity: Entity, ctx: &mut Context<'_>, lang: &str) { pub fn send_form(entity: Entity, ctx: &mut Context<'_>, _lang: Lang) {
info!("TicketdataState: processing entity[{:?}]", entity); info!("TicketdataState: processing entity[{:?}]", entity);
let mail_to_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize; let mail_to_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize;
@@ -139,6 +140,7 @@ impl TicketdataState {
trace!("eMail fields: {:?}", email); trace!("eMail fields: {:?}", email);
// send email via service // send email via service
let lang = Lang::De("");
if let Err(err) = sendticketdata(&email, &lang) { if let Err(err) = sendticketdata(&email, &lang) {
error!("sendticketdata error: {:?}", err); error!("sendticketdata error: {:?}", err);
Button::icon_brush_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_SEND), String::from("#008000")); Button::icon_brush_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_SEND), String::from("#008000"));
@@ -178,7 +180,8 @@ impl State for TicketdataState {
.expect("TicketState.init: Can't find resource entity 'target'.")); .expect("TicketState.init: Can't find resource entity 'target'."));
// Get language from environment // Get language from environment
self.lang = TicketdataState::get_lang(); //self.lang = TicketdataState::get_lang();
//let self.lang = Lang::De("");
Stack::visibility_set(&mut ctx.child(ID_TICKET_DATA_ACTION_STACK), Visibility::Collapsed); Stack::visibility_set(&mut ctx.child(ID_TICKET_DATA_ACTION_STACK), Visibility::Collapsed);
Button::icon_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_CLEAR), material_icons_font::MD_CLEAR); Button::icon_set(&mut ctx.child(ID_TICKET_DATA_ACTION_BUTTON_CLEAR), material_icons_font::MD_CLEAR);
@@ -203,7 +206,7 @@ impl State for TicketdataState {
TicketdataState::clear_form(ctx.entity(), &id, ctx); TicketdataState::clear_form(ctx.entity(), &id, ctx);
} }
TicketdataAction::SendForm() => { TicketdataAction::SendForm() => {
TicketdataState::send_form(ctx.entity(), ctx, &self.lang); TicketdataState::send_form(ctx.entity(), ctx, self.lang);
} }
TicketdataAction::UpdatePolicyCode(id) => { TicketdataAction::UpdatePolicyCode(id) => {
TicketdataState::update_policy_code(ctx.entity(), &id, ctx); TicketdataState::update_policy_code(ctx.entity(), &id, ctx);