Implement UpdateBalancesAt
This commit is contained in:
parent
b28c75c00f
commit
d78d6ed1fe
42
src/main.rs
42
src/main.rs
@ -20,8 +20,12 @@ use chrono::NaiveDate;
|
|||||||
use libdrcr::reporting::{
|
use libdrcr::reporting::{
|
||||||
builders::register_dynamic_builders,
|
builders::register_dynamic_builders,
|
||||||
calculator::solve_for,
|
calculator::solve_for,
|
||||||
steps::{register_lookup_fns, AllTransactionsExceptRetainedEarnings, CalculateIncomeTax},
|
steps::{
|
||||||
DateEofyArgs, DateStartDateEndArgs, ReportingContext, ReportingStep,
|
register_lookup_fns, AllTransactionsExceptRetainedEarnings,
|
||||||
|
AllTransactionsIncludingRetainedEarnings, CalculateIncomeTax,
|
||||||
|
},
|
||||||
|
DateArgs, DateEofyArgs, DateStartDateEndArgs, ReportingContext, ReportingProductKind,
|
||||||
|
ReportingStep,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -36,13 +40,43 @@ fn main() {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
Box::new(AllTransactionsExceptRetainedEarnings {
|
Box::new(AllTransactionsExceptRetainedEarnings {
|
||||||
args: DateStartDateEndArgs {
|
product_kinds: &[ReportingProductKind::BalancesBetween],
|
||||||
|
args: Box::new(DateStartDateEndArgs {
|
||||||
date_start: NaiveDate::from_ymd_opt(2024, 7, 1).unwrap(),
|
date_start: NaiveDate::from_ymd_opt(2024, 7, 1).unwrap(),
|
||||||
date_end: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(),
|
date_end: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(),
|
||||||
},
|
}),
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
println!("For income statement:");
|
||||||
|
match solve_for(targets, context) {
|
||||||
|
Ok(steps) => {
|
||||||
|
for step in steps {
|
||||||
|
println!("- {}", step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => panic!("Error: {:?}", err),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut context = ReportingContext::new(NaiveDate::from_ymd_opt(2025, 6, 30).unwrap());
|
||||||
|
register_lookup_fns(&mut context);
|
||||||
|
register_dynamic_builders(&mut context);
|
||||||
|
|
||||||
|
let targets: Vec<Box<dyn ReportingStep>> = vec![
|
||||||
|
Box::new(CalculateIncomeTax {
|
||||||
|
args: DateEofyArgs {
|
||||||
|
date_eofy: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Box::new(AllTransactionsIncludingRetainedEarnings {
|
||||||
|
product_kinds: &[ReportingProductKind::BalancesAt],
|
||||||
|
args: Box::new(DateArgs {
|
||||||
|
date: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
println!("For balance sheet:");
|
||||||
match solve_for(targets, context) {
|
match solve_for(targets, context) {
|
||||||
Ok(steps) => {
|
Ok(steps) => {
|
||||||
for step in steps {
|
for step in steps {
|
||||||
|
@ -25,12 +25,6 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn register_dynamic_builders(context: &mut ReportingContext) {
|
pub fn register_dynamic_builders(context: &mut ReportingContext) {
|
||||||
context.register_dynamic_builder(ReportingStepDynamicBuilder {
|
|
||||||
name: "BalancesAtToBalancesBetween",
|
|
||||||
can_build: BalancesAtToBalancesBetween::can_build,
|
|
||||||
build: BalancesAtToBalancesBetween::build,
|
|
||||||
});
|
|
||||||
|
|
||||||
context.register_dynamic_builder(ReportingStepDynamicBuilder {
|
context.register_dynamic_builder(ReportingStepDynamicBuilder {
|
||||||
name: "GenerateBalances",
|
name: "GenerateBalances",
|
||||||
can_build: GenerateBalances::can_build,
|
can_build: GenerateBalances::can_build,
|
||||||
@ -42,6 +36,19 @@ pub fn register_dynamic_builders(context: &mut ReportingContext) {
|
|||||||
can_build: UpdateBalancesBetween::can_build,
|
can_build: UpdateBalancesBetween::can_build,
|
||||||
build: UpdateBalancesBetween::build,
|
build: UpdateBalancesBetween::build,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context.register_dynamic_builder(ReportingStepDynamicBuilder {
|
||||||
|
name: "UpdateBalancesAt",
|
||||||
|
can_build: UpdateBalancesAt::can_build,
|
||||||
|
build: UpdateBalancesAt::build,
|
||||||
|
});
|
||||||
|
|
||||||
|
// This is the least efficient way of generating BalancesBetween
|
||||||
|
context.register_dynamic_builder(ReportingStepDynamicBuilder {
|
||||||
|
name: "BalancesAtToBalancesBetween",
|
||||||
|
can_build: BalancesAtToBalancesBetween::can_build,
|
||||||
|
build: BalancesAtToBalancesBetween::build,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -63,6 +70,10 @@ impl BalancesAtToBalancesBetween {
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
// Check for BalancesAt, BalancesAt -> BalancesBetween
|
// Check for BalancesAt, BalancesAt -> BalancesBetween
|
||||||
if kind == ReportingProductKind::BalancesBetween {
|
if kind == ReportingProductKind::BalancesBetween {
|
||||||
|
if !args.is::<DateStartDateEndArgs>() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let args = args.downcast_ref::<DateStartDateEndArgs>().unwrap();
|
let args = args.downcast_ref::<DateStartDateEndArgs>().unwrap();
|
||||||
|
|
||||||
match has_step_or_can_build(
|
match has_step_or_can_build(
|
||||||
@ -105,7 +116,10 @@ impl BalancesAtToBalancesBetween {
|
|||||||
|
|
||||||
impl Display for BalancesAtToBalancesBetween {
|
impl Display for BalancesAtToBalancesBetween {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("{} {{BalancesAtToBalancesBetween}}", self.id()))
|
f.write_fmt(format_args!(
|
||||||
|
"{} {{BalancesAtToBalancesBetween}}",
|
||||||
|
self.id()
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +241,133 @@ impl ReportingStep for GenerateBalances {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UpdateBalancesAt {
|
||||||
|
step_name: &'static str,
|
||||||
|
args: DateArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpdateBalancesAt {
|
||||||
|
// Implements (BalancesAt -> Transactions) -> BalancesAt
|
||||||
|
|
||||||
|
fn can_build(
|
||||||
|
name: &'static str,
|
||||||
|
kind: ReportingProductKind,
|
||||||
|
_args: &Box<dyn ReportingStepArgs>,
|
||||||
|
steps: &Vec<Box<dyn ReportingStep>>,
|
||||||
|
dependencies: &ReportingGraphDependencies,
|
||||||
|
context: &ReportingContext,
|
||||||
|
) -> bool {
|
||||||
|
// Check for Transactions -> BalancesAt
|
||||||
|
if kind == ReportingProductKind::BalancesAt {
|
||||||
|
// Initially no need to check args
|
||||||
|
if let Some(step) = steps.iter().find(|s| {
|
||||||
|
s.id().name == name
|
||||||
|
&& s.id()
|
||||||
|
.product_kinds
|
||||||
|
.contains(&ReportingProductKind::Transactions)
|
||||||
|
}) {
|
||||||
|
// Check for BalancesAt -> Transactions
|
||||||
|
let dependencies_for_step = dependencies.dependencies_for_step(&step.id());
|
||||||
|
if dependencies_for_step.len() == 1
|
||||||
|
&& dependencies_for_step[0].dependency.kind == ReportingProductKind::BalancesAt
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if BalancesBetween -> Transactions and BalancesAt is available
|
||||||
|
if dependencies_for_step.len() == 1
|
||||||
|
&& dependencies_for_step[0].dependency.kind
|
||||||
|
== ReportingProductKind::BalancesBetween
|
||||||
|
{
|
||||||
|
let date_end = dependencies_for_step[0]
|
||||||
|
.dependency
|
||||||
|
.args
|
||||||
|
.downcast_ref::<DateStartDateEndArgs>()
|
||||||
|
.unwrap()
|
||||||
|
.date_end;
|
||||||
|
|
||||||
|
match has_step_or_can_build(
|
||||||
|
&ReportingProductId {
|
||||||
|
name: dependencies_for_step[0].dependency.name,
|
||||||
|
kind: ReportingProductKind::BalancesAt,
|
||||||
|
args: Box::new(DateArgs { date: date_end }),
|
||||||
|
},
|
||||||
|
steps,
|
||||||
|
dependencies,
|
||||||
|
context,
|
||||||
|
) {
|
||||||
|
HasStepOrCanBuild::HasStep(_)
|
||||||
|
| HasStepOrCanBuild::CanLookup(_)
|
||||||
|
| HasStepOrCanBuild::CanBuild(_) => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
HasStepOrCanBuild::None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(
|
||||||
|
name: &'static str,
|
||||||
|
_kind: ReportingProductKind,
|
||||||
|
args: Box<dyn ReportingStepArgs>,
|
||||||
|
_steps: &Vec<Box<dyn ReportingStep>>,
|
||||||
|
_dependencies: &ReportingGraphDependencies,
|
||||||
|
_context: &ReportingContext,
|
||||||
|
) -> Box<dyn ReportingStep> {
|
||||||
|
Box::new(UpdateBalancesAt {
|
||||||
|
step_name: name,
|
||||||
|
args: *args.downcast().unwrap(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for UpdateBalancesAt {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{} {{UpdateBalancesAt}}", self.id()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReportingStep for UpdateBalancesAt {
|
||||||
|
fn id(&self) -> ReportingStepId {
|
||||||
|
ReportingStepId {
|
||||||
|
name: self.step_name,
|
||||||
|
product_kinds: &[ReportingProductKind::BalancesAt],
|
||||||
|
args: Box::new(self.args.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_graph(
|
||||||
|
&self,
|
||||||
|
steps: &Vec<Box<dyn ReportingStep>>,
|
||||||
|
dependencies: &mut ReportingGraphDependencies,
|
||||||
|
) {
|
||||||
|
// Add a dependency on the Transactions result
|
||||||
|
// Look up that step, so we can extract the appropriate args
|
||||||
|
let parent_step = steps
|
||||||
|
.iter()
|
||||||
|
.find(|s| {
|
||||||
|
s.id().name == self.step_name
|
||||||
|
&& s.id()
|
||||||
|
.product_kinds
|
||||||
|
.contains(&ReportingProductKind::Transactions)
|
||||||
|
})
|
||||||
|
.unwrap(); // Existence is checked in can_build
|
||||||
|
|
||||||
|
dependencies.add_dependency(
|
||||||
|
self.id(),
|
||||||
|
ReportingProductId {
|
||||||
|
name: self.step_name,
|
||||||
|
kind: ReportingProductKind::Transactions,
|
||||||
|
args: parent_step.id().args.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdateBalancesBetween {
|
pub struct UpdateBalancesBetween {
|
||||||
step_name: &'static str,
|
step_name: &'static str,
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ReportingContext, ReportingProductId, ReportingProductKind, ReportingStep,
|
ReportingContext, ReportingProductId, ReportingStep, ReportingStepDynamicBuilder,
|
||||||
ReportingStepDynamicBuilder, ReportingStepFromArgsFn, ReportingStepId,
|
ReportingStepFromArgsFn, ReportingStepId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -41,7 +41,7 @@ impl ReportingGraphDependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_target_dependency(&mut self, target: ReportingStepId, dependency: ReportingStepId) {
|
/*pub fn add_target_dependency(&mut self, target: ReportingStepId, dependency: ReportingStepId) {
|
||||||
for kind in target.product_kinds {
|
for kind in target.product_kinds {
|
||||||
match kind {
|
match kind {
|
||||||
ReportingProductKind::Transactions | ReportingProductKind::BalancesBetween => {
|
ReportingProductKind::Transactions | ReportingProductKind::BalancesBetween => {
|
||||||
@ -58,7 +58,7 @@ impl ReportingGraphDependencies {
|
|||||||
ReportingProductKind::Generic => todo!(),
|
ReportingProductKind::Generic => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub fn dependencies_for_step(&self, step: &ReportingStepId) -> Vec<&Dependency> {
|
pub fn dependencies_for_step(&self, step: &ReportingStepId) -> Vec<&Dependency> {
|
||||||
return self.vec.iter().filter(|d| d.step == *step).collect();
|
return self.vec.iter().filter(|d| d.step == *step).collect();
|
||||||
@ -206,46 +206,50 @@ pub fn solve_for(
|
|||||||
*name == dependency.dependency.name
|
*name == dependency.dependency.name
|
||||||
&& kinds.contains(&dependency.dependency.kind)
|
&& kinds.contains(&dependency.dependency.kind)
|
||||||
}) {
|
}) {
|
||||||
let (_, lookup_fn) = context.step_lookup_fn.get(lookup_key).unwrap();
|
let (takes_args_fn, from_args_fn) =
|
||||||
let new_step = lookup_fn(dependency.dependency.args.clone());
|
context.step_lookup_fn.get(lookup_key).unwrap();
|
||||||
|
if takes_args_fn(&dependency.dependency.args) {
|
||||||
|
let new_step = from_args_fn(dependency.dependency.args.clone());
|
||||||
|
|
||||||
// Check new step meets the dependency
|
// Check new step meets the dependency
|
||||||
if new_step.id().name != dependency.dependency.name {
|
if new_step.id().name != dependency.dependency.name {
|
||||||
panic!("Unexpected step returned from lookup function (expected name {}, got {})", dependency.dependency.name, new_step.id().name);
|
panic!("Unexpected step returned from lookup function (expected name {}, got {})", dependency.dependency.name, new_step.id().name);
|
||||||
}
|
}
|
||||||
if new_step.id().args != dependency.dependency.args {
|
if new_step.id().args != dependency.dependency.args {
|
||||||
panic!("Unexpected step returned from lookup function {} (expected args {:?}, got {:?})", dependency.dependency.name, dependency.dependency.args, new_step.id().args);
|
panic!("Unexpected step returned from lookup function {} (expected args {:?}, got {:?})", dependency.dependency.name, dependency.dependency.args, new_step.id().args);
|
||||||
}
|
}
|
||||||
if !new_step
|
if !new_step
|
||||||
.id()
|
.id()
|
||||||
.product_kinds
|
.product_kinds
|
||||||
.contains(&dependency.dependency.kind)
|
.contains(&dependency.dependency.kind)
|
||||||
{
|
{
|
||||||
panic!("Unexpected step returned from lookup function {} (expected kind {:?}, got {:?})", dependency.dependency.name, dependency.dependency.kind, new_step.id().product_kinds);
|
panic!("Unexpected step returned from lookup function {} (expected kind {:?}, got {:?})", dependency.dependency.name, dependency.dependency.kind, new_step.id().product_kinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_steps.push(new_step);
|
new_steps.push(new_step);
|
||||||
} else {
|
continue;
|
||||||
// No explicit step for product - try builders
|
}
|
||||||
for builder in context.step_dynamic_builders.iter() {
|
}
|
||||||
if (builder.can_build)(
|
|
||||||
|
// No explicit step for product - try builders
|
||||||
|
for builder in context.step_dynamic_builders.iter() {
|
||||||
|
if (builder.can_build)(
|
||||||
|
dependency.dependency.name,
|
||||||
|
dependency.dependency.kind,
|
||||||
|
&dependency.dependency.args,
|
||||||
|
&steps,
|
||||||
|
&dependencies,
|
||||||
|
&context,
|
||||||
|
) {
|
||||||
|
new_steps.push((builder.build)(
|
||||||
dependency.dependency.name,
|
dependency.dependency.name,
|
||||||
dependency.dependency.kind,
|
dependency.dependency.kind,
|
||||||
&dependency.dependency.args,
|
dependency.dependency.args.clone(),
|
||||||
&steps,
|
&steps,
|
||||||
&dependencies,
|
&dependencies,
|
||||||
&context,
|
&context,
|
||||||
) {
|
));
|
||||||
new_steps.push((builder.build)(
|
break;
|
||||||
dependency.dependency.name,
|
|
||||||
dependency.dependency.kind,
|
|
||||||
dependency.dependency.args.clone(),
|
|
||||||
&steps,
|
|
||||||
&dependencies,
|
|
||||||
&context,
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,9 +271,9 @@ pub fn solve_for(
|
|||||||
new_step.as_ref().init_graph(&steps, &mut dependencies);
|
new_step.as_ref().init_graph(&steps, &mut dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call after_init_graph on new steps
|
// Call after_init_graph on all steps
|
||||||
for new_step_index in new_step_indexes {
|
for step in steps.iter() {
|
||||||
steps[new_step_index].after_init_graph(&steps, &mut dependencies);
|
step.as_ref().after_init_graph(&steps, &mut dependencies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,11 +27,49 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn register_lookup_fns(context: &mut ReportingContext) {
|
pub fn register_lookup_fns(context: &mut ReportingContext) {
|
||||||
|
context.register_lookup_fn(
|
||||||
|
"AllTransactionsExceptRetainedEarnings",
|
||||||
|
&[ReportingProductKind::BalancesAt],
|
||||||
|
AllTransactionsExceptRetainedEarnings::takes_args,
|
||||||
|
|a| {
|
||||||
|
AllTransactionsExceptRetainedEarnings::from_args(&[ReportingProductKind::BalancesAt], a)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
context.register_lookup_fn(
|
context.register_lookup_fn(
|
||||||
"AllTransactionsExceptRetainedEarnings",
|
"AllTransactionsExceptRetainedEarnings",
|
||||||
&[ReportingProductKind::BalancesBetween],
|
&[ReportingProductKind::BalancesBetween],
|
||||||
AllTransactionsExceptRetainedEarnings::takes_args,
|
AllTransactionsExceptRetainedEarnings::takes_args,
|
||||||
AllTransactionsExceptRetainedEarnings::from_args,
|
|a| {
|
||||||
|
AllTransactionsExceptRetainedEarnings::from_args(
|
||||||
|
&[ReportingProductKind::BalancesBetween],
|
||||||
|
a,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
context.register_lookup_fn(
|
||||||
|
"AllTransactionsIncludingRetainedEarnings",
|
||||||
|
&[ReportingProductKind::BalancesAt],
|
||||||
|
AllTransactionsIncludingRetainedEarnings::takes_args,
|
||||||
|
|a| {
|
||||||
|
AllTransactionsIncludingRetainedEarnings::from_args(
|
||||||
|
&[ReportingProductKind::BalancesAt],
|
||||||
|
a,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
context.register_lookup_fn(
|
||||||
|
"AllTransactionsIncludingRetainedEarnings",
|
||||||
|
&[ReportingProductKind::BalancesBetween],
|
||||||
|
AllTransactionsIncludingRetainedEarnings::takes_args,
|
||||||
|
|a| {
|
||||||
|
AllTransactionsIncludingRetainedEarnings::from_args(
|
||||||
|
&[ReportingProductKind::BalancesBetween],
|
||||||
|
a,
|
||||||
|
)
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
context.register_lookup_fn(
|
context.register_lookup_fn(
|
||||||
@ -65,17 +103,22 @@ pub fn register_lookup_fns(context: &mut ReportingContext) {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AllTransactionsExceptRetainedEarnings {
|
pub struct AllTransactionsExceptRetainedEarnings {
|
||||||
pub args: DateStartDateEndArgs,
|
pub product_kinds: &'static [ReportingProductKind], // Must have single member
|
||||||
|
pub args: Box<dyn ReportingStepArgs>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllTransactionsExceptRetainedEarnings {
|
impl AllTransactionsExceptRetainedEarnings {
|
||||||
fn takes_args(args: &Box<dyn ReportingStepArgs>) -> bool {
|
fn takes_args(_args: &Box<dyn ReportingStepArgs>) -> bool {
|
||||||
args.is::<DateStartDateEndArgs>()
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_args(args: Box<dyn ReportingStepArgs>) -> Box<dyn ReportingStep> {
|
fn from_args(
|
||||||
|
product_kinds: &'static [ReportingProductKind],
|
||||||
|
args: Box<dyn ReportingStepArgs>,
|
||||||
|
) -> Box<dyn ReportingStep> {
|
||||||
Box::new(AllTransactionsExceptRetainedEarnings {
|
Box::new(AllTransactionsExceptRetainedEarnings {
|
||||||
args: *args.downcast().unwrap(),
|
product_kinds,
|
||||||
|
args,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,12 +133,58 @@ impl ReportingStep for AllTransactionsExceptRetainedEarnings {
|
|||||||
fn id(&self) -> ReportingStepId {
|
fn id(&self) -> ReportingStepId {
|
||||||
ReportingStepId {
|
ReportingStepId {
|
||||||
name: "AllTransactionsExceptRetainedEarnings",
|
name: "AllTransactionsExceptRetainedEarnings",
|
||||||
product_kinds: &[ReportingProductKind::BalancesBetween],
|
product_kinds: self.product_kinds,
|
||||||
args: Box::new(self.args.clone()),
|
args: self.args.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AllTransactionsIncludingRetainedEarnings {
|
||||||
|
pub product_kinds: &'static [ReportingProductKind], // Must have single member
|
||||||
|
pub args: Box<dyn ReportingStepArgs>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AllTransactionsIncludingRetainedEarnings {
|
||||||
|
fn takes_args(_args: &Box<dyn ReportingStepArgs>) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_args(
|
||||||
|
product_kinds: &'static [ReportingProductKind],
|
||||||
|
args: Box<dyn ReportingStepArgs>,
|
||||||
|
) -> Box<dyn ReportingStep> {
|
||||||
|
Box::new(AllTransactionsIncludingRetainedEarnings {
|
||||||
|
product_kinds,
|
||||||
|
args,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AllTransactionsIncludingRetainedEarnings {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}", self.id()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReportingStep for AllTransactionsIncludingRetainedEarnings {
|
||||||
|
fn id(&self) -> ReportingStepId {
|
||||||
|
ReportingStepId {
|
||||||
|
name: "AllTransactionsIncludingRetainedEarnings",
|
||||||
|
product_kinds: self.product_kinds,
|
||||||
|
args: self.args.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn requires(&self) -> Vec<ReportingProductId> {
|
||||||
|
vec![ReportingProductId {
|
||||||
|
name: "AllTransactionsExceptRetainedEarnings",
|
||||||
|
kind: self.product_kinds[0],
|
||||||
|
args: self.args.clone(),
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CalculateIncomeTax {
|
pub struct CalculateIncomeTax {
|
||||||
pub args: DateEofyArgs,
|
pub args: DateEofyArgs,
|
||||||
@ -147,11 +236,35 @@ impl ReportingStep for CalculateIncomeTax {
|
|||||||
) {
|
) {
|
||||||
for other in steps {
|
for other in steps {
|
||||||
if let Some(other) = other.downcast_ref::<AllTransactionsExceptRetainedEarnings>() {
|
if let Some(other) = other.downcast_ref::<AllTransactionsExceptRetainedEarnings>() {
|
||||||
if other.args.date_start <= self.args.date_eofy
|
// AllTransactionsExceptRetainedEarnings (in applicable periods) depends on CalculateIncomeTax
|
||||||
&& other.args.date_end >= self.args.date_eofy
|
if other.args.is::<DateArgs>() {
|
||||||
{
|
let other_args = other.args.downcast_ref::<DateArgs>().unwrap();
|
||||||
// AllTransactionsExceptRetainedEarnings (in applicable periods) depends on CalculateIncomeTax
|
if other_args.date >= self.args.date_eofy {
|
||||||
dependencies.add_target_dependency(other.id(), self.id());
|
dependencies.add_dependency(
|
||||||
|
other.id(),
|
||||||
|
ReportingProductId {
|
||||||
|
name: self.id().name,
|
||||||
|
kind: other.product_kinds[0],
|
||||||
|
args: other.id().args,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if other.args.is::<DateStartDateEndArgs>() {
|
||||||
|
let other_args = other.args.downcast_ref::<DateStartDateEndArgs>().unwrap();
|
||||||
|
if other_args.date_start <= self.args.date_eofy
|
||||||
|
&& other_args.date_end >= self.args.date_eofy
|
||||||
|
{
|
||||||
|
dependencies.add_dependency(
|
||||||
|
other.id(),
|
||||||
|
ReportingProductId {
|
||||||
|
name: self.id().name,
|
||||||
|
kind: other.product_kinds[0],
|
||||||
|
args: other.id().args,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user