1 package Bcd
::Data
::Deposits
;
3 # This file is part of the breadcrumbs daemon (bcd).
4 # Copyright (C) 2007 Pasqualino Ferrentino
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 # Contact: lino.ferrentino@yahoo.it (in Italian, English or German).
26 #use Math::BigInt lib => "GMP";
28 use Bcd
::Constants
::DepositsConstants
;
36 INSERT_DEPOSIT_OR_WITHDRAWAL_REQUEST
=>
37 qq{INSERT into deposits_and_withdrawals
(id_user
, is_deposit
, amount
, status
, booking_token
, }.
38 qq{full_receipt_token
, secret_token
) }.
39 qq{values (?
, ?
, ?
, } . Bcd
::Constants
::DepositsConstants
::CREATION_STATE
. qq{, ?
, ?
, ?
)},
41 SELECT_DEPOSIT_OR_WITHDRAWAL_USER_BOOKING
=>
42 qq{SELECT
* from deposits_and_withdrawals where id_user
= ?
and is_deposit
= ?
and booking_token
= ?
},
44 SELECT_BOOKING_FROM_TOKEN
=>
45 qq{SELECT
* from deposits_and_withdrawals where booking_token
= ?
},
47 SELECT_BOOKING_FROM_ID
=>
48 qq{SELECT
* from deposits_and_withdrawals where id
= ?
},
50 SELECT_COUNT_PENDING_USERS_REQUESTS
=>
51 qq{SELECT count
(*) from deposits_and_withdrawals where id_user
=?
and }.
52 qq{status
!=}.Bcd
::Constants
::DepositsConstants
::COLLECTED
,
54 SELECT_PENDING_USERS_REQUEST
=>
55 qq{SELECT
* from deposits_and_withdrawals where id_user
=?
and }.
56 qq{status
!=}.Bcd
::Constants
::DepositsConstants
::COLLECTED
,
59 qq{DELETE FROM deposits_and_withdrawals WHERE id
= ?
},
61 SELECT_ALL_ANT_NEST_BOOKINGS_STATUS
=>
62 qq{SELECT d
.booking_token
, d
.amount FROM deposits_and_withdrawals AS d
, users as u WHERE
}.
63 qq{ d
.id_user
= u
.id AND u
.id_ant_nest
= ? AND d
.is_deposit
= ? AND d
.status
= ?
}.
66 SELECT_ALL_ANT_NEST_BOOKINGS_STATUS_OFFLINE
=>
67 qq{SELECT d
.booking_token
, d
.amount
, d
.full_receipt_token FROM deposits_and_withdrawals AS d
, users as u WHERE
}.
68 qq{ d
.id_user
= u
.id AND u
.id_ant_nest
= ? AND d
.is_deposit
= ? AND d
.status
= ?
}.
69 qq{ ORDER BY d
.booking_token
},
75 SELECT_USER_DEPOSIT_TO_CLAIM
=> "Deposits_select_user_deposit_to_claim",
76 CLAIM_USER_DEPOSIT
=> "Deposits_claim_user_deposit",
77 INSERT_NEW_DEPOSIT_REQUEST
=> "Deposits_insert_deposit_request",
78 CHANGE_STATE_TO_DEPOSIT
=> "Deposits_change_state_to_deposit",
79 SELECT_DEPOSIT_USER_WITH_TOKEN
=> "Deposits_select_deposit_user_with_token",
80 SELECT_DEPOSIT_WITH_ID
=> "Deposits_select_deposit_with_id",
83 #this function is one shot... so it does not put the commands in the
86 my ($self, $stash) = @_;
87 my $conn = $stash->get_connection();
89 #ok, now I should insert the values in the table...
90 my $sth = $conn->prepare(qq{insert into deposit_withdrawal_statuses
values(?
,?
)});
92 foreach (Bcd
::Constants
::DepositsConstants
::LIST_DEPOSITS_STATES
){
93 $sth->bind_param(1, $_->[0]);
94 $sth->bind_param(2, $_->[1]);
102 sub get_deposits_to_do_offline_ds
{
103 my ($self, $stash, $ant_nest) = @_;
105 return $self->_get_bookings_to_collect_offline_ds
106 ($stash, $ant_nest, 1, Bcd
::Constants
::DepositsConstants
::CREATION_STATE
);
109 sub get_withdrawals_to_do_offline_ds
{
110 my ($self, $stash, $ant_nest) = @_;
112 return $self->_get_bookings_to_collect_offline_ds
113 ($stash, $ant_nest, 0, Bcd
::Constants
::DepositsConstants
::CREATION_STATE
);
116 sub _get_bookings_to_collect_offline_ds
{
117 my ($self, $stash, $ant_nest, $is_deposit, $status) = @_;
119 my $st = $stash->prepare_cached(SELECT_ALL_ANT_NEST_BOOKINGS_STATUS_OFFLINE
);
120 $st->bind_param(1, $ant_nest);
121 $st->bind_param(2, $is_deposit);
122 $st->bind_param(3, $status);
126 my $var = $st->{NAME_lc
};
127 my $arr = $st->fetchall_arrayref();
129 #I put at the front of the recordset the columns names.
130 unshift (@
{$arr}, $var);
136 sub get_withdrawals_to_collect_offline_ds
{
137 my ($self, $stash, $ant_nest) = @_;
139 return $self->_select_all_ant_nest_booking_status_ds
140 ($stash, $ant_nest, 0, Bcd
::Constants
::DepositsConstants
::OFFLINE_ACKNOWLEDGED
);
143 sub get_all_created_deposits_ant_nest_ds
{
144 my ($self, $stash, $ant_nest) = @_;
146 return $self->_select_all_ant_nest_booking_status_ds
147 ($stash, $ant_nest, 1, Bcd
::Constants
::DepositsConstants
::CREATION_STATE
);
150 sub get_all_created_withdrawals_ant_nest_ds
{
151 my ($self, $stash, $ant_nest) = @_;
153 return $self->_select_all_ant_nest_booking_status_ds
154 ($stash, $ant_nest, 0, Bcd
::Constants
::DepositsConstants
::CREATION_STATE
);
157 sub _select_all_ant_nest_booking_status_ds
{
158 my ($self, $stash, $ant_nest, $is_deposit, $status) = @_;
160 my $st = $stash->prepare_cached(SELECT_ALL_ANT_NEST_BOOKINGS_STATUS
);
161 $st->bind_param(1, $ant_nest);
162 $st->bind_param(2, $is_deposit);
163 $st->bind_param(3, $status);
167 my $var = $st->{NAME_lc
};
168 my $arr = $st->fetchall_arrayref();
170 #I put at the front of the recordset the columns names.
171 unshift (@
{$arr}, $var);
176 sub delete_booking_id
{
177 my ($self, $stash, $booking_id) = @_;
179 my $st = $stash->prepare_cached(DELETE_BOOKING_ID
);
180 $st->bind_param(1, $booking_id);
184 sub get_pending_booking_from_user_id_arr
{
185 my ($self, $stash, $user_id) = @_;
187 my $st = $stash->prepare_cached(SELECT_PENDING_USERS_REQUEST
);
188 $st->bind_param(1, $user_id);
191 my $res = $st->fetchrow_arrayref();
197 =head1 are_there_pending_deposit_for_this_user
199 This function simply looks if the user has already some OR withdrawals active...
202 sub is_there_a_pending_request_for_this_user
{
203 my ($self, $stash, $user_id) = @_;
205 my $st = $stash->prepare_cached(SELECT_COUNT_PENDING_USERS_REQUESTS
);
206 $st->bind_param(1, $user_id);
209 my $res = $st->fetchrow_arrayref();
212 if ( $res->[0] != 0 ) {
220 sub _create_deposit_or_withdrawal_booking
{
221 my ($self, $stash, $user_id, $amount, $is_deposit) = @_;
223 my $booking_token = Bcd
::Data
::Token
::generate_new_token
();
224 my ($long_token, $blinded_token, $secret_token) = Bcd
::Data
::Token
::generate_long_token
();
226 #ok, now I should make the hash of the secret token
227 my $sha = Digest
::SHA1
->new;
228 $sha->add($secret_token);
229 my $digest = $sha->hexdigest;
231 #ok, now I am ready to insert the data in the table
232 my $st = $stash->prepare_cached(INSERT_DEPOSIT_OR_WITHDRAWAL_REQUEST
);
234 $st->bind_param(1, $user_id);
235 $st->bind_param(2, $is_deposit);
236 $st->bind_param(3, $amount);
237 $st->bind_param(4, $booking_token);
239 #if it is a withdrawal I record in the db the blinded token, not the full one
240 if ($is_deposit != 0){
241 $st->bind_param(5, $long_token);
243 $st->bind_param(5, $blinded_token);
246 $st->bind_param(6, $digest);
250 #I return these tokens, but one of them is not returned to the user.
251 return ($booking_token, $long_token, $blinded_token);
256 This function should see create a user deposit
260 sub create_deposit_booking
{
261 my ($self, $stash, $user_id, $amount) = @_;
263 my ($booking_token, $long_token, $blinded_token) =
264 $self->_create_deposit_or_withdrawal_booking
265 ($stash, $user_id, $amount, 1);
267 #the long token is NOT returned for the deposits
268 return ($booking_token, $blinded_token);
272 sub create_withdrawal_booking
{
274 my ($self, $stash, $user_id, $amount) = @_;
276 my ($booking_token, $long_token, $blinded_token) =
277 $self->_create_deposit_or_withdrawal_booking
278 ($stash, $user_id, $amount, 0);
280 #the blinded_token is NOT returned for the withdrawals
281 return ($booking_token, $long_token);
286 This function simply changes the state of the booking
289 sub treasurer_acknowledged
{
290 my ($self, $stash, $booking_id) = @_;
292 my $st = $stash->get_statement(CHANGE_STATE_TO_DEPOSIT
, $self);
294 $st->bind_param(1, Bcd
::Constants
::DepositsConstants
::OFFLINE_ACKNOWLEDGED
);
295 $st->bind_param(2, $booking_id);
297 return $st->execute();
300 sub get_deposit_booking_from_user_and_token
{
302 my ($self, $stash, $user_id, $booking) = @_;
304 return $self->_get_deposit_or_withdrawal_booking_from_user_token
305 ($stash, $user_id, $booking, '1');
308 sub get_withdrawal_booking_from_user_and_token
{
310 my ($self, $stash, $user_id, $booking) = @_;
312 return $self->_get_deposit_or_withdrawal_booking_from_user_token
313 ($stash, $user_id, $booking, '0');
316 sub _get_deposit_or_withdrawal_booking_from_user_token
{
318 my ($self, $stash, $user_id, $booking, $is_deposit) = @_;
320 my $st = $stash->prepare_cached(SELECT_DEPOSIT_OR_WITHDRAWAL_USER_BOOKING
);
322 $st->bind_param(1, $user_id);
323 $st->bind_param(2, $is_deposit);
324 $st->bind_param(3, $booking);
328 my $row = $st->fetchrow_arrayref();
334 sub get_booking_from_token_arr
{
335 my ($self, $stash, $booking) = @_;
337 my $st = $stash->prepare_cached(SELECT_BOOKING_FROM_TOKEN
);
339 $st->bind_param(1, $booking);
343 my $arr = $st->fetchrow_arrayref();
349 sub get_booking_from_token_hash
{
351 my ($self, $stash, $booking) = @_;
353 my $st = $stash->prepare_cached(SELECT_BOOKING_FROM_TOKEN
);
355 $st->bind_param(1, $booking);
359 my $hash = $st->fetchrow_hashref();
366 sub get_booking_from_id_hash
{
367 my ($self, $stash, $id) = @_;
369 my $st = $stash->prepare_cached(SELECT_BOOKING_FROM_ID
);
371 $st->bind_param(1, $id);
375 my $hash = $st->fetchrow_hashref();
381 sub get_booking_from_id_arr
{
382 my ($self, $stash, $id) = @_;
384 my $st = $stash->prepare_cached(SELECT_BOOKING_FROM_ID
);
385 $st->bind_param(1, $id);
388 my $arr = $st->fetchrow_arrayref();
393 sub _claim_this_booking_object
{
394 my ($class, $stash, $ant_nest_code, $booking) = @_;
396 my $ticket_id = $booking->[0];
397 my $user = $booking->[2];
398 my $amount = $booking->[3];
400 my $amount_deposited_or_withdrawn;
403 if ($booking->[1] == 1){
404 ($amount_deposited_or_withdrawn, $new_total) = Bcd
::Data
::Bank
->deposit_user_account
405 ($stash, $user, $ant_nest_code, $amount);
407 ($amount_deposited_or_withdrawn, $new_total) = Bcd
::Data
::Bank
->withdraw_user_account
408 ($stash, $user, $ant_nest_code, $amount);
411 $class->change_state_to_booking
412 ($stash, $ticket_id, Bcd
::Constants
::DepositsConstants
::COLLECTED
);
414 return ($amount_deposited_or_withdrawn, $new_total);
417 sub change_state_to_booking
{
418 my ($class, $stash, $booking_id, $new_status) = @_;
420 my $st = $stash->get_statement(CHANGE_STATE_TO_DEPOSIT
, $class);
422 $st->bind_param(1, $new_status);
423 $st->bind_param(2, $booking_id);
428 sub claim_this_withdrawal_object
{
429 my ($class, $stash, $ant_nest_code, $booking) = @_;
430 $class->_claim_this_booking_object($stash, $ant_nest_code, $booking);
433 sub claim_this_deposit_object
{
434 my ($class, $stash, $ant_nest_code, $booking) = @_;
435 $class->_claim_this_booking_object($stash, $ant_nest_code, $booking);
438 sub claim_this_ticket
{
439 my ($self, $stash, $ant_nest_code, $ticket_id) = @_;
441 #first of all I should get the ticket from the db.
442 my $st = $stash->get_statement(SELECT_DEPOSIT_WITH_ID
, $self);
443 $st->bind_param(1, $ticket_id);
447 my $row = $st->fetchrow_arrayref();
451 my $is_deposit = $row->[1];
452 my $user = $row->[2];
453 my $amount = $row->[3];
456 #this should be given to the bank
457 my $amount_deposited_or_withdrawn;
460 if ( $is_deposit == '1'){
461 ($amount_deposited_or_withdrawn, $new_total) = Bcd
::Data
::Bank
->deposit_user_account
462 ($stash, $user, $ant_nest_code, $amount);
464 ($amount_deposited_or_withdrawn, $new_total) = Bcd
::Data
::Bank
->withdraw_user_account
465 ($stash, $user, $ant_nest_code, $amount);
468 #then I should change the status of the ticket
469 $st = $stash->get_statement(CHANGE_STATE_TO_DEPOSIT
, $self);
471 $st->bind_param(1, Bcd
::Constants
::DepositsConstants
::COLLECTED
);
472 $st->bind_param(2, $ticket_id);
475 return ($amount_deposited_or_withdrawn, $new_total);
478 sub populate_the_stash
{
479 my ($self, $db_stash) = @_;
483 $sql = qq{INSERT into deposits_and_withdrawals
(id_user
, is_deposit
, amount
, status
, booking_token
, }.
484 qq{full_receipt_token
, secret_token
) }.
485 qq{values (?
, 't', ?
, } . Bcd
::Constants
::DepositsConstants
::CREATION_STATE
. qq{, ?
, ?
, ?
)};
486 $db_stash->record_this_statement(INSERT_NEW_DEPOSIT_REQUEST
, $sql);
488 $sql = qq{UPDATE deposits_and_withdrawals SET status
=? where id
=?
};
489 $db_stash->record_this_statement(CHANGE_STATE_TO_DEPOSIT
, $sql);
491 $sql = qq{SELECT
* from deposits_and_withdrawals where id_user
=?
and is_deposit
='1' and booking_token
= ?
};
492 $db_stash->record_this_statement(SELECT_DEPOSIT_USER_WITH_TOKEN
, $sql);
494 $sql = qq{SELECT
* from deposits_and_withdrawals where id
= ?
};
495 $db_stash->record_this_statement(SELECT_DEPOSIT_WITH_ID
, $sql);