From 766bbed921d33a4a4c28671f0e2f5d47ff5878c6 Mon Sep 17 00:00:00 2001 From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Date: Tue, 10 Dec 2019 21:05:40 +0100 Subject: [PATCH] Bug 24157: New permission - edit_invoices Add a new permission to edit invoices Test plan: - Remove the new permission "edit_invoices" for a given patron, use it to log in into Koha - Create an invoice, edit it (click "detail") => You can see the detail of the invoice, but cannot edit it. It's a read-only view. - Add the permission => The form is back and you can modify the invoices and save the changes. Also, you are able to create adjustments. Sponsored-by: Galway-Mayo Institute of Technology --- acqui/invoice.pl | 6 +- installer/data/mysql/atomicupdate/bug_24157.perl | 8 +- installer/data/mysql/userpermissions.sql | 1 + .../intranet-tmpl/prog/en/includes/permissions.inc | 5 + .../intranet-tmpl/prog/en/modules/acqui/invoice.tt | 293 ++++++++++++--------- .../prog/en/modules/acqui/invoices.tt | 8 +- 6 files changed, 198 insertions(+), 123 deletions(-) diff --git a/acqui/invoice.pl b/acqui/invoice.pl index 5a7ce08f38..f784b3e4d0 100755 --- a/acqui/invoice.pl +++ b/acqui/invoice.pl @@ -53,10 +53,13 @@ my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( ); my $logged_in_patron = Koha::Patrons->find( $loggedinuser ); - my $invoiceid = $input->param('invoiceid'); my $op = $input->param('op'); +output_and_exit( $input, $cookie, $template, 'insufficient_permission' ) + if $op + && not $logged_in_patron->has_permission( { acquisition => 'edit_invoices' } ); + my $invoice_files; if ( C4::Context->preference('AcqEnableFiles') ) { $invoice_files = Koha::Misc::Files->new( @@ -242,6 +245,7 @@ $template->param( invoiceincgst => $bookseller->invoiceincgst, currency => Koha::Acquisition::Currencies->get_active, budgets => $budget_loop, + budget => GetBudget( $shipmentcost_budgetid ), ); defined( $invoice_files ) && $template->param( files => $invoice_files->GetFilesInfo() ); diff --git a/installer/data/mysql/atomicupdate/bug_24157.perl b/installer/data/mysql/atomicupdate/bug_24157.perl index 60536820ea..f03c3a37de 100644 --- a/installer/data/mysql/atomicupdate/bug_24157.perl +++ b/installer/data/mysql/atomicupdate/bug_24157.perl @@ -5,6 +5,12 @@ if( CheckVersion( $DBversion ) ) { (11, 'reopen_closed_invoices', 'Reopen closed invoices') |); + $dbh->do(q| + INSERT IGNORE INTO permissions (module_bit, code, description) VALUES + (11, 'edit_invoices', 'Edit invoices') + |); + + SetVersion( $DBversion ); - print "Upgrade to $DBversion done (Bug 24157: Add new permission reopen_closed_invoices)\n"; + print "Upgrade to $DBversion done (Bug 24157: Add new permissions reopen_closed_invoices, edit_invoices)\n"; } diff --git a/installer/data/mysql/userpermissions.sql b/installer/data/mysql/userpermissions.sql index 967c858b6d..df114d2311 100644 --- a/installer/data/mysql/userpermissions.sql +++ b/installer/data/mysql/userpermissions.sql @@ -61,6 +61,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES (11, 'budget_manage_all', 'Manage all funds'), (11, 'edi_manage', 'Manage EDIFACT transmissions'), (11, 'reopen_closed_invoices', 'Reopen closed invoices'), + (11, 'edit_invoices', 'Edit invoices'), (13, 'edit_news', 'Write news for the OPAC and staff interfaces'), (13, 'label_creator', 'Create printable labels and barcodes from catalog and patron data'), (13, 'edit_calendar', 'Define days when the library is closed'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc index ee7b230843..267abc3208 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc @@ -654,6 +654,11 @@ Reopen closed invoices </span> <span class="permissioncode">([% name | html %])</span> + [%- CASE 'edit_invoices' -%] + <span class="sub_permission edit_invoices_subpermission"> + Edit invoices + </span> + <span class="permissioncode">([% name | html %])</span> [%# self_check %] [%- CASE 'self_checkin_module' -%] <span class="sub_permission self_checkin_module_subpermission"> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt index 17524fa207..04acb4128a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt @@ -36,63 +36,85 @@ <fieldset class="rows"> <ol> <li> - <label for="shipmentdate" class="required">Invoice number:</label> [% IF readonly %] + <label for="shipmentdate">Invoice number:</label> [% invoicenumber | html %] [% ELSE %] + <label for="shipmentdate" class="required">Invoice number:</label> <input type="text" id="invoicenumber" name="invoicenumber" value="[% invoicenumber | html %]" class="required" required="required"/> <span class="required">Required</span> [% END %] </li> - <li><label for="shipmentdate">Shipment date:</label> - <input type="text" size="10" id="shipmentdate" name="shipmentdate" value="[% shipmentdate | $KohaDates %]" class="datepicker" /></li> - - <li><label for="billingdate">Billing date:</label> - <input type="text" size="10" id="billingdate" name="billingdate" value="[% billingdate | $KohaDates %]" class="datepicker" /></li> - - <li><label for="shipmentcost">Shipping cost:</label> - <input type="text" size="10" id="shipmentcost" name="shipmentcost" value="[% shipmentcost | $Price on_editing => 1 %]" /></li> + <li> + <label for="shipmentdate">Shipment date:</label> + [% IF readonly %] + [% shipmentdate | $KohaDates %] + [% ELSE %] + <input type="text" size="10" id="shipmentdate" name="shipmentdate" value="[% shipmentdate | $KohaDates %]" class="datepicker" /> + [% END %] + </li> - <li> - <label for="shipment_budget_id">Shipping fund: </label> - <select id="shipment_budget_id" name="shipment_budget_id"> - <option value="">No fund</option> - [% FOREACH budget IN budgets %] - [% IF ( budget.selected ) %] - <option value="[% budget.b_id | html %]" selected="selected">[% budget.b_txt | html %] [% IF ( !budget.b_active ) %](inactive)[% END %]</option> - [% ELSIF ( budget.b_active ) %] - <option value="[% budget.b_id | html %]">[% budget.b_txt | html %]</option> - [% ELSE %] - <option value="[% budget.b_id | html %]" class="b_inactive">[% budget.b_txt | html %] (inactive)</option> - [% END %] + <li> + <label for="billingdate">Billing date:</label> + [% IF readonly %] + [% billingdate | $KohaDates %] + [% ELSE %] + <input type="text" size="10" id="billingdate" name="billingdate" value="[% billingdate | $KohaDates %]" class="datepicker" /> [% END %] - </select> - <label for="showallfunds" style="float:none;width:auto;"> Show inactive:</label> - <input type="checkbox" id="showallfunds" /> + </li> - </li> + <li> + <label for="shipmentcost">Shipping cost:</label> + [% IF readonly %] + [% shipmentcost | $Price %] + [% ELSE %] + <input type="text" size="10" id="shipmentcost" name="shipmentcost" value="[% shipmentcost | $Price on_editing => 1 %]" /> + [% END %] + </li> + <li> + <label for="shipment_budget_id">Shipping fund: </label> + [% IF readonly %] + [% budget.budget_name | html %] + [% ELSE %] + <select id="shipment_budget_id" name="shipment_budget_id"> + <option value="">No fund</option> + [% FOREACH budget IN budgets %] + [% IF ( budget.selected ) %] + <option value="[% budget.b_id | html %]" selected="selected">[% budget.b_txt | html %] [% IF ( !budget.b_active ) %](inactive)[% END %]</option> + [% ELSIF ( budget.b_active ) %] + <option value="[% budget.b_id | html %]">[% budget.b_txt | html %]</option> + [% ELSE %] + <option value="[% budget.b_id | html %]" class="b_inactive">[% budget.b_txt | html %] (inactive)</option> + [% END %] + [% END %] + </select> + <label for="showallfunds" style="float:none;width:auto;"> Show inactive:</label> + <input type="checkbox" id="showallfunds" /> + [% END %] + </li> [% IF ( invoiceclosedate ) %] - <li><span class="label">Status:</span> - Closed on [% invoiceclosedate | $KohaDates %].</li> + <li><span class="label">Status:</span> + Closed on [% invoiceclosedate | $KohaDates %].</li> <li> <label for="reopen">Reopen: </label> - [% IF CAN_user_acquisition_reopen_closed_invoices %] + [% IF CAN_user_acquisition_reopen_closed_invoices AND NOT readonly %] <input type="checkbox" name="reopen" id="reopen" /> [% ELSE %] - <input type="checkbox" name="reopen" id="reopen" readonly="readonly" /> + <input type="checkbox" name="reopen" id="reopen" readonly="disabled" /> [% END %] </li> [% ELSE %] - <li><span class="label">Status:</span> - Open.</li> + <li><span class="label">Status:</span> + Open.</li> - <li><label for="close">Close: </label> <input type="checkbox" name="close" id="close" /> - </li> + <li><label for="close">Close: </label> <input type="checkbox" name="close" id="close" /> + </li> [% END %] </ol> + [% UNLESS readonly %] <input type="hidden" name="op" value="mod" /> <input type="hidden" name="invoiceid" value="[% invoiceid | html %]" /> <fieldset class="action"> @@ -101,6 +123,7 @@ <a href="invoice.pl?op=delete&invoiceid=[% invoiceid | uri %]" id="delete">Delete</a> [% END %] </fieldset> + [% END %] </fieldset> </form> @@ -120,128 +143,160 @@ <th>Note</th> <th>Fund</th> <th>Encumber while invoice open</th> - <th> </th> + [% UNLESS readonly %]<th> </th>[% END %] </tr> [% total_adj = 0 %] [% FOREACH adjustment IN adjustments %] [% total_adj = total_adj + adjustment.adjustment %] <tr> <td><input type="hidden" name="adjustment_id" value="[% adjustment.adjustment_id | html %]" />[% adjustment.adjustment_id | html %]</td> - <td><input type="text" name="adjustment" id="adjustment_[% adjustment.adjustment_id | html %]" value="[% adjustment.adjustment | $Price on_editing => 1 %]" /></td> <td> - [% reasons = AuthorisedValues.Get("ADJ_REASON") %] - [% IF reasons.0 %] - <select id="reason_[% adjustment.adjustment_id | html %]" name="reason"> - <option value="">No reason</option> - [% FOREACH reason IN reasons %] - [% IF ( adjustment.reason == reason.authorised_value ) %] - <option selected="selected" value="[% reason.authorised_value | html %]"> - [% ELSE %] - <option value="[% reason.authorised_value | html %]"> + [% IF readonly %] + [% adjustment.adjustment | $Price %] + [% ELSE %] + <input type="text" name="adjustment" id="adjustment_[% adjustment.adjustment_id | html %]" value="[% adjustment.adjustment | $Price on_editing => 1 %]" /> + [% END %] + </td> + <td> + [% IF readonly %] + [% AuthorisedValues.GetByCode('ADJ_REASON', adjustment.reason) | html %] + [% ELSE %] + [% reasons = AuthorisedValues.Get("ADJ_REASON") %] + [% IF reasons.0 %] + <select id="reason_[% adjustment.adjustment_id | html %]" name="reason"> + <option value="">No reason</option> + [% FOREACH reason IN reasons %] + [% IF ( adjustment.reason == reason.authorised_value ) %] + <option selected="selected" value="[% reason.authorised_value | html %]"> + [% ELSE %] + <option value="[% reason.authorised_value | html %]"> + [% END %] + [% reason.lib | html %] + </option> [% END %] - [% reason.lib | html %] - </option> - [% END %] - </select> + </select> + [% ELSE %] + <p title="Define values in authorised value category ADJ_REASON to enable">None</p> + <input type="hidden" name="reason" id="reason_[% adjustment.adjustment_id | html %]" value="" /> + [% END %] + [% END %] + </td> + <td> + [% IF readonly %] + [% adjustment.note | html %] [% ELSE %] - <p title="Define values in authorised value category ADJ_REASON to enable">None</p> - <input type="hidden" name="reason" id="reason_[% adjustment.adjustment_id | html %]" value="" /> - [% END %] + <input type="text" name="note" id="note_new" value="[% adjustment.note | html %]"/> + [% END %] </td> - <td><input type="text" name="note" id="note_new" value="[% adjustment.note | html %]"/></td> <td> - <select id="budget_id_[% adjustment.adjustment_id | html %]" name="budget_id"> + [% IF readonly %] + [% adjustement.fund.budget_name | html %] + [% ELSE %] + <select id="budget_id_[% adjustment.adjustment_id | html %]" name="budget_id"> <option value="">No fund</option> - [% FOREACH budget IN budgets %] - [% IF ( budget.b_id == adjustment.budget_id ) %] - <option selected="selected" value="[% budget.b_id | html %]"> - [% ELSE %] - <option value="[% budget.b_id | html %]"> + [% FOREACH budget IN budgets %] + [% IF ( budget.b_id == adjustment.budget_id ) %] + <option selected="selected" value="[% budget.b_id | html %]"> + [% ELSE %] + <option value="[% budget.b_id | html %]"> + [% END %] + [% budget.b_txt | html %] + </option> [% END %] - [% budget.b_txt | html %] - </option> - [% END %] - </select> + </select> + [% END %] </td> [% IF adjustment.encumber_open %] <td> + [% IF readonly %] + <input type="checkbox" checked="checked" readonly="readonly" /> + [% ELSE %] <input type="checkbox" name="encumber_open" id="encumber_[% adjustment.adjustment_id | html %]" value="[% adjustment.adjustment_id | html %]" checked/> + [% END %] </td> [% ELSE %] <td> + [% IF readonly %] + <input type="checkbox" disabled="disabled" /> + [% ELSE %] <input type="checkbox" name="encumber_open" id="encumber_[% adjustment.adjustment_id | html %]" value="[% adjustment.adjustment_id | html %]" /> + [% END %] + </td> + [% END %] + [% UNLESS readonly %] + <td> + <a class="btn btn-default btn-xs delete_adjustment" href="/cgi-bin/koha/acqui/invoice.pl?op=del_adj&adjustment_id=[% adjustment.adjustment_id | html %]&invoiceid=[% invoiceid | html %]"><i class="fa fa-trash"></i> Delete</a> </td> [% END %] - <td> - <a class="btn btn-default btn-xs delete_adjustment" href="/cgi-bin/koha/acqui/invoice.pl?op=del_adj&adjustment_id=[% adjustment.adjustment_id | html %]&invoiceid=[% invoiceid | html %]"><i class="fa fa-trash"></i> Delete</a> - </td> </tr> [% END %] </table> [% END %] - <p> - <a href="#" id="show_invoice_adjustment" class="toggle_invoice_adjustment"><i class="fa fa-plus"></i> Add an adjustment</a> - </p> + [% UNLESS readonly %] + <p> + <a href="#" id="show_invoice_adjustment" class="toggle_invoice_adjustment"><i class="fa fa-plus"></i> Add an adjustment</a> + </p> - <fieldset id="add_invoice_adjustment" style="display:none"> - <h4>Add an adjustment</h4> - <input type="hidden" name="adjustment_id" value="new" /> - <ol> - <li> - <label for="adjustment_new">Amount: </label> - <input type="text" name="adjustment" id="adjustment_new" /> - </li> - [% reasons = AuthorisedValues.Get("ADJ_REASON") %] - [% IF reasons.0 %] + <fieldset id="add_invoice_adjustment" style="display:none"> + <h4>Add an adjustment</h4> + <input type="hidden" name="adjustment_id" value="new" /> + <ol> <li> - <label for="reason_[% adjustment.adjustment_id | html %]">Reason: </label> - <select id="reason_[% adjustment.adjustment_id | html %]" name="reason"> - <option value="">No reason</option> - [% FOREACH reason IN reasons %] - <option value="[% reason.authorised_value | html %]"> - [% reason.lib | html %] + <label for="adjustment_new">Amount: </label> + <input type="text" name="adjustment" id="adjustment_new" /> + </li> + [% reasons = AuthorisedValues.Get("ADJ_REASON") %] + [% IF reasons.0 %] + <li> + <label for="reason_[% adjustment.adjustment_id | html %]">Reason: </label> + <select id="reason_[% adjustment.adjustment_id | html %]" name="reason"> + <option value="">No reason</option> + [% FOREACH reason IN reasons %] + <option value="[% reason.authorised_value | html %]"> + [% reason.lib | html %] + </option> + [% END %] + </select> + </li> + [% ELSE %] + <li> + <span class="label">Reason: </span> + <span>None</span> + <div class="hint">Define values in authorised value category ADJ_REASON to enable</div> + </li> + [% END %] + <li> + <label for="note_new">Note: </label> + <input type="text" name="note" id="note_new" value=""/> + </li> + <li> + <label for="budget_id_new">Fund: </label> + <select id="budget_id_new" name="budget_id"> + <option selected="selected" value="">No fund</option> + [% FOREACH budget IN budgets %] + <option value="[% budget.b_id | html %]"> + [% budget.b_txt | html %] </option> [% END %] </select> </li> - [% ELSE %] <li> - <span class="label">Reason: </span> - <span>None</span> - <div class="hint">Define values in authorised value category ADJ_REASON to enable</div> + <label for="encumber_new">Encumber while invoice open? </label> + <input type="checkbox" name="encumber_open" id="encumber_new" value="new" /> + <input type="hidden" name="delete" value=""> </li> - [% END %] - <li> - <label for="note_new">Note: </label> - <input type="text" name="note" id="note_new" value=""/> - </li> - <li> - <label for="budget_id_new">Fund: </label> - <select id="budget_id_new" name="budget_id"> - <option selected="selected" value="">No fund</option> - [% FOREACH budget IN budgets %] - <option value="[% budget.b_id | html %]"> - [% budget.b_txt | html %] - </option> - [% END %] - </select> - </li> - <li> - <label for="encumber_new">Encumber while invoice open? </label> - <input type="checkbox" name="encumber_open" id="encumber_new" value="new" /> - <input type="hidden" name="delete" value=""> - </li> - <li> - <span class="label"> </span> - <a href="#" id="cancel_invoice_adjustment" class="toggle_invoice_adjustment" style="display:none"><i class="fa fa-remove"></i> Cancel</a> - </li> - </ol> - </fieldset> - <fieldset class="action"> - <input type="hidden" name="op" value="mod_adj" /> - <input type="submit" value="Update adjustments" /> - </fieldset> + <li> + <span class="label"> </span> + <a href="#" id="cancel_invoice_adjustment" class="toggle_invoice_adjustment" style="display:none"><i class="fa fa-remove"></i> Cancel</a> + </li> + </ol> + </fieldset> + <fieldset class="action"> + <input type="hidden" name="op" value="mod_adj" /> + <input type="submit" value="Update adjustments" /> + </fieldset> + [% END %] </fieldset> </form> <p> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt index c314452f02..6704fb1f25 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt @@ -85,10 +85,14 @@ <li><a href="invoice.pl?op=reopen&invoiceid=[% invoice.invoiceid | uri %]&referer=/cgi-bin/koha/acqui/invoices.pl%3Fop=do_search%26invoicenumber=[% invoicenumber | uri %]%26supplier=[% booksellerid | uri %]%26shipmentdatefrom=[% shipmentdatefrom | $KohaDates %]%26shipmentdateto=[% shipmentdateto | $KohaDates %]%26billingdatefrom=[% billingdatefrom | $KohaDates %]%26billingdateto=[% billingdateto | $KohaDates %]%26isbneanissn=[% isbneanissn | uri %]%26title=[% title | uri %]%26author=[% author | uri %]%26publisher=[% publisher | uri %]%26publicationyear=[% publicationyear | uri %]%26branch=[% branch | uri %]"><i class="fa fa-refresh"></i> Reopen</a></li> [% END %] [% ELSE %] - <li><a href="invoice.pl?op=close&invoiceid=[% invoice.invoiceid | uri %]&referer=/cgi-bin/koha/acqui/invoices.pl%3Fop=do_search%26invoicenumber=[% invoicenumber | uri %]%26supplier=[% booksellerid | uri %]%26shipmentdatefrom=[% shipmentdatefrom | $KohaDates %]%26shipmentdateto=[% shipmentdateto | $KohaDates %]%26billingdatefrom=[% billingdatefrom | $KohaDates %]%26billingdateto=[% billingdateto | $KohaDates %]%26isbneanissn=[% isbneanissn | uri %]%26title=[% title | uri %]%26author=[% author | uri %]%26publisher=[% publisher | uri %]%26publicationyear=[% publicationyear | uri %]%26branch=[% branch | uri %]"><i class="fa fa-times-circle"></i> Close</a></li> + [% IF CAN_user_acquisition_edit_invoices %] + <li><a href="invoice.pl?op=close&invoiceid=[% invoice.invoiceid | uri %]&referer=/cgi-bin/koha/acqui/invoices.pl%3Fop=do_search%26invoicenumber=[% invoicenumber | uri %]%26supplier=[% booksellerid | uri %]%26shipmentdatefrom=[% shipmentdatefrom | $KohaDates %]%26shipmentdateto=[% shipmentdateto | $KohaDates %]%26billingdatefrom=[% billingdatefrom | $KohaDates %]%26billingdateto=[% billingdateto | $KohaDates %]%26isbneanissn=[% isbneanissn | uri %]%26title=[% title | uri %]%26author=[% author | uri %]%26publisher=[% publisher | uri %]%26publicationyear=[% publicationyear | uri %]%26branch=[% branch | uri %]"><i class="fa fa-times-circle"></i> Close</a></li> + [% END %] [% END %] [% UNLESS invoice.receivedbiblios || invoice.receiveditems %] - <li><a href="invoice.pl?op=delete&invoiceid=[% invoice.invoiceid | uri %]&referer=/cgi-bin/koha/acqui/invoices.pl%3Fop=do_search%26invoicenumber=[% invoicenumber | uri %]%26supplier=[% booksellerid | uri %]%26shipmentdatefrom=[% shipmentdatefrom | $KohaDates %]%26shipmentdateto=[% shipmentdateto | $KohaDates %]%26billingdatefrom=[% billingdatefrom | $KohaDates %]%26billingdateto=[% billingdateto | $KohaDates %]%26isbneanissn=[% isbneanissn | uri %]%26title=[% title | uri %]%26author=[% author | uri %]%26publisher=[% publisher | uri %]%26publicationyear=[% publicationyear | uri %]%26branch=[% branch | uri %]" class="delete_invoice"><i class="fa fa-trash"></i> Delete</a></li> + [% IF CAN_user_acquisition_edit_invoices %] + <li><a href="invoice.pl?op=delete&invoiceid=[% invoice.invoiceid | uri %]&referer=/cgi-bin/koha/acqui/invoices.pl%3Fop=do_search%26invoicenumber=[% invoicenumber | uri %]%26supplier=[% booksellerid | uri %]%26shipmentdatefrom=[% shipmentdatefrom | $KohaDates %]%26shipmentdateto=[% shipmentdateto | $KohaDates %]%26billingdatefrom=[% billingdatefrom | $KohaDates %]%26billingdateto=[% billingdateto | $KohaDates %]%26isbneanissn=[% isbneanissn | uri %]%26title=[% title | uri %]%26author=[% author | uri %]%26publisher=[% publisher | uri %]%26publicationyear=[% publicationyear | uri %]%26branch=[% branch | uri %]" class="delete_invoice"><i class="fa fa-trash"></i> Delete</a></li> + [% END %] [% END %] </ul> </div> -- 2.11.0