+=head3 GetInvoices
+
+ my @invoices = GetInvoices(
+ invoicenumber => $invoicenumber,
+ suppliername => $suppliername,
+ shipmentdatefrom => $shipmentdatefrom, # ISO format
+ shipmentdateto => $shipmentdateto, # ISO format
+ billingdatefrom => $billingdatefrom, # ISO format
+ billingdateto => $billingdateto, # ISO format
+ isbneanissn => $isbn_or_ean_or_issn,
+ title => $title,
+ author => $author,
+ publisher => $publisher,
+ publicationyear => $publicationyear,
+ branchcode => $branchcode,
+ order_by => $order_by
+ );
+
+Return a list of invoices that match all given criteria.
+
+$order_by is "column_name (asc|desc)", where column_name is any of
+'invoicenumber', 'booksellerid', 'shipmentdate', 'billingdate', 'closedate',
+'shipmentcost', 'shipmentcost_budgetid'.
+
+asc is the default if omitted
+
+=cut
+
+sub GetInvoices {
+ my %args = @_;
+
+ my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
+ closedate shipmentcost shipmentcost_budgetid);
+
+ my $dbh = C4::Context->dbh;
+ my $query = qq{
+ SELECT aqinvoices.*, aqbooksellers.name AS suppliername,
+ COUNT(
+ DISTINCT IF(
+ aqorders.datereceived IS NOT NULL,
+ aqorders.biblionumber,
+ NULL
+ )
+ ) AS receivedbiblios,
+ SUM(aqorders.quantityreceived) AS receiveditems
+ FROM aqinvoices
+ LEFT JOIN aqbooksellers ON aqbooksellers.id = aqinvoices.booksellerid
+ LEFT JOIN aqorders ON aqorders.invoiceid = aqinvoices.invoiceid
+ LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber
+ LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber
+ LEFT JOIN subscription ON biblio.biblionumber = subscription.biblionumber
+ };
+
+ my @bind_args;
+ my @bind_strs;
+ if($args{supplierid}) {
+ push @bind_strs, " aqinvoices.booksellerid = ? ";
+ push @bind_args, $args{supplierid};
+ }
+ if($args{invoicenumber}) {
+ push @bind_strs, " aqinvoices.invoicenumber LIKE ? ";
+ push @bind_args, "%$args{invoicenumber}%";
+ }
+ if($args{suppliername}) {
+ push @bind_strs, " aqbooksellers.name LIKE ? ";
+ push @bind_args, "%$args{suppliername}%";
+ }
+ if($args{shipmentdatefrom}) {
+ push @bind_strs, " aqinvoices.shipementdate >= ? ";
+ push @bind_args, $args{shipmentdatefrom};
+ }
+ if($args{shipmentdateto}) {
+ push @bind_strs, " aqinvoices.shipementdate <= ? ";
+ push @bind_args, $args{shipmentdateto};
+ }
+ if($args{billingdatefrom}) {
+ push @bind_strs, " aqinvoices.billingdate >= ? ";
+ push @bind_args, $args{billingdatefrom};
+ }
+ if($args{billingdateto}) {
+ push @bind_strs, " aqinvoices.billingdate <= ? ";
+ push @bind_args, $args{billingdateto};
+ }
+ if($args{isbneanissn}) {
+ push @bind_strs, " (biblioitems.isbn LIKE ? OR biblioitems.ean LIKE ? OR biblioitems.issn LIKE ? ) ";
+ push @bind_args, $args{isbneanissn}, $args{isbneanissn}, $args{isbneanissn};
+ }
+ if($args{title}) {
+ push @bind_strs, " biblio.title LIKE ? ";
+ push @bind_args, $args{title};
+ }
+ if($args{author}) {
+ push @bind_strs, " biblio.author LIKE ? ";
+ push @bind_args, $args{author};
+ }
+ if($args{publisher}) {
+ push @bind_strs, " biblioitems.publishercode LIKE ? ";
+ push @bind_args, $args{publisher};
+ }
+ if($args{publicationyear}) {
+ push @bind_strs, " biblioitems.publicationyear = ? ";
+ push @bind_args, $args{publicationyear};
+ }
+ if($args{branchcode}) {
+ push @bind_strs, " aqorders.branchcode = ? ";
+ push @bind_args, $args{branchcode};
+ }
+
+ $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs;
+ $query .= " GROUP BY aqinvoices.invoiceid ";
+
+ if($args{order_by}) {
+ my ($column, $direction) = split / /, $args{order_by};
+ if(grep /^$column$/, @columns) {
+ $direction ||= 'ASC';
+ $query .= " ORDER BY $column $direction";
+ }
+ }
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@bind_args);
+
+ my $results = $sth->fetchall_arrayref({});
+ return @$results;
+}
+
+=head3 GetInvoice
+
+ my $invoice = GetInvoice($invoiceid);
+
+Get informations about invoice with given $invoiceid
+
+Return a hash filled with aqinvoices.* fields
+
+=cut
+
+sub GetInvoice {
+ my ($invoiceid) = @_;
+ my $invoice;
+
+ return unless $invoiceid;
+
+ my $dbh = C4::Context->dbh;
+ my $query = qq{
+ SELECT *
+ FROM aqinvoices
+ WHERE invoiceid = ?
+ };
+ my $sth = $dbh->prepare($query);
+ $sth->execute($invoiceid);
+
+ $invoice = $sth->fetchrow_hashref;
+ return $invoice;
+}
+
+=head3 GetInvoiceDetails
+
+ my $invoice = GetInvoiceDetails($invoiceid)
+
+Return informations about an invoice + the list of related order lines
+
+Orders informations are in $invoice->{orders} (array ref)
+
+=cut
+
+sub GetInvoiceDetails {
+ my ($invoiceid) = @_;
+
+ if ( !defined $invoiceid ) {
+ carp 'GetInvoiceDetails called without an invoiceid';
+ return;
+ }
+
+ my $dbh = C4::Context->dbh;
+ my $query = qq{
+ SELECT aqinvoices.*, aqbooksellers.name AS suppliername
+ FROM aqinvoices
+ LEFT JOIN aqbooksellers ON aqinvoices.booksellerid = aqbooksellers.id
+ WHERE invoiceid = ?
+ };
+ my $sth = $dbh->prepare($query);
+ $sth->execute($invoiceid);
+
+ my $invoice = $sth->fetchrow_hashref;
+
+ $query = qq{
+ SELECT aqorders.*, biblio.*
+ FROM aqorders
+ LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber
+ WHERE invoiceid = ?
+ };
+ $sth = $dbh->prepare($query);
+ $sth->execute($invoiceid);
+ $invoice->{orders} = $sth->fetchall_arrayref({});
+ $invoice->{orders} ||= []; # force an empty arrayref if fetchall_arrayref fails
+
+ return $invoice;
+}
+
+=head3 AddInvoice
+
+ my $invoiceid = AddInvoice(
+ invoicenumber => $invoicenumber,
+ booksellerid => $booksellerid,
+ shipmentdate => $shipmentdate,
+ billingdate => $billingdate,
+ closedate => $closedate,
+ shipmentcost => $shipmentcost,
+ shipmentcost_budgetid => $shipmentcost_budgetid
+ );
+
+Create a new invoice and return its id or undef if it fails.
+
+=cut
+
+sub AddInvoice {
+ my %invoice = @_;
+
+ return unless(%invoice and $invoice{invoicenumber});
+
+ my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
+ closedate shipmentcost shipmentcost_budgetid);
+
+ my @set_strs;
+ my @set_args;
+ foreach my $key (keys %invoice) {
+ if(0 < grep(/^$key$/, @columns)) {
+ push @set_strs, "$key = ?";
+ push @set_args, ($invoice{$key} || undef);
+ }
+ }
+
+ my $rv;
+ if(@set_args > 0) {
+ my $dbh = C4::Context->dbh;
+ my $query = "INSERT INTO aqinvoices SET ";
+ $query .= join (",", @set_strs);
+ my $sth = $dbh->prepare($query);
+ $rv = $sth->execute(@set_args);
+ if($rv) {
+ $rv = $dbh->last_insert_id(undef, undef, 'aqinvoices', undef);
+ }
+ }
+ return $rv;
+}
+
+=head3 ModInvoice
+
+ ModInvoice(
+ invoiceid => $invoiceid, # Mandatory
+ invoicenumber => $invoicenumber,
+ booksellerid => $booksellerid,
+ shipmentdate => $shipmentdate,
+ billingdate => $billingdate,
+ closedate => $closedate,
+ shipmentcost => $shipmentcost,
+ shipmentcost_budgetid => $shipmentcost_budgetid
+ );
+
+Modify an invoice, invoiceid is mandatory.
+
+Return undef if it fails.
+
+=cut
+
+sub ModInvoice {
+ my %invoice = @_;
+
+ return unless(%invoice and $invoice{invoiceid});
+
+ my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
+ closedate shipmentcost shipmentcost_budgetid);
+
+ my @set_strs;
+ my @set_args;
+ foreach my $key (keys %invoice) {
+ if(0 < grep(/^$key$/, @columns)) {
+ push @set_strs, "$key = ?";
+ push @set_args, ($invoice{$key} || undef);
+ }
+ }
+
+ my $dbh = C4::Context->dbh;
+ my $query = "UPDATE aqinvoices SET ";
+ $query .= join(",", @set_strs);
+ $query .= " WHERE invoiceid = ?";
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@set_args, $invoice{invoiceid});
+}
+
+=head3 CloseInvoice
+
+ CloseInvoice($invoiceid);
+
+Close an invoice.
+
+Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => undef);
+
+=cut
+
+sub CloseInvoice {
+ my ($invoiceid) = @_;
+
+ return unless $invoiceid;
+
+ my $dbh = C4::Context->dbh;
+ my $query = qq{
+ UPDATE aqinvoices
+ SET closedate = CAST(NOW() AS DATE)
+ WHERE invoiceid = ?
+ };
+ my $sth = $dbh->prepare($query);
+ $sth->execute($invoiceid);
+}
+
+=head3 ReopenInvoice
+
+ ReopenInvoice($invoiceid);
+
+Reopen an invoice
+
+Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => C4::Dates->new()->output('iso'))
+
+=cut
+
+sub ReopenInvoice {
+ my ($invoiceid) = @_;
+
+ return unless $invoiceid;
+
+ my $dbh = C4::Context->dbh;
+ my $query = qq{
+ UPDATE aqinvoices
+ SET closedate = NULL
+ WHERE invoiceid = ?
+ };
+ my $sth = $dbh->prepare($query);
+ $sth->execute($invoiceid);