use crate::error::FormsError;
use crate::map::Form8275Map;
use crate::verify::{verify_flat, FlatPlacement};
use crate::{fmt_money, pdf};
use btctax_core::tax::packet::ReturnHeader;
use btctax_core::tax::printed::Printed8275;
fn push_free(
w: &mut Vec<(String, pdf::FieldValue)>,
p: &mut Vec<FlatPlacement>,
fqn: &str,
value: &str,
) {
if value.is_empty() {
return;
}
w.push((fqn.to_string(), pdf::FieldValue::Text(value.to_string())));
p.push(FlatPlacement::free(
fqn.to_string(),
crate::cells::page_of(fqn),
));
}
pub fn fill_form_8275(
printed: &Printed8275,
header: &ReturnHeader,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = Form8275Map::for_year(year)?;
fill_form_8275_inner(printed, Some(header), &map)
}
pub fn fill_form_8275_slice(
printed: &Printed8275,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = Form8275Map::for_year(year)?;
fill_form_8275_inner(printed, None, &map)
}
pub fn fill_form_8275_with_map(
printed: &Printed8275,
header: &ReturnHeader,
map: &Form8275Map,
) -> Result<Option<Vec<u8>>, FormsError> {
fill_form_8275_inner(printed, Some(header), map)
}
fn fill_form_8275_inner(
printed: &Printed8275,
filer: Option<&ReturnHeader>,
map: &Form8275Map,
) -> Result<Option<Vec<u8>>, FormsError> {
if printed.part_i.is_empty() {
return Ok(None);
}
if printed.part_i.len() > map.rows.len() {
return Err(FormsError::Overflow {
part: "Part I",
rows: printed.part_i.len(),
capacity: map.rows.len(),
});
}
let mut w: Vec<(String, pdf::FieldValue)> = Vec::new();
let mut p: Vec<FlatPlacement> = Vec::new();
for (row_map, item) in map.rows.iter().zip(printed.part_i.iter()) {
push_free(&mut w, &mut p, &row_map.item, &item.line);
push_free(&mut w, &mut p, &row_map.desc, &item.description);
push_free(
&mut w,
&mut p,
&row_map.form_schedule,
&format!("Form {}", item.form),
);
push_free(&mut w, &mut p, &row_map.amount, &fmt_money(item.amount));
}
push_free(&mut w, &mut p, &map.part_ii_narrative, &printed.part_ii);
if let Some(header) = filer {
let blank_for_identity = pdf::collect_fields(&pdf::load(pdf::f8275_pdf(map.year)?)?)?;
crate::cells::push_identity(
&mut w,
&mut p,
&map.identity,
&header.name_line,
&header.taxpayer.ssn,
&blank_for_identity,
)?;
}
let writes = w;
let placements = p;
let mut doc = pdf::load(pdf::f8275_pdf(map.year)?)?;
let index = pdf::index(&pdf::collect_fields(&doc)?);
pdf::drop_xfa_and_set_needappearances(&mut doc)?;
pdf::apply_writes(&mut doc, &index, &writes)?;
pdf::strip_nondeterminism(&mut doc);
let bytes = pdf::save(&mut doc)?;
let check = pdf::load(&bytes)?;
let fields = pdf::collect_fields(&check)?;
verify_flat(&check, &fields, &placements, &[])?;
Ok(Some(bytes))
}