summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xLedgerSMB.pm2
-rw-r--r--LedgerSMB/DBObject/Payment.pm30
-rw-r--r--UI/payments/payments_detail.html17
-rw-r--r--sql/modules/Payment.sql34
-rw-r--r--sql/modules/test/Payment.sql33
-rw-r--r--t/04-template-handling.t23
-rw-r--r--t/62-api.t17
-rw-r--r--t/data/62-request-data95
8 files changed, 225 insertions, 26 deletions
diff --git a/LedgerSMB.pm b/LedgerSMB.pm
index b3373f94..06d27d00 100755
--- a/LedgerSMB.pm
+++ b/LedgerSMB.pm
@@ -599,7 +599,7 @@ sub call_procedure {
}
push @results, $ref;
}
- @results;
+ return @results;
}
# Keeping this here due to common requirements
diff --git a/LedgerSMB/DBObject/Payment.pm b/LedgerSMB/DBObject/Payment.pm
index 65526609..b37eac62 100644
--- a/LedgerSMB/DBObject/Payment.pm
+++ b/LedgerSMB/DBObject/Payment.pm
@@ -439,24 +439,27 @@ This method sets appropriate project, department, etc. fields.
sub get_payment_detail_data {
my ($self) = @_;
$self->get_metadata();
+ if (!defined $self->{source_start}){
+ $self->error('No source start defined!');
+ }
my $source_inc;
my $source_src;
- if (defined ($self->{source_start})) {
- $self->{source_start} =~ /(\d*)\D*$/;
- $source_src = $1;
- if ($source_src) {
- $source_inc = $source_src;
- } else {
- $source_inc = 0;
- }
+ $self->{source_start} =~ /(\d*)\D*$/;
+ $source_src = $1;
+ if ($source_src) {
+ $source_inc = $source_src;
+ } else {
+ $source_inc = 0;
}
my $source_length = length($source_inc);
@{$self->{contact_invoices}} = $self->exec_method(
funcname => 'payment_get_all_contact_invoices');
for my $inv (@{$self->{contact_invoices}}) {
- if (defined $self->{source_start}) {
+ if (($self->{action} ne 'update_payments') or
+ (defined $self->{"id_$inv->{contact_id}"})
+ ) {
my $source = $self->{source_start};
if (length($source_inc) < $source_length) {
$source_inc = sprintf('%0*s', $source_length, $source_inc);
@@ -464,8 +467,13 @@ sub get_payment_detail_data {
$source =~ s/$source_src(\D*)$/$source_inc$1/;
++ $source_inc;
$inv->{source} = $source;
- }
- my $tmp_invoices = $inv->{invoices};
+ $self->{"source_$inv->{contact_id}"} = $source;
+ } else {
+ # Clear source numbers every time.
+ $inv->{source} = "";
+ $self->{"source_$inv->{contact_id}"} = "";
+ }
+ my $tmp_invoices = $inv->{invoices};
$inv->{invoices} = [];
@{$inv->{invoices}} = $self->_parse_array($tmp_invoices);
@{$inv->{invoices}} = sort { $a->[2] cmp $b->[2] } @{ $inv->{invoices} };
diff --git a/UI/payments/payments_detail.html b/UI/payments/payments_detail.html
index 2fc92804..193c30dc 100644
--- a/UI/payments/payments_detail.html
+++ b/UI/payments/payments_detail.html
@@ -240,6 +240,7 @@
</tr>
<?lsmb icount = 0 ?>
<?lsmb FOREACH i = r.invoices ?>
+ <?lsmb IF i.7 ?>
<?lsmb icount = icount + 1 ?>
<tr>
<td class="invoice_date_list">&nbsp;<?lsmb i.2 ?></td>
@@ -271,6 +272,22 @@
/>
</td>
</tr>
+ <?lsmb ELSE #not $i.7 ?>
+ <tr>
+ <td class="invoice_date_list">&nbsp;<?lsmb i.2 ?></td>
+ <td class="invoice_list">&nbsp;<?lsmb i.1 ?></td>
+ <td class="total_due_list">&nbsp;
+ <?lsmb i.3 ?></td>
+ <td class="paid_list">&nbsp;
+ <?lsmb i.4 ?></td>
+ <td class="net_due_list">&nbsp;
+ <?lsmb i.6 ?>
+ <?lsmb currency ?></td>
+ <td class="to_pay_list">
+ <?lsmb text("Locked by [_1]", i.8) ?>
+ </td>
+ </tr>
+ <?lsmb END # if i.8 ?>
<?lsmb END # foreach i ?>
<?lsmb INCLUDE input element_data = {
type = "hidden"
diff --git a/sql/modules/Payment.sql b/sql/modules/Payment.sql
index 175cac40..1bcba008 100644
--- a/sql/modules/Payment.sql
+++ b/sql/modules/Payment.sql
@@ -237,12 +237,18 @@ BEGIN
c.description as eca_description,
e.name AS contact_name,
c.meta_number AS account_number,
- sum (coalesce(p.due, 0) -
+ sum( case when u.username IS NULL or
+ u.username = SESSION_USER
+ THEN
+ coalesce(p.due::numeric, 0) -
CASE WHEN c.discount_terms
> extract('days' FROM age(a.transdate))
THEN 0
- ELSE (coalesce(p.due, 0)) * coalesce(c.discount, 0) / 100
- END) AS total_due,
+ ELSE (coalesce(p.due::numeric, 0)) *
+ coalesce(c.discount::numeric, 0) / 100
+ END
+ ELSE 0::numeric
+ END) AS total_due,
compound_array(ARRAY[[
a.id::text, a.invnumber, a.transdate::text,
a.amount::text, (a.amount - p.due)::text,
@@ -256,7 +262,14 @@ BEGIN
> extract('days' FROM age(a.transdate))
THEN 0
ELSE (coalesce(p.due, 0)) * coalesce(c.discount, 0) / 100
- END))::text]]),
+ END))::text,
+ case when u.username IS NOT NULL
+ and u.username <> SESSION_USER
+ THEN 0::text
+ ELSE 1::text
+ END,
+ COALESCE(u.username, 0::text)
+ ]]),
sum(case when a.batch_id = in_batch_id then 1
else 0 END),
bool_and(lock_record(a.id, (select max(session_id) FROM "session" where users_id = (
@@ -297,6 +310,8 @@ BEGIN
WHERE ((chart.link = 'AP' AND in_account_class = 1)
OR (chart.link = 'AR' AND in_account_class = 2))
GROUP BY trans_id) p ON (a.id = p.trans_id)
+ LEFT JOIN "session" s ON (s."session_id" = t.locked_by)
+ LEFT JOIN users u ON (u.id = s.users_id)
WHERE a.batch_id = in_batch_id
OR (a.invoice_class = in_account_class
AND a.approved
@@ -307,14 +322,11 @@ BEGIN
AND c.entity_class = in_account_class
AND a.curr = in_currency
AND a.entity_credit_account = c.id
+ AND (in_meta_number IS NULL OR
+ in_meta_number = c.meta_number)
AND p.due <> 0
AND a.amount <> a.paid
AND NOT a.on_hold
- AND NOT (t.locked_by IS NOT NULL AND t.locked_by IN
- (select "session_id" FROM "session"
- WHERE users_id IN
- (select id from users
- where username <> SESSION_USER)))
AND EXISTS (select trans_id FROM acc_trans
WHERE trans_id = a.id AND
chart_id = (SELECT id frOM chart
@@ -323,9 +335,7 @@ BEGIN
))
GROUP BY c.id, e.name, c.meta_number, c.threshold,
e.control_code, c.description
- HAVING (in_meta_number IS NULL
- OR in_meta_number = c.meta_number) AND
- (sum(p.due) >= c.threshold
+ HAVING (sum(p.due) >= c.threshold
OR sum(case when a.batch_id = in_batch_id then 1
else 0 END) > 0)
ORDER BY c.meta_number ASC
diff --git a/sql/modules/test/Payment.sql b/sql/modules/test/Payment.sql
index b74269e3..26b60eac 100644
--- a/sql/modules/test/Payment.sql
+++ b/sql/modules/test/Payment.sql
@@ -9,6 +9,15 @@ DELETE FROM users WHERE username = CURRENT_USER;
INSERT INTO users (entity_id, username)
SELECT -100, CURRENT_USER;
+INSERT INTO entity(name, id, entity_class, control_code)
+values ('test user 1', -200, 3, 'Test User 1');
+
+insert into users (entity_id, username, id)
+values (-200, '_test1', -200);
+
+insert into session (session_id, users_id, token, last_used, transaction_id)
+values (-200, -200, md5(random()::text), now(), 0);
+
INSERT INTO person(first_name, last_name, entity_id, id)
VALUES ('test', 'test', -100, -100);
@@ -55,6 +64,17 @@ VALUES (true, now()::date, '100000', currval('id'), (select id from chart where
INSERT INTO acc_trans (approved, transdate, amount, trans_id, chart_id)
VALUES (true, now()::date, '-100000', currval('id'), (select id from chart where accno = '00002'));
+INSERT INTO ap (id, invnumber, entity_credit_account, approved, amount, netamount, curr, transdate, paid)
+VALUES (-300, 'test_show3', -101, true, 1000000, 1000000, 'USD', now()::date, 0);
+
+INSERT INTO acc_trans (approved, transdate, amount, trans_id, chart_id)
+VALUES (true, now()::date, '1000000', -300, (select id from chart where accno = '00001'));
+
+INSERT INTO acc_trans (approved, transdate, amount, trans_id, chart_id)
+VALUES (true, now()::date, '-1000000', -300, (select id from chart where accno = '00002'));
+
+update transactions set locked_by = -200 where id = -300;
+
INSERT INTO ap (invnumber, entity_credit_account, approved, amount, netamount, curr, transdate, paid)
values ('test_show', -101, false, '1', '1', 'USD', now()::date, 0);
@@ -81,6 +101,14 @@ SELECT invoices FROM payment_get_all_contact_invoices(1, NULL, 'USD', NULL, NULL
)p));
INSERT INTO test_result(test_name, success)
+VALUES ('Locked Invoice In Payment Selection',
+ (SELECT test_convert_array(invoices) LIKE '%::test_show3::%'
+ FROM
+ (
+SELECT invoices FROM payment_get_all_contact_invoices(1, NULL, 'USD', NULL, NULL, currval('batch_id_seq')::int, '00001', 'TEST1')
+)p));
+
+INSERT INTO test_result(test_name, success)
VALUES ('Threshold met',
(SELECT test_convert_array(invoices) LIKE '%::test_show2::%'
FROM
@@ -95,6 +123,11 @@ VALUES ('Non-Batch Voucher Not In Payment Selection',
FROM
(SELECT invoices FROM payment_get_all_contact_invoices(1, NULL, 'USD', NULL, NULL, currval('batch_id_seq')::int, '00001', 'TEST1'))p ));
+INSERT INTO test_result(test_name, success)
+VALUES ('Locked Invoice not in total',
+ (SELECT total_due < 1000000
+ FROM payment_get_all_contact_invoices(1, NULL, 'USD', NULL, NULL, currval('batch_id_seq')::int, '00001', 'TEST1')) );
+
SELECT * FROM TEST_RESULT;
SELECT (select count(*) from test_result where success is true)
diff --git a/t/04-template-handling.t b/t/04-template-handling.t
index 7043f53f..38dcac37 100644
--- a/t/04-template-handling.t
+++ b/t/04-template-handling.t
@@ -421,6 +421,29 @@ is(grep (/value="1" selected/, @output), 0, 'Select box Value 1 unselected');
is(grep (/value="1000" selected/, @output), 1, 'Select box Value 1000 selected');
is(grep (/<td class="description">dtest1/, @output), 1, 'Contact description shows');
+# bulk payment template tests
+my $payment = LedgerSMB->new();
+$payment->merge({
+ contact_1 => 1, source_1 => 1, action=>'dispay_payments', id_1 => 1,
+ id_1_1 => 1,
+ contact_invoices => [{contact_id => 1, invoices =>[[101, 101, "2009-01-01", 1000, 0, 0, 1000, 0,
+ 'test']]}]});
+
+my $payment_template = LedgerSMB::Template->new(
+ path => 'UI/payments',
+ template => 'payments_detail',
+ format => 'HTML',
+ no_auto_output => 1,
+ output_file => 'payment_test1'
+);
+
+$payment_template->render($payment);
+my @output = get_output_line_array($payment_template);
+cmp_ok(grep(/101<\/td>/, @output), '>', 0, 'Invoice row exists');
+is(grep(/name="payment_101"/, @output), 0, 'Invoice locked');
+is(grep(/Locked by/, @output), 1, 'Invoice locked label shown');
+
+
# LPR PRinting Tests
use LedgerSMB::Sysconfig;
%LedgerSMB::Sysconfig::printer = ('test' => 'cat > t/var/04-lpr-test');
diff --git a/t/62-api.t b/t/62-api.t
index 02b5dea6..639145fe 100644
--- a/t/62-api.t
+++ b/t/62-api.t
@@ -79,13 +79,20 @@ for my $test (@$test_request_data){
}
package LedgerSMB::Template;
-
+use Test::More;
# Don't render templates. Just return so we can run tests on data structures.
sub render {
my ($self, $data) = @_;
if (ref $data->{_test_cases} eq 'CODE'){
$data->{_test_cases}($data);
}
+ if ($data->{_error_test}){
+ cmp_ok($data->{_died}, '==', '1',
+ "$data->{_test_id} died as expected");
+ } else {
+ ok(!defined $data->{_died},
+ "$data->{_test_id} did not error");
+ }
return 1;
}
@@ -103,3 +110,11 @@ sub _load_script {
do "bin/io.pl";
do "bin/$1[0]";
}
+
+package LedgerSMB;
+
+sub error {
+ my $self = shift;
+ $self->{_error} = shift;
+ $self->{_died} = 1;
+}
diff --git a/t/data/62-request-data b/t/data/62-request-data
index bb5e7747..58a52297 100644
--- a/t/data/62-request-data
+++ b/t/data/62-request-data
@@ -50,10 +50,72 @@ our $test_request_data = [
'module' => 'vouchers.pl',
},
{
+ '_test_id' => 'Payment source start error',
+ '_codebase' => 'new',
+ '_error_test' => 1,
+ 'account_class' => 1,
+ 'module' => 'payment.pl',
+ 'action' => 'display_payments',
+ 'approved' => 0,
+ 'currency' => 'USD',
+ 'datepaid' => '2008-07-22',
+ },
+ {
+ '_test_id' => 'Payment source numbering',
+ '_codebase' => 'new',
+ '_error_test' => 1,
+ 'account_class' => 1,
+ 'start_source' => 1,
+ 'module' => 'payment.pl',
+ 'action' => 'update_payments',
+ 'approved' => 0,
+ 'currency' => 'USD',
+ 'datepaid' => '2008-07-22',
+ 'id_1' => 1,
+ 'id_3' => 3,
+ '_exec_override' => {
+ 'payment_get_all_contact_invoices' => sub {
+ my $self = shift;
+ $retval = [ { contact_id => 1,
+ total_due => Math::BigFloat->new(1000),
+ econtrol_code => 'TEST1',
+ eca_description => 'test',
+ contact_name => 'test',
+ account_number => 'test',
+ invoices => '{{"100","101","2009-01-01",1000,1000}}',
+ has_vouchers => 0,
+ } ,
+ {
+ contact_id => 2,
+ total_due => Math::BigFloat->new(1000),
+ econtrol_code => 'TEST1',
+ eca_description => 'test',
+ contact_name => 'test',
+ account_number => 'test',
+ invoices => '{{101,101,2009-01-01,1000,1000}}',
+ has_vouchers => 0,
+ } ,
+ {
+ contact_id => 3,
+ total_due => Math::BigFloat->new(1000),
+ econtrol_code => 'TEST1',
+ eca_description => 'test',
+ contact_name => 'test',
+ account_number => 'test',
+ invoices => '{{102,101,2009-01-01,1000,1000}}',
+ has_vouchers => 0,
+ } ];
+ $self->{contact_invoices} = $retval;
+ $self->debug({'file' => '/tmp/test2'});
+ return @$retval;
+ }
+ }
+ },
+ {
'_test_id' => 'Payment print total',
'_codebase' => 'new',
'action' => 'print',
- 'approved' => 0,
+ 'approved' => 0,
'currency' => 'USD',
'datepaid' => '2008-07-22',
'contact_1' => '25',
@@ -93,6 +155,7 @@ our $test_request_data = [
'multiple' => 1,
},
+
];
our $pre_test_subs = {
@@ -138,6 +201,21 @@ our $api_test_cases = {
}), 'eq', '105900.00',
'Printed amount is correct'
);
+ },
+ 'Payment source start error' => sub {
+ my $self = shift;
+ cmp_ok($self->{_error}, 'eq', 'No source start defined!',
+ "Payment source start error: error correct");
+ },
+ 'Payment source numbering' => sub {
+ my $self = shift;
+ $self->debug({file => '/tmp/test'});
+ ok(defined $self->{source_1},
+ "$self->{_test_id} source 1 defined");
+ cmp_ok($self->{source_2}, 'eq', '',
+ "$self->{_test_id} source 2 not found");
+ ok(defined $self->{source_3},
+ "$self->{_test_id} source 3 defined");
}
};
@@ -145,3 +223,18 @@ opendir (D62, 't/data/62.d');
for my $testfile (readdir(D62)){
do "t/data/62.d/$testfile";
};
+
+# Overridden methods in classes for tests.
+
+package LedgerSMB::DBObject::Payment;
+sub exec_method {
+ my $self = shift;
+ my %args = @_;
+ my $funcname = $args{funcname};
+ if (ref $self->{_exec_override} eq 'HASH'){
+ if ($self->{_exec_override}->{"$funcname"}){
+ return $self->{_exec_override}->{"$args{funcname}"}($self);
+ }
+ }
+ LedgerSMB::DBObject::exec_method($self, @_);
+}