Bugzilla – Attachment 9944 Details for
Bug 7290
New permission for receiving all (independent of library)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
More granular permissions for order receiving
0001-Bug-7290-More-granular-permissions-for-order-receivi.patch (text/plain), 40.67 KB, created by
Julian Maurice
on 2012-06-06 08:42:11 UTC
(
hide
)
Description:
More granular permissions for order receiving
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2012-06-06 08:42:11 UTC
Size:
40.67 KB
patch
obsolete
>From f917c08733d09ba7637aa5b83dfc9e1ca600c548 Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >Date: Fri, 27 Apr 2012 16:28:12 +0200 >Subject: [PATCH] Bug 7290: More granular permissions for order receiving > >Add branch to aqorders. >Add subpermission acquisition => order_receive_all > >Users with order_receive_all can receive all orders. >Users with only order_receive can receive an order if: > - order branch is defined and is the same as the current working > branch > - order branch is not defined, basket branch is defined and basket > branch is the same as the current working branch > - order branch and basket branch are not defined > >Replace tablesorter by datatables in parcel.pl > >This patch needs patch for bug 7295 (for basket branch) > >Unit tests are available in t/Acquisition/CanUserReceiveBasket.t >--- > C4/Acquisition.pm | 71 ++++++++ > acqui/addorder.pl | 1 + > acqui/finishreceive.pl | 16 +- > acqui/neworderempty.pl | 6 +- > acqui/orderreceive.pl | 15 +- > acqui/parcel.pl | 56 ++---- > .../data/mysql/de-DE/mandatory/userpermissions.sql | 1 + > .../data/mysql/en/mandatory/userpermissions.sql | 1 + > .../data/mysql/es-ES/mandatory/userpermissions.sql | 1 + > .../mysql/fr-FR/1-Obligatoire/userpermissions.sql | 1 + > .../data/mysql/it-IT/necessari/userpermissions.sql | 1 + > installer/data/mysql/kohastructure.sql | 5 +- > .../mysql/nb-NO/1-Obligatorisk/userpermissions.sql | 1 + > .../data/mysql/pl-PL/mandatory/userpermissions.sql | 1 + > .../ru-RU/mandatory/permissions_and_user_flags.sql | 1 + > .../uk-UA/mandatory/permissions_and_user_flags.sql | 1 + > installer/data/mysql/updatedatabase.pl | 16 ++ > .../prog/en/modules/acqui/neworderempty.tt | 19 ++ > .../prog/en/modules/acqui/orderreceive.tt | 5 + > .../intranet-tmpl/prog/en/modules/acqui/parcel.tt | 191 ++++++-------------- > t/Acquisition/CanUserReceiveBasket.t | 111 ++++++++++++ > 21 files changed, 331 insertions(+), 190 deletions(-) > create mode 100644 t/Acquisition/CanUserReceiveBasket.t > >diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm >index cde2b22..6621d53 100644 >--- a/C4/Acquisition.pm >+++ b/C4/Acquisition.pm >@@ -48,6 +48,7 @@ BEGIN { > > &GetBasketUsers &ModBasketUsers > &CanUserManageBasket >+ &CanUserReceiveOrder > > &ModBasketHeader > >@@ -647,6 +648,76 @@ sub CanUserManageBasket { > return 1; > } > >+=head3 CanUserReceiveBasket >+ >+ my $bool = CanUserReceiveBasket($borrower, $order[, $userflags]); >+ my $bool = CanUserReceiveBasket($borrowernumber, $orderno[, $userflags]); >+ >+Check if a borrower can receive a order, according to user permissions, current >+working branch and order and basket branches. >+ >+First parameter can be either a borrowernumber or a hashref as returned by >+C4::Members::GetMember. >+ >+Second parameter can be either a ordernumber or a hashref as returned by >+C4::Acquisition::GetOrder. >+ >+The third parameter is optional. If given, it should be a hashref as returned >+by C4::Auth::getuserflags. If not, getuserflags is called. >+ >+If user is authorised to receive order, returns 1. >+Otherwise returns 0. >+ >+=cut >+ >+sub CanUserReceiveOrder { >+ my ($borrower, $order, $userflags) = @_; >+ >+ if (!ref $borrower) { >+ $borrower = C4::Members::GetMember(borrowernumber => $borrower); >+ } >+ if (!ref $order) { >+ $order = GetOrder($order); >+ } >+ >+ return 0 unless ($borrower and $order); >+ >+ if (!defined $userflags) { >+ my $dbh = C4::Context->dbh; >+ my $sth = $dbh->prepare("SELECT flags FROM borrowers WHERE borrowernumber = ?"); >+ $sth->execute($borrower->{borrowernumber}); >+ my ($flags) = $sth->fetchrow_array; >+ $sth->finish; >+ >+ $userflags = C4::Auth::getuserflags($flags, $borrower->{userid}, $dbh); >+ } >+ >+ my $branch = C4::Context->userenv->{'branch'}; >+ >+ unless ($userflags->{superlibrarian} >+ || (!ref $userflags->{acquisition} && $userflags->{acquisition}) >+ || (ref $userflags->{acquisition} && $userflags->{acquisition}->{order_receive_all}) ) >+ { >+ if (!ref $userflags->{acquisition} && !$userflags->{acquisition}) { >+ return 0; >+ } >+ if (ref $userflags->{acquisition} && !$userflags->{acquisition}->{order_receive}) { >+ return 0; >+ } >+ if (defined $order->{branch} && $order->{branch} ne $branch) { >+ return 0; >+ } >+ if (!defined $order->{branch}) { >+ my $basket = GetBasket($order->{basketno}); >+ if (!$basket || (defined $basket->{branch} && $basket->{branch} ne $branch)) { >+ return 0; >+ } >+ } >+ } >+ >+ return 1; >+} >+ > #------------------------------------------------------------# > > =head3 GetBasketsByBasketgroup >diff --git a/acqui/addorder.pl b/acqui/addorder.pl >index 279084b..f9ae2cc 100755 >--- a/acqui/addorder.pl >+++ b/acqui/addorder.pl >@@ -153,6 +153,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > my $orderinfo = $input->Vars; > $orderinfo->{'list_price'} ||= 0; > $orderinfo->{'uncertainprice'} ||= 0; >+$orderinfo->{branch} = undef if (defined $orderinfo->{branch} and $orderinfo->{branch} eq ''); > #my $ordernumber = $input->param('ordernumber'); > #my $basketno = $input->param('basketno'); > #my $booksellerid = $input->param('booksellerid'); >diff --git a/acqui/finishreceive.pl b/acqui/finishreceive.pl >index 84391f5..e0f94af 100755 >--- a/acqui/finishreceive.pl >+++ b/acqui/finishreceive.pl >@@ -35,7 +35,9 @@ use List::MoreUtils qw/any/; > my $input=new CGI; > my $flagsrequired = {acquisition => 'order_receive'}; > >-checkauth($input, 0, $flagsrequired, 'intranet'); >+my ($userid, $cookie, undef, $userflags) >+ = checkauth($input, 0, $flagsrequired, 'intranet'); >+ > > my $user=$input->remote_user; > my $biblionumber = $input->param('biblionumber'); >@@ -56,6 +58,18 @@ my $error_url_str; > my $ecost = $input->param('ecost'); > my $note = $input->param("note"); > >+my $borrower = C4::Members::GetMember(userid => $userid); >+unless (CanUserReceiveOrder($borrower, $ordernumber, $userflags)) { >+ my $error = "cannot_receive_order"; >+ $error_url_str = "&error=$error"; >+ print $input->redirect( >+ "/cgi-bin/koha/acqui/parcel.pl?invoice=$invoiceno" >+ . "&booksellerid=$booksellerid&freight=$freight&gst=$gst" >+ . "&datereceived=$datereceived$error_url_str" >+ ); >+ exit; >+} >+ > #need old recievedate if we update the order, parcel.pl only shows the right parcel this way FIXME > if ($quantityrec > $origquantityrec ) { > # now, add items if applicable >diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl >index c99863a..b3d1df2 100755 >--- a/acqui/neworderempty.pl >+++ b/acqui/neworderempty.pl >@@ -66,8 +66,8 @@ the item's id in the breeding reservoir > > =cut > >-use warnings; >-use strict; >+use Modern::Perl; >+ > use CGI; > use C4::Context; > use C4::Input; >@@ -239,7 +239,7 @@ foreach my $thisbranch ( sort {$branches->{$a}->{'branchname'} cmp $branches->{$ > value => $thisbranch, > branchname => $branches->{$thisbranch}->{'branchname'}, > ); >- $row{'selected'} = 1 if( $thisbranch && $data->{branchcode} && $thisbranch eq $data->{branchcode}) ; >+ $row{'selected'} = 1 if( $thisbranch && $data->{branch} && $thisbranch eq $data->{branch}) ; > push @branchloop, \%row; > } > $template->param( branchloop => \@branchloop ); >diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl >index 1ea0bd1..92db347 100755 >--- a/acqui/orderreceive.pl >+++ b/acqui/orderreceive.pl >@@ -97,7 +97,8 @@ my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst')); > my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0; > my $results = SearchOrder($ordernumber,$search); > >-my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ >+my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user( > { > template_name => "acqui/orderreceive.tmpl", > query => $input, >@@ -113,6 +114,18 @@ my $count = scalar @$results; > if ( $count == 1 ) { > my $order = $results->[0]; > >+ unless (CanUserReceiveOrder($loggedinuser, $order, $userflags)) { >+ $template->param( >+ cannot_receive_order => 1, >+ ordernumber => $ordernumber, >+ invoice => $invoice, >+ booksellerid => $booksellerid, >+ name => $bookseller->{name} >+ ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+ exit; >+ } >+ > # Check if ACQ framework exists > my $acq_fw = GetMarcStructure(1, 'ACQ'); > unless($acq_fw) { >diff --git a/acqui/parcel.pl b/acqui/parcel.pl >index 5d0d164..a69d06b 100755 >--- a/acqui/parcel.pl >+++ b/acqui/parcel.pl >@@ -56,8 +56,8 @@ To filter the results list on this given date. > > =cut > >-use strict; >-#use warnings; FIXME - Bug 2505 >+use Modern::Perl; >+ > use C4::Auth; > use C4::Acquisition; > use C4::Budgets; >@@ -76,7 +76,8 @@ my $bookseller=GetBookSellerFromId($booksellerid); > > my $invoice=$input->param('invoice') || ''; > my $freight=$input->param('freight'); >-my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst')); >+my $input_gst = $input->param('gst'); >+$input_gst = (!defined $input_gst or $input_gst eq '') ? undef : $input_gst; > my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0; > my $datereceived = ($input->param('op') eq 'new') ? C4::Dates->new($input->param('datereceived')) > : C4::Dates->new($input->param('datereceived'), 'iso') ; >@@ -85,12 +86,8 @@ my $code = $input->param('code'); > my @rcv_err = $input->param('error'); > my @rcv_err_barcode = $input->param('error_bc'); > >-my $startfrom=$input->param('startfrom'); >-my $resultsperpage = $input->param('resultsperpage'); >-$resultsperpage = 20 unless ($resultsperpage); >-$startfrom=0 unless ($startfrom); >- >-if($input->param('format') eq "json"){ >+my $format = $input->param('format'); >+if ($format and $format eq 'json'){ > my ($template, $loggedinuser, $cookie) > = get_template_and_user({template_name => "acqui/ajax.tmpl", > query => $input, >@@ -132,7 +129,7 @@ if($input->param('format') eq "json"){ > exit; > } > >-my ($template, $loggedinuser, $cookie) >+my ($template, $loggedinuser, $cookie, $userflags) > = get_template_and_user({template_name => "acqui/parcel.tmpl", > query => $input, > type => "intranet", >@@ -250,50 +247,20 @@ for (my $i = 0 ; $i < $countpendings ; $i++) { > $line{biblios} = $countbiblio - 1; > $line{left_subscription} = 1 if scalar @subscriptions >= 1; > $line{subscriptions} = scalar @subscriptions; >- $line{left_holds} = 1 if $holds >= 1; >+ $line{left_holds} = ($holds >= 1) ? 1 : 0; > $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds ); > $line{holds} = $holds; > $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order}; > >+ $line{can_receive} = CanUserReceiveOrder($loggedinuser, $pendingorders->[$i], $userflags); > >- push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage); >+ push @loop_orders, \%line; > } > $freight = $totalfreight unless $freight; > > my $count = $countpendings; > >-if ($count>$resultsperpage){ >- my $displaynext=0; >- my $displayprev=$startfrom; >- if(($count - ($startfrom+$resultsperpage)) > 0 ) { >- $displaynext = 1; >- } >- >- my @numbers = (); >- for (my $i=1; $i<$count/$resultsperpage+1; $i++) { >- my $highlight=0; >- ($startfrom/$resultsperpage==($i-1)) && ($highlight=1); >- push @numbers, { number => $i, >- highlight => $highlight , >- startfrom => ($i-1)*$resultsperpage}; >- } >- >- my $from = $startfrom*$resultsperpage+1; >- my $to; >- if($count < (($startfrom+1)*$resultsperpage)){ >- $to = $count; >- } else { >- $to = (($startfrom+1)*$resultsperpage); >- } >- $template->param(numbers=>\@numbers, >- displaynext=>$displaynext, >- displayprev=>$displayprev, >- nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count), >- prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0) >- ); >-} >- >-#$totalfreight=$freight; >+$tototal //= 0; > $tototal = $tototal + $freight; > > $template->param( >@@ -321,7 +288,6 @@ $template->param( > totalPquantity => $totalPquantity, > totalPqtyrcvd => $totalPqtyrcvd, > totalPecost => sprintf("%.2f", $totalPecost), >- resultsperpage => $resultsperpage, > ); > output_html_with_http_headers $input, $cookie, $template->output; > >diff --git a/installer/data/mysql/de-DE/mandatory/userpermissions.sql b/installer/data/mysql/de-DE/mandatory/userpermissions.sql >index 66cb734..2c737e5 100644 >--- a/installer/data/mysql/de-DE/mandatory/userpermissions.sql >+++ b/installer/data/mysql/de-DE/mandatory/userpermissions.sql >@@ -16,6 +16,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Bestellgruppen vewalten'), > (11, 'order_receive', 'Lieferungen verwalten'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Konten hinzufügen/ändern, aber bestehende nicht ändern'), > (13, 'edit_news', 'Nachrichten für OPAC und Dienstoberfläche verfassen'), > (13, 'label_creator', 'Etiketten und Barcodes aus Katalog- und Benutzerdaten erstellen'), >diff --git a/installer/data/mysql/en/mandatory/userpermissions.sql b/installer/data/mysql/en/mandatory/userpermissions.sql >index e9fc3a6..10a64c7 100644 >--- a/installer/data/mysql/en/mandatory/userpermissions.sql >+++ b/installer/data/mysql/en/mandatory/userpermissions.sql >@@ -16,6 +16,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Manage orders & basketgroups'), > (11, 'order_receive', 'Manage orders & basket'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Add and delete budgets (but cant modify budgets)'), > (13, 'edit_news', 'Write news for the OPAC and staff interfaces'), > (13, 'label_creator', 'Create printable labels and barcodes from catalog and patron data'), >diff --git a/installer/data/mysql/es-ES/mandatory/userpermissions.sql b/installer/data/mysql/es-ES/mandatory/userpermissions.sql >index e9fc3a6..10a64c7 100644 >--- a/installer/data/mysql/es-ES/mandatory/userpermissions.sql >+++ b/installer/data/mysql/es-ES/mandatory/userpermissions.sql >@@ -16,6 +16,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Manage orders & basketgroups'), > (11, 'order_receive', 'Manage orders & basket'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Add and delete budgets (but cant modify budgets)'), > (13, 'edit_news', 'Write news for the OPAC and staff interfaces'), > (13, 'label_creator', 'Create printable labels and barcodes from catalog and patron data'), >diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql b/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql >index e4e267a..573c305 100644 >--- a/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql >+++ b/installer/data/mysql/fr-FR/1-Obligatoire/userpermissions.sql >@@ -33,6 +33,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Gérer toutes les commandes et panier'), > (11, 'group_manage', 'Gérer les commandes et les bons de commande'), > (11, 'order_receive', 'Gérer les réceptions'), >+ (11, 'order_receive_all', 'Gérer toutes les réceptions'), > (11, 'budget_add_del', 'Ajouter et supprimer les budgets (mais pas modifier)'), > (13, 'manage_csv_profiles', 'Gérer les profils d''export CSV'), > (13, 'moderate_tags', 'Modérer les tags des adhérents'), >diff --git a/installer/data/mysql/it-IT/necessari/userpermissions.sql b/installer/data/mysql/it-IT/necessari/userpermissions.sql >index 2a0b6b9..6d935da 100644 >--- a/installer/data/mysql/it-IT/necessari/userpermissions.sql >+++ b/installer/data/mysql/it-IT/necessari/userpermissions.sql >@@ -18,6 +18,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Gestisci ordini e raccoglitori raggruppati'), > (11, 'order_receive', 'Gestisci arrivi'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Aggiungi e cancella budgets (senza modificarli)'), > (13, 'edit_news', 'Scrivi le news per l\'OPAC e per l\'interfaccia staff'), > (13, 'label_creator', 'Crea etichette da stampare e barcodes dal catalogo e dai dati degli utenti'), >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index f78a1a4..3a5c81b 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -2763,12 +2763,15 @@ CREATE TABLE `aqorders` ( > `uncertainprice` tinyint(1), > `claims_count` int(11) default 0, > `claimed_date` date default NULL, >+ branch varchar(10) default NULL, > PRIMARY KEY (`ordernumber`), > KEY `basketno` (`basketno`), > KEY `biblionumber` (`biblionumber`), > KEY `budget_id` (`budget_id`), >+ KEY branch (branch), > CONSTRAINT `aqorders_ibfk_1` FOREIGN KEY (`basketno`) REFERENCES `aqbasket` (`basketno`) ON DELETE CASCADE ON UPDATE CASCADE, >- CONSTRAINT `aqorders_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE >+ CONSTRAINT `aqorders_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE, >+ CONSTRAINT aqorders_ibfk_3 FOREIGN KEY (branch) REFERENCES branches (branchcode) ON UPDATE CASCADE ON DELETE SET NULL > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > > >diff --git a/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql >index 8330f9f..9ac8be3 100644 >--- a/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql >+++ b/installer/data/mysql/nb-NO/1-Obligatorisk/userpermissions.sql >@@ -37,6 +37,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Administrere bestillinger og kurv-grupper'), > (11, 'order_receive', 'Administrere bestillinger og kurver'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Legge til og slette budsjetter (men ikke endre budsjetter)'), > (13, 'edit_news', 'Legge ut nyhter i OPACen og det interne grensesnittet'), > (13, 'label_creator', 'Lage etiketter og strekkoder basert pÃ¥ bibliografiske poster og lÃ¥nerdata'), >diff --git a/installer/data/mysql/pl-PL/mandatory/userpermissions.sql b/installer/data/mysql/pl-PL/mandatory/userpermissions.sql >index 1fd859b..2a5b58c 100644 >--- a/installer/data/mysql/pl-PL/mandatory/userpermissions.sql >+++ b/installer/data/mysql/pl-PL/mandatory/userpermissions.sql >@@ -16,6 +16,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Manage orders & basketgroups'), > (11, 'order_receive', 'Manage orders & basket'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Add and delete budgets (but cant modify budgets)'), > (13, 'edit_news', 'RTworzeniei publikowanie wiadomoÅci w interfejsie bibliotekarza i OPAC'), > (13, 'label_creator', 'Create printable labels and barcodes from catalog and patron data'), >diff --git a/installer/data/mysql/ru-RU/mandatory/permissions_and_user_flags.sql b/installer/data/mysql/ru-RU/mandatory/permissions_and_user_flags.sql >index f703432..f5214f8 100644 >--- a/installer/data/mysql/ru-RU/mandatory/permissions_and_user_flags.sql >+++ b/installer/data/mysql/ru-RU/mandatory/permissions_and_user_flags.sql >@@ -40,6 +40,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Manage orders & basketgroups'), > (11, 'order_receive', 'Manage orders & basket'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Add and delete budgets (but cant modify budgets)'), > (13, 'edit_news', 'ÐапиÑание новоÑÑей Ð´Ð»Ñ ÑлекÑÑонного каÑалога и инÑеÑÑейÑа библиоÑекаÑей'), > (13, 'label_creator', 'Создание пеÑаÑнÑÑ Ð½Ð°ÐºÐ»ÐµÐµÐº и ÑÑÑиÑкодов из каÑалога и Ñ Ð´Ð°Ð½Ð½Ñми о полÑзоваÑелÑÑ'), >diff --git a/installer/data/mysql/uk-UA/mandatory/permissions_and_user_flags.sql b/installer/data/mysql/uk-UA/mandatory/permissions_and_user_flags.sql >index edff234..2f2a441 100644 >--- a/installer/data/mysql/uk-UA/mandatory/permissions_and_user_flags.sql >+++ b/installer/data/mysql/uk-UA/mandatory/permissions_and_user_flags.sql >@@ -40,6 +40,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (11, 'order_manage_all', 'Manage all orders & baskets'), > (11, 'group_manage', 'Manage orders & basketgroups'), > (11, 'order_receive', 'Manage orders & basket'), >+ (11, 'order_receive_all', 'Receive all orders'), > (11, 'budget_add_del', 'Add and delete budgets (but cant modify budgets)'), > (13, 'edit_news', 'ÐапиÑÐ°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ð½ Ð´Ð»Ñ ÐµÐ»ÐµÐºÑÑонного каÑÐ°Ð»Ð¾Ð³Ñ Ñа ÑнÑеÑÑейÑÑ Ð±ÑблÑоÑекаÑÑв'), > (13, 'label_creator', 'СÑвоÑÐµÐ½Ð½Ñ Ð´ÑÑÐºÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°ÐºÐ»ÐµÐ¹Ð¾Ðº Ñ ÑÑÑиÑ-кодÑв з каÑÐ°Ð»Ð¾Ð³Ñ Ñа з даними пÑо коÑиÑÑÑваÑÑв'), >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 2bbcc6f..e7532ea 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -5341,6 +5341,22 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "XXX"; >+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { >+ $dbh->do(" >+ ALTER TABLE aqorders >+ ADD COLUMN branch VARCHAR(10) DEFAULT NULL, >+ ADD CONSTRAINT aqorders_ibfk_3 FOREIGN KEY (branch) >+ REFERENCES branches (branchcode) ON UPDATE CASCADE ON DELETE SET NULL >+ "); >+ $dbh->do(" >+ INSERT INTO permissions (module_bit, code, description) >+ VALUES (11, 'order_receive_all', 'Receive all orders') >+ "); >+ print "Upgrade to $DBversion done (Add aqorders.branch and permission order_receive_all)\n"; >+ SetVersion($DBversion); >+} >+ > > =head1 FUNCTIONS > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt >index 4cd6b49..41738bb 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt >@@ -208,6 +208,25 @@ $(document).ready(function() > <form action="/cgi-bin/koha/acqui/addorder.pl" method="post" id="Aform" onsubmit="return Check(this);"> > > <fieldset class="rows"> >+ <legend>Order details</legend> >+ <ol> >+ <li> >+ <span class="label">Branch:</span> >+ <select name="branch"> >+ <option value=""> </option> >+ [% FOREACH branch IN branchloop %] >+ [% IF branch.selected %] >+ <option selected="selected" value="[% branch.value %]">[% branch.branchname %]</option> >+ [% ELSE %] >+ <option value="[% branch.value %]">[% branch.branchname %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ </ol> >+</fieldset> >+ >+<fieldset class="rows"> > <legend> > Catalog details > [% IF ( biblionumber ) %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt >index 821dcd3..56c9ceb 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt >@@ -113,6 +113,10 @@ > > <h1>Receive items from : [% name %] [% IF ( invoice ) %][[% invoice %]] [% END %] (order #[% ordernumber %])</h1> > >+ [% IF (cannot_receive_order) %] >+ <p class="error">You are not authorised to receive this order.</p> >+ [% ELSE %] >+ > [% IF ( count ) %] > <form action="/cgi-bin/koha/acqui/finishreceive.pl" method="post" onsubmit="return Check(this);"> > <div class="yui-g"> >@@ -329,6 +333,7 @@ > </div> > [% END %] > >+[% END %][%# IF (cannot_receive_order) %] > </div> > </div> > <div class="yui-b"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt >index a5d3e1a..22eb9fd 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt >@@ -1,136 +1,54 @@ > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Acquisitions › [% IF ( date ) %] > Receipt summary for [% name %] [% IF ( invoice ) %]invoice [% invoice %][% END %] on [% formatteddatereceived %][% ELSE %]Receive orders from [% name %][% END %]</title> >+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> > [% INCLUDE 'doc-head-close.inc' %] > [% INCLUDE 'greybox.inc' %] > <script type="text/javascript" src="[% yuipath %]/json/json-min.js"></script> >-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script> >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >+[% INCLUDE 'datatables-strings.inc' %] >+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> > <script type="text/javascript"> > //<![CDATA[ >+ var dt_pending; > >- var rowsToCollapse = 5; >- >- $.tablesorter.addParser({ >- id: 'articles', >- is: function(s) {return false; }, >- format: function(s) { return s.toLowerCase().replace(/^(the|an|a) /,''); }, >- type: 'text' >- }); >- >- $(document).ready(function(){ >- $("#pendingt").tablesorter({ >- headers: { 2: { sorter: 'articles' },3: { sorter: false },7:{sorter:false}} >- }); >- >- rowCountPending = $("#pendingt tbody.filterclass tr").length; >- rowCountReceived = $("#receivedt tbody.filterclass tr").length; >- if (rowCountPending > rowsToCollapse) { pendingCollapse(); } >- if (rowCountReceived > rowsToCollapse) { receivedCollapse(); } >- }); >- >- // Case-insensitive version of jquery's contains function >- jQuery.extend(jQuery.expr[':'], { >- icontains : "jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0" >- }); >- >- // Contains exactly function >- jQuery.extend(jQuery.expr[':'], { >- containsExactly: "$(a).text() == m[3]" >- }); >- >- >- // Collapse pending items table >- function pendingCollapse() { >- $("#pendingcollapserow").remove(); >- $("#pendingt tr").show(); >- $("#pendingt tbody.filterclass tr:gt(" + (rowsToCollapse-1) + ")").hide(); >- $("#pendingt").before("<p id=\"pendingcollapserow\">" + _("Only the first ") + rowsToCollapse + _(" items are displayed.") + "<a href=\"javascript:pendingExpand();\">" + _("Click here to show all ") + rowCountPending + _(" items") + "<\/a>.<\/p>"); >- >- } >- >- // Expend pending items table >- function pendingExpand() { >- $("#pendingcollapserow").remove(); >- $("#pendingt tr").show(); >- $("#pendingt tbody.filterclass tr.orderfound").remove(); >- $("#pendingt").before("<p id=\"pendingcollapserow\">" + rowCountPending + _(" items are displayed.") + "<a href=\"javascript:pendingCollapse();\">" + _("Click here to show only the first ") + rowsToCollapse + _(" items") + "<\/a>.<\/p>"); >- } >- >- // Collapse already received items table >- function receivedCollapse() { >- $("#receivedcollapserow").remove(); >- $("#receivedt tbody.filterclass tr:gt(" + (rowsToCollapse-1) + ")").hide(); >- $("#receivedt").before("<p id=\"receivedcollapserow\">" + _("Only the first ") + rowsToCollapse + _(" items are displayed.") + "<a href=\"javascript:receivedExpand();\">" + _("Click here to show all ") + rowCountReceived + _(" items") + "<\/a>.<\/p>"); >- } >- >- // Expand already received items table >- function receivedExpand() { >- $("#receivedcollapserow").remove(); >- $("#receivedt tr").show(); >- $("#receivedt").before("<p id=\"receivedcollapserow\">" + _("All ") + rowCountReceived + _(" items are displayed.") + "<a href=\"javascript:receivedCollapse();\">" + _("Click here to show only the first ") + rowsToCollapse + _(" items") + "<\/a>.<\/p>"); >- } >- >- // Launch filtering > function filter() { >- >- var summaryStatus = jQuery.trim($("#summaryfilter").val()); >- var basketStatus = $("#basketfilter").val(); >- var orderStatus = $("#orderfilter").val(); >- >- if (summaryStatus == '' && basketStatus == '' && orderStatus == '') { clearFilters(); return false; } >- >- var filtered = "table#pendingt tbody.filterclass tr"; >- >- // We hide everything >- $("#nothingfoundrow").remove(); >- $(filtered).hide(); >- >- // Do the search >- var callback = { >- success: function(o) { >- var jsonString = o.responseText; >- var gst = "[% gst %]"; >- try { >- var orders = YAHOO.lang.JSON.parse(jsonString); >- var foundCount = orders.length; >- >- for( i = 0 ; i < orders.length ; i++){ >- order = orders[i]; >- $('<tr class="orderfound">' >- + '<td class="basketfilterclass"><a href="/cgi-bin/koha/acqui/basket.pl?basketno=' + order.basketno + '">' + order.basketno + '</a></td>' >- + '<td class="orderfilterclass"> <a href="neworderempty.pl?ordernumber=' + order.ordernumber + '&booksellerid=' + order.booksellerid + '">' + order.ordernumber + ' </a></td>' >- + '<td class="summaryfilterclass">' >- + '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=' + order.biblionumber + '">' + order.title + '</a>' + _(" by ") + order.author + ' – ' + order.isbn + '</td>' >- + '<td><a href="/cgi-bin/koha/catalogue/showmarc.pl?id=' + order.biblionumber + '" title="MARC" rel="gb_page_center[600,500]">MARC</a> | <a href="/cgi-bin/koha/catalogue/showmarc.pl?viewas=card&id=' + order.biblionumber + '" title="MARC" rel="gb_page_center[600,500]">Card</a></td>' >- + '<td>' + order.quantity + '</td>' >- + '<td>' + order.ecost + '</td>' >- + '<td>' + order.ordertotal + '</td>' >- + '<td>' >- + '<a href="orderreceive.pl?ordernumber=' + order.ordernumber + '&datereceived=[% invoicedatereceived %]&invoice=[% invoice %]&gst=' + gst + '&freight=' + order.freight + '&booksellerid=[% booksellerid %]">Receive</a> /' >- + '<a href="parcel.pl?type=intra&ordernumber=' + order.ordernumber + '&biblionumber=' + order.biblionumber + '&action=cancelorder&booksellerid=[% booksellerid %]&datereceived=[% invoicedatereceived %]&invoice=[% invoice %]" onclick="return confirm(\'' + _('Are you sure you want to cancel this order?') + '\');">Cancel</a>' >- + '</td></tr>').appendTo("table#pendingt"); >- } >- >- // If nothing has been found, we tell the user so >- if (orders.length == 0) { >- $("<tr><td id=\"nothingfoundrow\" colspan=\"8\">No items match your criteria.<\/tr>").appendTo("#pendingt"); >- } >- }catch(e){alert(e);} >- } >- } >- var transaction = YAHOO.util.Connect.asyncRequest('GET', '/cgi-bin/koha/acqui/parcel.pl?booksellerid=[% booksellerid %]&search='+summaryStatus+'&basketno='+basketStatus+'&orderno='+orderStatus+'&format=json', callback, null); >- >- return false; >+ var summaryStatus = jQuery.trim($("#summaryfilter").val()); >+ var basketStatus = $("#basketfilter").val(); >+ var orderStatus = $("#orderfilter").val(); >+ >+ if (summaryStatus == '' && basketStatus == '' && orderStatus == '') { >+ clearFilters(); >+ return false; >+ } >+ dt_pending.fnFilter(summaryStatus,2); >+ dt_pending.fnFilter(orderStatus,1); >+ dt_pending.fnFilter(basketStatus,0); >+ >+ return false; > } > > // Clear already applied filters > function clearFilters() { >- $("#nothingfoundrow").remove(); >- $("#pendingt tbody.filterclass tr").show(); >- //$("#pendingt tbody.filterclass tr.orderfound").remove(); >- pendingExpand(); >+ $("#summaryfilter").val(''); >+ $("#basketfilter").val(''); >+ $("#orderfilter").val(''); >+ var oSettings = dt_pending.fnSettings(); >+ for(iCol = 0; iCol < oSettings.aoPreSearchCols.length; iCol++) { >+ oSettings.aoPreSearchCols[ iCol ].sSearch = ''; >+ } >+ dt_pending.fnDraw(); > } > >+ $(document).ready(function() { >+ var dt_options = $.extend(true, {}, dataTablesDefaults, { >+ 'aLengthMenu': [[5, 10, 20, 50, -1], [5, 10, 20, 50, _("All")]], >+ 'iDisplayLength': 5, >+ 'sDom': '<"top pager"ilp>t' >+ }); >+ dt_pending = $("#pendingt").dataTable(dt_options); >+ $("#receivedt").dataTable(dt_options); >+ }); > //]]> > </script> > <script type="text/javascript"> >@@ -170,11 +88,19 @@ > <div class="yui-b"> > [% IF ( receive_error ) %] > <div class="dialog alert"> >- <h3>Error adding items:</h3> >+ <h3>Error receiving items:</h3> > <ul> >- [% FOREACH error_loo IN error_loop %] >- <li>[% error_loo.error_param %][% IF ( error_loo.error_duplicate_barcode ) %]Duplicate Barcode[% END %] <!-- todo: other error conditions come here. --></li> >- [% END %] >+ [% FOREACH error IN error_loop %] >+ <li> >+ [% error.error_param %] >+ [% IF ( error.error_duplicate_barcode ) %] >+ Duplicate Barcode >+ [% ELSIF (error.error_cannot_receive_order) %] >+ You were not authorised to receive this order >+ [% END %] >+ <!-- todo: other error conditions come here. --> >+ </li> >+ [% END %] > </ul> > </div> > [% END %] >@@ -258,8 +184,11 @@ > <td>[% loop_order.ecost %]</td> > <td>[% loop_order.ordertotal %]</td> > <td> >- <a href="orderreceive.pl?ordernumber=[% loop_order.ordernumber %]&datereceived=[% loop_order.invoicedatereceived %]&invoice=[% loop_order.invoice %]&gst=[% loop_order.gst %]&freight=[% loop_order.freight %]&booksellerid=[% loop_order.booksellerid %]">Receive</a> >- >+ [% IF (loop_order.can_receive) %] >+ <a href="orderreceive.pl?ordernumber=[% loop_order.ordernumber %]&datereceived=[% loop_order.invoicedatereceived %]&invoice=[% loop_order.invoice %]&gst=[% loop_order.gst %]&freight=[% loop_order.freight %]&booksellerid=[% loop_order.booksellerid %]">Receive</a> >+ [% ELSE %] >+ Can't receive order >+ [% END %] > </td> > <td> > [% IF ( loop_order.left_holds_on_order ) %] >@@ -289,22 +218,6 @@ > [% END %] > </tbody> > </table>[% ELSE %]There are no pending orders.[% END %] >- <div id="resultnumber"> >- <!-- Row of numbers corresponding to search result pages --> >- [% IF ( displayprev ) %] >- <a href="parcel.pl?type=intra&booksellerid=[% booksellerid %]&startfrom=[% prevstartfrom %][% IF ( datereceived ) %]&datereceived=[% datereceived %][% END %][% IF ( invoice ) %]&invoice=[% invoice %][% END %][% IF ( resultsperpage ) %]&resultsperpage=[% resultsperpage %][% END %]#resultnumber"><< Previous</a> >- [% END %] >- [% FOREACH number IN numbers %] >- [% IF ( number.highlight ) %] >- <span class="current">[% number.number %]</span> >- [% ELSE %] >- <a href="parcel.pl?type=intra&booksellerid=[% booksellerid %]&startfrom=[% number.startfrom %][% IF ( datereceived ) %]&datereceived=[% datereceived %][% END %][% IF ( invoice ) %]&invoice=[% invoice %][% END %][% IF ( resultsperpage ) %]&resultsperpage=[% resultsperpage %][% END %]#resultnumber">[% number.number %]</a> >- [% END %] >- [% END %] >- [% IF ( displaynext ) %] >- <a href="parcel.pl?type=intra&booksellerid=[% booksellerid %]&startfrom=[% nextstartfrom %][% IF ( datereceived ) %]&datereceived=[% datereceived %][% END %][% IF ( invoice ) %]&invoice=[% invoice %][% END %][% IF ( resultsperpage ) %]&resultsperpage=[% resultsperpage %][% END %]#resultnumber">Next >></a> >- [% END %] >- </div> > </div> > <div id="acqui_receive_receivelist"> > <h3>Already received</h3> >diff --git a/t/Acquisition/CanUserReceiveBasket.t b/t/Acquisition/CanUserReceiveBasket.t >new file mode 100644 >index 0000000..a0c4633 >--- /dev/null >+++ b/t/Acquisition/CanUserReceiveBasket.t >@@ -0,0 +1,111 @@ >+#!/usr/bin/perl >+ >+use Modern::Perl; >+use Test::MockModule; >+use Test::More tests => 30; >+ >+use C4::Acquisition; >+ >+my $C4_Acquisition_module = new Test::MockModule('C4::Acquisition'); >+$C4_Acquisition_module->mock('GetBasket', \&Mock_GetBasket); >+my $C4_Context_module = new Test::MockModule('C4::Context'); >+$C4_Context_module->mock('userenv', \&Mock_userenv); >+ >+my $baskets = { >+ 1 => {}, >+ 2 => { >+ branch => 'B1' >+ }, >+ 3 => { >+ branch => 'B2' >+ } >+}; >+ >+my $userenv = {}; >+ >+my $borrower = {}; >+ >+my $order1 = { >+ basketno => 1 >+}; >+my $order2 = { >+ basketno => 1, >+ branch => 'B1' >+}; >+my $order3 = { >+ basketno => 1, >+ branch => 'B2' >+}; >+my $order4 = { >+ basketno => 2 >+}; >+my $order5 = { >+ basketno => 2, >+ branch => 'B1' >+}; >+my $order6 = { >+ basketno => 2, >+ branch => 'B2' >+}; >+my $order7 = { >+ basketno => 3 >+}; >+my $order8 = { >+ basketno => 3, >+ branch => 'B1' >+}; >+my $order9 = { >+ basketno => 3, >+ branch => 'B2' >+}; >+ >+$userenv->{branch} = 'B1'; >+ >+ok( CanUserReceiveOrder($borrower, $order1, {superlibrarian => 1}) ); >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => 1}) ); >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive_all => 1 }}) ); >+ >+ok( not CanUserReceiveOrder($borrower, $order1, {}) ); >+ok( not CanUserReceiveOrder($borrower, $order1, {acquisition => 0}) ); >+ok( not CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive => 0 }}) ); >+ >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order2, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order3, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order4, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order5, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order6, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order7, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order8, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order9, {acquisition => { order_receive => 1 }}) ); >+ >+ >+$userenv->{branch} = 'B2'; >+ >+ok( CanUserReceiveOrder($borrower, $order1, {superlibrarian => 1}) ); >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => 1}) ); >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive_all => 1 }}) ); >+ >+ok( not CanUserReceiveOrder($borrower, $order1, {}) ); >+ok( not CanUserReceiveOrder($borrower, $order1, {acquisition => 0}) ); >+ok( not CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive => 0 }}) ); >+ >+ok( CanUserReceiveOrder($borrower, $order1, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order2, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order3, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order4, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order5, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order6, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order7, {acquisition => { order_receive => 1 }}) ); >+ok( not CanUserReceiveOrder($borrower, $order8, {acquisition => { order_receive => 1 }}) ); >+ok( CanUserReceiveOrder($borrower, $order9, {acquisition => { order_receive => 1 }}) ); >+ >+sub Mock_GetBasket { >+ my ($basketno) = @_; >+ >+ return $baskets->{$basketno}; >+} >+ >+sub Mock_userenv { >+ return $userenv; >+} >-- >1.7.10 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 7290
:
9314
|
9399
|
9944
|
11444
|
13214
|
14517
|
25068
|
26669
|
26671
|
26676
|
28386
|
28387
|
28388
|
28405
|
28406
|
28407
|
30337
|
30338
|
30339
|
30340
|
30926
|
30927
|
30928
|
32074
|
32075
|
32076
|
32077
|
35700
|
35701
|
35702
|
35935
|
35936
|
35937