feat: enhance forms with decimal formatting and validation
- Updated CustomersPage.vue to use decimalString for standard discount percent. - Enhanced IncomingInvoicesPage.vue to format item quantities, unit prices, and tax rates using decimalString. - Improved ItemsPage.vue with new supplier price management and decimal formatting for prices. - Modified OrganizationSetupPage.vue to use a dropdown for default tax rates and ensure numeric input for payment days. - Updated OutgoingInvoicesPage.vue to apply decimal formatting for customer discounts and item details. - Enhanced PriceImportsPage.vue to include additional fields in the import format. - Improved PriceRulesPage.vue to use decimal input for markup percentages. - Updated QuotesPage.vue to apply decimal formatting for customer discounts and item details. - Enhanced SuppliersPage.vue to use decimal input for standard discount percent. - Added a new SQL migration to set default unit for items to 'Stck'. - Introduced format.ts for centralized decimal and currency formatting utilities.
This commit is contained in:
@@ -585,6 +585,75 @@ fn number_or_pending(number: &str) -> &str {
|
||||
}
|
||||
}
|
||||
|
||||
fn unit_combo(ui: &mut egui::Ui, unit: &mut String) {
|
||||
let selected_text = if unit.trim().is_empty() {
|
||||
"Bitte wählen".to_string()
|
||||
} else {
|
||||
unit.clone()
|
||||
};
|
||||
egui::ComboBox::from_id_salt(ui.next_auto_id())
|
||||
.selected_text(selected_text)
|
||||
.show_ui(ui, |ui| {
|
||||
ui.text_edit_singleline(unit);
|
||||
ui.separator();
|
||||
for option in ["Stck", "kg", "g", "L", "mg", "ml", "qm", "m", "cm", "mm"] {
|
||||
ui.selectable_value(unit, option.to_string(), option);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn tax_rate_combo(ui: &mut egui::Ui, tax_rate: &mut String) {
|
||||
egui::ComboBox::from_id_salt(ui.next_auto_id())
|
||||
.selected_text(format!("{} %", tax_rate.trim()))
|
||||
.show_ui(ui, |ui| {
|
||||
for option in ["0", "7", "19"] {
|
||||
ui.selectable_value(tax_rate, option.to_string(), format!("{option} %"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn normalize_tax_rate(value: &str) -> String {
|
||||
match value.trim().parse::<f64>() {
|
||||
Ok(number) if (number - 0.0).abs() < f64::EPSILON => "0".to_string(),
|
||||
Ok(number) if (number - 7.0).abs() < f64::EPSILON => "7".to_string(),
|
||||
Ok(number) if (number - 19.0).abs() < f64::EPSILON => "19".to_string(),
|
||||
_ => value.trim().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_euro(value: Option<&str>) -> String {
|
||||
let Some(value) = value else {
|
||||
return "-".to_string();
|
||||
};
|
||||
let normalized = if value.contains(',') {
|
||||
value.replace('.', "").replace(',', ".")
|
||||
} else {
|
||||
value.to_string()
|
||||
};
|
||||
match normalized.trim().parse::<f64>() {
|
||||
Ok(number) => format!("{} EUR", format_number_de(number, 2)),
|
||||
Err(_) => value.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_number_de(number: f64, decimals: usize) -> String {
|
||||
let raw = format!("{number:.decimals$}");
|
||||
let (integer, fraction) = raw.split_once('.').unwrap_or((&raw, ""));
|
||||
let mut grouped = String::new();
|
||||
for (index, character) in integer.chars().rev().enumerate() {
|
||||
if index > 0 && index % 3 == 0 {
|
||||
grouped.push('.');
|
||||
}
|
||||
grouped.push(character);
|
||||
}
|
||||
let integer = grouped.chars().rev().collect::<String>();
|
||||
if decimals == 0 {
|
||||
integer
|
||||
} else {
|
||||
format!("{integer},{fraction}")
|
||||
}
|
||||
}
|
||||
|
||||
fn customer_combo(
|
||||
ui: &mut egui::Ui,
|
||||
selected_id: &mut String,
|
||||
@@ -688,7 +757,21 @@ fn apply_quote_item_defaults(line: &mut QuoteItemForm, items: &[Item]) {
|
||||
.clone()
|
||||
.unwrap_or_else(|| "0".to_string());
|
||||
line.original_unit_price = item.default_sales_price.clone();
|
||||
line.tax_rate = item.tax_rate.clone();
|
||||
line.tax_rate = normalize_tax_rate(&item.tax_rate);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_quote_customer_defaults(form: &mut QuoteForm, customers: &[Customer]) {
|
||||
if let Some(customer) = customers.iter().find(|customer| customer.id == form.customer_id) {
|
||||
form.customer_discount_percent = customer.standard_discount_percent.clone();
|
||||
form.cash_discount_term_id = customer.cash_discount_term_id.clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_outgoing_invoice_customer_defaults(form: &mut OutgoingInvoiceForm, customers: &[Customer]) {
|
||||
if let Some(customer) = customers.iter().find(|customer| customer.id == form.customer_id) {
|
||||
form.customer_discount_percent = customer.standard_discount_percent.clone();
|
||||
form.cash_discount_term_id = customer.cash_discount_term_id.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,7 +804,7 @@ fn invoice_items_editor(
|
||||
.clone()
|
||||
.unwrap_or_else(|| "0".to_string());
|
||||
line.original_unit_price = item.default_sales_price.clone();
|
||||
line.tax_rate = item.tax_rate.clone();
|
||||
line.tax_rate = normalize_tax_rate(&item.tax_rate);
|
||||
}
|
||||
}
|
||||
form_row(ui, "Beschreibung", |ui| {
|
||||
@@ -741,7 +824,7 @@ fn invoice_items_editor(
|
||||
ui.text_edit_singleline(&mut line.discount_percent);
|
||||
ui.end_row();
|
||||
ui.label("Steuer %");
|
||||
ui.text_edit_singleline(&mut line.tax_rate);
|
||||
tax_rate_combo(ui, &mut line.tax_rate);
|
||||
ui.end_row();
|
||||
});
|
||||
if can_remove && ui.button("Entfernen").clicked() {
|
||||
@@ -794,7 +877,7 @@ fn incoming_invoice_items_editor(
|
||||
ui.text_edit_singleline(&mut line.unit_price);
|
||||
ui.end_row();
|
||||
ui.label("Steuer %");
|
||||
ui.text_edit_singleline(&mut line.tax_rate);
|
||||
tax_rate_combo(ui, &mut line.tax_rate);
|
||||
ui.end_row();
|
||||
});
|
||||
if can_remove && ui.button("Entfernen").clicked() {
|
||||
@@ -1006,6 +1089,7 @@ struct CompanyToolApp {
|
||||
customer_list_search: String,
|
||||
supplier_list_search: String,
|
||||
item_list_search: String,
|
||||
item_sort_mode: String,
|
||||
activity_list_search: String,
|
||||
quote_list_search: String,
|
||||
outgoing_invoice_list_search: String,
|
||||
@@ -1142,6 +1226,7 @@ impl CompanyToolApp {
|
||||
customer_list_search: String::new(),
|
||||
supplier_list_search: String::new(),
|
||||
item_list_search: String::new(),
|
||||
item_sort_mode: "name_desc".to_string(),
|
||||
activity_list_search: String::new(),
|
||||
quote_list_search: String::new(),
|
||||
outgoing_invoice_list_search: String::new(),
|
||||
@@ -1626,7 +1711,7 @@ impl CompanyToolApp {
|
||||
},
|
||||
AdminEvent::ActivityDeleted(result) => {
|
||||
self.activities_status = result
|
||||
.map(|_| "Aktivität storniert.".to_string())
|
||||
.map(|_| "Aktivität deaktiviert.".to_string())
|
||||
.unwrap_or_else(|message| message);
|
||||
self.load_activities();
|
||||
}
|
||||
@@ -2638,6 +2723,7 @@ impl CompanyToolApp {
|
||||
self.restore_window("items");
|
||||
self.items_window_open = true;
|
||||
self.load_items();
|
||||
self.load_suppliers();
|
||||
}
|
||||
|
||||
fn open_activities_window(&mut self) {
|
||||
@@ -4091,8 +4177,25 @@ impl CompanyToolApp {
|
||||
self.reserve_next_number("items");
|
||||
}
|
||||
ui.text_edit_singleline(&mut self.item_list_search);
|
||||
egui::ComboBox::from_id_salt("item_sort_mode")
|
||||
.selected_text(match self.item_sort_mode.as_str() {
|
||||
"number_desc" => "Artikelnummer absteigend",
|
||||
_ => "Artikelname absteigend",
|
||||
})
|
||||
.show_ui(ui, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut self.item_sort_mode,
|
||||
"name_desc".to_string(),
|
||||
"Artikelname absteigend",
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut self.item_sort_mode,
|
||||
"number_desc".to_string(),
|
||||
"Artikelnummer absteigend",
|
||||
);
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
let filtered_items: Vec<Item> = self
|
||||
let mut filtered_items: Vec<Item> = self
|
||||
.items
|
||||
.iter()
|
||||
.filter(|item| {
|
||||
@@ -4104,6 +4207,18 @@ impl CompanyToolApp {
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
if self.item_sort_mode == "number_desc" {
|
||||
filtered_items.sort_by(|left, right| {
|
||||
right
|
||||
.item_number
|
||||
.to_lowercase()
|
||||
.cmp(&left.item_number.to_lowercase())
|
||||
});
|
||||
} else {
|
||||
filtered_items.sort_by(|left, right| {
|
||||
right.name.to_lowercase().cmp(&left.name.to_lowercase())
|
||||
});
|
||||
}
|
||||
for item in filtered_items {
|
||||
if ui
|
||||
.selectable_label(
|
||||
@@ -4125,14 +4240,17 @@ impl CompanyToolApp {
|
||||
form_row(ui, "Artikelnummer", |ui| {
|
||||
ui.label(number_or_pending(&self.item_form.item_number));
|
||||
});
|
||||
form_row(ui, "Hersteller-Code", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.manufacturer_code);
|
||||
});
|
||||
form_row(ui, "Bezeichnung", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.name);
|
||||
});
|
||||
form_row(ui, "Einheit", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.unit);
|
||||
unit_combo(ui, &mut self.item_form.unit);
|
||||
});
|
||||
form_row(ui, "Steuersatz %", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.tax_rate);
|
||||
tax_rate_combo(ui, &mut self.item_form.tax_rate);
|
||||
});
|
||||
form_row(ui, "Einkaufspreis", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.default_purchase_price);
|
||||
@@ -4140,6 +4258,46 @@ impl CompanyToolApp {
|
||||
form_row(ui, "Verkaufspreis", |ui| {
|
||||
ui.text_edit_singleline(&mut self.item_form.default_sales_price);
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.heading("Lieferantenpreise");
|
||||
if ui.button("Lieferant hinzufügen").clicked() {
|
||||
self.item_form
|
||||
.supplier_prices
|
||||
.push(ItemSupplierPriceForm::default());
|
||||
}
|
||||
});
|
||||
let suppliers = self.suppliers.clone();
|
||||
let mut remove_supplier_price = None;
|
||||
for (index, supplier_price) in
|
||||
self.item_form.supplier_prices.iter_mut().enumerate()
|
||||
{
|
||||
ui.separator();
|
||||
form_row(ui, "Lieferant", |ui| {
|
||||
supplier_combo(
|
||||
ui,
|
||||
&mut supplier_price.supplier_id,
|
||||
&suppliers,
|
||||
&mut self.supplier_lookup_search,
|
||||
);
|
||||
});
|
||||
form_row(ui, "Externe Artikelnr.", |ui| {
|
||||
ui.text_edit_singleline(&mut supplier_price.external_item_number);
|
||||
});
|
||||
form_row(ui, "Einkaufspreis", |ui| {
|
||||
ui.text_edit_singleline(&mut supplier_price.purchase_price);
|
||||
});
|
||||
form_row(ui, "Währung", |ui| {
|
||||
ui.text_edit_singleline(&mut supplier_price.currency);
|
||||
});
|
||||
ui.checkbox(&mut supplier_price.is_preferred, "Bevorzugt");
|
||||
if ui.button("Lieferantenpreis entfernen").clicked() {
|
||||
remove_supplier_price = Some(index);
|
||||
}
|
||||
}
|
||||
if let Some(index) = remove_supplier_price {
|
||||
self.item_form.supplier_prices.remove(index);
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Speichern").clicked() {
|
||||
self.save_item();
|
||||
@@ -4166,12 +4324,9 @@ impl CompanyToolApp {
|
||||
ui.label(format!("ID {}", &entry.id[..entry.id.len().min(8)]));
|
||||
ui.label(format!(
|
||||
"EK {}",
|
||||
entry.purchase_price.as_deref().unwrap_or("-")
|
||||
));
|
||||
ui.label(format!(
|
||||
"VK {}",
|
||||
entry.sales_price.as_deref().unwrap_or("-")
|
||||
format_euro(entry.purchase_price.as_deref())
|
||||
));
|
||||
ui.label(format!("VK {}", format_euro(entry.sales_price.as_deref())));
|
||||
ui.label(&entry.source);
|
||||
ui.label(format!(
|
||||
"Item {}",
|
||||
@@ -4237,6 +4392,8 @@ impl CompanyToolApp {
|
||||
ui.label("Aktion");
|
||||
ui.label("Artikelnummer");
|
||||
ui.label("Name");
|
||||
ui.label("Hersteller");
|
||||
ui.label("Lieferant");
|
||||
ui.label("Einheit");
|
||||
ui.label("Steuer");
|
||||
ui.label("EK");
|
||||
@@ -4248,9 +4405,26 @@ impl CompanyToolApp {
|
||||
ui.label(&row.action);
|
||||
ui.label(&row.item_number);
|
||||
ui.label(&row.name);
|
||||
ui.label(row.manufacturer_code.as_deref().unwrap_or("-"));
|
||||
ui.label(
|
||||
row.supplier_number
|
||||
.as_deref()
|
||||
.map(|supplier| {
|
||||
format!(
|
||||
"{} / {}",
|
||||
supplier,
|
||||
row.supplier_item_number.as_deref().unwrap_or("-")
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| "-".to_string()),
|
||||
);
|
||||
ui.label(&row.unit);
|
||||
ui.label(&row.tax_rate);
|
||||
ui.label(row.purchase_price.as_deref().unwrap_or("-"));
|
||||
ui.label(format!(
|
||||
"{} {}",
|
||||
row.purchase_price.as_deref().unwrap_or("-"),
|
||||
row.currency.as_deref().unwrap_or("EUR")
|
||||
));
|
||||
ui.label(row.sales_price.as_deref().unwrap_or("-"));
|
||||
ui.label(row.error.as_deref().unwrap_or("-"));
|
||||
ui.end_row();
|
||||
@@ -4624,12 +4798,16 @@ impl CompanyToolApp {
|
||||
ui.label(number_or_pending(&self.quote_form.quote_number));
|
||||
});
|
||||
form_row(ui, "Kunde", |ui| {
|
||||
let previous_customer_id = self.quote_form.customer_id.clone();
|
||||
customer_combo(
|
||||
ui,
|
||||
&mut self.quote_form.customer_id,
|
||||
&self.customers,
|
||||
&mut self.customer_lookup_search,
|
||||
);
|
||||
if self.quote_form.customer_id != previous_customer_id {
|
||||
apply_quote_customer_defaults(&mut self.quote_form, &self.customers);
|
||||
}
|
||||
});
|
||||
form_row(ui, "Status", |ui| {
|
||||
egui::ComboBox::from_id_salt("quote_status")
|
||||
@@ -4703,7 +4881,7 @@ impl CompanyToolApp {
|
||||
ui.text_edit_singleline(&mut line.discount_percent);
|
||||
ui.end_row();
|
||||
ui.label("Steuer %");
|
||||
ui.text_edit_singleline(&mut line.tax_rate);
|
||||
tax_rate_combo(ui, &mut line.tax_rate);
|
||||
ui.end_row();
|
||||
});
|
||||
if can_remove_quote_item && ui.button("Position entfernen").clicked() {
|
||||
@@ -4814,12 +4992,20 @@ impl CompanyToolApp {
|
||||
));
|
||||
});
|
||||
form_row(ui, "Kunde", |ui| {
|
||||
let previous_customer_id =
|
||||
self.outgoing_invoice_form.customer_id.clone();
|
||||
customer_combo(
|
||||
ui,
|
||||
&mut self.outgoing_invoice_form.customer_id,
|
||||
&self.customers,
|
||||
&mut self.customer_lookup_search,
|
||||
);
|
||||
if self.outgoing_invoice_form.customer_id != previous_customer_id {
|
||||
apply_outgoing_invoice_customer_defaults(
|
||||
&mut self.outgoing_invoice_form,
|
||||
&self.customers,
|
||||
);
|
||||
}
|
||||
});
|
||||
form_row(ui, "Status", |ui| {
|
||||
ui.text_edit_singleline(&mut self.outgoing_invoice_form.status);
|
||||
@@ -5063,7 +5249,23 @@ impl CompanyToolApp {
|
||||
ui.text_edit_singleline(&mut self.activity_form.activity_type);
|
||||
});
|
||||
form_row(ui, "Status", |ui| {
|
||||
ui.text_edit_singleline(&mut self.activity_form.status);
|
||||
egui::ComboBox::from_id_salt("activity_status")
|
||||
.selected_text(match self.activity_form.status.as_str() {
|
||||
"inactive" => "Nicht aktiv",
|
||||
_ => "Aktiv",
|
||||
})
|
||||
.show_ui(ui, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut self.activity_form.status,
|
||||
"active".to_string(),
|
||||
"Aktiv",
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut self.activity_form.status,
|
||||
"inactive".to_string(),
|
||||
"Nicht aktiv",
|
||||
);
|
||||
});
|
||||
});
|
||||
form_row(ui, "Priorität", |ui| {
|
||||
ui.text_edit_singleline(&mut self.activity_form.priority);
|
||||
@@ -5078,7 +5280,7 @@ impl CompanyToolApp {
|
||||
if ui
|
||||
.add_enabled(
|
||||
self.selected_activity_id.is_some(),
|
||||
egui::Button::new("Stornieren"),
|
||||
egui::Button::new("Deaktivieren"),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
@@ -5536,11 +5738,22 @@ struct Item {
|
||||
id: String,
|
||||
item_number: String,
|
||||
name: String,
|
||||
manufacturer_code: Option<String>,
|
||||
unit: String,
|
||||
tax_rate: String,
|
||||
default_purchase_price: Option<String>,
|
||||
default_sales_price: Option<String>,
|
||||
status: String,
|
||||
supplier_prices: Vec<ItemSupplierPrice>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct ItemSupplierPrice {
|
||||
supplier_id: String,
|
||||
external_item_number: String,
|
||||
purchase_price: String,
|
||||
currency: String,
|
||||
is_preferred: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
@@ -5558,22 +5771,35 @@ struct ItemPriceHistory {
|
||||
struct ItemForm {
|
||||
item_number: String,
|
||||
name: String,
|
||||
manufacturer_code: String,
|
||||
unit: String,
|
||||
tax_rate: String,
|
||||
default_purchase_price: String,
|
||||
default_sales_price: String,
|
||||
status: String,
|
||||
supplier_prices: Vec<ItemSupplierPriceForm>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct ItemSupplierPriceForm {
|
||||
supplier_id: String,
|
||||
external_item_number: String,
|
||||
purchase_price: String,
|
||||
currency: String,
|
||||
is_preferred: bool,
|
||||
}
|
||||
impl Default for ItemForm {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
item_number: String::new(),
|
||||
name: String::new(),
|
||||
unit: "Stk".to_string(),
|
||||
manufacturer_code: String::new(),
|
||||
unit: "Stck".to_string(),
|
||||
tax_rate: "19".to_string(),
|
||||
default_purchase_price: "0".to_string(),
|
||||
default_sales_price: "0".to_string(),
|
||||
status: "active".to_string(),
|
||||
supplier_prices: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5582,11 +5808,41 @@ impl From<&Item> for ItemForm {
|
||||
Self {
|
||||
item_number: value.item_number.clone(),
|
||||
name: value.name.clone(),
|
||||
manufacturer_code: value.manufacturer_code.clone().unwrap_or_default(),
|
||||
unit: value.unit.clone(),
|
||||
tax_rate: value.tax_rate.clone(),
|
||||
tax_rate: normalize_tax_rate(&value.tax_rate),
|
||||
default_purchase_price: value.default_purchase_price.clone().unwrap_or_default(),
|
||||
default_sales_price: value.default_sales_price.clone().unwrap_or_default(),
|
||||
status: value.status.clone(),
|
||||
supplier_prices: value
|
||||
.supplier_prices
|
||||
.iter()
|
||||
.map(ItemSupplierPriceForm::from)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ItemSupplierPriceForm {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
supplier_id: String::new(),
|
||||
external_item_number: String::new(),
|
||||
purchase_price: "0".to_string(),
|
||||
currency: "EUR".to_string(),
|
||||
is_preferred: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&ItemSupplierPrice> for ItemSupplierPriceForm {
|
||||
fn from(value: &ItemSupplierPrice) -> Self {
|
||||
Self {
|
||||
supplier_id: value.supplier_id.clone(),
|
||||
external_item_number: value.external_item_number.clone(),
|
||||
purchase_price: value.purchase_price.clone(),
|
||||
currency: value.currency.clone(),
|
||||
is_preferred: value.is_preferred,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5695,7 +5951,7 @@ impl From<&QuoteItem> for QuoteItemForm {
|
||||
unit_price: value.unit_price.clone(),
|
||||
original_unit_price: value.original_unit_price.clone(),
|
||||
discount_percent: value.discount_percent.clone(),
|
||||
tax_rate: value.tax_rate.clone(),
|
||||
tax_rate: normalize_tax_rate(&value.tax_rate),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5813,7 +6069,7 @@ impl From<&OutgoingInvoiceItem> for OutgoingInvoiceItemForm {
|
||||
unit_price: value.unit_price.clone(),
|
||||
original_unit_price: value.original_unit_price.clone(),
|
||||
discount_percent: value.discount_percent.clone(),
|
||||
tax_rate: value.tax_rate.clone(),
|
||||
tax_rate: normalize_tax_rate(&value.tax_rate),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5913,7 +6169,7 @@ impl From<&IncomingInvoiceItem> for IncomingInvoiceItemForm {
|
||||
description: value.description.clone(),
|
||||
quantity: value.quantity.clone(),
|
||||
unit_price: value.unit_price.clone(),
|
||||
tax_rate: value.tax_rate.clone(),
|
||||
tax_rate: normalize_tax_rate(&value.tax_rate),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5946,7 +6202,7 @@ impl Default for ActivityForm {
|
||||
activity_type: "task".to_string(),
|
||||
title: String::new(),
|
||||
body: String::new(),
|
||||
status: "open".to_string(),
|
||||
status: "active".to_string(),
|
||||
priority: "normal".to_string(),
|
||||
due_at: None,
|
||||
}
|
||||
@@ -5977,7 +6233,7 @@ impl Default for PriceListImportForm {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
source_name: "Preisliste.csv".to_string(),
|
||||
content: "item_number;name;unit;tax_rate;purchase_price;sales_price\nAR-IMPORT-1;Importartikel;Stk;19;10.00;25.00".to_string(),
|
||||
content: "item_number;name;manufacturer_code;unit;tax_rate;purchase_price;sales_price;supplier_number;supplier_item_number;currency\nAR-IMPORT-1;Importartikel;HERST-001;Stck;19,00;10,00;25,00;LI000000001;EXT-4711;EUR".to_string(),
|
||||
delimiter: Some(";".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -5996,10 +6252,14 @@ struct PriceListImportRow {
|
||||
row_number: usize,
|
||||
item_number: String,
|
||||
name: String,
|
||||
manufacturer_code: Option<String>,
|
||||
unit: String,
|
||||
tax_rate: String,
|
||||
purchase_price: Option<String>,
|
||||
sales_price: Option<String>,
|
||||
supplier_number: Option<String>,
|
||||
supplier_item_number: Option<String>,
|
||||
currency: Option<String>,
|
||||
action: String,
|
||||
error: Option<String>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user