Don't assume reporting step names/kinds are 'static

Preparation for plugins
This commit is contained in:
RunasSudo 2025-05-31 23:15:56 +10:00
parent 5d573ac421
commit d147f1a569
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
8 changed files with 171 additions and 178 deletions

View File

@ -136,8 +136,8 @@ pub struct CalculateIncomeTax {}
impl CalculateIncomeTax {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"CalculateIncomeTax",
&[ReportingProductKind::Transactions],
"CalculateIncomeTax".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -162,8 +162,8 @@ impl Display for CalculateIncomeTax {
impl ReportingStep for CalculateIncomeTax {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "CalculateIncomeTax",
product_kinds: &[
name: "CalculateIncomeTax".to_string(),
product_kinds: vec![
ReportingProductKind::DynamicReport,
ReportingProductKind::Transactions,
],
@ -174,7 +174,7 @@ impl ReportingStep for CalculateIncomeTax {
fn requires(&self, context: &ReportingContext) -> Vec<ReportingProductId> {
// CalculateIncomeTax depends on CombineOrdinaryTransactions
vec![ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: sofy_from_eofy(context.eofy_date),
@ -198,8 +198,8 @@ impl ReportingStep for CalculateIncomeTax {
other.id(),
ReportingProductId {
name: self.id().name,
kind: other.product_kinds[0],
args: if other.product_kinds[0] == ReportingProductKind::Transactions {
kind: other.product_kind,
args: if other.product_kind == ReportingProductKind::Transactions {
Box::new(VoidArgs {})
} else {
other.id().args
@ -222,7 +222,7 @@ impl ReportingStep for CalculateIncomeTax {
// Get balances for current year
let balances = &products
.get_or_err(&ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: sofy_from_eofy(context.eofy_date),

View File

@ -51,7 +51,7 @@ async fn main() {
let targets = vec![
ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
@ -63,7 +63,7 @@ async fn main() {
// }),
// },
ReportingProductId {
name: "BalanceSheet",
name: "BalanceSheet".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateArgs {
dates: vec![DateArgs {
@ -72,7 +72,7 @@ async fn main() {
}),
},
ReportingProductId {
name: "IncomeStatement",
name: "IncomeStatement".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateStartDateEndArgs {
dates: vec![DateStartDateEndArgs {
@ -91,12 +91,12 @@ async fn main() {
let targets = vec![
ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: NaiveDate::from_ymd_opt(YEAR - 1, 7, 1).unwrap(),
@ -111,7 +111,7 @@ async fn main() {
let result = products
.get_or_err(&ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(VoidArgs {}),
})
@ -122,7 +122,7 @@ async fn main() {
let result = products
.get_or_err(&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: NaiveDate::from_ymd_opt(YEAR - 1, 7, 1).unwrap(),
@ -138,12 +138,12 @@ async fn main() {
let targets = vec![
ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
ReportingProductId {
name: "BalanceSheet",
name: "BalanceSheet".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateArgs {
dates: vec![DateArgs {
@ -158,7 +158,7 @@ async fn main() {
.unwrap();
let result = products
.get_or_err(&ReportingProductId {
name: "BalanceSheet",
name: "BalanceSheet".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateArgs {
dates: vec![DateArgs {
@ -178,12 +178,12 @@ async fn main() {
let targets = vec![
ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
ReportingProductId {
name: "TrialBalance",
name: "TrialBalance".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(DateArgs {
date: NaiveDate::from_ymd_opt(YEAR, 6, 30).unwrap(),
@ -196,7 +196,7 @@ async fn main() {
.unwrap();
let result = products
.get_or_err(&ReportingProductId {
name: "TrialBalance",
name: "TrialBalance".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(DateArgs {
date: NaiveDate::from_ymd_opt(YEAR, 6, 30).unwrap(),

View File

@ -49,7 +49,7 @@ pub fn register_dynamic_builders(context: &mut ReportingContext) {
/// This dynamic builder automatically generates a [BalancesBetween] by subtracting [BalancesAt] between two dates
#[derive(Debug)]
pub struct BalancesAtToBalancesBetween {
step_name: &'static str,
step_name: String,
args: DateStartDateEndArgs,
}
@ -65,7 +65,7 @@ impl BalancesAtToBalancesBetween {
}
fn can_build(
name: &'static str,
name: &str,
kind: ReportingProductKind,
args: &Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -82,7 +82,7 @@ impl BalancesAtToBalancesBetween {
match has_step_or_can_build(
&ReportingProductId {
name,
name: name.to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: args.date_start.clone(),
@ -104,7 +104,7 @@ impl BalancesAtToBalancesBetween {
}
fn build(
name: &'static str,
name: String,
_kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
_steps: &Vec<Box<dyn ReportingStep>>,
@ -131,8 +131,8 @@ impl Display for BalancesAtToBalancesBetween {
impl ReportingStep for BalancesAtToBalancesBetween {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: self.step_name,
product_kinds: &[ReportingProductKind::BalancesBetween],
name: self.step_name.clone(),
product_kinds: vec![ReportingProductKind::BalancesBetween],
args: Box::new(self.args.clone()),
}
}
@ -141,14 +141,14 @@ impl ReportingStep for BalancesAtToBalancesBetween {
// BalancesAtToBalancesBetween depends on BalancesAt at both time points
vec![
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date_start.pred_opt().unwrap(), // Opening balance is the closing balance of the preceding day
}),
},
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date_end,
@ -169,7 +169,7 @@ impl ReportingStep for BalancesAtToBalancesBetween {
// Get balances at dates
let balances_start = &products
.get_or_err(&ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date_start.pred_opt().unwrap(), // Opening balance is the closing balance of the preceding day
@ -181,7 +181,7 @@ impl ReportingStep for BalancesAtToBalancesBetween {
let balances_end = &products
.get_or_err(&ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date_end,
@ -218,7 +218,7 @@ impl ReportingStep for BalancesAtToBalancesBetween {
/// This dynamic builder automatically generates a [BalancesAt] from a step which has no dependencies and generates [Transactions] (e.g. [PostUnreconciledStatementLines][super::steps::PostUnreconciledStatementLines])
#[derive(Debug)]
pub struct GenerateBalances {
step_name: &'static str,
step_name: String,
args: DateArgs,
}
@ -232,7 +232,7 @@ impl GenerateBalances {
}
fn can_build(
name: &'static str,
name: &str,
kind: ReportingProductKind,
args: &Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -244,7 +244,7 @@ impl GenerateBalances {
// Try DateArgs
match has_step_or_can_build(
&ReportingProductId {
name,
name: name.to_string(),
kind: ReportingProductKind::Transactions,
args: args.clone(),
},
@ -271,7 +271,7 @@ impl GenerateBalances {
// Try VoidArgs
match has_step_or_can_build(
&ReportingProductId {
name,
name: name.to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
@ -299,7 +299,7 @@ impl GenerateBalances {
}
fn build(
name: &'static str,
name: String,
_kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
_steps: &Vec<Box<dyn ReportingStep>>,
@ -323,8 +323,8 @@ impl Display for GenerateBalances {
impl ReportingStep for GenerateBalances {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: self.step_name,
product_kinds: &[ReportingProductKind::BalancesAt],
name: self.step_name.clone(),
product_kinds: vec![ReportingProductKind::BalancesAt],
args: Box::new(self.args.clone()),
}
}
@ -341,7 +341,7 @@ impl ReportingStep for GenerateBalances {
// Try DateArgs
match has_step_or_can_build(
&ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
},
@ -355,7 +355,7 @@ impl ReportingStep for GenerateBalances {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
},
@ -369,7 +369,7 @@ impl ReportingStep for GenerateBalances {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
@ -408,7 +408,7 @@ impl ReportingStep for GenerateBalances {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
},
@ -423,7 +423,7 @@ impl ReportingStep for GenerateBalances {
/// - a step which generates [Transactions] from [BalancesBetween], and for which a [BalancesAt] is also available
#[derive(Debug)]
pub struct UpdateBalancesAt {
step_name: &'static str,
step_name: String,
args: DateArgs,
}
@ -439,7 +439,7 @@ impl UpdateBalancesAt {
}
fn can_build(
name: &'static str,
name: &str,
kind: ReportingProductKind,
args: &Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -474,7 +474,7 @@ impl UpdateBalancesAt {
{
match has_step_or_can_build(
&ReportingProductId {
name: dependencies_for_step[0].product.name,
name: dependencies_for_step[0].product.name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: args.downcast_ref::<DateArgs>().unwrap().date,
@ -498,7 +498,7 @@ impl UpdateBalancesAt {
}
fn build(
name: &'static str,
name: String,
_kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
_steps: &Vec<Box<dyn ReportingStep>>,
@ -522,8 +522,8 @@ impl Display for UpdateBalancesAt {
impl ReportingStep for UpdateBalancesAt {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: self.step_name,
product_kinds: &[ReportingProductKind::BalancesAt],
name: self.step_name.clone(),
product_kinds: vec![ReportingProductKind::BalancesAt],
args: Box::new(self.args.clone()),
}
}
@ -549,7 +549,7 @@ impl ReportingStep for UpdateBalancesAt {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: parent_step.id().args.clone(),
},
@ -567,7 +567,7 @@ impl ReportingStep for UpdateBalancesAt {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: dependency.name,
name: dependency.name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date,
@ -600,7 +600,7 @@ impl ReportingStep for UpdateBalancesAt {
// Get transactions
let transactions = &products
.get_or_err(&ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: parent_step.id().args,
})?
@ -624,7 +624,7 @@ impl ReportingStep for UpdateBalancesAt {
// As checked in can_build, must depend on BalancesBetween -> Transaction with a BalancesAt available
opening_balances_at = products
.get_or_err(&ReportingProductId {
name: dependency.name,
name: dependency.name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: self.args.date,
@ -649,7 +649,7 @@ impl ReportingStep for UpdateBalancesAt {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
},
@ -662,7 +662,7 @@ impl ReportingStep for UpdateBalancesAt {
/// This dynamic builder automatically generates a [BalancesBetween] from a step which generates [Transactions] from [BalancesBetween]
#[derive(Debug)]
pub struct UpdateBalancesBetween {
step_name: &'static str,
step_name: String,
args: DateStartDateEndArgs,
}
@ -676,7 +676,7 @@ impl UpdateBalancesBetween {
}
fn can_build(
name: &'static str,
name: &str,
kind: ReportingProductKind,
_args: &Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -706,7 +706,7 @@ impl UpdateBalancesBetween {
}
fn build(
name: &'static str,
name: String,
_kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
_steps: &Vec<Box<dyn ReportingStep>>,
@ -730,8 +730,8 @@ impl Display for UpdateBalancesBetween {
impl ReportingStep for UpdateBalancesBetween {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: self.step_name,
product_kinds: &[ReportingProductKind::BalancesBetween],
name: self.step_name.clone(),
product_kinds: vec![ReportingProductKind::BalancesBetween],
args: Box::new(self.args.clone()),
}
}
@ -757,7 +757,7 @@ impl ReportingStep for UpdateBalancesBetween {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: parent_step.id().args,
},
@ -779,7 +779,7 @@ impl ReportingStep for UpdateBalancesBetween {
dependencies.add_dependency(
self.id(),
ReportingProductId {
name: balances_between_product.name,
name: balances_between_product.name.clone(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(self.args.clone()),
},
@ -810,7 +810,7 @@ impl ReportingStep for UpdateBalancesBetween {
// Get transactions
let transactions = &products
.get_or_err(&ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::Transactions,
args: parent_step.id().args,
})?
@ -825,7 +825,7 @@ impl ReportingStep for UpdateBalancesBetween {
// Get opening balances
let opening_balances = &products
.get_or_err(&ReportingProductId {
name: balances_between_product.name,
name: balances_between_product.name.clone(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(self.args.clone()),
})?
@ -849,7 +849,7 @@ impl ReportingStep for UpdateBalancesBetween {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: self.step_name,
name: self.step_name.clone(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(self.args.clone()),
},

View File

@ -104,7 +104,7 @@ pub fn has_step_or_can_build<'a, 'b>(
// No explicit step for product - try builders
for builder in context.step_dynamic_builders.iter() {
if (builder.can_build)(
product.name,
&product.name,
product.kind,
&product.args,
steps,
@ -162,7 +162,7 @@ fn build_step_for_product(
}
HasStepOrCanBuild::CanBuild(builder) => {
new_step = (builder.build)(
product.name,
product.name.clone(),
product.kind,
product.args.clone(),
&steps,

View File

@ -34,9 +34,7 @@ use crate::util::{get_eofy, sofy_from_eofy};
use crate::QuantityInt;
use super::calculator::ReportingGraphDependencies;
use super::dynamic_report::{
entries_for_kind, DynamicReport, DynamicReportEntry, Row, Section,
};
use super::dynamic_report::{entries_for_kind, DynamicReport, DynamicReportEntry, Row, Section};
use super::executor::ReportingExecutionError;
use super::types::{
BalancesBetween, DateArgs, MultipleDateArgs, MultipleDateStartDateEndArgs, ReportingContext,
@ -74,8 +72,8 @@ pub struct AllTransactionsExceptEarningsToEquity {
impl AllTransactionsExceptEarningsToEquity {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"AllTransactionsExceptEarningsToEquity",
&[ReportingProductKind::Transactions],
"AllTransactionsExceptEarningsToEquity".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -102,8 +100,8 @@ impl Display for AllTransactionsExceptEarningsToEquity {
impl ReportingStep for AllTransactionsExceptEarningsToEquity {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "AllTransactionsExceptEarningsToEquity",
product_kinds: &[ReportingProductKind::Transactions],
name: "AllTransactionsExceptEarningsToEquity".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(self.args.clone()),
}
}
@ -111,7 +109,7 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquity {
fn requires(&self, _context: &ReportingContext) -> Vec<ReportingProductId> {
// AllTransactionsExceptEarningsToEquity always depends on CombineOrdinaryTransactions at least
vec![ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
}]
@ -135,24 +133,24 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquity {
/// Used as the basis for the income statement.
#[derive(Debug)]
pub struct AllTransactionsExceptEarningsToEquityBalances {
pub product_kinds: &'static [ReportingProductKind; 1], // Must have single member - represented as static array for compatibility with ReportingStepId
pub product_kind: ReportingProductKind,
pub args: Box<dyn ReportingStepArgs>,
}
impl AllTransactionsExceptEarningsToEquityBalances {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"AllTransactionsExceptEarningsToEquity",
&[ReportingProductKind::BalancesAt],
"AllTransactionsExceptEarningsToEquity".to_string(),
vec![ReportingProductKind::BalancesAt],
Self::takes_args,
|a| Self::from_args(&[ReportingProductKind::BalancesAt], a),
|a| Self::from_args(ReportingProductKind::BalancesAt, a),
);
context.register_lookup_fn(
"AllTransactionsExceptEarningsToEquity",
&[ReportingProductKind::BalancesBetween],
"AllTransactionsExceptEarningsToEquity".to_string(),
vec![ReportingProductKind::BalancesBetween],
Self::takes_args,
|a| Self::from_args(&[ReportingProductKind::BalancesBetween], a),
|a| Self::from_args(ReportingProductKind::BalancesBetween, a),
);
}
@ -161,13 +159,10 @@ impl AllTransactionsExceptEarningsToEquityBalances {
}
fn from_args(
product_kinds: &'static [ReportingProductKind; 1],
product_kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
) -> Box<dyn ReportingStep> {
Box::new(AllTransactionsExceptEarningsToEquityBalances {
product_kinds,
args,
})
Box::new(AllTransactionsExceptEarningsToEquityBalances { product_kind, args })
}
}
@ -181,8 +176,8 @@ impl Display for AllTransactionsExceptEarningsToEquityBalances {
impl ReportingStep for AllTransactionsExceptEarningsToEquityBalances {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "AllTransactionsExceptEarningsToEquity",
product_kinds: self.product_kinds,
name: "AllTransactionsExceptEarningsToEquity".to_string(),
product_kinds: vec![self.product_kind],
args: self.args.clone(),
}
}
@ -190,8 +185,8 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquityBalances {
fn requires(&self, _context: &ReportingContext) -> Vec<ReportingProductId> {
// AllTransactionsExceptEarningsToEquity always depends on CombineOrdinaryTransactions at least
vec![ReportingProductId {
name: "CombineOrdinaryTransactions",
kind: self.product_kinds[0],
name: "CombineOrdinaryTransactions".to_string(),
kind: self.product_kind,
args: self.args.clone(),
}]
}
@ -210,8 +205,6 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquityBalances {
// Identify the product_kind dependency most recently generated
// TODO: Make this deterministic - parallel execution may cause the order to vary
let product_kind = self.product_kinds[0];
for (product_id, product) in products.map().iter().rev() {
if step_dependencies.iter().any(|d| d.product == *product_id) {
// Store the result
@ -219,7 +212,7 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquityBalances {
result.insert(
ReportingProductId {
name: self.id().name,
kind: product_kind,
kind: self.product_kind,
args: self.args.clone(),
},
product.clone(),
@ -231,7 +224,7 @@ impl ReportingStep for AllTransactionsExceptEarningsToEquityBalances {
// No dependencies?! - this is likely a mistake
panic!(
"Requested {:?} but no available dependencies to provide it",
self.product_kinds[0]
self.product_kind
);
}
}
@ -249,8 +242,8 @@ pub struct AllTransactionsIncludingEarningsToEquity {
impl AllTransactionsIncludingEarningsToEquity {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"AllTransactionsIncludingEarningsToEquity",
&[ReportingProductKind::BalancesAt],
"AllTransactionsIncludingEarningsToEquity".to_string(),
vec![ReportingProductKind::BalancesAt],
Self::takes_args,
Self::from_args,
);
@ -277,8 +270,8 @@ impl Display for AllTransactionsIncludingEarningsToEquity {
impl ReportingStep for AllTransactionsIncludingEarningsToEquity {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "AllTransactionsIncludingEarningsToEquity",
product_kinds: &[ReportingProductKind::BalancesAt],
name: "AllTransactionsIncludingEarningsToEquity".to_string(),
product_kinds: vec![ReportingProductKind::BalancesAt],
args: Box::new(self.args.clone()),
}
}
@ -287,19 +280,19 @@ impl ReportingStep for AllTransactionsIncludingEarningsToEquity {
vec![
// AllTransactionsIncludingEarningsToEquity requires AllTransactionsExceptEarningsToEquity
ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
},
// AllTransactionsIncludingEarningsToEquity requires CurrentYearEarningsToEquity
ReportingProductId {
name: "CurrentYearEarningsToEquity",
name: "CurrentYearEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
},
// AllTransactionsIncludingEarningsToEquity requires RetainedEarningsToEquity
ReportingProductId {
name: "RetainedEarningsToEquity",
name: "RetainedEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
},
@ -318,7 +311,7 @@ impl ReportingStep for AllTransactionsIncludingEarningsToEquity {
// Get opening balances from AllTransactionsExceptEarningsToEquity
let opening_balances = products
.get_or_err(&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
})?
@ -328,7 +321,7 @@ impl ReportingStep for AllTransactionsIncludingEarningsToEquity {
// Get CurrentYearEarningsToEquity transactions
let transactions_current = products
.get_or_err(&ReportingProductId {
name: "CurrentYearEarningsToEquity",
name: "CurrentYearEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
})?
@ -338,7 +331,7 @@ impl ReportingStep for AllTransactionsIncludingEarningsToEquity {
// Get RetainedEarningsToEquity transactions
let transactions_retained = products
.get_or_err(&ReportingProductId {
name: "RetainedEarningsToEquity",
name: "RetainedEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(self.args.clone()),
})?
@ -381,8 +374,8 @@ pub struct BalanceSheet {
impl BalanceSheet {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"BalanceSheet",
&[ReportingProductKind::DynamicReport],
"BalanceSheet".to_string(),
vec![ReportingProductKind::DynamicReport],
Self::takes_args,
Self::from_args,
);
@ -409,8 +402,8 @@ impl Display for BalanceSheet {
impl ReportingStep for BalanceSheet {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "BalanceSheet",
product_kinds: &[ReportingProductKind::DynamicReport],
name: "BalanceSheet".to_string(),
product_kinds: vec![ReportingProductKind::DynamicReport],
args: Box::new(self.args.clone()),
}
}
@ -421,7 +414,7 @@ impl ReportingStep for BalanceSheet {
// BalanceSheet depends on AllTransactionsIncludingEarningsToEquity in each requested period
for date_args in self.args.dates.iter() {
result.push(ReportingProductId {
name: "AllTransactionsIncludingEarningsToEquity",
name: "AllTransactionsIncludingEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(date_args.clone()),
});
@ -443,7 +436,7 @@ impl ReportingStep for BalanceSheet {
let mut balances: Vec<&HashMap<String, QuantityInt>> = Vec::new();
for date_args in self.args.dates.iter() {
let product = products.get_or_err(&ReportingProductId {
name: "AllTransactionsIncludingEarningsToEquity",
name: "AllTransactionsIncludingEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(date_args.clone()),
})?;
@ -534,7 +527,7 @@ impl ReportingStep for BalanceSheet {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: "BalanceSheet",
name: "BalanceSheet".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(self.args.clone()),
},
@ -555,8 +548,8 @@ pub struct CombineOrdinaryTransactions {
impl CombineOrdinaryTransactions {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"CombineOrdinaryTransactions",
&[ReportingProductKind::Transactions],
"CombineOrdinaryTransactions".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -583,8 +576,8 @@ impl Display for CombineOrdinaryTransactions {
impl ReportingStep for CombineOrdinaryTransactions {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "CombineOrdinaryTransactions",
product_kinds: &[ReportingProductKind::Transactions],
name: "CombineOrdinaryTransactions".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(self.args.clone()),
}
}
@ -593,13 +586,13 @@ impl ReportingStep for CombineOrdinaryTransactions {
vec![
// CombineOrdinaryTransactions depends on DBTransactions
ReportingProductId {
name: "DBTransactions",
name: "DBTransactions".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
// CombineOrdinaryTransactions depends on PostUnreconciledStatementLines
ReportingProductId {
name: "PostUnreconciledStatementLines",
name: "PostUnreconciledStatementLines".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
@ -628,8 +621,8 @@ pub struct CombineOrdinaryTransactionsBalances {
impl CombineOrdinaryTransactionsBalances {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"CombineOrdinaryTransactions",
&[ReportingProductKind::BalancesAt],
"CombineOrdinaryTransactions".to_string(),
vec![ReportingProductKind::BalancesAt],
Self::takes_args,
Self::from_args,
);
@ -656,8 +649,8 @@ impl Display for CombineOrdinaryTransactionsBalances {
impl ReportingStep for CombineOrdinaryTransactionsBalances {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "CombineOrdinaryTransactions",
product_kinds: &[ReportingProductKind::BalancesAt],
name: "CombineOrdinaryTransactions".to_string(),
product_kinds: vec![ReportingProductKind::BalancesAt],
args: Box::new(self.args.clone()),
}
}
@ -666,13 +659,13 @@ impl ReportingStep for CombineOrdinaryTransactionsBalances {
vec![
// CombineOrdinaryTransactions depends on DBBalances
ReportingProductId {
name: "DBBalances",
name: "DBBalances".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
},
// CombineOrdinaryTransactions depends on PostUnreconciledStatementLines
ReportingProductId {
name: "PostUnreconciledStatementLines",
name: "PostUnreconciledStatementLines".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
},
@ -729,8 +722,8 @@ pub struct CurrentYearEarningsToEquity {
impl CurrentYearEarningsToEquity {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"CurrentYearEarningsToEquity",
&[ReportingProductKind::Transactions],
"CurrentYearEarningsToEquity".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -757,8 +750,8 @@ impl Display for CurrentYearEarningsToEquity {
impl ReportingStep for CurrentYearEarningsToEquity {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "CurrentYearEarningsToEquity",
product_kinds: &[ReportingProductKind::Transactions],
name: "CurrentYearEarningsToEquity".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(self.args.clone()),
}
}
@ -766,7 +759,7 @@ impl ReportingStep for CurrentYearEarningsToEquity {
fn requires(&self, context: &ReportingContext) -> Vec<ReportingProductId> {
// CurrentYearEarningsToEquity depends on AllTransactionsExceptEarningsToEquity
vec![ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: sofy_from_eofy(get_eofy(&self.args.date, &context.eofy_date)),
@ -787,7 +780,7 @@ impl ReportingStep for CurrentYearEarningsToEquity {
// Get balances for this financial year
let balances = products
.get_or_err(&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(DateStartDateEndArgs {
date_start: sofy_from_eofy(get_eofy(&self.args.date, &context.eofy_date)),
@ -866,8 +859,8 @@ pub struct DBBalances {
impl DBBalances {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"DBBalances",
&[ReportingProductKind::BalancesAt],
"DBBalances".to_string(),
vec![ReportingProductKind::BalancesAt],
Self::takes_args,
Self::from_args,
);
@ -894,8 +887,8 @@ impl Display for DBBalances {
impl ReportingStep for DBBalances {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "DBBalances",
product_kinds: &[ReportingProductKind::BalancesAt],
name: "DBBalances".to_string(),
product_kinds: vec![ReportingProductKind::BalancesAt],
args: Box::new(self.args.clone()),
}
}
@ -933,8 +926,8 @@ pub struct DBTransactions {}
impl DBTransactions {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"DBTransactions",
&[ReportingProductKind::Transactions],
"DBTransactions".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -959,8 +952,8 @@ impl Display for DBTransactions {
impl ReportingStep for DBTransactions {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "DBTransactions",
product_kinds: &[ReportingProductKind::Transactions],
name: "DBTransactions".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(VoidArgs {}),
}
}
@ -1000,8 +993,8 @@ pub struct IncomeStatement {
impl IncomeStatement {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"IncomeStatement",
&[ReportingProductKind::DynamicReport],
"IncomeStatement".to_string(),
vec![ReportingProductKind::DynamicReport],
Self::takes_args,
Self::from_args,
);
@ -1028,8 +1021,8 @@ impl Display for IncomeStatement {
impl ReportingStep for IncomeStatement {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "IncomeStatement",
product_kinds: &[ReportingProductKind::DynamicReport],
name: "IncomeStatement".to_string(),
product_kinds: vec![ReportingProductKind::DynamicReport],
args: Box::new(self.args.clone()),
}
}
@ -1040,7 +1033,7 @@ impl ReportingStep for IncomeStatement {
// IncomeStatement depends on AllTransactionsExceptEarningsToEquity in each requested period
for date_args in self.args.dates.iter() {
result.push(ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(date_args.clone()),
});
@ -1062,7 +1055,7 @@ impl ReportingStep for IncomeStatement {
let mut balances: Vec<&HashMap<String, QuantityInt>> = Vec::new();
for date_args in self.args.dates.iter() {
let product = products.get_or_err(&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesBetween,
args: Box::new(date_args.clone()),
})?;
@ -1154,7 +1147,7 @@ impl ReportingStep for IncomeStatement {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: "IncomeStatement",
name: "IncomeStatement".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(self.args.clone()),
},
@ -1171,8 +1164,8 @@ pub struct PostUnreconciledStatementLines {}
impl PostUnreconciledStatementLines {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"PostUnreconciledStatementLines",
&[ReportingProductKind::Transactions],
"PostUnreconciledStatementLines".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -1197,8 +1190,8 @@ impl Display for PostUnreconciledStatementLines {
impl ReportingStep for PostUnreconciledStatementLines {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "PostUnreconciledStatementLines",
product_kinds: &[ReportingProductKind::Transactions],
name: "PostUnreconciledStatementLines".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(VoidArgs {}),
}
}
@ -1278,8 +1271,8 @@ pub struct RetainedEarningsToEquity {
impl RetainedEarningsToEquity {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"RetainedEarningsToEquity",
&[ReportingProductKind::Transactions],
"RetainedEarningsToEquity".to_string(),
vec![ReportingProductKind::Transactions],
Self::takes_args,
Self::from_args,
);
@ -1306,8 +1299,8 @@ impl Display for RetainedEarningsToEquity {
impl ReportingStep for RetainedEarningsToEquity {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "RetainedEarningsToEquity",
product_kinds: &[ReportingProductKind::Transactions],
name: "RetainedEarningsToEquity".to_string(),
product_kinds: vec![ReportingProductKind::Transactions],
args: Box::new(self.args.clone()),
}
}
@ -1318,7 +1311,7 @@ impl ReportingStep for RetainedEarningsToEquity {
// RetainedEarningsToEquity depends on CombineOrdinaryTransactions for last financial year
vec![ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: last_eofy_date,
@ -1340,7 +1333,7 @@ impl ReportingStep for RetainedEarningsToEquity {
// Get balances at end of last financial year
let balances_last_eofy = products
.get_or_err(&ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: last_eofy_date.clone(),
@ -1418,8 +1411,8 @@ pub struct TrialBalance {
impl TrialBalance {
fn register_lookup_fn(context: &mut ReportingContext) {
context.register_lookup_fn(
"TrialBalance",
&[ReportingProductKind::DynamicReport],
"TrialBalance".to_string(),
vec![ReportingProductKind::DynamicReport],
Self::takes_args,
Self::from_args,
);
@ -1446,8 +1439,8 @@ impl Display for TrialBalance {
impl ReportingStep for TrialBalance {
fn id(&self) -> ReportingStepId {
ReportingStepId {
name: "TrialBalance",
product_kinds: &[ReportingProductKind::DynamicReport],
name: "TrialBalance".to_string(),
product_kinds: vec![ReportingProductKind::DynamicReport],
args: Box::new(self.args.clone()),
}
}
@ -1457,7 +1450,7 @@ impl ReportingStep for TrialBalance {
// TrialBalance depends on AllTransactionsExceptEarningsToEquity at the requested date
result.push(ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
});
@ -1477,7 +1470,7 @@ impl ReportingStep for TrialBalance {
// Get balances for each period
let balances = &products
.get_or_err(&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(self.args.clone()),
})?
@ -1551,7 +1544,7 @@ impl ReportingStep for TrialBalance {
let mut result = ReportingProducts::new();
result.insert(
ReportingProductId {
name: "TrialBalance",
name: "TrialBalance".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(self.args.clone()),
},

View File

@ -49,7 +49,7 @@ pub struct ReportingContext {
// State
pub(crate) step_lookup_fn: HashMap<
(&'static str, &'static [ReportingProductKind]),
(String, Vec<ReportingProductKind>),
(ReportingStepTakesArgsFn, ReportingStepFromArgsFn),
>,
pub(crate) step_dynamic_builders: Vec<ReportingStepDynamicBuilder>,
@ -76,8 +76,8 @@ impl ReportingContext {
/// A lookup function generates concrete [ReportingStep]s from a [ReportingStepId].
pub fn register_lookup_fn(
&mut self,
name: &'static str,
product_kinds: &'static [ReportingProductKind],
name: String,
product_kinds: Vec<ReportingProductKind>,
takes_args_fn: ReportingStepTakesArgsFn,
from_args_fn: ReportingStepFromArgsFn,
) {
@ -118,7 +118,7 @@ pub type ReportingStepFromArgsFn = fn(args: Box<dyn ReportingStepArgs>) -> Box<d
pub struct ReportingStepDynamicBuilder {
pub name: &'static str,
pub can_build: fn(
name: &'static str,
name: &str,
kind: ReportingProductKind,
args: &Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -126,7 +126,7 @@ pub struct ReportingStepDynamicBuilder {
context: &ReportingContext,
) -> bool,
pub build: fn(
name: &'static str,
name: String,
kind: ReportingProductKind,
args: Box<dyn ReportingStepArgs>,
steps: &Vec<Box<dyn ReportingStep>>,
@ -141,7 +141,7 @@ pub struct ReportingStepDynamicBuilder {
/// Identifies a [ReportingProduct]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ReportingProductId {
pub name: &'static str,
pub name: String,
pub kind: ReportingProductKind,
pub args: Box<dyn ReportingStepArgs>,
}
@ -276,8 +276,8 @@ impl Display for ReportingProducts {
/// Identifies a [ReportingStep]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ReportingStepId {
pub name: &'static str,
pub product_kinds: &'static [ReportingProductKind],
pub name: String,
pub product_kinds: Vec<ReportingProductKind>,
pub args: Box<dyn ReportingStepArgs>,
}

View File

@ -29,7 +29,7 @@ pub(crate) async fn get_tax_summary(state: State<'_, Mutex<AppState>>) -> Result
Ok(get_report(
state,
&ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(VoidArgs {}),
},

View File

@ -61,7 +61,7 @@ pub(crate) async fn get_report(
let targets = vec![
// FIXME: Make this configurable
ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
},
@ -80,7 +80,7 @@ pub(crate) async fn get_all_transactions_except_earnings_to_equity(
let transactions = get_report(
state,
&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(DateArgs {
date: NaiveDate::from_ymd_opt(9999, 12, 31).unwrap(),
@ -103,7 +103,7 @@ pub(crate) async fn get_all_transactions_except_earnings_to_equity_for_account(
let transactions = get_report(
state,
&ReportingProductId {
name: "AllTransactionsExceptEarningsToEquity",
name: "AllTransactionsExceptEarningsToEquity".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(DateArgs {
date: NaiveDate::from_ymd_opt(9999, 12, 31).unwrap(),
@ -139,7 +139,7 @@ pub(crate) async fn get_balance_sheet(
Ok(get_report(
state,
&ReportingProductId {
name: "BalanceSheet",
name: "BalanceSheet".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateArgs {
dates: date_args.clone(),
@ -168,7 +168,7 @@ pub(crate) async fn get_income_statement(
Ok(get_report(
state,
&ReportingProductId {
name: "IncomeStatement",
name: "IncomeStatement".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(MultipleDateStartDateEndArgs {
dates: date_args.clone(),
@ -191,7 +191,7 @@ pub(crate) async fn get_trial_balance(
Ok(get_report(
state,
&ReportingProductId {
name: "TrialBalance",
name: "TrialBalance".to_string(),
kind: ReportingProductKind::DynamicReport,
args: Box::new(DateArgs { date }),
},
@ -238,14 +238,14 @@ pub(crate) async fn get_validated_balance_assertions(
// Get report targets
let mut targets = vec![ReportingProductId {
name: "CalculateIncomeTax",
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: Box::new(VoidArgs {}),
}];
for dt in dates {
// Request ordinary transaction balances at each balance assertion date
targets.push(ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs { date: dt.date() }),
});
@ -259,7 +259,7 @@ pub(crate) async fn get_validated_balance_assertions(
for balance_assertion in balance_assertions {
let balances_at_date = products
.get_or_err(&ReportingProductId {
name: "CombineOrdinaryTransactions",
name: "CombineOrdinaryTransactions".to_string(),
kind: ReportingProductKind::BalancesAt,
args: Box::new(DateArgs {
date: balance_assertion.dt.date(),