View | Details | Raw Unified | Return to bug 8352
Collapse All | Expand All

(-)a/C4/Installer/PerlDependencies.pm (+10 lines)
Lines 647-657 our $PERL_DEPS = { Link Here
647
        'required' => '1',
647
        'required' => '1',
648
        'min_ver'  => '0.22',
648
        'min_ver'  => '0.22',
649
      },
649
      },
650
    'Printer' => {
651
        'usage'    => 'Push to printer',
652
        'required' => '0',
653
        'min_ver'  => '0.98',
654
    },
650
    'Net::Printer' => {
655
    'Net::Printer' => {
651
        'usage'    => 'Push to printer',
656
        'usage'    => 'Push to printer',
652
        'required' => '0',
657
        'required' => '0',
653
        'min_ver'  => '1.11',
658
        'min_ver'  => '1.11',
654
    },
659
    },
660
    'HTML::HTMLDoc' => {
661
        'usage'    => 'Push to printer',
662
        'required' => '0',
663
        'min_ver'  => '0.10',
664
    },
655
    'File::Temp' => {
665
    'File::Temp' => {
656
        'usage'    => 'Plugins',
666
        'usage'    => 'Plugins',
657
        'required' => '0',
667
        'required' => '0',
(-)a/Koha/Schema/Result/Printer.pm (-26 / +72 lines)
Lines 1-21 Link Here
1
use utf8;
2
package Koha::Schema::Result::Printer;
1
package Koha::Schema::Result::Printer;
3
2
4
# Created by DBIx::Class::Schema::Loader
3
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
5
7
=head1 NAME
8
9
Koha::Schema::Result::Printer
10
11
=cut
12
13
use strict;
6
use strict;
14
use warnings;
7
use warnings;
15
8
16
use base 'DBIx::Class::Core';
9
use base 'DBIx::Class::Core';
17
10
18
=head1 TABLE: C<printers>
11
12
=head1 NAME
13
14
Koha::Schema::Result::Printer
19
15
20
=cut
16
=cut
21
17
Lines 23-74 __PACKAGE__->table("printers"); Link Here
23
19
24
=head1 ACCESSORS
20
=head1 ACCESSORS
25
21
26
=head2 printername
22
=head2 id
23
24
  data_type: 'integer'
25
  is_auto_increment: 1
26
  is_nullable: 0
27
28
=head2 name
27
29
28
  data_type: 'varchar'
30
  data_type: 'varchar'
29
  default_value: (empty string)
31
  default_value: (empty string)
30
  is_nullable: 0
32
  is_nullable: 0
31
  size: 40
33
  size: 40
32
34
33
=head2 printqueue
35
=head2 queue
34
36
35
  data_type: 'varchar'
37
  data_type: 'varchar'
36
  is_nullable: 1
38
  is_nullable: 1
37
  size: 20
39
  size: 20
38
40
39
=head2 printtype
41
=head2 type
40
42
41
  data_type: 'varchar'
43
  data_type: 'text'
42
  is_nullable: 1
44
  is_nullable: 1
43
  size: 20
44
45
45
=cut
46
=cut
46
47
47
__PACKAGE__->add_columns(
48
__PACKAGE__->add_columns(
48
  "printername",
49
  "id",
50
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
51
  "name",
49
  { data_type => "varchar", default_value => "", is_nullable => 0, size => 40 },
52
  { data_type => "varchar", default_value => "", is_nullable => 0, size => 40 },
50
  "printqueue",
53
  "queue",
51
  { data_type => "varchar", is_nullable => 1, size => 20 },
52
  "printtype",
53
  { data_type => "varchar", is_nullable => 1, size => 20 },
54
  { data_type => "varchar", is_nullable => 1, size => 20 },
55
  "type",
56
  { data_type => "text", is_nullable => 1 },
54
);
57
);
58
__PACKAGE__->set_primary_key("id");
55
59
56
=head1 PRIMARY KEY
57
60
58
=over 4
61
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2014-05-19 09:04:19
62
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uapO0jjBiwFJZjpbJMas/g
59
63
60
=item * L</printername>
64
sub print {
65
    my ( $self, $params ) = @_;
61
66
62
=back
67
    my $data    = $params->{data};
68
    my $is_html = $params->{is_html};
63
69
64
=cut
70
    return unless ($data);
71
72
    if ($is_html) {
73
        require HTML::HTMLDoc;
74
        my $htmldoc = new HTML::HTMLDoc();
75
        $htmldoc->set_output_format('ps');
76
        $htmldoc->set_html_content($data);
77
        my $doc = $htmldoc->generate_pdf();
78
        $data = $doc->to_string();
79
    }
80
81
    my ( $result, $error );
82
83
    if ( $self->queue() =~ /:/ ) {
84
85
        # Printer has a server:port address, use Net::Printer
86
        require Net::Printer;
87
88
        my ( $server, $port ) = split( /:/, $self->queue() );
89
90
        my $printer = new Net::Printer(
91
            printer     => $self->name(),
92
            server      => $server,
93
            port        => $port,
94
            lineconvert => "YES"
95
        );
96
97
        $result = $printer->printstring($data);
98
99
        $error = $printer->printerror();
100
    }
101
    else {
102
        require Printer;
65
103
66
__PACKAGE__->set_primary_key("printername");
104
        my $printer_name = $self->name();
67
105
106
        my $printer = new Printer( 'linux' => 'lp' );
107
        $printer->print_command(
108
            linux => {
109
                type    => 'pipe',
110
                command => "lp -d $printer_name",
111
            }
112
        );
68
113
69
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
114
        $result = $printer->print($data);
70
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OaIxwtdwn0TJLggwOygC2w
115
    }
71
116
117
    return ( $result eq '1', $error );
118
}
72
119
73
# You can replace this text with custom content, and it will be preserved on regeneration
74
1;
120
1;
(-)a/admin/printers.pl (-125 / +20 lines)
Lines 1-26 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
2
3
#script to administer the aqbudget table
3
# Copyright 2014 ByWater Solutions
4
#written 20/02/2002 by paul.poulain@free.fr
4
# Copyright 2012 Foundations Bible College Inc.
5
# This software is placed under the gnu General Public License, v2 (http://www.gnu.org/licenses/gpl.html)
6
7
# ALGO :
8
# this script use an $op to know what to do.
9
# if $op is empty or none of the above values,
10
#	- the default screen is build (with all records, or filtered datas).
11
#	- the   user can clic on add, modify or delete record.
12
# if $op=add_form
13
#	- if primkey exists, this is a modification,so we read the $primkey record
14
#	- builds the add/modify form
15
# if $op=add_validate
16
#	- the user has just send datas, so we create/modify the record
17
# if $op=delete_form
18
#	- we show the record having primkey=$primkey and ask for deletion validation form
19
# if $op=delete_confirm
20
#	- we delete the record having primkey=$primkey
21
22
23
# Copyright 2000-2002 Katipo Communications
24
#
5
#
25
# This file is part of Koha.
6
# This file is part of Koha.
26
#
7
#
Lines 38-150 Link Here
38
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39
20
40
use strict;
21
use strict;
41
#use warnings; FIXME - Bug 2505
22
use warnings;
23
42
use CGI;
24
use CGI;
25
use autouse 'Data::Dumper' => qw(Dumper);
26
27
use C4::Auth;
28
use C4::Koha;
43
use C4::Context;
29
use C4::Context;
44
use C4::Output;
30
use C4::Output;
45
use C4::Auth;
46
47
sub StringSearch  {
48
	my ($searchstring,$type)=@_;		# why bother with $type if we don't use it?!
49
	$searchstring=~ s/\'/\\\'/g;
50
	my @data=split(' ',$searchstring);
51
	my $sth = C4::Context->dbh->prepare("
52
		SELECT printername,printqueue,printtype from printers 
53
		WHERE (printername like ?) order by printername
54
	");
55
	$sth->execute("$data[0]%");
56
	my $data=$sth->fetchall_arrayref({});
57
	return (scalar(@$data),$data);
58
}
59
60
my $input = new CGI;
61
my $searchfield=$input->param('searchfield');
62
#my $branchcode=$input->param('branchcode');
63
my $offset=$input->param('offset') || 0;
64
my $script_name="/cgi-bin/koha/admin/printers.pl";
65
66
my $pagesize=20;
67
my $op = $input->param('op');
68
$searchfield=~ s/\,//g;
69
70
my ($template, $loggedinuser, $cookie) = get_template_and_user({
71
	   template_name => "admin/printers.tmpl",
72
			   query => $input,
73
			 	type => "intranet",
74
	 authnotrequired => 0,
75
       flagsrequired => {parameters => 'parameters_remaining_permissions'},
76
		       debug => 1,
77
});
78
79
$template->param(searchfield => $searchfield,
80
		 script_name => $script_name);
81
82
#start the page and read in includes
83
84
my $dbh = C4::Context->dbh;
85
################## ADD_FORM ##################################
86
# called by default. Used to create form to add or  modify a record
87
if ($op eq 'add_form') {
88
	$template->param(add_form => 1);
89
	#---- if primkey exists, it's a modify action, so read values to modify...
90
	my $data;
91
	if ($searchfield) {
92
		my $sth=$dbh->prepare("SELECT printername,printqueue,printtype from printers where printername=?");
93
		$sth->execute($searchfield);
94
		$data=$sth->fetchrow_hashref;
95
	}
96
97
	$template->param(printqueue => $data->{'printqueue'},
98
			 printtype => $data->{'printtype'});
99
													# END $OP eq ADD_FORM
100
################## ADD_VALIDATE ##################################
101
# called by add_form, used to insert/modify data in DB
102
} elsif ($op eq 'add_validate') {
103
	$template->param(add_validate => 1);
104
	if ($input->param('add')){
105
		my $sth=$dbh->prepare("INSERT INTO printers (printername,printqueue,printtype) VALUES (?,?,?)");
106
		$sth->execute($input->param('printername'),$input->param('printqueue'),$input->param('printtype'));
107
	} else {
108
		my $sth=$dbh->prepare("UPDATE printers SET printqueue=?,printtype=? WHERE printername=?");
109
		$sth->execute($input->param('printqueue'),$input->param('printtype'),$input->param('printername'));
110
	}
111
													# END $OP eq ADD_VALIDATE
112
################## DELETE_CONFIRM ##################################
113
# called by default form, used to confirm deletion of data in DB
114
} elsif ($op eq 'delete_confirm') {
115
	$template->param(delete_confirm => 1);
116
	my $sth=$dbh->prepare("select printername,printqueue,printtype from printers where printername=?");
117
	$sth->execute($searchfield);
118
	my $data=$sth->fetchrow_hashref;
119
	$template->param(printqueue => $data->{'printqueue'},
120
			 printtype  => $data->{'printtype'});
121
													# END $OP eq DELETE_CONFIRM
122
################## DELETE_CONFIRMED ##################################
123
# called by delete_confirm, used to effectively confirm deletion of data in DB
124
} elsif ($op eq 'delete_confirmed') {
125
	$template->param(delete_confirmed => 1);
126
	my $sth=$dbh->prepare("delete from printers where printername=?");
127
	$sth->execute($searchfield);
128
													# END $OP eq DELETE_CONFIRMED
129
################## DEFAULT ###########################################
130
} else { # DEFAULT
131
	$template->param(else => 1);
132
	my ($count,$results)=StringSearch($searchfield,'web');
133
	my $max = ($offset+$pagesize < $count) ? $offset+$pagesize : $count;
134
	my @loop = (@$results)[$offset..$max];
135
	
136
	$template->param(loop => \@loop);
137
	
138
	if ($offset>0) {
139
		$template->param(offsetgtzero => 1,
140
				 prevpage => $offset-$pagesize);
141
	}
142
	if ($offset+$pagesize<$count) {
143
		$template->param(ltcount => 1,
144
				 nextpage => $offset+$pagesize);
145
	}
146
31
147
} #---- END $OP eq DEFAULT
32
my $cgi = new CGI;
148
33
149
output_html_with_http_headers $input, $cookie, $template->output;
34
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
35
    {
36
        template_name   => "admin/printers.tt",
37
        query           => $cgi,
38
        type            => "intranet",
39
        authnotrequired => 0,
40
        flagsrequired   => { parameters => 'parameters_remaining_permissions' },
41
        debug           => 1,
42
    }
43
);
150
44
45
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/installer/data/mysql/updatedatabase.pl (-15 / +19 lines)
Lines 8553-8577 if (CheckVersion($DBversion)) { Link Here
8553
8553
8554
$DBversion = "3.17.00.XXX";
8554
$DBversion = "3.17.00.XXX";
8555
if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
8555
if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
8556
    $dbh->do("ALTER TABLE reserves ADD printed BOOLEAN NULL AFTER suspend_until");
8556
    $dbh->do("ALTER TABLE reserves ADD printed DATETIME NULL AFTER suspend_until");
8557
    $dbh->do("INSERT INTO  `letter` (
8557
    $dbh->do("
8558
    `module` ,
8558
        INSERT INTO letter (
8559
    `code` ,
8559
            module, code, branchcode, name, is_html, title, content
8560
    `branchcode` ,
8560
        ) VALUES (
8561
    `name` ,
8561
             'reserves',  'HOLD_PLACED_PRINT',  '',  'Hold Placed ( Auto-Print )',  '0',  'Hold Placed ( Auto-Print )',
8562
    `is_html` ,
8562
'Hold to pull at <<branches.branchname>>
8563
    `title` ,
8564
    `content`
8565
    )
8566
    VALUES (
8567
    'reserves',  'HOLD_PLACED_PRINT',  '',  'Hold Placed ( Auto-Print )',  '0',  'Hold Placed ( Auto-Print )',  'Hold to pull at <<branches.branchname>>
8568
8563
8569
    For <<borrowers.firstname>> <<borrowers.surname>> ( <<borrowers.cardnumber>> )
8564
For <<borrowers.firstname>> <<borrowers.surname>> ( <<borrowers.cardnumber>> )
8570
8565
8571
    <<biblio.title>> by <<biblio.author>>'
8566
<<biblio.title>> by <<biblio.author>>'
8572
    )");
8567
    )");
8573
8568
8574
    print "Upgrade to $DBversion done (Add print holds to pull notices on demand feature)\n";
8569
    $dbh->do(q{
8570
        ALTER TABLE printers
8571
            DROP PRIMARY KEY,
8572
            ADD id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST,
8573
            CHANGE printername name  TEXT NOT NULL DEFAULT '',
8574
            CHANGE printqueue  queue TEXT NULL DEFAULT NULL,
8575
            CHANGE printtype   type  TEXT NULL DEFAULT NULL
8576
    });
8577
8578
    print "Upgrade to $DBversion done (Bug 8352 - Add automatic printing of 'hold to pull' notices)\n";
8575
    SetVersion($DBversion);
8579
    SetVersion($DBversion);
8576
}
8580
}
8577
8581
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/printers-admin-search.inc (-28 lines)
Lines 1-28 Link Here
1
<div class="gradient">
2
<h1 id="logo"><a href="/cgi-bin/koha/mainpage.pl">[% LibraryName %]</a></h1><!-- Begin Printers Resident Search Box -->
3
<div id="header_search">
4
	<div id="printer_search" class="residentsearch">
5
    <p class="tip">Printer search:</p>
6
<form action="[% script_name %]" method="post">
7
                <input type="text" size="40" name="description" value="[% searchfield %]" />
8
                <input type="submit" name="submit" value="Search" />
9
        </form>
10
	</div>
11
    [% INCLUDE 'patron-search-box.inc' %]
12
	[% IF ( CAN_user_catalogue ) %]
13
    <div id="catalog_search" class="residentsearch">
14
	<p class="tip">Enter search keywords:</p>
15
		<form action="/cgi-bin/koha/catalogue/search.pl"  method="get" id="cat-search-block">
16
			 <input type="text" name="q" id="search-form" size="40" value="" title="Enter the terms you wish to search for." class="form-text" />
17
				<input type="submit" value="Submit"  class="submit" />
18
		</form>
19
	</div>
20
	[% END %]
21
			<ul>
22
            <li><a href="#printer_search">Search printers</a></li>
23
            [% IF ( CAN_user_circulate ) %]<li><a href="#circ_search">Check out</a></li>[% END %]
24
            [% IF ( CAN_user_catalogue ) %]<li><a href="#catalog_search">Search the catalog</a></li>[% END %]
25
			</ul>	
26
</div>
27
</div><!-- /gradient -->
28
<!-- End Printers Resident Search Box -->
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/printers-toolbar.inc (+4 lines)
Line 0 Link Here
1
<div id="toolbar" class="btn-toolbar">
2
        <div class="btn-group"><a class="btn btn-small" id="add_printer" href="#"><i class="icon-plus"></i> Add printer</a></div>
3
        <div class="btn-group"><a class="btn btn-small" id="delete_printer" href="#"><i class="icon-remove"></i> Delete printer(s)</a></div>
4
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt (-2 / +4 lines)
Lines 98-107 Link Here
98
98
99
<h3>Additional parameters</h3>
99
<h3>Additional parameters</h3>
100
<dl>
100
<dl>
101
	<!-- <dt><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></dt>
101
    <dt><a href="/cgi-bin/koha/admin/printers.pl">Printers</a></dt>
102
	<dd>Printers (UNIX paths).</dd> -->
102
    <dd>Define your configured network printers</dd>
103
103
    <dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></dt>
104
    <dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></dt>
104
	<dd>Define which servers to query for MARC data in the integrated Z39.50 client.</dd>
105
	<dd>Define which servers to query for MARC data in the integrated Z39.50 client.</dd>
106
105
    <dt><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></dt>
107
    <dt><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></dt>
106
    <dd>Choose which plugins to use to suggest searches to patrons and staff.</dd>
108
    <dd>Choose which plugins to use to suggest searches to patrons and staff.</dd>
107
</dl>
109
</dl>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/printers.tt (-176 / +195 lines)
Lines 1-191 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Administration &rsaquo;
2
<title>Koha &rsaquo; Administration &rsaquo; Printer editor</title>
3
[% IF ( add_form ) %][% IF ( searchfield ) %] Printers &rsaquo; Modify printer '[% searchfield %]'[% ELSE %] Printers &rsaquo; New printer[% END %][% END %]
4
[% IF ( add_validate ) %] Printers &rsaquo; Printer added[% END %]
5
[% IF ( delete_confirm ) %] Printers &rsaquo; Confirm deletion of printer '[% searchfield %]'[% END %]
6
[% IF ( delete_confirmed ) %] Printers &rsaquo; Printer deleted[% END %]
7
[% IF ( else ) %]Printers[% END %]</title>
8
[% INCLUDE 'doc-head-close.inc' %]
3
[% INCLUDE 'doc-head-close.inc' %]
9
[% IF ( add_form ) %]<script type="text/javascript">
4
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
5
[% INCLUDE 'datatables.inc' %]
6
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/dataTables.fnReloadAjax.js"></script>
7
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.jeditable.mini.js"></script>
8
<script type="text/javascript">
10
//<![CDATA[
9
//<![CDATA[
11
        //
10
var MSG_ID_HELP = _("Click on the printer's id to select or deselect the printer. Multiple printers may be selected.");
12
        function isNotNull(f,noalert) {
11
13
                if (f.value.length ==0) {
12
var oTable; /* oTable needs to be global */
14
   return false;
13
var sEmptyTable = _("No printers available. Please use the \"Add printer\" button to add a printer."); /* override the default message in datatables-strings.inc */
15
                }
14
$(document).ready(function() {
16
                return true;
15
    oTable = $("#printers_editor").dataTable({
16
                "bAutoWidth"        : false,
17
                "bProcessing"       : true,
18
                "bPaginate"         : true,
19
                "sPaginationType"   : "full_numbers",
20
                "sDom": '<"top pager"iflp>rt<"bottom pager"flp><"clear">',
21
                "sAjaxSource"       : "/cgi-bin/koha/svc/printer",
22
                "aoColumns"         : [
23
                    { "sWidth": "5%"  },
24
                    { "sWidth": "40%" },
25
                    { "sWidth": "55%" },
26
                    { "bVisible": false },
27
                ],
28
                "oLanguage"          : {
29
                    "oPaginate": {
30
                                   "sFirst": MSG_DT_FIRST,
31
                                   "sLast": MSG_DT_LAST,
32
                                   "sNext": MSG_DT_NEXT,
33
                                   "sPrevious": MSG_DT_PREVIOUS,
34
                                 },
35
                    "sEmptyTable": MSG_DT_EMPTY_TABLE,
36
                    "sInfo": MSG_DT_INFO,
37
                    "sInfoEmpty": MSG_DT_INFO_EMPTY,
38
                    "sInfoFiltered": MSG_DT_INFO_FILTERED,
39
                    "sLengthMenu": MSG_DT_LENGTH_MENU,
40
                    "sLoadingRecords": MSG_DT_LOADING_RECORDS,
41
                    "sProcessing": MSG_DT_PROCESSING,
42
                    "sSearch": MSG_DT_SEARCH,
43
                    "sZeroRecords": MSG_DT_ZERO_RECORDS,
44
                },
45
                "fnPreDrawCallback": function(oSettings) {
46
                    return true;
47
                },
48
                "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
49
                    /* do foo on the current row and its child nodes */
50
                    var noEditFields = [];
51
                    var printerID = $('td', nRow)[0].innerHTML;
52
                    $(nRow).attr("id", printerID); /* set row ids to printer id */
53
                    $('td:eq(0)', nRow).click(function() {$(this.parentNode).toggleClass('selected',this.clicked);}); /* add row selectors */
54
                    $('td:eq(0)', nRow).attr("title", _("Click ID to select/deselect printer"));
55
                    $('td', nRow).attr("id",printerID);
56
                    if ( printerID == "NA") {
57
                        $('td', nRow)[0].setAttribute("id","no_edit");
58
                        $('td', nRow)[1].setAttribute("id","no_edit");
59
                        $('td', nRow)[2].setAttribute("id","no_edit");
60
                    }
61
                    else {
62
                        $('td', nRow)[0].setAttribute("id","no_edit");
63
                    }
64
                    return nRow;
65
                },
66
               "fnDrawCallback": function(oSettings) {
67
                    /* Apply the jEditable handlers to the table on all fields w/o the no_edit id */
68
                    $('#printers_editor tbody td[id!="no_edit"]').editable( "/cgi-bin/koha/svc/printer", {
69
                        "submitdata"    : function ( value, settings ) {
70
                            return {
71
                                "column": oTable.fnGetPosition( this )[2],
72
                                "action": "edit",
73
                            };
74
                        },
75
                        "height"        : "14px",
76
                        "placeholder"   : "",
77
                    });
78
               },
79
    });
80
    $("#add_printer").click(function(){
81
        fnClickAddRow();
82
        return false;
83
    });
84
    $("#delete_printer").click(function(){
85
        fnClickDeleteRow();
86
        return false;
87
    });
88
});
89
90
    function fnClickAddPrinter(e, node) {
91
        if (e.keyCode == 13) {
92
93
            var printerName  = $('#printerName').val();
94
            var printerQueue = $('#printerQueue').val()
95
            var printerType  = $('#printerType').val()
96
97
            /* If passed a printer source, add the printer to the db */
98
            if (printerName) {
99
                $.ajax({
100
                    url: "/cgi-bin/koha/svc/printer",
101
                    type: "POST",
102
                    data: {
103
                            "name"    : printerName,
104
                            "queue"   : printerQueue,
105
                            "type"    : printerType,
106
                            "action"  : "add",
107
                    },
108
                    success: function(data){
109
                                var newPrinter = data[0];
110
                                var aRow = oTable.fnUpdate(
111
                                    newPrinter,
112
                                    node,
113
                                    undefined,
114
                                    false,
115
                                    false
116
                                );
117
                                oTable.fnPageChange( 'last' );
118
                                $('.add_printer_button').attr('onclick', 'fnClickAddRow()'); // re-enable add button
119
                    }
120
                });
121
            }
122
            else {
123
                alert(_("Please supply a printer name."));
124
            }
125
        }
126
        else if (e.keyCode == 27) {
127
            if (confirm(_("Are you sure you want to cancel adding this printer?"))) {
128
                oTable.fnDeleteRow(node);
129
            }
130
            else {
131
                return;
132
            }
17
        }
133
        }
18
        //
134
    }
19
        function isNum(v,maybenull) {
135
20
        var n = new Number(v.value);
136
    function fnClickAddRow() {
21
        if (isNaN(n)) {
137
        $('.add_printer_button').removeAttr('onclick'); // disable add button once it has been clicked
22
                return false;
138
        var aRow = oTable.fnAddData(
23
                }
139
            [
24
        if (maybenull==0 && v.value=="") {
140
                'NA',
25
                return false;
141
                '<input id="printerName"  type="text" style="height:14px; width:99%" onkeydown="fnClickAddPrinter(event,this.parentNode.parentNode)"/>',
142
                '<input id="printerQueue" type="text" style="height:14px; width:99%" onkeydown="fnClickAddPrinter(event,this.parentNode.parentNode)"/>',
143
                '<input id="printerType"  type="text" style="height:14px; width:99%" onkeydown="fnClickAddPrinter(event,this.parentNode.parentNode)"/>',
144
            ],
145
            false
146
        );
147
        oTable.fnPageChange( 'last' );
148
        $('#printerName').focus();
149
    }
150
151
    function fnClickDeleteRow() {
152
        var idsToDelete = oTable.$('.selected').map(function() {
153
              return this.id;
154
        }).get().join(', ');
155
        if (!idsToDelete) {
156
            alert(_("No printers selected!"));
26
        }
157
        }
27
        return true;
158
        else if (confirm(_("Are you sure you wish to delete printer(s) ") + idsToDelete + "?")) {
159
            oTable.$('.selected').each(function(){
160
                    var printerID = $(this).attr('id');
161
                        $.ajax({
162
                            url: "/cgi-bin/koha/svc/printer",
163
                            type: "POST",
164
                            data: {
165
                                    "id"        : printerID,
166
                                    "action"    : "delete",
167
                            },
168
                            /* Delete the row from the datatable */
169
                            success: function(){
170
                                oTable.fnDeleteRow(this);
171
                                oTable.fnReloadAjax(null, null, true);
172
                            }
173
                        });
174
                });
28
        }
175
        }
29
        //
176
        else {
30
        function Check(f) {
177
            return;
31
                var ok=1;
32
                var _alertString="";
33
                var alertString2;
34
                if (f.printername.value.length==0) {
35
                        _alertString += "- printer name missing\n";
36
                }
37
                if (f.printqueue.value.length==0) {
38
                        _alertString += "- Queue missing\n";
39
                }
40
                if (_alertString.length==0) {
41
                        document.Aform.submit();
42
                } else {
43
                        alertString2 = "Form not submitted because of the following problem(s)\n";
44
                        alertString2 += "------------------------------------------------------------------------------------\n\n";
45
                        alertString2 += _alertString;
46
                        alert(alertString2);
47
                }
48
        }
178
        }
49
        //]]>
179
    }
180
//]]>
50
</script>
181
</script>
51
	[% END %]
52
</head>
182
</head>
53
<body id="admin_printers" class="admin">
183
<body id="tools_printers" class="tools">
54
[% INCLUDE 'header.inc' %]
184
[% INCLUDE 'header.inc' %]
55
[% INCLUDE 'printers-admin-search.inc' %]
185
[% INCLUDE 'cat-search.inc' %]
56
186
57
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> &rsaquo; [% IF ( add_form ) %][% IF ( searchfield ) %] <a href="/cgi-bin/koha/admin/printers.pl">Printers</a> &rsaquo; Modify printer '[% searchfield %]'[% ELSE %] <a href="/cgi-bin/koha/admin/printers.pl">Printers</a> &rsaquo; New printer[% END %][% END %]
187
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> &rsaquo; Printers</div>
58
[% IF ( add_validate ) %] <a href="/cgi-bin/koha/admin/printers.pl">Printers</a> &rsaquo; Printer added[% END %]
59
[% IF ( delete_confirm ) %] <a href="/cgi-bin/koha/admin/printers.pl">Printers</a> &rsaquo; Confirm deletion of printer '[% searchfield %]'[% END %]
60
[% IF ( delete_confirmed ) %] <a href="/cgi-bin/koha/admin/printers.pl">Printers</a> &rsaquo; Printer deleted[% END %]
61
[% IF ( else ) %]Printers[% END %]</div>
62
188
63
<div id="doc3" class="yui-t2">
189
<div id="doc3" class="yui-t2">
64
   
190
    <div id="bd">
65
   <div id="bd">
191
        <div id="yui-main">
66
	<div id="yui-main">
192
            <div class="yui-b">
67
	<div class="yui-b">
193
                [% INCLUDE 'printers-toolbar.inc' %]
68
194
                <h2>Printers</h2>
69
[% IF ( add_form ) %]
195
                <table id="printers_editor">
70
196
                    <thead>
71
[% IF ( searchfield ) %]
197
                        <tr>
72
		<h1>Modify printer</h1>
198
                            <th><span style="cursor: help" onclick="event.stopPropagation();alert(MSG_ID_HELP);">ID</span></th>
73
	[% ELSE %]
199
                            <th>Name</th>
74
		<h1>New printer</h1>
200
                            <th>Server:Port</th>
75
	[% END %]
201
                            <th>Type</th>
76
        <form action="[% script_name %]" name="Aform" method="post">
202
                        </tr>
77
        <input type="hidden" name="op" value="add_validate" />
203
                    </thead>
78
	[% IF ( searchfield ) %]
204
                </table>
79
		<input type="hidden" name="add" value="0" />
205
            </div>
80
	[% ELSE %]
206
        </div>
81
		<input type="hidden" name="add" value="1" />
207
    <div class="yui-b noprint">
82
	[% END %]
208
    </div>
83
	<fieldset class="rows">
84
<ol>	[% IF ( searchfield ) %]
85
		<li>
86
            <span class="label">Printer name: </span>
87
				<input type="hidden" name="printername" id="" value="[% searchfield %]" />[% searchfield %]
88
		</li>
89
	[% ELSE %]
90
		<li>
91
            <label for="printername">Printer name: </label>
92
				<input type="text" name="printername" id="printername" size="50" maxlength="50" />
93
		</li>
94
	[% END %]
95
        	<li>
96
			<label for="printqueue">Queue: </label>
97
			<input type="text" name="printqueue" id="printqueue" size="50" maxlength="50" value="[% printqueue %]" /> 
98
		</li>
99
        	<li>
100
			<label for="printtype">Type: </label>
101
			<input type="text" name="printtype" id="printtype" size="50" maxlength="50" value="[% printtype %]" /> 
102
		</li></ol>
103
        </fieldset>
104
		<fieldset class="action"><input type="submit" value="Submit" onclick="Check(this.form);" /> <a class="cancel" href="/cgi-bin/koha/admin/printers.pl">Cancel</a></fieldset>
105
        </form>
106
107
[% END %]
108
109
[% IF ( add_validate ) %]
110
<h3>Printer added</h3>
111
<form action="[% script_name %]" method="post">
112
       <fieldset class="action"> <input type="submit" value="OK" /></fieldset>
113
</form>
114
[% END %]
115
116
[% IF ( delete_confirm ) %]
117
<h3>Confirm deletion of printer <em>[% searchfield %]</em></h3>
118
<ul>
119
		<li>
120
			<strong>Printer: </strong>
121
			[% searchfield %]
122
		</li>
123
		<li>
124
			<strong>Queue: </strong>
125
			[% printqueue %]
126
		</li>
127
        	<li>
128
			<strong>Type: </strong>
129
			[% printtype %]
130
		</li>
131
	</ul>
132
    	<form action="[% script_name %]" method="post">
133
			<input type="hidden" name="op" value="delete_confirmed" />
134
			<input type="hidden" name="searchfield" value="[% searchfield %]" />
135
			<input type="submit" value="Delete this printer" />
136
			</form> <form action="[% script_name %]" method="post">
137
				<input type="submit" value="Do not Delete" />
138
			</form>
139
[% END %]
140
141
[% IF ( delete_confirmed ) %]
142
<h3>Printer deleted</h3>
143
<form action="[% script_name %]" method="post">
144
		<fieldset class="action"><input type="submit" value="OK" /></fieldset>
145
</form>
146
[% END %]
147
148
[% IF ( else ) %]
149
150
<div id="toolbar" class="btn-toolbar">
151
    <a class="btn btn-small" id="newprinter" href="/cgi-bin/koha/admin/printers.pl?op=add_form"><i class="icon-plus"></i> New printer</a>
152
</div>
153
154
<h2>Printers</h2>
155
	[% IF ( searchfield ) %]
156
		You searched for [% searchfield %]</span>
157
	[% END %]
158
159
[% IF ( loop ) %]<table>
160
		<tr>
161
			<th>Name</th>
162
			<th>Queue</th>
163
			<th>Type</th>
164
			<th>&nbsp;</th>
165
		</tr>
166
		[% FOREACH loo IN loop %]
167
		[% IF ( loop.odd ) %]<tr>[% ELSE %]<tr class="highlight">[% END %]
168
			<td>[% loo.printername %]</td>
169
			<td>[% loo.printqueue %]</td>
170
			<td>[% loo.printtype %]</td>
171
			<td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.printername %]">Edit</a> <a href="[% loo.script_name %]?op=delete_confirm&amp;searchfield=[% loo.printername %]">Delete</a></td>
