evergreen/common/
noncat.rs

1use crate as eg;
2use eg::common::org;
3use eg::common::settings::Settings;
4use eg::date;
5use eg::editor::Editor;
6use eg::result::EgResult;
7use eg::EgValue;
8use std::time::Duration;
9
10/// Create X number of non-cat checkouts.
11///
12/// Returns a list of checkouts with the duedate calculated.
13pub fn checkout(
14    editor: &mut Editor,
15    patron_id: i64,
16    noncat_type: i64,
17    circ_lib: i64,
18    count: i64,
19    circ_time: Option<&str>,
20) -> EgResult<Vec<EgValue>> {
21    let mut circs = Vec::new();
22
23    for _ in 0..count {
24        let noncat = eg::hash! {
25            "patron": patron_id,
26            "staff": editor.requestor_id()?,
27            "circ_lib": circ_lib,
28            "item_type": noncat_type,
29            "circ_time": circ_time,
30        };
31
32        let noncat = EgValue::create("ancc", noncat)?;
33        let mut noncat = editor.create(noncat)?;
34
35        noncat["duedate"] = EgValue::from(noncat_due_date(editor, &noncat)?);
36
37        circs.push(noncat);
38    }
39
40    Ok(circs)
41}
42
43/// Calculate the due date of a noncat circulation, which is a function
44/// of the checkout time, the duration of the noncat type, plus org
45/// open time checks.
46pub fn noncat_due_date(editor: &mut Editor, noncat: &EgValue) -> EgResult<String> {
47    let duration = if noncat["item_type"].is_object() {
48        noncat["item_type"]["circ_duration"].string()?
49    } else {
50        let nct = editor
51            .retrieve("cnct", noncat["item_type"].int()?)?
52            .ok_or(format!("Invalid noncat_type: {}", noncat["item_type"]))?;
53
54        nct["circ_duration"].string()?
55    };
56
57    let circ_lib = noncat["circ_lib"].int()?;
58    let mut settings = Settings::new(editor);
59
60    let timezone = settings.get_value_at_org("lib.timezone", circ_lib)?;
61    let timezone = timezone.as_str().unwrap_or("local");
62
63    let checkout_time = noncat["circ_time"]
64        .as_str()
65        .ok_or(format!("Invalid noncat circ_time: {}", noncat["circ_time"]))?;
66
67    let duedate = date::parse_datetime(checkout_time)?;
68    let duedate = date::set_timezone(duedate, timezone)?;
69
70    let seconds = date::interval_to_seconds(&duration)?;
71    let mut duedate = duedate + Duration::from_secs(seconds as u64);
72
73    let org_open_data = org::next_open_date(editor, circ_lib, &duedate)?;
74
75    if let org::OrgOpenState::OpensOnDate(future_date) = org_open_data {
76        duedate = future_date;
77    }
78
79    Ok(date::to_iso(&duedate))
80}