848 lines
32 KiB
Rust
848 lines
32 KiB
Rust
/*
|
|
* advotracker - Hotline tackingtool for Advocats
|
|
*
|
|
* Copyright 2021 Ralf Zerres <ralf.zerres@networkx.de>
|
|
* SPDX-License-Identifier: (0BSD or MIT)
|
|
*/
|
|
|
|
// suppress creation of a new console window on window
|
|
#![windows_subsystem = "windows"]
|
|
|
|
use cfg_if::cfg_if;
|
|
use locales::t;
|
|
use orbtk::{
|
|
prelude::*,
|
|
theme_default::{THEME_DEFAULT, THEME_DEFAULT_COLORS_DARK, THEME_DEFAULT_FONTS},
|
|
theming::config::ThemeConfig,
|
|
};
|
|
use serde::Deserialize;
|
|
use std::env;
|
|
use std::time::SystemTime;
|
|
use tracing::{info, trace, Level};
|
|
|
|
use advotracker::{
|
|
data::{constants::*, structures::Email},
|
|
widgets::global_state::GlobalState,
|
|
widgets::main_view,
|
|
//services::exports::send_ticketdata::sendticketdata,
|
|
widgets::policycheck::*,
|
|
widgets::policycheck_state::*,
|
|
widgets::ticketdata::*,
|
|
};
|
|
|
|
#[cfg(target_os = "windows")]
|
|
use orbtk::theme_fluent::{THEME_FLUENT, THEME_FLUENT_COLORS_DARK, THEME_FLUENT_FONTS};
|
|
|
|
pub enum TicketdataAction {
|
|
ClearForm(),
|
|
SendForm(),
|
|
UpdatePolicyCode(String),
|
|
}
|
|
|
|
// German localization file.
|
|
static ADVOTRACKER_DE_DE: &str = include_str!("../assets/advotracker/advotracker_de_DE.ron");
|
|
|
|
/// Get the active language environment.
|
|
fn get_lang() -> String {
|
|
// get system environment
|
|
let mut lang = env::var("LANG").unwrap_or_else(|_| "C".to_string());
|
|
lang = lang.substring(0, 5).to_string(); // "de_DE.UTF-8" -> "de_DE"
|
|
info!("GUI-Language: preset to {:?}", lang);
|
|
|
|
// return the active language
|
|
lang
|
|
}
|
|
|
|
cfg_if! {
|
|
if #[cfg(windows)] {
|
|
/// Extend and register theme assets.
|
|
fn theme() -> Theme {
|
|
register_default_fonts(Theme::from_config(
|
|
ThemeConfig::from(DEFAULT_DARK_EXT)
|
|
.extend(ThemeConfig::from(THEME_DEFAULT))
|
|
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
|
|
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
|
|
))
|
|
}
|
|
fn theme_fluent() -> Theme {
|
|
register_fluent_fonts(Theme::from_config(
|
|
ThemeConfig::from(FLUENT_DARK_EXT)
|
|
.extend(ThemeConfig::from(THEME_FLUENT))
|
|
.extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
|
|
.extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
|
|
))
|
|
// register_fluent_fonts(Theme::from_config(
|
|
// ThemeConfig::from(FLUENT_LIGHT_EXT)
|
|
// .extend(ThemeConfig::from(THEME_FLUENT))
|
|
// .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
|
|
// .extend(ThemeConfig::from(THEME_FLUENT_FONTS)),
|
|
}
|
|
} else {
|
|
/// Extend and register theme assets.
|
|
fn theme() -> Theme {
|
|
register_default_fonts(Theme::from_config(
|
|
ThemeConfig::from(DEFAULT_DARK_EXT)
|
|
.extend(ThemeConfig::from(THEME_DEFAULT))
|
|
.extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
|
|
.extend(ThemeConfig::from(THEME_DEFAULT_FONTS)),
|
|
))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Main
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// initialize the tracing subsystem
|
|
// a drop in replacement for classical logging
|
|
// reference: https://tokio.rs/blog/2019-08-tracing/
|
|
let span = tracing::span!(Level::TRACE, "advotracker");
|
|
let _enter = span.enter();
|
|
let subscriber = fmt::Subscriber::builder()
|
|
.with_env_filter(trace)
|
|
//.with_max_level(tracing::Level::DEBUG)
|
|
.finish();
|
|
|
|
tracing::subscriber::with_default(subscriber, || {
|
|
// get system environment
|
|
let lang = get_lang();
|
|
|
|
let mut state = t!("state.started", lang);
|
|
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);
|
|
|
|
// how to handle unimplemented lang resources??
|
|
res = t!("parse.environment", lang);
|
|
trace!(target: "advotracker", environment = "envy", lang = ?lang);
|
|
state = t!("state.finished", lang);
|
|
trace!(target: "advotracker", process = ?res, state = ?state);
|
|
|
|
// main tasks
|
|
res = t!("main.started", lang);
|
|
state = t!("state.started", lang);
|
|
trace!(target: "advotracker", process = ?res, state = ?state);
|
|
|
|
// use this only if you want to run it as web application.
|
|
orbtk::initialize();
|
|
|
|
// Preset localization and language from given environment.
|
|
// if no dictionary is set for the chosen default language
|
|
// the content of the text property will be drawn.
|
|
//let language = lang.substring(0,5); // "de_DE.UTF-8" -> "de_DE"
|
|
//info!("GUI-Language: preset to {:?}", language);
|
|
let localization = RonLocalization::create()
|
|
.language(&lang)
|
|
.dictionary("de_DE", ADVOTRACKER_DE_DE)
|
|
.build();
|
|
|
|
Application::from_name("nwx.advotracker")
|
|
.localization(localization)
|
|
.theme(theme())
|
|
.window(|ctx| {
|
|
Window::new()
|
|
.title("AdvoTracker - DirectCall")
|
|
.position((500.0, 100.0))
|
|
.size(800.0, 600.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(())
|
|
}
|
|
|
|
// View
|
|
|
|
widget!(MainView {
|
|
policycheck_view: PolicyCheck
|
|
});
|
|
|
|
impl Template for MainView {
|
|
fn template(self, _id: Entity, ctx: &mut BuildContext<'_>) -> Self {
|
|
let ticketdata_view = TicketdataView::new().build(ctx);
|
|
|
|
let policycheck_view = PolicycheckView::new().target(ticketdata_view.0).build(ctx);
|
|
|
|
self.name("MainView").child(
|
|
TabWidget::new()
|
|
.tab(ID_POLICY_CHECK_VIEW, policycheck_view)
|
|
.tab(ID_TICKET_DATA_VIEW, ticketdata_view)
|
|
.build(ctx),
|
|
)
|
|
}
|
|
}
|
|
|
|
// Macro that initializes the widget structures/variables for the policy check view
|
|
widget!(
|
|
/// Form to enter data of a ticket record
|
|
TicketdataView<TicketdataState> {
|
|
// language used inside the widget
|
|
lang: String,
|
|
// title used in the header
|
|
ticket_data_title: String,
|
|
// entity id that will receive the messages
|
|
target: u32
|
|
}
|
|
);
|
|
|
|
/// The template implementation of the ticket view
|
|
/// All GUI elements are styled using the "style" attribute referencing to a ron based css
|
|
impl Template for TicketdataView {
|
|
fn template(self, id: Entity, ctx: &mut BuildContext<'_>) -> Self {
|
|
let tenent_logo = Container::new()
|
|
.margin((16, 16, 0, 0))
|
|
.attach(Grid::column(0))
|
|
.v_align("center")
|
|
.child(
|
|
ImageWidget::new()
|
|
.image("assets/advotracker/hiedemann_logo.png")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.build(ctx);
|
|
|
|
let ticket_data_bottom_bar = Container::new()
|
|
.id(ID_TICKET_DATA_BOTTOM_BAR)
|
|
.style(STYLE_BOTTOM_BAR)
|
|
.attach(Grid::row(4))
|
|
.attach(Grid::column(1))
|
|
.attach(Grid::column_span(2))
|
|
.v_align("end")
|
|
.child(
|
|
Container::new()
|
|
.attach(Grid::column(1))
|
|
.h_align("end")
|
|
.v_align("end")
|
|
.child(
|
|
TextBlock::new()
|
|
.margin((0, 9, 48, 0))
|
|
.text("©Networkx GmbH")
|
|
.build(ctx),
|
|
)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx);
|
|
|
|
let ticket_data_button_menu = Button::new()
|
|
.id(ID_TICKET_DATA_BUTTON_MENU)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column(2))
|
|
.h_align("end")
|
|
.icon(material_icons_font::MD_MENU)
|
|
//.style("button_single_content")
|
|
.style(STYLE_BUTTON_MENU)
|
|
.build(ctx);
|
|
|
|
let ticket_data_form = Container::new()
|
|
.id(ID_TICKET_DATA_FORM)
|
|
.name(ID_TICKET_DATA_FORM)
|
|
.attach(Grid::row(2))
|
|
.attach(Grid::column(1))
|
|
.style("container_form")
|
|
.child(
|
|
Grid::new()
|
|
.id(ID_TICKET_DATA_GRID)
|
|
.name(ID_TICKET_DATA_GRID)
|
|
.columns(
|
|
Columns::create()
|
|
.push("auto") // Label
|
|
.push(16) // Delimiter
|
|
.push("*") // Data
|
|
.push(32), // Delimiter (2x margin)
|
|
)
|
|
.rows(
|
|
Rows::create()
|
|
.push("auto") // Row 0
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 2
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 4
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 6
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 8
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 10
|
|
.push(14) // Seperator
|
|
.push("auto") // Row 12
|
|
.push(14), // Seperator
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_POLICY_CODE)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column(0))
|
|
.text("Policy code")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_POLICY_CODE)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_POLICY_HOLDER)
|
|
.attach(Grid::row(2))
|
|
.attach(Grid::column(0))
|
|
.text("Policy holder")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_POLICY_HOLDER)
|
|
.attach(Grid::row(2))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("Name des Versicherungsnehmers")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_DEDUCTIBLE)
|
|
.attach(Grid::row(4))
|
|
.attach(Grid::column(0))
|
|
.text("Deductible")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_DEDUCTIBLE)
|
|
.attach(Grid::row(4))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("im Beratungsgespräch erfragen")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_CALLBACK_NUMBER)
|
|
.attach(Grid::row(6))
|
|
.attach(Grid::column(0))
|
|
.text("Callback number")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_CALLBACK_NUMBER)
|
|
.attach(Grid::row(6))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("wie zu erreichen")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_CALLBACK_DATE)
|
|
.attach(Grid::row(8))
|
|
.attach(Grid::column(0))
|
|
.text("Callback date")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_CALLBACK_DATE)
|
|
.attach(Grid::row(8))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("Rückruf gewünscht um")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_HARM_TYPE)
|
|
.attach(Grid::row(10))
|
|
.attach(Grid::column(0))
|
|
.text("Harm type")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_HARM_TYPE)
|
|
.name(ID_TICKET_DATA_HARM_TYPE)
|
|
.attach(Grid::row(10))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("Schadenstyp")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_IVR_COMMENT)
|
|
.attach(Grid::row(12))
|
|
.attach(Grid::column(0))
|
|
.text("IVR comment")
|
|
.h_align("end")
|
|
.v_align("center")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBox::new()
|
|
.id(ID_TICKET_DATA_IVR_COMMENT)
|
|
.attach(Grid::row(12))
|
|
.attach(Grid::column(2))
|
|
.text("")
|
|
.water_mark("Kommentar zur Haftung, bzw. zur Deckung")
|
|
//.height(48.0)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx);
|
|
|
|
let ticket_data_form_action = Container::new()
|
|
.id(ID_TICKET_DATA_ACTION_GRID)
|
|
.attach(Grid::row(3))
|
|
.attach(Grid::column(1))
|
|
//.style(STYLE_CONTAINER_ACTION)
|
|
.padding(14)
|
|
.h_align("center")
|
|
.child(
|
|
Stack::new()
|
|
//.style(STYLE_STACK_ACTION)
|
|
.orientation("horizontal")
|
|
.spacing(50)
|
|
.child(
|
|
Button::new()
|
|
.id(ID_TICKET_DATA_ACTION_BUTTON_CLEAR)
|
|
.style(STYLE_BUTTON_ACTION)
|
|
.text("Clear")
|
|
.on_click(move |states, _| {
|
|
states.send_message(TicketdataAction::ClearForm(), id);
|
|
false
|
|
})
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
Button::new()
|
|
.id(ID_TICKET_DATA_ACTION_BUTTON_SEND)
|
|
.style(STYLE_BUTTON_ACTION)
|
|
.text("Send")
|
|
//.visibility(Visibility::Collapsed)
|
|
.on_click(move |states, _entity| {
|
|
states.send_message(TicketdataAction::SendForm(), id);
|
|
false
|
|
})
|
|
.build(ctx),
|
|
)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx);
|
|
|
|
// vector with valid mail recipients addresses (mail_to)
|
|
let items_mail_to = vec![
|
|
PROP_MAIL_TO_1,
|
|
PROP_MAIL_TO_2,
|
|
PROP_MAIL_TO_3,
|
|
PROP_MAIL_TO_4,
|
|
];
|
|
let items_mail_to_count = items_mail_to.len();
|
|
|
|
// vector with valid carbon copy recipients addresses (mail_to)
|
|
let items_mail_cc = vec![PROP_MAIL_CC_1, PROP_MAIL_CC_2];
|
|
let items_mail_cc_count = items_mail_cc.len();
|
|
|
|
let ticket_data_form_mail = Container::new()
|
|
.id(ID_TICKET_DATA_CONTAINER_MAIL)
|
|
.name(ID_TICKET_DATA_CONTAINER_MAIL)
|
|
.attach(Grid::row(1))
|
|
.attach(Grid::column(1))
|
|
.style(STYLE_CONTAINER_MAIL)
|
|
.child(
|
|
Grid::new()
|
|
.columns(
|
|
Columns::create()
|
|
.push(16) // Delimiter
|
|
.push("stretch") // Label
|
|
.push(16) // Delimiter
|
|
.push("auto") // MailAddress
|
|
.push("32"), // Delimiter (2x margin)
|
|
)
|
|
.rows(
|
|
Rows::create()
|
|
.push("auto") // Row 0
|
|
.push(2) // Seperator
|
|
.push("auto") // Row 2
|
|
.push(2), // Seperator
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_MAIL_TO)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column(1))
|
|
.style(STYLE_MAIL_LABEL)
|
|
.text("Recipient (To)")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
/// WIP: get selected item
|
|
ComboBox::new()
|
|
.id(ID_TICKET_DATA_MAIL_TO)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column(3))
|
|
.style(STYLE_MAIL_TO)
|
|
.count(items_mail_to_count)
|
|
.items_builder(move |ibc, index| {
|
|
let text_mail_to =
|
|
TicketdataView::items_mail_to_ref(&ibc.get_widget(id))[index]
|
|
.clone();
|
|
TextBox::new()
|
|
.text(text_mail_to)
|
|
.v_align("center")
|
|
.build(ibc)
|
|
})
|
|
.selected_index(0)
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
TextBlock::new()
|
|
.id(ID_TICKET_DATA_LABEL_MAIL_CC)
|
|
.attach(Grid::row(2))
|
|
.attach(Grid::column(1))
|
|
.style(STYLE_MAIL_LABEL)
|
|
.text("Copie (CC)")
|
|
.build(ctx),
|
|
)
|
|
.child(
|
|
ComboBox::new()
|
|
.id(ID_TICKET_DATA_MAIL_CC)
|
|
.attach(Grid::row(2))
|
|
.attach(Grid::column(3))
|
|
.style(STYLE_MAIL_CC)
|
|
.count(items_mail_cc_count)
|
|
.items_builder(move |ibc, index| {
|
|
let text_mail_cc =
|
|
TicketdataView::items_mail_cc_ref(&ibc.get_widget(id))[index]
|
|
.clone();
|
|
TextBox::new()
|
|
.text(text_mail_cc)
|
|
.v_align("center")
|
|
.build(ibc)
|
|
})
|
|
.selected_index(0)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx),
|
|
)
|
|
.build(ctx);
|
|
|
|
let ticket_data_header_text = TextBlock::new()
|
|
.id(ID_TICKET_DATA_HEADER)
|
|
.attach(Grid::column(0))
|
|
.style(STYLE_HEADER_TEXT)
|
|
.text("Ticket Data")
|
|
.build(ctx);
|
|
|
|
let ticket_data_header_bar = Container::new()
|
|
.id(ID_TICKET_DATA_HEADER_BAR)
|
|
.attach(Grid::row(0))
|
|
.attach(Grid::column_span(3))
|
|
.style(STYLE_HEADER_BAR)
|
|
.child(tenent_logo)
|
|
.child(ticket_data_header_text)
|
|
.child(ticket_data_button_menu)
|
|
.build(ctx);
|
|
|
|
// Widget: Ticket data view
|
|
self.id(ID_TICKET_DATA_VIEW)
|
|
.name(ID_TICKET_DATA_VIEW)
|
|
.min_height(410.0)
|
|
.child(
|
|
Grid::new()
|
|
.id(ID_TICKET_DATA_GRID)
|
|
.columns(
|
|
Columns::create()
|
|
.push(50) // Left margin
|
|
.push("*") // Content
|
|
.push(50), // Right margin
|
|
)
|
|
.rows(
|
|
Rows::create()
|
|
.push("auto") // Header_Bar
|
|
.push("auto") // Mail_Form
|
|
.push("*") // Input_Form
|
|
.push("auto") // Action
|
|
.push("auto"), // Bottom_Bar
|
|
)
|
|
.child(ticket_data_header_bar) // row 0
|
|
.child(ticket_data_form_mail) // row 1
|
|
.child(ticket_data_form) // row 2
|
|
.child(ticket_data_form_action) // row 3
|
|
.child(ticket_data_bottom_bar) // row 4
|
|
.build(ctx),
|
|
)
|
|
}
|
|
}
|
|
|
|
// State
|
|
impl GlobalState for TicketdataState {}
|
|
|
|
/// Method definitions, that react on any given state change inside the `Ticketdata` widget.
|
|
impl TicketdataState {
|
|
/// Clear the text property of all children of the given form entity
|
|
pub fn clear_form(entity: Entity, ctx: &mut Context<'_>) {
|
|
if let Some(count) = ctx.get_widget(entity).children_count() {
|
|
info!(
|
|
"Widget name: {:?}",
|
|
ctx.get_widget(entity).get::<String>("name")
|
|
);
|
|
info!(
|
|
"Widget id: {:?}",
|
|
ctx.get_widget(entity).get::<String>("id")
|
|
);
|
|
}
|
|
|
|
// identify the form by its id
|
|
if let form_entity = ctx.child(ID_TICKET_DATA_GRID).entity() {
|
|
info!(
|
|
"Form id: {:?}",
|
|
ctx.get_widget(form_entity).get::<String>("id")
|
|
);
|
|
info!(
|
|
"Form node name: {:?}",
|
|
ctx.get_widget(form_entity).get::<String>("name")
|
|
);
|
|
|
|
// Loop through children
|
|
if let Some(count) = ctx.get_widget(form_entity).children_count() {
|
|
for c in 1..=count {
|
|
info!("WIP clear entry of child {:?}", c);
|
|
//info!("WIP clear entry of child {:?}: {:?}", c, ctx.get_child(form_entity).get::<String>("name"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn send_form(entity: Entity, ctx: &mut Context<'_>, lang: &str) {
|
|
// type conversion (String -> u64)
|
|
//let policy_code = ctx.child(ID_TICKET_DATA_POLICY_CODE).get::<String>("text").unwrap().parse::<u64>().unwrap();
|
|
|
|
// WIP: get selected items ComboBox'es
|
|
//let mail_cc_index = *TicketdataView::selected_index_ref(&ctx.widget()) as usize;
|
|
//let mail_cc_selected = TicketdataView::mail_cc_ref(&ctx.widget())[mail_cc_index].clone();
|
|
|
|
// create Email structures
|
|
let email = Email {
|
|
// WIP: mail_to -> selected index auslesen
|
|
//mail_to: ctx.child(ID_TICKET_DATA_MAIL_TO).get::<String>("text").to_string(),
|
|
// WIP: mail_cc -> selected index auslesen
|
|
//mail_cc: ctx.child(ID_TICKET_DATA_MAIL_CC).get::<String>("text").to_string(),
|
|
mail_to: PROP_MAIL_TO_1.to_string(),
|
|
mail_cc: PROP_MAIL_CC_1.to_string(),
|
|
mail_bcc: PROP_MAIL_BCC_1.to_string(),
|
|
mail_from: PROP_MAIL_FROM.to_string(),
|
|
mail_reply: PROP_MAIL_REPLY.to_string(),
|
|
subject: PROP_MAIL_SUBJECT.to_string(),
|
|
policy_code: ctx
|
|
.child(ID_TICKET_DATA_POLICY_CODE)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
policy_holder: ctx
|
|
.child(ID_TICKET_DATA_POLICY_HOLDER)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
deductible: ctx
|
|
.child(ID_TICKET_DATA_DEDUCTIBLE)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
callback_number: ctx
|
|
.child(ID_TICKET_DATA_CALLBACK_NUMBER)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
callback_date: ctx
|
|
.child(ID_TICKET_DATA_CALLBACK_DATE)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
harm_type: ctx
|
|
.child(ID_TICKET_DATA_HARM_TYPE)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
ivr_comment: ctx
|
|
.child(ID_TICKET_DATA_IVR_COMMENT)
|
|
.get::<String>("text")
|
|
.to_string(),
|
|
};
|
|
|
|
info!("WIP: Sending form to construct eMail to {:?}", email);
|
|
// send email via service
|
|
let _ = sendticketdata(&email, &lang);
|
|
}
|
|
}
|
|
|
|
/// Supported methods handled inside the `TicketState`
|
|
impl State for TicketdataState {
|
|
/// Initialize the state of widgets inside `TicketState`
|
|
fn init(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
|
|
let time_start = SystemTime::now();
|
|
|
|
trace!(target: "advotracker", ticketdata_state = "init", status = "started");
|
|
|
|
// Initialize required entities
|
|
self.button_menu = ctx
|
|
.entity_of_child(ID_TICKET_DATA_BUTTON_MENU)
|
|
.expect("TicketState.init: Can't find resource entity 'ID_TICKET_DATA_BUTTON_MENU'.");
|
|
|
|
self.target = Entity::from(
|
|
ctx.widget()
|
|
.try_clone::<u32>("target")
|
|
.expect("TicketState.init: Can't find resource entity 'target'."),
|
|
);
|
|
|
|
// Get language from environment
|
|
self.lang = TicketdataState::get_lang();
|
|
|
|
let time_end = SystemTime::now();
|
|
let duration = time_end.duration_since(time_start);
|
|
|
|
trace!(target: "advotracker", ticketdata_state = "init", status = "finished", duration = ?duration);
|
|
}
|
|
|
|
fn messages(
|
|
&mut self,
|
|
mut messages: MessageReader,
|
|
_registry: &mut Registry,
|
|
ctx: &mut Context<'_>,
|
|
) {
|
|
for message in messages.read::<TicketdataAction>() {
|
|
match message {
|
|
TicketdataAction::ClearForm() => {
|
|
info!("message: {:?} recieved", message);
|
|
TicketdataState::clear_form(ctx.entity(), ctx);
|
|
}
|
|
TicketdataAction::SendForm() => {
|
|
info!("message: {:?} recieved", message);
|
|
TicketdataState::send_form(ctx.entity(), ctx, &self.lang);
|
|
}
|
|
_ => {
|
|
println!("messages: action not implemented!");
|
|
}
|
|
}
|
|
}
|
|
for message in messages.read::<PolicycheckAction>() {
|
|
match message {
|
|
PolicycheckAction::UpdatePolicyCode => {
|
|
info!("Message received: 'PolicycheckAction::UpdatePolicyCode'");
|
|
TextBlock::text_set(&mut ctx.child(ID_TICKET_DATA_POLICY_CODE), policy_code);
|
|
}
|
|
_ => {
|
|
println!("messages: action not implemented!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, _: &mut Registry, ctx: &mut Context<'_>) {
|
|
let actions: Vec<TicketdataAction> = self.actions.drain(..).collect();
|
|
|
|
for action in actions {
|
|
match action {
|
|
TicketdataAction::ClearForm() => {
|
|
info!("update: send_message {:?}", action);
|
|
ctx.send_message(TicketdataAction::ClearForm(), self.target);
|
|
}
|
|
TicketdataAction::SendForm() => {
|
|
//ctx.send_message(TicketdataAction::SendForm(), self.ID_TICKETDATA_FORM);
|
|
info!("update: send_message {:?}", action);
|
|
}
|
|
_ => {
|
|
println!("TicketdataAction: action not implemented!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// send ticket data via eMail
|
|
pub fn sendticketdata(email: &Email, lang: &str) -> Result<(), Box<dyn Error>> {
|
|
let mut res = t!("sendticketdata.export.started", lang);
|
|
let mut state = t!("state.started", lang);
|
|
trace!(target: "sendticketdata", process = ?res, state = ?state);
|
|
|
|
let ascii_body = String::new()
|
|
+ &"Vers.-Schein/Schadennummer".to_string()
|
|
+ &(email.policy_code)
|
|
+ &"\n"
|
|
+ &"Versicherungsnehmer: ".to_string()
|
|
+ &(email.policy_holder)
|
|
+ &"\n"
|
|
+ &"Selbstbehalt: ".to_string()
|
|
+ &(email.deductible)
|
|
+ &"\n"
|
|
+ &"Rückrufnummer: ".to_string()
|
|
+ &(email.callback_number)
|
|
+ &"\n"
|
|
+ &"Erreichbarkeit: ".to_string()
|
|
+ &(email.callback_date)
|
|
+ &"\n"
|
|
+ &"Rechtsproblem: ".to_string()
|
|
+ &(email.harm_type)
|
|
+ &"\n"
|
|
+ &"Rechtsrat: ".to_string()
|
|
+ &(email.ivr_comment)
|
|
+ &"\n";
|
|
|
|
info!("email body: {:?}", ascii_body);
|
|
|
|
let message = Message::builder()
|
|
//.reply_to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
|
|
.to("Kanzlei Hiedemann <info@hiedemann.de>".parse().unwrap())
|
|
.cc(" <ralf.zerres@networkx.de>".parse().unwrap())
|
|
.reply_to((email.mail_reply).parse().unwrap())
|
|
//.to((email.mail_to).parse().unwrap())
|
|
//.cc((email.mail_cc).parse().unwrap())
|
|
//.bcc((email.mail_bcc).parse().unwrap())
|
|
.from((email.mail_from).parse().unwrap())
|
|
.subject(
|
|
String::new()
|
|
+ &email.subject.to_string()
|
|
+ &" (".to_string()
|
|
+ &email.policy_code.to_string()
|
|
+ &")".to_string(),
|
|
)
|
|
.multipart(
|
|
MultiPart::alternative() // This is composed of two parts.
|
|
.singlepart(
|
|
SinglePart::builder()
|
|
.header(header::ContentType(
|
|
"text/plain; charset=utf8".parse().unwrap(),
|
|
))
|
|
.body(String::from(ascii_body)),
|
|
),
|
|
)
|
|
.expect("failed to build email");
|
|
|
|
info!("message: {:?}", message);
|
|
|
|
trace!(target: "sendticketdata", email = ?email);
|
|
state = t!("state.finished", lang);
|
|
res = t!("sendticketdata.export.finished", lang);
|
|
trace!(target: "sendticketdata", process = ?res, state = ?state);
|
|
|
|
Ok(())
|
|
}
|