Circulations are how we keep track of a certain type of item (material) usage in Evergreen. When an item "circulates", it is checked out to (loaned to, or placed in custody of) a patron (in the common case, "user" is more general). The item generally leaves the building, but doesn't have to, and after a set amount of time may become "due" for return. Patrons may "renew" the loan period for their items, and usually get fined for any that are overdue. Evergreen doesn't allow "nested" circulations. An item may be actively circulating only once at any given time.
In Evergreen, circulations are a type of billable transaction (in an object oriented sense, circulations inherit from billable transactions). A transaction is either opened or closed, and may or may not contain (or be linked to from) billings and payments. If the total monetary amount of the billings is greater than that of the payments, then the patron owes money for that billable transaction. For circulations, each overdue/late fine per fine interval is recorded as a line item billing that is attached to the circulation/billable transaction.
<class id="circ" controller="open-ils.cstore" oils_obj:fieldmapper="action::circulation" oils_persist:tablename="action.circulation" reporter:core="true" reporter:label="Circulation"> <fields oils_persist:primary="id" oils_persist:sequence="money.billable_xact_id_seq"> <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" /> <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" /> <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" /> <field reporter:label="Check In Library" name="checkin_lib" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="org_unit"/> <field reporter:label="Check In Staff" name="checkin_staff" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Check In Date/Time" name="checkin_time" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/> <field reporter:label="Circulating Library" name="circ_lib" oils_obj:array_position="6" oils_persist:virtual="false" reporter:datatype="org_unit"/> <field reporter:label="Circulating Staff" name="circ_staff" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Desk Renewal" name="desk_renewal" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="bool"/> <field reporter:label="Due Date/Time" name="due_date" oils_obj:array_position="9" oils_persist:virtual="false" reporter:datatype="timestamp"/> <field reporter:label="Circulation Duration" name="duration" oils_obj:array_position="10" oils_persist:virtual="false" reporter:datatype="interval"/> <field reporter:label="Circ Duration Rule" name="duration_rule" oils_obj:array_position="11" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Fine Interval" name="fine_interval" oils_obj:array_position="12" oils_persist:virtual="false" reporter:datatype="interval"/> <field reporter:label="Circ ID" name="id" oils_obj:array_position="13" oils_persist:virtual="false" reporter:datatype="id" /> <field reporter:label="Max Fine Amount" name="max_fine" oils_obj:array_position="14" oils_persist:virtual="false" reporter:datatype="money" /> <field reporter:label="Max Fine Rule" name="max_fine_rule" oils_obj:array_position="15" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="OPAC Renewal" name="opac_renewal" oils_obj:array_position="16" oils_persist:virtual="false" reporter:datatype="bool"/> <field reporter:label="Phone Renewal" name="phone_renewal" oils_obj:array_position="17" oils_persist:virtual="false" reporter:datatype="bool"/> <field reporter:label="Recurring Fine Amount" name="recuring_fine" oils_obj:array_position="18" oils_persist:virtual="false" reporter:datatype="money" /> <field reporter:label="Recurring Fine Rule" name="recuring_fine_rule" oils_obj:array_position="19" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Remaining Renewals" name="renewal_remaining" oils_obj:array_position="20" oils_persist:virtual="false" reporter:datatype="int" /> <field reporter:label="Fine Stop Reason" name="stop_fines" oils_obj:array_position="21" oils_persist:virtual="false" reporter:datatype="text"/> <field reporter:label="Fine Stop Date/Time" name="stop_fines_time" oils_obj:array_position="22" oils_persist:virtual="false" reporter:datatype="timestamp"/> <field reporter:label="Circulating Item" name="target_copy" oils_obj:array_position="23" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Patron" name="usr" oils_obj:array_position="24" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Transaction Finish Date/Time" name="xact_finish" oils_obj:array_position="25" oils_persist:virtual="false" reporter:datatype="timestamp" /> <field reporter:label="Check Out Date/Time" name="xact_start" oils_obj:array_position="26" oils_persist:virtual="false" reporter:datatype="timestamp" /> <field reporter:label="Record Creation Date/Time" name="create_time" oils_obj:array_position="27" oils_persist:virtual="false" reporter:datatype="timestamp" /> <field reporter:label="Transaction Billings" name="billings" oils_obj:array_position="28" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Transaction Payments" name="payments" oils_obj:array_position="29" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Base Transaction" name="billable_transaction" oils_obj:array_position="30" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Circulation Type" name="circ_type" oils_obj:array_position="31" oils_persist:virtual="true" reporter:datatype="text"/> <field reporter:label="Billing Totals" name="billing_total" oils_obj:array_position="32" oils_persist:virtual="true" reporter:datatype="money"/> <field reporter:label="Payment Totals" name="payment_total" oils_obj:array_position="33" oils_persist:virtual="true" reporter:datatype="money"/> </fields> <links> <link field="billable_transaction" reltype="might_have" key="id" map="" class="mbt"/> <link field="circ_staff" reltype="has_a" key="id" map="" class="au"/> <link field="checkin_lib" reltype="has_a" key="id" map="" class="aou"/> <link field="target_copy" reltype="has_a" key="id" map="" class="acp"/> <link field="checkin_staff" reltype="has_a" key="id" map="" class="au"/> <link field="usr" reltype="has_a" key="id" map="" class="au"/> <link field="circ_lib" reltype="has_a" key="id" map="" class="aou"/> <link field="payments" reltype="has_many" key="xact" map="" class="mp"/> <link field="billings" reltype="has_many" key="xact" map="" class="mb"/> <link field="duration_rule" reltype="has_a" key="name" map="" class="crcd"/> <link field="max_fine_rule" reltype="has_a" key="name" map="" class="crmf"/> <link field="recuring_fine_rule" reltype="has_a" key="name" map="" class="crrf"/> <link field="circ_type" reltype="might_have" key="id" map="" class="rcirct"/> <link field="billing_total" reltype="might_have" key="xact" map="" class="rxbt"/> <link field="payment_total" reltype="might_have" key="xact" map="" class="rxpt"/> </links> </class>
evergreen=# \d "action".circulation Table "action.circulation" Column | Type | Modifiers --------------------+--------------------------+------------------------------------------------------------------ id | bigint | not null default nextval('money.billable_xact_id_seq'::regclass) usr | integer | not null xact_start | timestamp with time zone | not null default now() xact_finish | timestamp with time zone | target_copy | bigint | not null circ_lib | integer | not null circ_staff | integer | not null checkin_staff | integer | checkin_lib | integer | renewal_remaining | integer | not null due_date | timestamp with time zone | stop_fines_time | timestamp with time zone | checkin_time | timestamp with time zone | create_time | timestamp with time zone | not null default now() duration | interval | fine_interval | interval | not null default '1 day'::interval recuring_fine | numeric(6,2) | max_fine | numeric(6,2) | phone_renewal | boolean | not null default false desk_renewal | boolean | not null default false opac_renewal | boolean | not null default false duration_rule | text | not null recuring_fine_rule | text | not null max_fine_rule | text | not null stop_fines | text | Indexes: "circulation_pkey" PRIMARY KEY, btree (id) "circ_checkin_time" btree (checkin_time) WHERE checkin_time IS NOT NULL "circ_circ_lib_idx" btree (circ_lib) "circ_open_date_idx" btree (xact_start) WHERE xact_finish IS NULL "circ_open_xacts_idx" btree (usr) WHERE xact_finish IS NULL "circ_outstanding_idx" btree (usr) WHERE checkin_time IS NULL Check constraints: "circulation_stop_fines_check" CHECK (stop_fines = ANY (ARRAY['CHECKIN'::text, 'CLAIMSRETURNED'::text, 'LOST'::text, 'MAXFINES'::text, 'RENEW'::text, 'LONGOVERDUE'::text])) Foreign-key constraints: "action_circulation_circ_lib_fkey" FOREIGN KEY (circ_lib) REFERENCES actor.org_unit(id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED "action_circulation_target_copy_fkey" FOREIGN KEY (target_copy) REFERENCES asset."copy"(id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED "action_circulation_usr_fkey" FOREIGN KEY (usr) REFERENCES actor.usr(id) DEFERRABLE INITIALLY DEFERRED Triggers: action_circulation_stop_fines_tgr BEFORE UPDATE ON "action".circulation FOR EACH ROW EXECUTE PROCEDURE "action".circulation_claims_returned() Inherits: billable_xact
<class id="mbt" controller="open-ils.cstore" oils_obj:fieldmapper="money::billable_transaction" oils_persist:tablename="money.billable_xact" reporter:label="Billable Transaction"> <fields oils_persist:primary="id" oils_persist:sequence="money.billable_xact_id_seq"> <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" /> <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" /> <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" /> <field reporter:label="Transaction ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="id" /> <field reporter:label="User" name="usr" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="link"/> <field reporter:label="Transaction Finish Date/Time" name="xact_finish" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/> <field reporter:label="Transaction Start Date/Time" name="xact_start" oils_obj:array_position="6" oils_persist:virtual="false" reporter:datatype="timestamp"/> <field reporter:label="Grocery Billing link" name="grocery" oils_obj:array_position="7" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Circulation Billing link" name="circulation" oils_obj:array_position="8" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Billing Line Items" name="billings" oils_obj:array_position="9" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Payment Line Items" name="payments" oils_obj:array_position="10" oils_persist:virtual="true" reporter:datatype="link"/> <field reporter:label="Billing Totals" name="billing_total" oils_obj:array_position="11" oils_persist:virtual="true" reporter:datatype="money"/> <field reporter:label="Payment Totals" name="payment_total" oils_obj:array_position="12" oils_persist:virtual="true" reporter:datatype="money"/> </fields> <links> <link field="grocery" reltype="might_have" key="id" map="" class="mg"/> <link field="circulation" reltype="might_have" key="id" map="" class="circ"/> <link field="usr" reltype="has_a" key="id" map="" class="au"/> <link field="payments" reltype="has_many" key="xact" map="" class="mp"/> <link field="billings" reltype="has_many" key="xact" map="" class="mb"/> <link field="billing_total" reltype="might_have" key="xact" map="" class="rxbt"/> <link field="payment_total" reltype="might_have" key="xact" map="" class="rxpt"/> </links> </class>
evergreen=# \d money.billable_xact Table "money.billable_xact" Column | Type | Modifiers -------------+--------------------------+------------------------------------------------------------------ id | bigint | not null default nextval('money.billable_xact_id_seq'::regclass) usr | integer | not null xact_start | timestamp with time zone | not null default now() xact_finish | timestamp with time zone | Indexes: "billable_xact_pkey" PRIMARY KEY, btree (id) "m_b_x_open_xacts_idx" btree (usr) Foreign-key constraints: "money_billable_xact_usr_fkey" FOREIGN KEY (usr) REFERENCES actor.usr(id) DEFERRABLE INITIALLY DEFERRED