klirr 0.2.14

Zero-maintenance and smart FOSS generating beautiful invoices for services and expenses.
use inquire::{CustomType, Text, error::InquireResult};

use crate::{Currency, InvoiceDataFromTuiError, PaymentInformation, PaymentTerms, Result, Vat};

pub fn build_payment_info(default: &PaymentInformation) -> Result<PaymentInformation> {
    fn inner(default: &PaymentInformation) -> InquireResult<PaymentInformation> {
        let text = |part: &str| format!("Payment {part}?");
        let bank_name = Text::new(&text("Bank Name"))
            .with_default(default.bank_name())
            .prompt()?;
        let iban = Text::new(&text("IBAN"))
            .with_default(default.iban())
            .prompt()?;

        let bic = Text::new(&text("BIC"))
            .with_default(default.bic())
            .prompt()?;

        let currency = CustomType::<Currency>::new("Currency?")
            .with_help_message("The currency you want to use for the invoice, e.g. 'EUR'")
            .with_default(*default.currency())
            .prompt()?;

        let payment_terms = CustomType::<PaymentTerms>::new("Payment terms?")
            .with_help_message("The payment terms for this invoice, e.g. 'Net 30'")
            .with_default(PaymentTerms::net30())
            .prompt()?;

        let vat = CustomType::<Vat>::new("VAT percentage?")
            .with_help_message(
                "Value-added tax rate added on top of the VAT-exclusive subtotal \
                 (your service unit price excludes VAT), e.g. '25' for 25%. \
                 Enter '0' to omit the VAT row entirely.",
            )
            .with_default(*default.vat())
            .prompt()?;

        let payment_info = default
            .clone()
            .with_bank_name(bank_name)
            .with_iban(iban)
            .with_bic(bic)
            .with_currency(currency)
            .with_terms(payment_terms)
            .with_vat(vat);

        Ok(payment_info)
    }
    inner(default)
        .map_err(InvoiceDataFromTuiError::invalid_payment_info)
        .map_err(crate::Error::from)
}