<class id="mb" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="money::billing" oils_persist:tablename="money.billing" reporter:label="Billing Line Item">
<fields oils_persist:primary="id" oils_persist:sequence="money.billing_id_seq">
<field reporter:label="Amount" name="amount" reporter:datatype="money" />
- <field reporter:label="Billing Timestamp" name="billing_ts" reporter:datatype="timestamp"/>
+ <field reporter:label="Create Date" name="create_date" reporter:datatype="timestamp"/>
+ <field reporter:label="Billing Period Start" name="period_start" reporter:datatype="timestamp"/>
+ <field reporter:label="Billing Period End" name="period_end" reporter:datatype="timestamp"/>
+ <field reporter:label="Legacy Billing Timestamp" name="billing_ts" reporter:datatype="timestamp"/>
<field reporter:label="Legacy Billing Type" name="billing_type" reporter:datatype="text"/>
<field reporter:label="Billing ID" name="id" reporter:datatype="id" />
<field reporter:label="Note" name="note" reporter:datatype="text"/>
sub create_bill {
- my($class, $e, $amount, $btype, $type, $xactid, $note, $billing_ts) = @_;
+ my($class, $e, $amount, $btype, $type, $xactid, $note, $period_start, $period_end) = @_;
$logger->info("The system is charging $amount [$type] on xact $xactid");
$note ||= 'SYSTEM GENERATED';
my $bill = Fieldmapper::money::billing->new;
$bill->xact($xactid);
$bill->amount($amount);
- $bill->billing_ts($billing_ts);
+ $bill->period_start($period_start);
+ $bill->period_end($period_end);
$bill->billing_type($type);
$bill->btype($btype);
$bill->note($note);
my $tz = $U->ou_ancestor_setting_value(
$c->$circ_lib_method, 'lib.timezone') || 'local';
- my ($latest_billing_ts, $latest_amount) = ('',0);
+ my ($latest_period_end, $latest_amount) = ('',0);
for (my $bill = 1; $bill <= $pending_fine_count; $bill++) {
if ($current_fine_total >= $max_fine) {
}
# Use org time zone (or default to 'local')
- my $billing_ts = DateTime->from_epoch( epoch => $last_fine, time_zone => $tz );
+ my $period_end = DateTime->from_epoch( epoch => $last_fine, time_zone => $tz );
my $current_bill_count = $bill;
while ( $current_bill_count ) {
- $billing_ts->add( seconds_to_interval_hash( $fine_interval ) );
+ $period_end->add( seconds_to_interval_hash( $fine_interval ) );
$current_bill_count--;
}
+ my $period_start = $period_end->clone->subtract( seconds_to_interval_hash( $fine_interval - 1 ) );
- my $timestamptz = $billing_ts->strftime('%FT%T%z');
+ my $timestamptz = $period_end->strftime('%FT%T%z');
if (!$skip_closed_check) {
- my $dow = $billing_ts->day_of_week_0();
+ my $dow = $period_end->day_of_week_0();
my $dow_open = "dow_${dow}_open";
my $dow_close = "dow_${dow}_close";
}
$current_fine_total += $this_billing_amount;
$latest_amount += $this_billing_amount;
- $latest_billing_ts = $timestamptz;
+ $latest_period_end = $timestamptz;
my $bill = Fieldmapper::money::billing->new;
$bill->xact($c->id);
$bill->billing_type("Overdue materials");
$bill->btype(1);
$bill->amount(sprintf('%0.2f', $this_billing_amount/100));
- $bill->billing_ts($timestamptz);
+ $bill->period_start($period_start->strftime('%FT%T%z'));
+ $bill->period_end($timestamptz);
$e->create_money_billing($bill);
}
- $conn->respond( "\t\tAdding fines totaling $latest_amount for overdue up to $latest_billing_ts\n" )
- if ($conn and $latest_billing_ts and $latest_amount);
+ $conn->respond( "\t\tAdding fines totaling $latest_amount for overdue up to $latest_period_end\n" )
+ if ($conn and $latest_period_end and $latest_amount);
# Calculate penalties inline
CREATE TABLE money.billing (
id BIGSERIAL PRIMARY KEY,
xact BIGINT NOT NULL, -- money.billable_xact.id
- billing_ts TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+ billing_ts TIMESTAMP WITH TIME ZONE NOT NULL, -- DEPRECATED, legacy only
voided BOOL NOT NULL DEFAULT FALSE,
voider INT,
void_time TIMESTAMP WITH TIME ZONE,
amount NUMERIC(6,2) NOT NULL,
billing_type TEXT NOT NULL,
btype INT NOT NULL REFERENCES config.billing_type (id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
- note TEXT
+ note TEXT,
+ create_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+ period_start TIMESTAMP WITH TIME ZONE,
+ period_end TIMESTAMP WITH TIME ZONE
);
CREATE INDEX m_b_xact_idx ON money.billing (xact);
CREATE INDEX m_b_time_idx ON money.billing (billing_ts);
+CREATE INDEX m_b_create_date_idx ON money.billing (create_date);
+CREATE INDEX m_b_period_start_idx ON money.billing (period_start);
+CREATE INDEX m_b_period_end_idx ON money.billing (period_end);
CREATE INDEX m_b_voider_idx ON money.billing (voider); -- helps user merge function speed
+CREATE OR REPLACE FUNCTION money.maintain_billing_ts () RETURNS TRIGGER AS $$
+BEGIN
+ NEW.billing_ts := COALESCE(NEW.period_end, NEW.create_date);
+ RETURN NEW;
+END;
+$$ LANGUAGE PLPGSQL;
+CREATE TRIGGER maintain_billing_ts_tgr BEFORE INSERT OR UPDATE ON money.billing FOR EACH ROW EXECUTE PROCEDURE money.maintain_billing_ts();
+
CREATE TABLE money.payment (
id BIGSERIAL PRIMARY KEY,