use crate::conventions::Usd;
use crate::tax::tables::AmtParams;
use crate::tax::types::FilingStatus;
use rust_decimal_macros::dec;
pub fn amt_should_file_6251(
status: FilingStatus,
agi: Usd,
qbi_deduction: Usd,
state_refund_and_8z: Usd,
regular_tax_l16: Usd,
sch2_l1z: Usd,
amt: &AmtParams,
) -> bool {
let line5 = agi - qbi_deduction - state_refund_and_8z;
let exemption = amt.exemption(status);
if line5 <= exemption {
return false;
}
let line7 = line5 - exemption;
let phaseout_start = amt.phaseout_start(status);
let line11 = if line5 > phaseout_start {
let line9 = line5 - phaseout_start;
let line10 = (dec!(0.25) * line9).min(exemption);
line7 + line10
} else {
line7
};
if line11 > amt.breakpoint_28pct(status) {
return true;
}
let line12 = dec!(0.26) * line11;
let line13 = regular_tax_l16 + sch2_l1z;
line12 > line13
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tax::tables::AmtParams;
fn amt() -> AmtParams {
AmtParams {
exemption_single_hoh: dec!(85700),
exemption_mfj_qss: dec!(133300),
exemption_mfs: dec!(66650),
phaseout_start_single_hoh_mfs: dec!(609350),
phaseout_start_mfj_qss: dec!(1218700),
breakpoint_28pct: dec!(232600),
breakpoint_28pct_mfs: dec!(116300),
}
}
#[test]
fn below_exemption_clears() {
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(50000),
Usd::ZERO,
Usd::ZERO,
dec!(5000),
Usd::ZERO,
&amt()
));
}
#[test]
fn over_breakpoint_forces_6251() {
assert!(amt_should_file_6251(
FilingStatus::Single,
dec!(900000),
Usd::ZERO,
Usd::ZERO,
dec!(300000),
Usd::ZERO,
&amt()
));
}
#[test]
fn next_test_high_amti_low_regular_tax() {
assert!(amt_should_file_6251(
FilingStatus::Single,
dec!(300000),
Usd::ZERO,
Usd::ZERO,
dec!(45000),
Usd::ZERO,
&amt()
));
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(300000),
Usd::ZERO,
Usd::ZERO,
dec!(60000),
Usd::ZERO,
&amt()
));
}
#[test]
fn state_refund_lowers_line5() {
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(90000),
Usd::ZERO,
dec!(6000),
dec!(9000),
Usd::ZERO,
&amt()
));
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(90000),
Usd::ZERO,
Usd::ZERO,
dec!(9000),
Usd::ZERO,
&amt()
));
}
#[test]
fn mfs_lower_thresholds() {
assert!(amt_should_file_6251(
FilingStatus::Mfs,
dec!(200000),
Usd::ZERO,
Usd::ZERO,
dec!(40000),
Usd::ZERO,
&amt()
));
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(200000),
Usd::ZERO,
Usd::ZERO,
dec!(40000),
Usd::ZERO,
&amt()
));
}
#[test]
fn breakpoint_stop_is_load_bearing() {
assert!(amt_should_file_6251(
FilingStatus::Single,
dec!(325700),
Usd::ZERO,
Usd::ZERO,
dec!(70000),
Usd::ZERO,
&amt()
));
}
#[test]
fn ftc_cancels_from_the_amt_decision() {
let a = amt();
for l16 in [dec!(50000), dec!(55000), dec!(55718), dec!(56000)] {
let decision = amt_should_file_6251(
FilingStatus::Single,
dec!(300000),
Usd::ZERO,
Usd::ZERO,
l16,
Usd::ZERO,
&a,
);
assert_eq!(decision, dec!(55718) > l16, "L16 = {l16}");
}
}
#[test]
fn qbi_reduces_line3() {
assert!(!amt_should_file_6251(
FilingStatus::Single,
dec!(90000),
dec!(10000),
Usd::ZERO,
dec!(9000),
Usd::ZERO,
&amt()
));
}
}