--- /dev/null
+package Koha::Desk;
+
+# Copyright (C) 2020 BULAC
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Carp;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Desk - Koha Desk Object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 _type
+
+=cut
+
+sub _type {
+ return 'Desk';
+}
+
+1;
--- /dev/null
+package Koha::Desks;
+
+# Copyright (C) 2020 BULAC
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+
+use Modern::Perl;
+
+use Carp;
+
+use Koha::Database;
+
+use Koha::Desk;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Desks - Koha Desk Object set class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 _type
+
+=cut
+
+sub _type {
+ return 'Desk';
+}
+
+=head3 object_class
+
+=cut
+
+sub object_class {
+ return 'Koha::Desk';
+}
+
+1;
--- /dev/null
+#! /usr/bin/perl
+
+# Copyright (C) 2020 BULAC
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+
+use Modern::Perl;
+use CGI qw ( -utf8 );
+use C4::Context;
+use C4::Auth;
+use C4::Output;
+
+use Koha::Desks;
+
+my $input = new CGI;
+my $searchfield = $input->param('desk_name') // q||;
+my $desk_id = $input->param('desk_id') || '';
+my $op = $input->param('op') || 'list';
+my @messages;
+
+my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+ { template_name => "admin/desks.tt",
+ query => $input,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { parameters => 'manage_desks' },
+ debug => 1,
+ }
+);
+
+my $branches = Koha::Libraries->search( {}, { order_by => ['branchname'] } )->unblessed;
+
+if ( $op eq 'add_form' ) {
+ my $desk;
+ if ($desk_id) {
+ $desk = Koha::Desks->find($desk_id);
+ }
+
+ $template->param( desk => $desk, );
+} elsif ( $op eq 'add_validate' ) {
+ my $desk_id = $input->param('desk_id');
+ my $desk_name = $input->param('desk_name');
+ my $branchcode = $input->param('branchcode');
+
+ if (Koha::Desks->find($desk_id)) {
+ my $desk = Koha::Desks->find($desk_id);
+ $desk->desk_name($desk_name);
+ $desk->branchcode($branchcode);
+ eval { $desk->store; };
+ if ($@) {
+ push @messages, { type => 'error', code => 'error_on_update' };
+ } else {
+ push @messages, { type => 'message', code => 'success_on_update' };
+ }
+ } else {
+ my $desk = Koha::Desk->new(
+ {
+ desk_id => $desk_id,
+ desk_name => $desk_name,
+ branchcode => $branchcode,
+ }
+ );
+ eval { $desk->store; };
+ if ($@) {
+ push @messages, { type => 'error', code => 'error_on_insert' };
+ } else {
+ push @messages, { type => 'message', code => 'success_on_insert' };
+ }
+ }
+ $searchfield = q||;
+ $op = 'list';
+} elsif ( $op eq 'delete_confirm' ) {
+ my $desk = Koha::Desks->find($desk_id);
+ $template->param( desk => $desk, );
+} elsif ( $op eq 'delete_confirmed' ) {
+ my $desk = Koha::Desks->find($desk_id);
+ my $deleted = eval { $desk->delete; };
+
+ if ( $@ or not $deleted ) {
+ push @messages, { type => 'error', code => 'error_on_delete' };
+ } else {
+ push @messages, { type => 'message', code => 'success_on_delete' };
+ }
+ $op = 'list';
+}
+
+if ( $op eq 'list' || ! $op) {
+ my $desks = Koha::Desks->search( { desk_name => { -like => "%$searchfield%" } } );
+ $template->param( desks => $desks, );
+}
+
+$template->param(
+ desk_id => $desk_id,
+ searchfield => $searchfield,
+ messages => \@messages,
+ op => $op,
+ branches => $branches,
+);
+
+output_html_with_http_headers $input, $cookie, $template->output;
[% IF ( CAN_user_parameters_manage_libraries ) %]
<li><a href="/cgi-bin/koha/admin/branches.pl">Libraries</a></li>
<li><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></li>
+ <li><a href="/cgi-bin/koha/admin/desks.pl">Desks</a></li>
[% END %]
[% IF ( CAN_user_parameters_manage_itemtypes ) %]
<li><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></li>
--- /dev/null
+[% USE Koha %]
+<div class="gradient">
+<h1 id="logo"><a href="/cgi-bin/koha/mainpage.pl">[% LibraryName|html %]</a></h1><!-- Begin Desks Resident Search Box -->
+<div id="header_search">
+ <div id="desk_search" class="residentsearch">
+ <p class="tip">Desk search:</p>
+ <form action="[% script_name|html %]" method="post">
+ <input class="head-searchbox" type="text" name="desk_name" value="[% searchfield|html %]" size="40" />
+ <input type="submit" name="submit" value="OK" class="submit" />
+ </form>
+ </div>
+
+ [% INCLUDE 'patron-search-box.inc' %]
+
+ [% IF ( CAN_user_catalogue ) %]
+ <div id="catalog_search" class="residentsearch">
+ <p class="tip">Enter search keywords:</p>
+ <form action="/cgi-bin/koha/catalogue/search.pl" method="get" id="cat-search-block">
+ [% IF ( Koha.Preference('IntranetCatalogSearchPulldown') ) %][% INCLUDE 'search_indexes.inc' %][% END %]
+ <input type="text" name="q" id="search-form" size="40" value="" title="Enter the terms you wish to search for." class="head-searchbox form-text" />
+ <input type="submit" value="Submit" class="submit" />
+ </form>
+ </div>[% END %]
+ <ul>
+ <li><a class="keep_text" href="#desk_search">Search desks</a></li>
+ [% IF ( CAN_user_circulate_circulate_remaining_permissions ) %]<li><a class="keep_text" href="#circ_search">Check out</a></li>[% END %]
+ [% IF ( CAN_user_catalogue ) %]<li><a class="keep_text" href="#catalog_search">Search the catalog</a></li>[% END %]
+ </ul>
+</div>
+</div>
+<!-- End Desks Resident Search Box -->
<dd>Define libraries.</dd>
<dt><a href="/cgi-bin/koha/admin/library_groups.pl">Library groups</a></dt>
<dd>Define hierarchical library groups.</dd>
+ <dt><a href="/cgi-bin/koha/admin/desks.pl">Desks</a></dt>
+ <dd>Define desks.</dd>
[% END %]
[% IF ( CAN_user_parameters_manage_itemtypes ) %]
<dt><a href="/cgi-bin/koha/admin/itemtypes.pl">Item types</a></dt>
--- /dev/null
+[% USE raw %]
+[% USE Branches %]
+[% USE Asset %]
+[% SET footerjs = 1 %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Koha › Administration › [% IF op =='add_form' %]Desks › [% IF desk.desk_id %] Modify desk[% ELSE %] New desk[% END %][% ELSE %][% IF op == 'delete_confirm' %]Desks › Confirm deletion of desk[% ELSE %] Desks[% END %][% END %]</title>
+[% INCLUDE 'doc-head-close.inc' %]
+</head>
+
+<body id="admin_desks" class="admin">
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'desks-admin-search.inc' %]
+
+<div id="breadcrumbs">
+ <a href="/cgi-bin/koha/mainpage.pl">Home</a>
+ › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
+ › <a href="/cgi-bin/koha/admin/desks.pl">Desks</a>
+ [% IF op == 'add_form' %]
+ › [% IF desk.desk_id %]Modify[% ELSE %]New[% END %] Desk
+ [% ELSIF op == 'delete_confirm' %]
+ › Confirm deletion of desk
+ [% END %]
+</div>
+
+<div class="main container-fluid">
+ <div class="row">
+ <div class="col-sm-10 col-sm-push-2">
+ <main>
+
+[% FOR m IN messages %]
+ <div class="dialog [% m.type | html %]">
+ [% SWITCH m.code %]
+ [% CASE 'error_on_update' %]
+ An error occurred when updating this desk. Perhaps it already exists.
+ [% CASE 'error_on_insert' %]
+ An error occurred when adding this desk. The desk id might already exist.
+ [% CASE 'error_on_delete' %]
+ An error occurred when deleting this desk. Check the logs.
+ [% CASE 'success_on_update' %]
+ Desk updated successfully.
+ [% CASE 'success_on_insert' %]
+ Desk added successfully.
+ [% CASE 'success_on_delete' %]
+ Desk deleted successfully.
+ [% CASE 'already_exists' %]
+ This desk already exists.
+ [% CASE %]
+ [% m.code | html %]
+ [% END %]
+ </div>
+[% END %]
+
+[% IF op == 'add_form' %]
+ [% IF desk %]
+ <h1>Modify a desk</h1>
+ [% ELSE %]
+ <h1>New desk</h1>
+ [% END %]
+
+ <form action="/cgi-bin/koha/admin/desks.pl" name="Aform" method="post" class="validated">
+ <input type="hidden" name="op" value="add_validate" />
+ <input type="hidden" name="desk_id" value="[% desk.desk_id | html %]" />
+
+ <fieldset class="rows">
+ <ol>
+ [% IF desk %]
+ <li><span class="label">Desk ID: </span>[% desk.desk_id | html %]</li>
+ [% END %]
+ <li>
+ <label for="desk_name" class="required">Desk: </label>
+ <input type="text" name="desk_name" id="desk_name" size="80" maxlength="100" value="[% desk.desk_name | html %]" required="required" class="required" /> <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="branchcode" class="required">Library: </label>
+ <select id="branchcode" name="branchcode" required="required">
+ <option value=""></option>
+ [% FOREACH branch IN branches %]
+ [% IF (Branches.GetLoggedInBranchcode == branch.branchcode) %]
+ <option value="[% branch.branchcode|html %]" selected="selected">[% branch.branchname|html %]</option>
+ [% ELSE %]
+ <option value="[% branch.branchcode|html %]">[% branch.branchname|html %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </li>
+
+ </ol>
+ </fieldset>
+
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <a class="cancel" href="/cgi-bin/koha/admin/desks.pl">Cancel</a>
+ </fieldset>
+ </form>
+[% END %]
+
+[% IF op == 'delete_confirm' %]
+ <div class="dialog alert">
+ <h3>Delete desk "[% desk.desk_name | html %]?"</h3>
+ <table>
+ <tr><th>Desk id</th>
+ <td>[% desk.desk_id | html %]</td>
+ </tr>
+ <tr><th>Desk</th>
+ <td>[% desk.desk_name | html %]</td>
+ </tr>
+ <tr><th>Branchcode</th>
+ <td>[% desk.branchcode | html %]</td>
+ </tr>
+ </table>
+ <form action="/cgi-bin/koha/admin/desks.pl" method="post">
+ <input type="hidden" name="op" value="delete_confirmed" />
+ <input type="hidden" name="desk_id" value="[% desk.desk_id | html %]" />
+ <button type="submit" class="approve"><i class="fa fa-fw fa-check"></i> Yes, delete</button>
+ </form>
+ <form action="/cgi-bin/koha/admin/desks.pl" method="get">
+ <button type="submit" class="deny"><i class="fa fa-fw fa-remove"></i> No, do not delete</button>
+ </form>
+ </div>
+[% END %]
+
+[% IF op == 'list' %]
+
+ <div id="toolbar" class="btn-toolbar">
+ <a class="btn btn-default" id="newdesk" href="/cgi-bin/koha/admin/desks.pl?op=add_form"><i class="fa fa-plus"></i> New desk</a>
+ </div>
+
+ <h2>Desks</h2>
+ [% IF searchfield %]
+ Searching: [% searchfield | html %]
+ [% END %]
+
+ [% IF desks.count %]
+ <table id="table_desks">
+ <thead>
+ <tr>
+ <th>Desk ID</th>
+ <th>Desk</th>
+ <th>Library</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOREACH desk IN desks %]
+ <tr>
+ <td>[% desk.desk_id | html %]</td>
+ <td>[% desk.desk_name | html %]</td>
+ <td>[% desk.branchcode | html %]</td>
+ <td class="actions">
+ <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/desks.pl?op=add_form&desk_id=[% desk.desk_id | html %]"><i class="fa fa-pencil"></i> Edit</a>
+ <a class="btn btn-default btn-xs" href="/cgi-bin/koha/admin/desks.pl?op=delete_confirm&desk_id=[% desk.desk_id | html %]"><i class="fa fa-trash"></i> Delete</a>
+ </td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+ [% ELSE %]
+ <div class="dialog message">
+ There are no desks defined. <a href="/cgi-bin/koha/admin/desks.pl?op=add_form">Create a new desk</a>.
+ </div>
+ [% END %]
+[% END %]
+
+ </main>
+ </div> <!-- /.col-sm-10.col-sm-push-2 -->
+
+ <div class="col-sm-2 col-sm-pull-10">
+ <aside>
+ [% INCLUDE 'admin-menu.inc' %]
+ </aside>
+ </div> <!-- /.col-sm-2.col-sm-pull-10 -->
+ </div> <!-- /.row -->
+
+[% MACRO jsinclude BLOCK %]
+ [% Asset.js("js/admin-menu.js") | $raw %]
+ [% INCLUDE 'datatables.inc' %]
+ <script>
+ $(document).ready(function() {
+ $("#table_desks").dataTable($.extend(true, {}, dataTablesDefaults, {
+ "aoColumnDefs": [
+ { "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable": false },
+ ],
+ "aaSorting": [[ 1, "asc" ]],
+ "iDisplayLength": 10,
+ "sPaginationType": "full_numbers"
+ }));
+ });
+ </script>
+[% END %]
+[% INCLUDE 'intranet-bottom.inc' %]
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2015 Koha Development team
+# Copyright 2020 BULAC
+#
+# This file is part of Koha
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 4;
+
+use Koha::Desk;
+use Koha::Desks;
+use Koha::Database;
+use Koha::Libraries;
+
+use t::lib::TestBuilder;
+
+my $schema = Koha::Database->new->schema;
+$schema->storage->txn_begin;
+
+# Add CPL if missing.
+if (not defined Koha::Libraries->find('CPL')) {
+ Koha::Library->new({ branchcode => 'CPL', branchname => 'Centerville' })->store;
+}
+
+my $builder = t::lib::TestBuilder->new;
+my $nb_of_desks = Koha::Desks->search->count;
+my $new_desk_1 = Koha::Desk->new({
+ desk_name => 'my_desk_name_for_test_1',
+ branchcode => 'CPL',
+})->store;
+my $new_desk_2 = Koha::Desk->new({
+ desk_name => 'my_desk_name_for_test_2',
+ branchcode => 'CPL',
+})->store;
+
+like( $new_desk_1->desk_id, qr|^\d+$|, 'Adding a new desk should have set the desk_id');
+is( Koha::Desks->search->count, $nb_of_desks + 2, 'The 2 desks should have been added' );
+
+my $retrieved_desk_1 = Koha::Desks->find( $new_desk_1->desk_id );
+is( $retrieved_desk_1->desk_name, $new_desk_1->desk_name, 'Find a desk by id should return the correct desk' );
+
+$retrieved_desk_1->delete;
+is( Koha::Desks->search->count, $nb_of_desks + 1, 'Delete should have deleted the desk' );
+
+$schema->storage->txn_rollback;