+ if ($form->{parts_partnumber}) {
+ $where .= <<SQL;
+ AND EXISTS (
+ SELECT invoice.trans_id
+ FROM invoice
+ LEFT JOIN parts ON (invoice.parts_id = parts.id)
+ WHERE (invoice.trans_id = a.id)
+ AND (parts.partnumber ILIKE ?)
+ LIMIT 1
+ )
+SQL
+ push @values, like($form->{parts_partnumber});
+ }
+
+ if ($form->{parts_description}) {
+ $where .= <<SQL;
+ AND EXISTS (
+ SELECT invoice.trans_id
+ FROM invoice
+ WHERE (invoice.trans_id = a.id)
+ AND (invoice.description ILIKE ?)
+ LIMIT 1
+ )
+SQL
+ push @values, like($form->{parts_description});
+ }
+
+ if ($where) {
+ $where =~ s{\s*AND\s*}{ WHERE };
+ $query .= $where;
+ }
+
+ my @a = qw(transdate invnumber name);
+ push @a, "employee" if $form->{l_employee};
+ my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
+ my $sortorder = join(', ', map { "$_ $sortdir" } @a);
+
+ if (grep({ $_ eq $form->{sort} } qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee transaction_description direct_debit department))) {
+ $sortorder = $form->{sort} . " $sortdir";
+ }
+
+ $query .= " ORDER BY $sortorder";
+
+ my @result = selectall_hashref_query($form, $dbh, $query, @values);
+
+ $form->{AP} = [ @result ];
+
+ $main::lxdebug->leave_sub();
+}
+
+sub get_transdate {
+ $main::lxdebug->enter_sub();
+
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = SL::DB->client->dbh;
+
+ my $query =
+ "SELECT COALESCE(" .
+ " (SELECT transdate FROM ap WHERE id = " .
+ " (SELECT MAX(id) FROM ap) LIMIT 1), " .
+ " current_date)";
+ ($form->{transdate}) = $dbh->selectrow_array($query);
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _delete_payments {
+ $main::lxdebug->enter_sub();
+
+ my ($self, $form, $dbh) = @_;
+
+ my @delete_acc_trans_ids;
+
+ # Delete old payment entries from acc_trans.
+ my $query =
+ qq|SELECT acc_trans_id
+ FROM acc_trans
+ WHERE (trans_id = ?) AND fx_transaction
+
+ UNION
+
+ SELECT at.acc_trans_id
+ FROM acc_trans at
+ LEFT JOIN chart c ON (at.chart_id = c.id)
+ WHERE (trans_id = ?) AND (c.link LIKE '%AP_paid%')|;
+ push @delete_acc_trans_ids, selectall_array_query($form, $dbh, $query, conv_i($form->{id}), conv_i($form->{id}));
+
+ $query =
+ qq|SELECT at.acc_trans_id
+ FROM acc_trans at
+ LEFT JOIN chart c ON (at.chart_id = c.id)
+ WHERE (trans_id = ?)
+ AND ((c.link = 'AP') OR (c.link LIKE '%:AP') OR (c.link LIKE 'AP:%'))
+ ORDER BY at.acc_trans_id
+ OFFSET 1|;
+ push @delete_acc_trans_ids, selectall_array_query($form, $dbh, $query, conv_i($form->{id}));
+
+ if (@delete_acc_trans_ids) {
+ $query = qq|DELETE FROM acc_trans WHERE acc_trans_id IN (| . join(", ", @delete_acc_trans_ids) . qq|)|;
+ do_query($form, $dbh, $query);
+ }
+
+ $main::lxdebug->leave_sub();
+}
+
+sub post_payment {
+ my ($self, $myconfig, $form, $locale) = @_;
+ $main::lxdebug->enter_sub();
+
+ my $rc = SL::DB->client->with_transaction(\&_post_payment, $self, $myconfig, $form, $locale);
+
+ $::lxdebug->leave_sub;
+ return $rc;
+}
+
+sub _post_payment {
+ my ($self, $myconfig, $form, $locale) = @_;
+
+ my $dbh = SL::DB->client->dbh;
+
+ my (%payments, $old_form, $row, $item, $query, %keep_vars);
+
+ $old_form = save_form();
+
+ $query = <<SQL;
+ SELECT at.acc_trans_id, at.amount, at.cleared, c.accno
+ FROM acc_trans at
+ LEFT JOIN chart c ON (at.chart_id = c.id)
+ WHERE (at.trans_id = ?)
+SQL
+
+ my %already_cleared = selectall_as_map($form, $dbh, $query, 'acc_trans_id', [ qw(amount cleared accno) ], $form->{id});
+
+ # Delete all entries in acc_trans from prior payments.
+ if (SL::DB::Default->get->payments_changeable != 0) {
+ $self->_delete_payments($form, $dbh);
+ }
+
+ # Save the new payments the user made before cleaning up $form.
+ my $payments_re = '^datepaid_\d+$|^gldate_\d+$|^acc_trans_id_\d+$|^memo_\d+$|^source_\d+$|^exchangerate_\d+$|^paid_\d+$|^paid_project_id_\d+$|^AP_paid_\d+$|^paidaccounts$';
+ map { $payments{$_} = $form->{$_} } grep m/$payments_re/, keys %{ $form };
+
+ # Clean up $form so that old content won't tamper the results.
+ %keep_vars = map { $_, 1 } qw(login password id);
+ map { delete $form->{$_} unless $keep_vars{$_} } keys %{ $form };
+
+ # Retrieve the invoice from the database.
+ $form->create_links('AP', $myconfig, 'vendor', $dbh);
+
+ # Restore the payment options from the user input.
+ map { $form->{$_} = $payments{$_} } keys %payments;
+
+ # Set up the content of $form in the way that AR::post_transaction() expects.
+
+ $self->setup_form($form, 1);
+
+ $form->{exchangerate} = $form->format_amount($myconfig, $form->{exchangerate});
+ $form->{defaultcurrency} = $form->get_default_currency($myconfig);
+
+ # Get the AP accno.
+ $query =
+ qq|SELECT c.id
+ FROM acc_trans at
+ LEFT JOIN chart c ON (at.chart_id = c.id)
+ WHERE (trans_id = ?)
+ AND ((c.link = 'AP') OR (c.link LIKE '%:AP') OR (c.link LIKE 'AP:%'))
+ ORDER BY at.acc_trans_id
+ LIMIT 1|;
+
+ ($form->{AP_chart_id}) = selectfirst_array_query($form, $dbh, $query, conv_i($form->{id}));
+
+ # Post the new payments.
+ $self->post_transaction($myconfig, $form, $dbh, payments_only => 1, already_cleared => \%already_cleared);