]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/money.pm
"correct" open_user_summary method
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / money.pm
1 package OpenILS::Application::Storage::Publisher::money;
2 use base qw/OpenILS::Application::Storage/;
3 use OpenSRF::Utils::Logger qw/:level/;
4
5 my $log = 'OpenSRF::Utils::Logger';
6
7 sub _make_mbts {
8         my @xacts = @_;
9
10         my @mbts;
11         for my $x (@xacts) {
12                 my $s = new Fieldmapper::money::billable_transaction_summary;
13                 $s->id( $x->id );
14                 $s->usr( $x->usr );
15                 $s->xact_start( $x->xact_start );
16                 $s->xact_finish( $x->xact_finish );
17
18                 my $to = 0;
19                 my $lb = undef;
20                 for my $b ($x->billings) {
21                         next if ($b->voided);
22                         #$log->debug( "billing is ".$b->amount, DEBUG );
23                         $to += ($b->amount * 100);
24                         $lb ||= $b->billing_ts;
25                         if ($b->billing_ts ge $lb) {
26                                 $lb = $b->billing_ts;
27                                 $s->last_billing_note($b->note);
28                                 $s->last_billing_ts($b->billing_ts);
29                                 $s->last_billing_type($b->billing_type);
30                         }
31                 }
32
33                 $s->total_owed( sprintf('%0.2f', ($to) / 100 ) );
34
35                 my $tp = 0;
36                 my $lp = undef;
37                 for my $p ($x->payments) {
38                         #$log->debug( "payment is ".$p->amount." voided = ".$p->voided, DEBUG );
39                         next if ($p->voided eq 't');
40                         $tp += ($p->amount * 100);
41                         $lp ||= $p->payment_ts;
42                         if ($p->payment_ts ge $lp) {
43                                 $lp = $p->payment_ts;
44                                 $s->last_payment_note($p->note);
45                                 $s->last_payment_ts($p->payment_ts);
46                                 $s->last_payment_type($p->payment_type);
47                         }
48                 }
49                 $s->total_paid( sprintf('%0.2f', ($tp) / 100 ) );
50
51                 $s->balance_owed( sprintf('%0.2f', (($to) - ($tp)) / 100) );
52                 #$log->debug( "balance of ".$x->id." == ".$s->balance_owed, DEBUG );
53
54                 $s->xact_type( 'grocery' ) if (money::grocery->retrieve($x->id));
55                 $s->xact_type( 'circulation' ) if (action::circulation->retrieve($x->id));
56
57                 push @mbts, $s;
58         }
59
60         return @mbts;
61 }
62
63 sub search_mbts {
64         my $self = shift;
65         my $client = shift;
66         my $search = shift;
67
68         my @xacts = money::billable_transaction->search_where( $search );
69         $client->respond( $_ ) for (_make_mbts(@xacts));
70
71         return undef;
72 }
73 __PACKAGE__->register_method(
74         method          => 'search_mbts',
75         api_name        => 'open-ils.storage.money.billable_transaction.summary.search',
76         stream          => 1,
77         argc            => 1,
78 );
79
80 sub search_ous {
81         my $self = shift;
82         my $client = shift;
83         my $usr = shift;
84
85         my @xacts = $self->method_lookup( 'open-ils.storage.money.billable_transaction.summary.search' )->run( { usr => $usr } );
86
87         my ($total,$owed,$paid) = (0.0,0.0,0.0);
88         for my $x (@xacts) {
89                 $total += $x->total_owed;
90                 $owed += $x->balance_owed;
91                 $paid += $x->total_paid;
92         }
93
94         my $ous = Fieldmapper::money::open_user_summary->new;
95         $ous->usr( $usr );
96         $ous->total_paid( sprintf('%0.2f', $paid) );
97         $ous->total_owed( sprintf('%0.2f', $total) );
98         $ous->balance_owed( sprintf('%0.2f', $owed) );
99
100         return $ous;
101 }
102 __PACKAGE__->register_method(
103         method          => 'search_ous',
104         api_name        => 'open-ils.storage.money.open_user_summary.search',
105         argc            => 1,
106 );
107
108
109 sub new_collections {
110         my $self = shift;
111         my $client = shift;
112         my $age = shift;
113         my $amount = shift;
114         my @loc = @_;
115
116         my $mct = money::collections_tracker->table;
117         my $mb = money::billing->table;
118         my $circ = action::circulation->table;
119         my $mg = money::grocery->table;
120         my $descendants = "actor.org_unit_descendants((select id from actor.org_unit where shortname = ?))";
121
122         my $SQL = <<"   SQL";
123                 SELECT  lt.usr,
124                         MAX(bl.billing_ts) AS last_pertinent_billing,
125                         SUM(bl.amount) - COALESCE(SUM((SELECT SUM(amount) FROM money.payment WHERE xact = lt.id)),0) AS threshold_amount
126                   FROM  ( SELECT id,usr,billing_location AS location FROM money.grocery
127                                 UNION ALL
128                           SELECT id,usr,circ_lib AS location FROM action.circulation ) AS lt
129                         JOIN $descendants d ON (lt.location = d.id)
130                         JOIN money.billing bl ON (lt.id = bl.xact AND bl.voided IS FALSE)
131                   WHERE AGE(bl.billing_ts) > ?
132                   GROUP BY lt.usr
133                   HAVING  SUM(
134                                 (SELECT COUNT(*)
135                                   FROM  money.collections_tracker
136                                   WHERE usr = lt.usr
137                                         AND location in (
138                                                 (SELECT id
139                                                   FROM  $descendants )
140                                         )
141                                 ) ) = 0
142                         AND (SUM(bl.amount) - COALESCE(SUM((SELECT SUM(amount) FROM money.payment WHERE xact = lt.id)),0)) > ? 
143         SQL
144
145         my @l_ids;
146         for my $l (@loc) {
147                 my $sth = money::collections_tracker->db_Main->prepare($SQL);
148                 $sth->execute(uc($l), $age, uc($l), $amount );
149                 while (my $row = $sth->fetchrow_hashref) {
150                         #$row->{usr} = actor::user->retrieve($row->{usr})->to_fieldmapper;
151                         $client->respond( $row );
152                 }
153         }
154         return undef;
155 }
156 __PACKAGE__->register_method(
157         method          => 'new_collections',
158         api_name        => 'open-ils.storage.money.collections.users_of_interest',
159         stream          => 1,
160         argc            => 3,
161 );
162
163 sub active_in_collections {
164         my $self = shift;
165         my $client = shift;
166         my $startdate = shift;
167         my $enddate = shift;
168         my @loc = @_;
169
170         my $mct = money::collections_tracker->table;
171         my $mb = money::billing->table;
172         my $circ = action::circulation->table;
173         my $mg = money::grocery->table;
174         my $descendants = "actor.org_unit_descendants((select id from actor.org_unit where shortname = ?))";
175
176         my $SQL = <<"   SQL";
177                 SELECT  lt.usr,
178                         MAX(bl.billing_ts) AS last_pertinent_billing,
179                         MAX(pm.payment_ts) AS last_pertinent_payment
180                   FROM  ( SELECT id,usr,billing_location AS location, 'g'::char AS x_type FROM money.grocery
181                                 UNION ALL
182                           SELECT id,usr,circ_lib AS location, 'c'::char AS x_type FROM action.circulation
183                                 UNION ALL
184                           SELECT id,usr,circ_lib AS location, 'i'::char AS x_type FROM action.circulation
185                             WHERE checkin_time between ? and ? ) AS lt
186                         JOIN $descendants d ON (lt.location = d.id)
187                         JOIN money.collections_tracker cl ON (lt.usr = cl.usr)
188                         LEFT JOIN money.billing bl ON (lt.id = bl.xact)
189                         LEFT JOIN money.payment pm ON (lt.id = pm.xact)
190                   WHERE bl.billing_ts between ? and ?
191                         OR pm.payment_ts between ? and ?
192                         OR lt.x_type = 'i'::char
193                   GROUP BY 1
194         SQL
195
196         my @l_ids;
197         for my $l (@loc) {
198                 my $sth = money::collections_tracker->db_Main->prepare($SQL);
199                 $sth->execute( $startdate, $enddate, uc($l), $startdate, $enddate, $startdate, $enddate );
200                 while (my $row = $sth->fetchrow_hashref) {
201                         $row->{usr} = actor::user->retrieve($row->{usr})->to_fieldmapper;
202                         $client->respond( $row );
203                 }
204         }
205         return undef;
206 }
207 __PACKAGE__->register_method(
208         method          => 'active_in_collections',
209         api_name        => 'open-ils.storage.money.collections.users_with_activity',
210         stream          => 1,
211         argc            => 3,
212 );
213
214 sub ou_desk_payments {
215         my $self = shift;
216         my $client = shift;
217         my $lib = shift;
218         my $startdate = shift;
219         my $enddate = shift;
220
221         return undef unless ($startdate =~ /^\d{4}-\d{2}-\d{2}$/o);
222         return undef unless ($enddate =~ /^\d{4}-\d{2}-\d{2}$/o);
223         return undef unless ($lib =~ /^\d+$/o);
224
225         my $sql = <<"   SQL";
226
227 SELECT  *
228   FROM  crosstab(\$\$
229          SELECT ws.id,
230                 p.payment_type,
231                 SUM(COALESCE(p.amount,0.0))
232           FROM  money.desk_payment_view p
233                 JOIN actor.workstation ws ON (ws.id = p.cash_drawer)
234           WHERE p.payment_ts >= '$startdate'
235                 AND p.payment_ts < '$enddate'::TIMESTAMPTZ + INTERVAL '1 day'
236                 AND p.voided IS FALSE
237                 AND ws.owning_lib = $lib
238          GROUP BY 1, 2
239          ORDER BY 1,2
240         \$\$) AS X(
241           workstation int,
242           cash_payment numeric(10,2),
243           check_payment numeric(10,2),
244           credit_card_payment numeric(10,2) );
245
246         SQL
247
248         my $rows = money::payment->db_Main->selectall_arrayref( $sql );
249
250         for my $r (@$rows) {
251                 my $x = new Fieldmapper::money::workstation_payment_summary;
252                 $x->workstation( actor::workstation->retrieve($$r[0])->to_fieldmapper );
253                 $x->cash_payment($$r[1]);
254                 $x->check_payment($$r[2]);
255                 $x->credit_card_payment($$r[3]);
256
257                 $client->respond($x);
258         }
259
260         return undef;
261 }
262 __PACKAGE__->register_method(
263         method          => 'ou_desk_payments',
264         api_name        => 'open-ils.storage.money.org_unit.desk_payments',
265         stream          => 1,
266         argc            => 3,
267 );
268
269 sub ou_user_payments {
270         my $self = shift;
271         my $client = shift;
272         my $lib = shift;
273         my $startdate = shift;
274         my $enddate = shift;
275
276         return undef unless ($startdate =~ /^\d{4}-\d{2}-\d{2}$/o);
277         return undef unless ($enddate =~ /^\d{4}-\d{2}-\d{2}$/o);
278         return undef unless ($lib =~ /^\d+$/o);
279
280         my $sql = <<"   SQL";
281
282 SELECT  *
283   FROM  crosstab(\$\$
284          SELECT au.id,
285                 p.payment_type,
286                 SUM(COALESCE(p.amount,0.0))
287           FROM  money.bnm_payment_view p
288                 JOIN actor.usr au ON (au.id = p.accepting_usr)
289           WHERE p.payment_ts >= '$startdate'
290                 AND p.payment_ts < '$enddate'::TIMESTAMPTZ + INTERVAL '1 day'
291                 AND p.voided IS FALSE
292                 AND au.home_ou = $lib
293                 AND p.payment_type IN ('credit_payment','forgive_payment','work_payment')
294          GROUP BY 1, 2
295          ORDER BY 1,2
296         \$\$) AS X(
297           usr int,
298           forgive_payment numeric(10,2),
299           work_payment numeric(10,2),
300           credit_payment numeric(10,2) );
301
302         SQL
303
304         my $rows = money::payment->db_Main->selectall_arrayref( $sql );
305
306         for my $r (@$rows) {
307                 my $x = new Fieldmapper::money::user_payment_summary;
308                 $x->usr( actor::user->retrieve($$r[0])->to_fieldmapper );
309                 $x->forgive_payment($$r[1]);
310                 $x->work_payment($$r[2]);
311                 $x->credit_payment($$r[3]);
312
313                 $client->respond($x);
314         }
315
316         return undef;
317 }
318 __PACKAGE__->register_method(
319         method          => 'ou_user_payments',
320         api_name        => 'open-ils.storage.money.org_unit.user_payments',
321         stream          => 1,
322         argc            => 3,
323 );
324
325
326 1;