@@ -, +, @@ > prove t/db_dependent/Acquisition/Invoices.t least one order on each. created. listed on it. --- C4/Acquisition.pm | 26 ++++ acqui/invoice.pl | 3 + acqui/invoices.pl | 9 ++ .../intranet-tmpl/prog/en/css/staff-global.css | 26 +++- .../prog/en/modules/acqui/invoices.tt | 93 +++++++++++- t/db_dependent/Acquisition/Invoices.t | 156 ++++++++++++++++++++ 6 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 t/db_dependent/Acquisition/Invoices.t --- a/C4/Acquisition.pm +++ a/C4/Acquisition.pm @@ -72,6 +72,7 @@ BEGIN { &CloseInvoice &ReopenInvoice &DelInvoice + &MergeInvoices &GetItemnumbersFromOrder @@ -2554,6 +2555,31 @@ sub DelInvoice { return; } +=head3 MergeInvoices + + MergeInvoices($invoiceid, \@sourceids); + +Merge the invoices identified by the IDs in \@sourceids into +the invoice identified by $invoiceid. + +=cut + +sub MergeInvoices { + my ($invoiceid, $sourceids) = @_; + + return unless $invoiceid; + foreach my $sourceid (@$sourceids) { + next if $sourceid == $invoiceid; + my $source = GetInvoiceDetails($sourceid); + foreach my $order (@{$source->{'orders'}}) { + $order->{'invoiceid'} = $invoiceid; + ModOrder($order); + } + DelInvoice($source->{'invoiceid'}); + } + return; +} + 1; __END__ --- a/acqui/invoice.pl +++ a/acqui/invoice.pl @@ -83,6 +83,9 @@ elsif ( $op && $op eq 'mod' ) { ReopenInvoice($invoiceid); } elsif ($input->param('close')) { CloseInvoice($invoiceid); + } elsif ($input->param('merge')) { + my @sources = $input->param('merge'); + MergeInvoices($invoiceid, \@sources); } $template->param( modified => 1 ); } --- a/acqui/invoices.pl +++ a/acqui/invoices.pl @@ -36,6 +36,7 @@ use C4::Output; use C4::Acquisition qw/GetInvoices/; use C4::Bookseller qw/GetBookSeller/; use C4::Branch qw/GetBranches/; +use C4::Budgets; my $input = CGI->new; my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( @@ -121,6 +122,14 @@ foreach ( sort keys %$branches ) { }; } +my $budgets = GetBudgets(); +my @budgets_loop; +foreach my $budget (@$budgets) { + push @budgets_loop, $budget if CanUserUseBudget( $loggedinuser, $budget, $flags ); +} + +$template->{'VARS'}->{'budgets_loop'} = \@budgets_loop; + $template->param( do_search => ( $op and $op eq 'do_search' ) ? 1 : 0, invoices => $invoices, --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -1556,11 +1556,11 @@ div#header_search input.submit { padding : .1em; } -input[type=submit]:active, input[type=button]:active, button.submit:active { +input[type=submit]:active, input[type=button]:active, button.submit:active, a.submit:active { border : 1px inset #999999; } -input[type=submit], input[type=reset], input[type=button], input.submit, button.submit { +input[type=submit], input[type=reset], input[type=button], input.submit, button.submit, a.submit { border: 1px outset #999999; border-top-color: #666; border-left-color: #666; @@ -1581,16 +1581,21 @@ input[type=submit]:disabled, input[type=reset]:disabled, input[type=button]:disabled, input.submit:disabled, -button.submit:disabled { +button.submit:disabled, +a.submit:disabled { color : #999; border : 1px solid #C0C0C0; background : #EEE none; } -input[type=reset]:active, input[type=button]:active, input.submit:active, button.submit:active { +input[type=reset]:active, input[type=button]:active, input.submit:active, button.submit:active, a.submit:active { border : 1px inset #999999; } +a.submit { + display: inline-block; +} + ul li input.submit { font-size : 87%; padding : 2px; @@ -2652,3 +2657,16 @@ span.browse-button { float: right; padding-right: 1em; } + +#merge_invoices { + display: none; + margin: 1em auto; +} + +#merge { + margin: 0.5em 0 0 0; +} + +#merge_table tr.active td { + background-color: #FFFFCC; +} --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt @@ -20,9 +20,58 @@ $(document).ready(function() { bFilter: false, sDom: "t", aoColumnDefs: [ - { "bSortable": false, "aTargets": [6] } + { "bSortable": false, "aTargets": [0, 7] } ] })); + + $('#merge').click(function (ev) { + var booksellerid; + var mismatch; + var invoices = [ ]; + if ($('.select-invoice:checked').size() < 2) { + alert(_("You must select at least two invoices to merge.")); + return false; + } + $('.select-invoice:checked').each(function () { + var row = $(this).parents('tr'); + booksellerid = booksellerid || $(row).attr('data-booksellerid'); + if (booksellerid !== $(row).attr('data-booksellerid')) { + mismatch = true; + } + invoices.push({ 'invoiceid': $(row).attr('data-invoiceid'), + 'invoicenumber': $(row).find('td:nth-child(2) a').text(), + 'shipmentdate': $(row).attr('data-shipmentdate'), + 'billingdate': $(row).attr('data-billingdate'), + 'shipmentcost': $(row).attr('data-shipmentcost'), + 'shipment_budgetid': $(row).attr('data-shipment_budgetid'), + 'closedate': $(row).attr('data-closedate'), }); + $('#merge_invoice_form').append(''); + }); + if (mismatch) { + alert(_("All invoices for merging must be from the same vendor")); + } else { + $('#merge_table tbody').empty(); + $.each(invoices, function (idx, invoice) { + var row = $('' + invoice.invoicenumber + '' + invoice.shipmentdate + '' + invoice.billingdate + '' + invoice.shipmentcost + ''); + $(row).appendTo('#merge_table tbody'); + $(row).click(function () { + $('#merge_table tbody tr').removeClass('active'); + $(this).addClass('active'); + $('#merge_invoicenumber').text(invoice.invoicenumber); + $.each(['invoiceid', 'shipmentdate', 'billingdate', 'shipmentcost', 'shipment_budgetid'], function (idx, prop) { + $('#merge_' + prop).val(invoice[prop]); + }); + if (invoice.closedate) { + $('#merge_status').text(_("Closed on " + invoice.closedate + "")); + } else { + $('#merge_status').text(_("Open")); + } + }); + }); + $('#merge_table tbody tr:first').click(); + $('#merge_invoices').show(); + } + }); }); //]]> @@ -45,6 +94,7 @@ $(document).ready(function() { + @@ -56,7 +106,8 @@ $(document).ready(function() { [% FOREACH invoice IN invoices %] - + +
  Invoice no. Vendor Billing date
[% invoice.invoicenumber %] [% invoice.suppliername %] @@ -88,6 +139,44 @@ $(document).ready(function() { [% END %]
+ Merge selected invoices +
+
+
+
    +
  1. Merge invoices

  2. +
  3. + + + +
    Invoice no.Shipment dateBilling dateShipment cost
  4. +
  5. +
  6. +
  7. + +
  8. +
  9. + +
  10. +
  11. +
  12. +
  13. + +
  14. Status:
  15. +
  16. +
+ + +
+
+
[% ELSE %]

Sorry, but there is no results for your search.

Search was: --- a/t/db_dependent/Acquisition/Invoices.t +++ a/t/db_dependent/Acquisition/Invoices.t @@ -0,0 +1,156 @@ +#!/usr/bin/perl +# +# This Koha test module is a stub! +# Add more tests here!!! + +use strict; +use warnings; + +use C4::Bookseller qw( GetBookSellerFromId ); +use C4::Biblio qw( AddBiblio ); + +use Test::More tests => 14; + +BEGIN { + use_ok('C4::Acquisition'); +} + +my $dbh = C4::Context->dbh; +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +my $booksellerid = C4::Bookseller::AddBookseller( + { + name => "my vendor", + address1 => "bookseller's address", + phone => "0123456", + active => 1 + } +); + +my $booksellerinfo = GetBookSellerFromId( $booksellerid ); +my $basketno = NewBasket($booksellerid, 1); +my $basket = GetBasket($basketno); + +my $budgetid = C4::Budgets::AddBudget( + { + budget_code => "budget_code_test_getordersbybib", + budget_name => "budget_name_test_getordersbybib", + } +); +my $budget = C4::Budgets::GetBudget( $budgetid ); + +my ($ordernumber1, $ordernumber2, $ordernumber3); +my ($biblionumber1, $biblioitemnumber1) = AddBiblio(MARC::Record->new, ''); +my ($biblionumber2, $biblioitemnumber2) = AddBiblio(MARC::Record->new, ''); +my ($biblionumber3, $biblioitemnumber3) = AddBiblio(MARC::Record->new, ''); +( undef, $ordernumber1 ) = C4::Acquisition::NewOrder( + { + basketno => $basketno, + quantity => 2, + biblionumber => $biblionumber1, + budget_id => $budget->{budget_id}, + } +); + +( undef, $ordernumber2 ) = C4::Acquisition::NewOrder( + { + basketno => $basketno, + quantity => 1, + biblionumber => $biblionumber2, + budget_id => $budget->{budget_id}, + } +); + +( undef, $ordernumber3 ) = C4::Acquisition::NewOrder( + { + basketno => $basketno, + quantity => 1, + biblionumber => $biblionumber3, + budget_id => $budget->{budget_id}, + ecost => 42, + rrp => 42, + } +); + +my $invoiceid1 = AddInvoice(invoicenumber => 'invoice1', booksellerid => $booksellerid, unknown => "unknown"); +my $invoiceid2 = AddInvoice(invoicenumber => 'invoice2', booksellerid => $booksellerid, unknown => "unknown"); + +my ($datereceived, $new_ordernumber) = ModReceiveOrder( + $biblionumber1, + $ordernumber1, + 2, + undef, + 12, + 12, + $invoiceid1, + 42 + ); + +($datereceived, $new_ordernumber) = ModReceiveOrder( + $biblionumber2, + $ordernumber2, + 1, + undef, + 5, + 5, + $invoiceid2, + 42 + ); + +($datereceived, $new_ordernumber) = ModReceiveOrder( + $biblionumber3, + $ordernumber3, + 1, + undef, + 12, + 12, + $invoiceid2, + 42 + ); + + +my $invoice1 = GetInvoiceDetails($invoiceid1); +my $invoice2 = GetInvoiceDetails($invoiceid2); + +is(scalar @{$invoice1->{'orders'}}, 1, 'Invoice1 has only one order'); +is(scalar @{$invoice2->{'orders'}}, 2, 'Invoice2 has only two orders'); + +my @invoices = GetInvoices(); +cmp_ok(scalar @invoices, '>=', 2, 'GetInvoices returns at least two invoices'); + +@invoices = GetInvoices(invoicenumber => 'invoice2'); +cmp_ok(scalar @invoices, '>=', 1, 'GetInvoices returns at least one invoice when a specific invoice is requested'); + +my $invoicesummary1 = GetInvoice($invoiceid1); +is($invoicesummary1->{'invoicenumber'}, 'invoice1', 'GetInvoice retrieves correct invoice'); +is($invoicesummary1->{'invoicenumber'}, $invoice1->{'invoicenumber'}, 'GetInvoice and GetInvoiceDetails retrieve same information'); + +ModInvoice(invoiceid => $invoiceid1, invoicenumber => 'invoice11'); +$invoice1 = GetInvoiceDetails($invoiceid1); +is($invoice1->{'invoicenumber'}, 'invoice11', 'ModInvoice changed invoice number'); + +is($invoice1->{'closedate'}, undef, 'Invoice is not closed before CloseInvoice call'); +CloseInvoice($invoiceid1); +$invoice1 = GetInvoiceDetails($invoiceid1); +isnt($invoice1->{'closedate'}, undef, 'Invoice is closed after CloseInvoice call'); +ReopenInvoice($invoiceid1); +$invoice1 = GetInvoiceDetails($invoiceid1); +is($invoice1->{'closedate'}, undef, 'Invoice is open after ReopenInvoice call'); + + +MergeInvoices($invoiceid1, [ $invoiceid2 ]); + +my $mergedinvoice = GetInvoiceDetails($invoiceid1); +is(scalar @{$mergedinvoice->{'orders'}}, 3, 'Merged invoice has three orders'); + +my $invoiceid3 = AddInvoice(invoicenumber => 'invoice3', booksellerid => $booksellerid, unknown => "unknown"); +my $invoicecount = GetInvoices(); +DelInvoice($invoiceid3); +@invoices = GetInvoices(); +is(scalar @invoices, $invoicecount - 1, 'DelInvoice deletes invoice'); +is(GetInvoice($invoiceid3), undef, 'DelInvoice deleted correct invoice'); + +END { + $dbh and $dbh->rollback; +} --