emergency_closing INT NOT NULL REFERENCES action.emergency_closing (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
hold INT NOT NULL REFERENCES action.hold_request (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
original_shelf_expire_time TIMESTAMPTZ,
+ orginal_expire_time TIMESTAMPTZ,
process_time TIMESTAMPTZ
);
CREATE INDEX emergency_closing_hold_emergency_closing_idx ON action.emergency_closing_hold (emergency_closing);
JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
JOIN action.hold_request hold ON (
pickup_lib = closing.org_unit
- AND hold.shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
- AND hold.fulfillment_time IS NULL
+ AND
+ (
+ hold.shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ OR hold.expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ )
+ AND hold.fulfillment_time IS NULL
AND hold.cancel_time IS NULL
)
WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_hold t WHERE t.emergency_closing = e_closing AND t.hold = hold.id);
-- Record the processing
UPDATE action.emergency_closing_hold
SET original_shelf_expire_time = hold.shelf_expire_time,
+ original_expire_time = hold.expire_time,
process_time = NOW()
WHERE id = hold_closing_entry;
WHERE id = e_closing.id;
UPDATE action.hold_request
- SET shelf_expire_time = evergreen.find_next_open_time(closing.org_unit, hold.shelf_expire_time, TRUE)
+ SET shelf_expire_time = CASE
+ WHEN shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ THEN evergreen.find_next_open_time(closing.org_unit, hold.shelf_expire_time, TRUE)
+ ELSE hold.shelf_expire_time
+ END,
+ expire_time = CASE
+ WHEN expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ THEN evergreen.find_next_open_time(closing.org_unit, hold.expire_time, TRUE)
+ ELSE hold.expire_time
+ END
WHERE id = hold.id;
RETURN TRUE;
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('xxxx', :eg_version);
+
+ALTER TABLE action.emergency_closing_hold ADD COLUMN original_expire_time timestamptz;
+
+CREATE TYPE action.emergency_closing_stage_1_count AS (circulations INT, reservations INT, holds INT);
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_1 ( e_closing INT )
+ RETURNS SETOF action.emergency_closing_stage_1_count AS $$
+DECLARE
+ tmp INT;
+ touched action.emergency_closing_stage_1_count%ROWTYPE;
+BEGIN
+ -- First, gather circs
+ INSERT INTO action.emergency_closing_circulation (emergency_closing, circulation)
+ SELECT e_closing,
+ circ.id
+ FROM actor.org_unit_closed closing
+ JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+ JOIN action.circulation circ ON (
+ circ.circ_lib = closing.org_unit
+ AND circ.due_date BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ AND circ.xact_finish IS NULL
+ )
+ WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_circulation t WHERE t.emergency_closing = e_closing AND t.circulation = circ.id);
+
+ GET DIAGNOSTICS tmp = ROW_COUNT;
+ touched.circulations := tmp;
+
+ INSERT INTO action.emergency_closing_reservation (emergency_closing, reservation)
+ SELECT e_closing,
+ res.id
+ FROM actor.org_unit_closed closing
+ JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+ JOIN booking.reservation res ON (
+ res.pickup_lib = closing.org_unit
+ AND res.end_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ )
+ WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_reservation t WHERE t.emergency_closing = e_closing AND t.reservation = res.id);
+
+ GET DIAGNOSTICS tmp = ROW_COUNT;
+ touched.reservations := tmp;
+
+ INSERT INTO action.emergency_closing_hold (emergency_closing, hold)
+ SELECT e_closing,
+ hold.id
+ FROM actor.org_unit_closed closing
+ JOIN action.emergency_closing ec ON (closing.emergency_closing = ec.id AND ec.id = e_closing)
+ JOIN action.hold_request hold ON (
+ pickup_lib = closing.org_unit
+ AND
+ (
+ hold.shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ OR hold.expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ )
+ AND hold.fulfillment_time IS NULL
+ AND hold.cancel_time IS NULL
+ )
+ WHERE NOT EXISTS (SELECT 1 FROM action.emergency_closing_hold t WHERE t.emergency_closing = e_closing AND t.hold = hold.id);
+
+ GET DIAGNOSTICS tmp = ROW_COUNT;
+ touched.holds := tmp;
+
+ UPDATE action.emergency_closing
+ SET process_start_time = NOW(),
+ last_update_time = NOW()
+ WHERE id = e_closing;
+
+ RETURN NEXT touched;
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION action.emergency_closing_stage_2_hold ( hold_closing_entry INT )
+ RETURNS BOOL AS $$
+DECLARE
+ hold action.hold_request%ROWTYPE;
+ e_closing action.emergency_closing%ROWTYPE;
+ e_c_hold action.emergency_closing_hold%ROWTYPE;
+ closing actor.org_unit_closed%ROWTYPE;
+ day_number INT;
+ hoo_close TIME WITHOUT TIME ZONE;
+ plus_days INT;
+BEGIN
+ -- Gather objects involved
+ SELECT * INTO e_c_hold
+ FROM action.emergency_closing_hold
+ WHERE id = hold_closing_entry;
+
+ IF e_c_hold.process_time IS NOT NULL THEN
+ -- Already processed ... moving on
+ RETURN FALSE;
+ END IF;
+
+ SELECT * INTO e_closing
+ FROM action.emergency_closing
+ WHERE id = e_c_hold.emergency_closing;
+
+ IF e_closing.process_start_time IS NULL THEN
+ -- Huh... that's odd. And wrong.
+ RETURN FALSE;
+ END IF;
+
+ SELECT * INTO closing
+ FROM actor.org_unit_closed
+ WHERE emergency_closing = e_closing.id;
+
+ SELECT * INTO hold
+ FROM action.hold_request h
+ WHERE id = e_c_hold.hold;
+
+ -- Record the processing
+ UPDATE action.emergency_closing_hold
+ SET original_shelf_expire_time = hold.shelf_expire_time,
+ original_expire_time = hold.expire_time,
+ process_time = NOW()
+ WHERE id = hold_closing_entry;
+
+ UPDATE action.emergency_closing
+ SET last_update_time = NOW()
+ WHERE id = e_closing.id;
+
+ UPDATE action.hold_request
+ SET shelf_expire_time = CASE
+ WHEN shelf_expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ THEN evergreen.find_next_open_time(closing.org_unit, hold.shelf_expire_time, TRUE)
+ ELSE hold.shelf_expire_time
+ END,
+ expire_time = CASE
+ WHEN expire_time BETWEEN closing.close_start AND (closing.close_end + '1s'::INTERVAL)
+ THEN evergreen.find_next_open_time(closing.org_unit, hold.expire_time, TRUE)
+ ELSE hold.expire_time
+ END
+ WHERE id = hold.id;
+
+ RETURN TRUE;
+END;
+$$ LANGUAGE PLPGSQL;
+
+COMMIT;