| 1 | -- |
|---|
| 2 | -- PostgreSQL create schema for CRCnet Configuration Systems billing module |
|---|
| 3 | -- |
|---|
| 4 | -- All prices in these tables should be sales tax exclusive |
|---|
| 5 | -- |
|---|
| 6 | -- Author: Ivan Meredith <ijm1@cs.waikato.ac.nz> |
|---|
| 7 | -- Matt Brown <matt@crc.net.nz> |
|---|
| 8 | -- Version: $Id$ |
|---|
| 9 | -- |
|---|
| 10 | |
|---|
| 11 | -- Create a customer contact_type |
|---|
| 12 | INSERT INTO contact_types VALUES ('customer', 'Customer'); |
|---|
| 13 | |
|---|
| 14 | -- List of plans that are dealt with via RADIUS |
|---|
| 15 | CREATE TABLE radius_plan ( |
|---|
| 16 | plan_id SERIAL PRIMARY KEY, |
|---|
| 17 | -- machine readable name for the plan ascii only, no spaces |
|---|
| 18 | plan_name varchar(40) NOT NULL, |
|---|
| 19 | -- Upstream (away from customer) rate |
|---|
| 20 | upstream_kbps integer NOT NULL, |
|---|
| 21 | -- Downstream (towards customer) rate |
|---|
| 22 | downstream_kbps integer NOT NULL |
|---|
| 23 | ); |
|---|
| 24 | |
|---|
| 25 | -- Billing Plans that customers can be placed on |
|---|
| 26 | CREATE TABLE billing_plan ( |
|---|
| 27 | plan_id SERIAL PRIMARY KEY, |
|---|
| 28 | plan_name varchar(40) NOT NULL, |
|---|
| 29 | description varchar(255) NOT NULL, |
|---|
| 30 | -- The monthly cost of the plan |
|---|
| 31 | price real NOT NULL, |
|---|
| 32 | -- The RADIUS plan that the user of the plan is initially placed on |
|---|
| 33 | radius_plan integer NOT NULL REFERENCES radius_plan (plan_id) |
|---|
| 34 | ON DELETE RESTRICT, |
|---|
| 35 | -- The number of MB the user can transfer before they reach the 'cap', |
|---|
| 36 | -- NULL for uncapped |
|---|
| 37 | included_mb integer, |
|---|
| 38 | -- What time period the cap operates on (daily, weekly, monthly) |
|---|
| 39 | cap_period varchar(20) NOT NULL DEFAULT 'monthly', |
|---|
| 40 | -- What to do when the 'cap' is reached, one of (throttle, purchase) |
|---|
| 41 | cap_action varchar(20) NOT NULL DEFAULT 'throttle', |
|---|
| 42 | -- Additional information for the cap |
|---|
| 43 | -- If cap_action is throttle, this is the ID of the RADIUS plan to |
|---|
| 44 | -- place the user onto when the cap is reached |
|---|
| 45 | -- If cap_action is purchase, this is the number of mb to add to the |
|---|
| 46 | -- cap_at_mb parameter in the state table |
|---|
| 47 | cap_param integer, |
|---|
| 48 | -- The cost of taking the cap action |
|---|
| 49 | cap_price real |
|---|
| 50 | ); |
|---|
| 51 | |
|---|
| 52 | -- Discounts that can be applied to a customers account each month |
|---|
| 53 | CREATE TABLE billing_discount ( |
|---|
| 54 | discount_id SERIAL PRIMARY KEY, |
|---|
| 55 | discount_name varchar(40) NOT NULL, |
|---|
| 56 | description varchar(255) NOT NULL, |
|---|
| 57 | -- The amount of the discount, must be a positive integer |
|---|
| 58 | amount real NOT NULL |
|---|
| 59 | ); |
|---|
| 60 | |
|---|
| 61 | -- Further details about each customers account |
|---|
| 62 | CREATE TABLE customer_account ( |
|---|
| 63 | contact_id integer NOT NULL REFERENCES contact (contact_id) |
|---|
| 64 | ON DELETE CASCADE, |
|---|
| 65 | -- The billing plan the customer has chosen |
|---|
| 66 | plan_id integer NOT NULL REFERENCES billing_plan (plan_id) |
|---|
| 67 | ON DELETE RESTRICT, |
|---|
| 68 | -- Who to make the invoice out to |
|---|
| 69 | billing_name varchar(50) NOT NULL, |
|---|
| 70 | -- The address to send the invoice to |
|---|
| 71 | billing_address varchar(200) NOT NULL, |
|---|
| 72 | -- The customers current account balance |
|---|
| 73 | account_balance real DEFAULT 0, |
|---|
| 74 | -- Join date of the customer, used for working out when data history starts |
|---|
| 75 | join_date timestamp with time zone DEFAULT current_timestamp |
|---|
| 76 | ); |
|---|
| 77 | |
|---|
| 78 | -- Details of the discounts that apply to individual customers |
|---|
| 79 | CREATE TABLE customer_discount ( |
|---|
| 80 | customer_discount_id integer PRIMARY KEY, |
|---|
| 81 | contact_id integer NOT NULL REFERENCES contact (contact_id) |
|---|
| 82 | ON DELETE CASCADE, |
|---|
| 83 | discount_id integer NOT NULL REFERENCES billing_discount |
|---|
| 84 | (discount_id) ON DELETE CASCADE, |
|---|
| 85 | -- The first date this discount should be applied to the customers account |
|---|
| 86 | start_date timestamp with time zone NOT NULL, |
|---|
| 87 | -- True if the discount should be applied for every subsequent month |
|---|
| 88 | recurring boolean NOT NULL, |
|---|
| 89 | -- Followed by an optional (inclusive) end date after which the discount |
|---|
| 90 | -- Will no longer be applied to the customers account |
|---|
| 91 | end_date timestamp with time zone |
|---|
| 92 | ); |
|---|
| 93 | |
|---|
| 94 | -- Current state of the customer |
|---|
| 95 | -- This table is updated regularly to track how much traffic the customer has |
|---|
| 96 | -- used. Only completed sessions are added to the traffic used in this table. |
|---|
| 97 | CREATE TABLE customer_state ( |
|---|
| 98 | contact_id integer NOT NULL REFERENCES contact (contact_id) |
|---|
| 99 | ON DELETE CASCADE, |
|---|
| 100 | -- The plan the customer is currently active on |
|---|
| 101 | plan_id integer NOT NULL REFERENCES billing_plan (plan_id) |
|---|
| 102 | ON DELETE RESTRICT, |
|---|
| 103 | -- The date that this entry was last reset back to plan defaults |
|---|
| 104 | plan_start timestamp with time zone NOT NULL, |
|---|
| 105 | -- The current cap limit, may be greater than the plans included_mb if |
|---|
| 106 | -- extra MBs have been purchased |
|---|
| 107 | cap_at_mb integer NOT NULL, |
|---|
| 108 | -- The number of MB used since the last reset of this entry |
|---|
| 109 | used_mb integer NOT NULL DEFAULT 0, |
|---|
| 110 | -- The last time the used_mb counter was updated |
|---|
| 111 | last_updated timestamp with time zone NOT NULL, |
|---|
| 112 | -- The RADIUS plan that is currently active for this user |
|---|
| 113 | radius_plan integer NOT NULL REFERENCES radius_plan (plan_id) |
|---|
| 114 | ON DELETE RESTRICT |
|---|
| 115 | ); |
|---|
| 116 | |
|---|
| 117 | -- The real current state of this customer |
|---|
| 118 | -- This takes into accunt the used_mb's recorded in the above state table, plus |
|---|
| 119 | -- the number of megabytes used in the currently active session |
|---|
| 120 | CREATE VIEW current_customer_state AS SELECT |
|---|
| 121 | cs.contact_id, cs.plan_start, cs.used_mb, |
|---|
| 122 | cs.used_mb+COALESCE(t.acctinputoctets+t.acctoutputoctets,0)/1024/1024 AS |
|---|
| 123 | current_mb, ras.acctsessionid FROM customer_state cs, contact c LEFT JOIN |
|---|
| 124 | radius_active_sessions ras ON c.username=ras.username LEFT JOIN |
|---|
| 125 | radius_latest_traffic t ON ras.acctsessionid=t.acctsessionid WHERE |
|---|
| 126 | cs.contact_id=c.contact_id; |
|---|
| 127 | |
|---|
| 128 | -- Billing records for the customer |
|---|
| 129 | CREATE TABLE billing_record ( |
|---|
| 130 | contact_id integer NOT NULL REFERENCES contact (contact_id) |
|---|
| 131 | ON DELETE CASCADE, |
|---|
| 132 | -- The invoice that this record was billed on, NULL if not yet billed |
|---|
| 133 | invoice_id integer, |
|---|
| 134 | -- The date this record was added |
|---|
| 135 | record_date timestamp with time zone, |
|---|
| 136 | -- Description of the charge |
|---|
| 137 | description varchar(255) NOT NULL, |
|---|
| 138 | -- The per unit amount of the charge (negative for refunds) |
|---|
| 139 | amount real NOT NULL, |
|---|
| 140 | -- The quantity to charge. Eg. final cost for record is amount * quantity |
|---|
| 141 | quantity real NOT NULL |
|---|
| 142 | ); |
|---|
| 143 | |
|---|
| 144 | -- Record of invoices sent to the customer |
|---|
| 145 | CREATE TABLE billing_invoice ( |
|---|
| 146 | contact_id integer NOT NULL REFERENCES contact (contact_id) |
|---|
| 147 | ON DELETE CASCADE, |
|---|
| 148 | invoice_id integer NOT NULL, |
|---|
| 149 | invoice_date timestamp with time zone NOT NULL, |
|---|
| 150 | invoice_subtotal real NOT NULL, |
|---|
| 151 | -- Filesystem path to the invoice PDF |
|---|
| 152 | invoice_file varchar(4096), |
|---|
| 153 | -- True if invoice has been emailed to the customer |
|---|
| 154 | email_sent boolean NOT NULL DEFAULT FALSE, |
|---|
| 155 | -- The date and filesystem path to the file that this invoice was |
|---|
| 156 | -- exported to for payment processing |
|---|
| 157 | payment_export_date timestamp with time zone, |
|---|
| 158 | payment_export_file varchar(4096), |
|---|
| 159 | -- The date and filesystem path to the file that this invoice was |
|---|
| 160 | -- exported to for external accounting purposes |
|---|
| 161 | acct_export_date timestamp with time zone, |
|---|
| 162 | acct_export_file varchar(4096), |
|---|
| 163 | -- True if the invoice has been paid |
|---|
| 164 | invoice_paid boolean NOT NULL DEFAULT FALSE, |
|---|
| 165 | -- Details of the date and input file that we received the payment |
|---|
| 166 | -- details via |
|---|
| 167 | payment_import_date timestamp with time zone, |
|---|
| 168 | payment_import_file varchar(4096) |
|---|
| 169 | ); |
|---|
| 170 | |
|---|
| 171 | -- Sequence to assist in generating invoice IDs |
|---|
| 172 | CREATE SEQUENCE billing_invoice_id_seq MINVALUE 100000 START 100000 NO CYCLE; |
|---|
| 173 | |
|---|
| 174 | -- List of billing records that have not yet been invoived |
|---|
| 175 | CREATE VIEW non_invoiced_billing_records AS SELECT |
|---|
| 176 | * FROM billing_record WHERE invoice_id IS NULL; |
|---|
| 177 | |
|---|
| 178 | -- List of customer type contacts along with their additional information |
|---|
| 179 | CREATE VIEW customers AS SELECT c.*, a.plan_id, a.billing_name, |
|---|
| 180 | a.billing_address, a.account_balance, b.plan_name |
|---|
| 181 | FROM billing_plan b,contact c LEFT JOIN customer_account a ON |
|---|
| 182 | c.contact_id=a.contact_id HAVING c.type='customer' AND b.plan_id=a.plan_id; |
|---|
| 183 | |
|---|
| 184 | -- List of plans overviews, including rate data. |
|---|
| 185 | CREATE VIEW plans AS SELECT p.*, r.plan_name AS rad_plan_name,r.upstream_kbps, |
|---|
| 186 | r.downstream_kbps FROM billing_plan p, radius_plan r WHERE r.plan_id=p.radius_plan; |
|---|
| 187 | |
|---|
| 188 | -- Gets information needed for rollover. use with "WHERE cap_period='weekly' |
|---|
| 189 | -- to get rollovers that are done weekly |
|---|
| 190 | CREATE VIEW rollover AS SELECT a.plan_name, a.description, a.price, |
|---|
| 191 | a.included_mb, a.cap_period, a.radius_plan, b.contact_id FROM billing_plan a, |
|---|
| 192 | customer_state b WHERE b.plan_id=a.plan_id; |
|---|
| 193 | |
|---|
| 194 | -- vim: ft=sql |
|---|