172
		</tr>
173
		[% END %]
174
	</table>[% ELSE %]<div class="notice">No printers defined.</div>[% END %]
175
176
	[% IF ( offsetgtzero ) %]
177
		<a href="[% script_name %]?offset=[% prevpage %]">&lt;&lt; Previous</a>
178
	[% END %]
179
180
	[% IF ( ltcount ) %]
181
		<a href="[% script_name %]?offset=[% nextpage %]">Next &gt;&gt;</a>	
182
	[% END %]
183
[% END %]
184
185
</div>
186
</div>
187
<div class="yui-b">
188
[% INCLUDE 'admin-menu.inc' %]
189
</div>
190
</div>
209
</div>
191
[% INCLUDE 'intranet-bottom.inc' %]
210
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/printers.tt (+34 lines)
Line 0 Link Here
1
[% INCLUDE 'help-top.inc' %]
2
3
<h1>Printers</h1>
4
5
<h2>Adding and modifying printers</h2>
6
7
<p>Click on the 'Add printer' button to add a single printer; Press the &lt;Enter&gt; key to save the printer.</p>
8
<p>Click on any field to edit the contents; Press the &lt;Enter&gt; key to save edit.</p>
9
<p>Click on one or more printer IDs to select entire printers for deletion; Click the 'Delete printer(s)' button to delete selected printers.</p>
10
11
<p>Printers defined in this area can be used to print automatic reserve notices</p>
12
13
<h2>How printers are defined</h2>
14
<p>Printers can be utilized in two ways, either by sending the data directly to a networked printer via lpr, or by printing to a printer set up on the Koha server via CUPS.</p>
15
16
<h3>Printing via LPR</h3>
17
<p>
18
    To configure a printer for this mode, create a new printer in Koha and give it a name, and under the Queue / Server:Port field enter the printer address and the port the LPR service is running under ( usually port 515 ).
19
</p>
20
21
<h3>Printing via CUPS</h3>
22
<p>
23
    To configure a printer for this mode, simply enter the CUPS name for this printer in the Name field. No other options are needed.
24
</p>
25
26
<h2>Caveats</h2>
27
<p>
28
    Printing plain text is supported by both methods. When printing HTML, the output will be sent to the printer as PostScript. If you are printing via LPR, and you want to print HTML, you will need to ensure that your printer can recieve and print PostScript data.
29
</p>
30
<p>
31
    For printing slips and notices, this behavior can be controlled via the "HTML message" flag of the HOLD_PLACED_PRINT notice. Leaving this checkbox unchecked will result in plain text being printed, whereas checking this checkbox will result in HTML converted to PostScript being printed.
32
33
</p>
34
[% INCLUDE 'help-bottom.inc' %]
(-)a/misc/cronjobs/holds/print_holds.pl (-25 / +26 lines)
Lines 34-39 use Net::Printer; Link Here
34
use C4::Context;
34
use C4::Context;
35
use C4::Members qw(GetMember);
35
use C4::Members qw(GetMember);
36
use C4::Letters qw(GetPreparedLetter);
36
use C4::Letters qw(GetPreparedLetter);
37
use Koha::Database;
37
38
38
my $help    = 0;
39
my $help    = 0;
39
my $test    = 0;
40
my $test    = 0;
Lines 48-61 GetOptions( Link Here
48
pod2usage(1) if $help;
49
pod2usage(1) if $help;
49
pod2usage(1) unless @printers;
50
pod2usage(1) unless @printers;
50
51
52
my $schema = Koha::Database->new()->schema();
53
51
my %printers;
54
my %printers;
52
foreach my $p (@printers) {
55
foreach my $p (@printers) {
53
    my ( $branchcode, $printer, $server, $port ) = split( /,/, $p );
56
    my ( $branchcode, $printer_id ) = split( /:/, $p );
54
    my %options;
57
    $printers{$branchcode} = $schema->resultset('Printer')->find($printer_id);
55
    $options{'printer'} = $printer if ($printer);
56
    $options{'server'}  = $server  if ($server);
57
    $options{'port'}    = $port    if ($port);
58
    $printers{$branchcode} = new Net::Printer(%options);
59
}
58
}
60
59
61
my $dbh   = C4::Context->dbh;
60
my $dbh   = C4::Context->dbh;
Lines 65-81 $sth->execute(); Link Here
65
64
66
my $set_printed_query = "
65
my $set_printed_query = "
67
    UPDATE reserves
66
    UPDATE reserves
68
    SET printed = 1
67
    SET printed = NOW()
69
    WHERE reserve_id = ?
68
    WHERE reserve_id = ?
70
";
69
";
71
my $set_printed_sth = $dbh->prepare($set_printed_query);
70
my $set_printed_sth = $dbh->prepare($set_printed_query);
72
71
73
while ( my $hold = $sth->fetchrow_hashref() ) {
72
while ( my $hold = $sth->fetchrow_hashref() ) {
74
    if ($verbose) {
73
    if ($verbose) {
75
        print "\nFound Notice to Print\n";
74
        say "\nFound Notice to Print";
76
        print "Borrowernumber: " . $hold->{'borrowernumber'} . "\n";
75
        say "Borrowernumber: " . $hold->{'borrowernumber'};
77
        print "Biblionumber: " . $hold->{'biblionumber'} . "\n";
76
        say "Biblionumber: " . $hold->{'biblionumber'};
78
        print "Branch: " . $hold->{'branchcode'} . "\n";
77
        say "Branch: " . $hold->{'branchcode'};
79
    }
78
    }
80
79
81
    my $borrower =
80
    my $borrower =
Lines 96-107 while ( my $hold = $sth->fetchrow_hashref() ) { Link Here
96
95
97
    if ( defined( $printers{ $hold->{branchcode} } ) ) {
96
    if ( defined( $printers{ $hold->{branchcode} } ) ) {
98
        unless ($test) {
97
        unless ($test) {
99
            my $result =
98
            my ( $success, $error ) = $printers{ $hold->{'branchcode'} }->print(
100
              $printers{ $hold->{'branchcode'} }
99
                {
101
              ->printstring( $letter->{'content'} );
100
                    data    => $letter->{content},
102
            my $error = $printers{ $hold->{'branchcode'} }->printerror();
101
                    is_html => $letter->{is_html},
103
102
                }
104
            unless ($error) {
103
            );
104
105
            if ($success) {
105
                $set_printed_sth->execute( $hold->{'reserve_id'} );
106
                $set_printed_sth->execute( $hold->{'reserve_id'} );
106
            }
107
            }
107
            else {
108
            else {
Lines 109-120 while ( my $hold = $sth->fetchrow_hashref() ) { Link Here
109
            }
110
            }
110
        }
111
        }
111
        else {
112
        else {
112
            print "TEST MODE, notice will not be printed\n";
113
            say "TEST MODE, notice will not be printed";
113
            print $letter->{'content'} . "\n";
114
            say $letter->{'content'};
114
        }
115
        }
115
    }
116
    }
116
    else {
117
    else {
117
        print "WARNING: No printer defined for branchcode "
118
        say "WARNING: No printer defined for branchcode "
118
          . $hold->{'branchcode'}
119
          . $hold->{'branchcode'}
119
          if ($verbose);
120
          if ($verbose);
120
    }
121
    }
Lines 129-149 Print Holds Link Here
129
130
130
=head1 SYNOPSIS
131
=head1 SYNOPSIS
131
132
132
print_holds.pl --printer <branchcode>,<printer>,<server>,<port>
133
print_holds.pl --printer <branchcode>=<printer_id>
133
134
134
=head1 OPTIONS
135
=head1 OPTIONS
135
136
136
=over 8
137
=over 8
137
138
138
=item B<-help>
139
=item B<--help>
139
140
140
Print a brief help message and exits.
141
Print a brief help message and exits.
141
142
142
=item B<-printer>
143
=item B<--printer>
143
144
144
Adds a printer, the value is the branchcode, printer name, server name and server port separated by commas.
145
Adds a printer to use in the format BRANCHCODE=PRINTER_ID.
145
146
146
e.g. print_holds.pl --printer MPL,lp,printserver,515 --printer CPL,lp2,printserver,516
147
e.g. print_holds.pl --printer MPL:1 --printer CPL:2
147
148
148
would add printers for branchcodes MPL and CPL. If a printer is not defined for a given branch, notices for
149
would add printers for branchcodes MPL and CPL. If a printer is not defined for a given branch, notices for
149
that branch will not be printed.
150
that branch will not be printed.
(-)a/svc/printer (-1 / +114 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2014 ByWater Solutions
4
# Copyright 2012 Foundations Bible College Inc.
5
#
6
# This file is part of Koha.
7
#
8
# Koha is free software; you can redistribute it and/or modify it under the
9
# terms of the GNU General Public License as published by the Free Software
10
# Foundation; either version 2 of the License, or (at your option) any later
11
# version.
12
#
13
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21
use strict;
22
use warnings;
23
24
use CGI;
25
use JSON;
26
use autouse 'Data::Dumper' => qw(Dumper);
27
28
use C4::Auth;
29
use C4::Context;
30
31
my $cgi          = CGI->new;
32
my $dbh          = C4::Context->dbh;
33
my $sort_columns = [ "id", "source", "text", "timestamp" ];
34
35
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
36
    {
37
        template_name   => "",
38
        query           => $cgi,
39
        type            => "intranet",
40
        authnotrequired => 0,
41
        flagsrequired   => { tools => 'edit_printers' },
42
        debug           => 1,
43
    }
44
);
45
46
my $params = $cgi->Vars;
47
48
print $cgi->header('application/json; charset=utf-8');
49
50
unless ( $params->{action} ) {
51
    my $sth = $dbh->prepare("SELECT * FROM printers");
52
    $sth->execute();
53
54
    my $aaData = $sth->fetchall_arrayref;
55
56
    print to_json(
57
        {
58
            iTotalRecords        => @$aaData,
59
            iTotalDisplayRecords => @$aaData,
60
            sEcho                => $params->{sEcho},
61
            aaData               => $aaData,
62
        },
63
        { utf8 => 1 }
64
    );
65
}
66
elsif ( $params->{action} eq 'add' ) {
67
    my $sth = $dbh->prepare(
68
        'INSERT INTO printers ( name, queue, type ) VALUES (?, ?, ?)');
69
    $sth->execute( $params->{name}, $params->{queue}, $params->{type} );
70
    if ( $sth->err ) {
71
        warn
72
          sprintf( 'Database returned the following error: %s', $sth->errstr );
73
        exit 1;
74
    }
75
    my $new_printer_id = $dbh->{q{mysql_insertid}};    # ALERT: mysqlism here
76
    $sth = $dbh->prepare('SELECT * FROM printers WHERE id = ?;');
77
    $sth->execute($new_printer_id);
78
    print to_json( $sth->fetchall_arrayref, { utf8 => 1 } );
79
    exit 1;
80
}
81
elsif ( $params->{action} eq 'edit' ) {
82
    my $aaData           = [];
83
    my $editable_columns = [qw(name queue type)]
84
      ; # pay attention to element order; these columns match the printers table columns
85
86
    my $sth = $dbh->prepare(
87
"UPDATE printers SET $editable_columns->[$params->{column}-1]  = ? WHERE id = ?;"
88
    );
89
    $sth->execute( $params->{value}, $params->{id} );
90
    if ( $sth->err ) {
91
        warn
92
          sprintf( 'Database returned the following error: %s', $sth->errstr );
93
        exit 1;
94
    }
95
96
    $sth = $dbh->prepare(
97
"SELECT $editable_columns->[$params->{column}-1] FROM printers WHERE id = ?;"
98
    );
99
    $sth->execute( $params->{id} );
100
    $aaData = $sth->fetchrow_array();
101
    print Encode::encode( 'utf8', $aaData );
102
103
    exit 1;
104
}
105
elsif ( $params->{action} eq 'delete' ) {
106
    my $sth = $dbh->prepare("DELETE FROM printers WHERE id = ?;");
107
    $sth->execute( $params->{id} );
108
    if ( $sth->err ) {
109
        warn
110
          sprintf( 'Database returned the following error: %s', $sth->errstr );
111
        exit 1;
112
    }
113
    exit 0;
114
}

Return to bug 8352