From 62e53aca78c76ff1199b171b325eac943ed838ec Mon Sep 17 00:00:00 2001
From: Mark Tompsett <mtompset@hotmail.com>
Date: Wed, 6 Nov 2013 23:11:41 -0500
Subject: [PATCH] Bug 7567 - News by Branch

By selecting a particular branch, news specific to a branch
can be showed once the user logs into the opac (or the staff)
client.

This includes adding a non-NULL default '' branchcode field
to the opac_news table.

When a user is logged in they receive both '' and their branch
news. When no user is logged in, they only receive '' news. ''
means all branches.

TEST PLAN
---------
 1) Do a fresh install, to ensure that branchcode is created as a field
     in the opac_news table.
 2) Do an upgrade to confirm that the branchcode field is added
     to the opac_news table.
 3) prove -v t/db_dependent/NewsChannels.t
     This should test all the changes in C4::NewsChannels functions.
 4) Log into the staff client
    - Does the News display on the main page bust?
 5) Go to Tools->News
    - Are the locations properly display?
 6) Add a News item, for 'All' interfaces for 'All Branches'.
 7) Add a News item, for 'Slip' interfaces at your user branch.
 8) Add a News item, for 'OPAC' interface at your user branch.
 9) Change the Location and Branch filters.
    - Do they show what you select after you click the Filter button?
          (Unpatched the Location does not!)
    - Are the items displayed matching what is selected?
    - Are the drop downs containing the expected values?
          (All, Librarian Interface, Slip,
            and OPAC (<lang> -- for each <lang> installed)
          (All Branches, and every branch listed)
10) Click 'Edit' for one of the news items added.
    - Does what comes up match what was displayed?
          ( Unpatched the Location may be 'All' )
    - Are the drop downs containing the expected values?
          (All, Librarian Interface, Slip,
            and OPAC (<lang> -- for each <lang> installed)
          (All Branches, and every branch listed)
    - Does the submitted values match the changes made?
11) Find a patron to print a slip for. Print Slip.
    - Does both the 'All' and 'Slip' news show up on the print slip?
12) In a new tab, go to OPAC
    - Does the News display on the main page bust?
    - Does it display the news item for a specific branch?
          (It shouldn't when patched, but unpatched it would)
          (Only one of the new things added should be displayed)
13) Log in as a user with the branch you added the news item for.
    - Does that piece of News display now too?
          (Both things added should be displayed)
14) Check the news items added and click the delete button in the staff client.
    - Did it delete them appropriately?
---
 C4/Members.pm                                      |    2 +-
 C4/NewsChannels.pm                                 |  172 +++++++++++++-------
 installer/data/mysql/kohastructure.sql             |    5 +-
 installer/data/mysql/updatedatabase.pl             |   15 ++
 .../prog/en/modules/tools/koha-news.tt             |  134 +++++++++++----
 koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt   |    8 +-
 mainpage.pl                                        |    6 +-
 opac/opac-main.pl                                  |   11 +-
 t/NewsChannels.t                                   |   14 --
 t/db_dependent/NewsChannels.t                      |  120 ++++++++++++++
 tools/koha-news.pl                                 |   41 ++++-
 11 files changed, 407 insertions(+), 121 deletions(-)
 delete mode 100755 t/NewsChannels.t
 create mode 100755 t/db_dependent/NewsChannels.t

diff --git a/C4/Members.pm b/C4/Members.pm
index b04cc64..20d8ed2 100644
--- a/C4/Members.pm
+++ b/C4/Members.pm
@@ -2425,7 +2425,7 @@ sub IssueSlip {
             'news' => [ map {
                 $_->{'timestamp'} = $_->{'newdate'};
                 { opac_news => $_ }
-            } @{ GetNewsToDisplay("slip") } ],
+            } @{ GetNewsToDisplay("slip",$branch) } ],
         );
     }
 
diff --git a/C4/NewsChannels.pm b/C4/NewsChannels.pm
index 0201729..cbe35b9 100644
--- a/C4/NewsChannels.pm
+++ b/C4/NewsChannels.pm
@@ -1,37 +1,41 @@
 package C4::NewsChannels;
 
-# Copyright 2000-2002 Katipo Communications
-#
 # 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 2 of the License, or (at your option) any later
-# version.
+# Copyright (C) 2000  Katipo Communications
+# Copyright (C) 2013  Mark Tompsett
+#
+# 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.
+# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
-use strict;
-use warnings;
 
+use Modern::Perl;
 use C4::Context;
 use C4::Dates qw(format_date);
 
 use vars qw($VERSION @ISA @EXPORT);
 
 BEGIN { 
-    $VERSION = 3.07.00.049;	# set the version for version checking
-	@ISA = qw(Exporter);
-	@EXPORT = qw(
-		&GetNewsToDisplay
-		&add_opac_new &upd_opac_new &del_opac_new &get_opac_new &get_opac_news
-	);
+    $VERSION = 3.07.00.049;        # set the version for version checking
+        @ISA = qw(Exporter);
+        @EXPORT = qw(
+                     &add_opac_new
+                     &upd_opac_new
+                     &del_opac_new
+                     &get_opac_new
+                     &get_opac_news
+                     &GetNewsToDisplay
+                    );
 }
 
 =head1 NAME
@@ -47,30 +51,51 @@ This module provides the functions needed to mange OPAC and intranet news.
 =cut
 
 sub add_opac_new {
-    my ($title, $new, $lang, $expirationdate, $timestamp, $number) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare("INSERT INTO opac_news (title, new, lang, expirationdate, timestamp, number) VALUES (?,?,?,?,?,?)");
-    $sth->execute($title, $new, $lang, $expirationdate, $timestamp, $number);
-    $sth->finish;
-    return 1;
+    my ($href_entry) = @_;
+    my $retval=0;
+
+    if ($href_entry) {
+        my @fields = keys %{$href_entry};
+        my @values = values %{$href_entry};
+        my $field_string = join ",",@fields;
+        $field_string = $field_string // q{};
+        my $values_string = "?," x ($#fields) . "?";
+
+        my $dbh = C4::Context->dbh;
+        my $sth = $dbh->prepare("INSERT INTO opac_news ( $field_string ) VALUES ( $values_string );");
+        $sth->execute(@values);
+        $retval = 1;
+    }
+    return $retval;
 }
 
 sub upd_opac_new {
-    my ($idnew, $title, $new, $lang, $expirationdate, $timestamp,$number) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare("
-        UPDATE opac_news SET 
-            title = ?,
-            new = ?,
-            lang = ?,
-            expirationdate = ?,
-            timestamp = ?,
-            number = ?
-        WHERE idnew = ?
-    ");
-    $sth->execute($title, $new, $lang, $expirationdate, $timestamp,$number,$idnew);
-    $sth->finish;
-    return 1;
+    my ($href_entry) = @_;
+    my $retval = 0;
+
+    if ($href_entry) {
+        # take the keys of hash entry and make a list, but...
+        my @fields = keys %{$href_entry};
+        my @values;
+        $#values = -1;
+        my $field_string = q{};
+        foreach my $field_name (@fields) {
+            # exclude idnew
+            if ( $field_name ne 'idnew' ) {
+                $field_string = $field_string . "$field_name = ?,";
+                push @values,$href_entry->{$field_name};
+            }
+        }
+        # put idnew at the end, so we know which record to update
+        push @values,$href_entry->{'idnew'};
+        chop $field_string; # remove that excess ,
+
+        my $dbh = C4::Context->dbh;
+        my $sth = $dbh->prepare("UPDATE opac_news SET $field_string WHERE idnew = ?;");
+        $sth->execute(@values);
+        $retval = 1;
+    }
+    return $retval;
 }
 
 sub del_opac_new {
@@ -79,7 +104,6 @@ sub del_opac_new {
         my $dbh = C4::Context->dbh;
         my $sth = $dbh->prepare("DELETE FROM opac_news WHERE idnew IN ($ids)");
         $sth->execute();
-        $sth->finish;
         return 1;
     } else {
         return 0;
@@ -89,35 +113,61 @@ sub del_opac_new {
 sub get_opac_new {
     my ($idnew) = @_;
     my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare("SELECT * FROM opac_news WHERE idnew = ?");
+    my $query = q{
+                  SELECT opac_news.*,branches.branchname,timestamp AS newdate
+                  FROM opac_news LEFT JOIN branches ON opac_news.branchcode=branches.branchcode
+                  WHERE opac_news.idnew = ?;
+                };
+    my $sth = $dbh->prepare($query);
     $sth->execute($idnew);
     my $data = $sth->fetchrow_hashref;
     $data->{$data->{'lang'}} = 1 if defined $data->{lang};
     $data->{expirationdate} = format_date($data->{expirationdate});
     $data->{timestamp}      = format_date($data->{timestamp});
-    $sth->finish;
+    if (!defined($data->{branchcode}) || $data->{branchcode} eq '') {
+        $data->{branchname}     = "All Branches";
+    }
     return $data;
 }
 
 sub get_opac_news {
-    my ($limit, $lang) = @_;
+    my ($limit, $lang, $branchcode) = @_;
+    my @values;
     my $dbh = C4::Context->dbh;
-    my $query = "SELECT *, timestamp AS newdate FROM opac_news";
-    if ($lang) {
-        $query.= " WHERE lang = '" .$lang ."' ";
+    my $query = q{
+                  SELECT opac_news.*,branches.branchname,timestamp AS newdate
+                  FROM opac_news LEFT JOIN branches ON opac_news.branchcode=branches.branchcode
+                };
+    if ($lang && $branchcode) {
+        $query.= " WHERE (opac_news.lang='' OR opac_news.lang=?)";
+        $query .= " AND  (opac_news.branchcode IS NULL OR opac_news.branchcode=?)";
+        push @values,$lang;
+        push @values,$branchcode;
+    }
+    elsif ($lang) {
+        $query.= " WHERE (opac_news.lang='' OR opac_news.lang=?)";
+        push @values,$lang;
+    }
+    elsif ($branchcode) {
+        $query .= " WHERE (opac_news.branchcode IS NULL OR opac_news.branchcode=?)";
+        push @values,$branchcode;
+    }
+    else {
+       # nothing
     }
     $query.= " ORDER BY timestamp DESC ";
     #if ($limit) {
     #    $query.= "LIMIT 0, " . $limit;
     #}
     my $sth = $dbh->prepare($query);
-    $sth->execute();
+    $sth->execute(@values);
     my @opac_news;
     my $count = 0;
     while (my $row = $sth->fetchrow_hashref) {
         if ((($limit) && ($count < $limit)) || (!$limit)) {
             $row->{'newdate'} = format_date($row->{'newdate'});
             $row->{'expirationdate'} = format_date($row->{'expirationdate'});
+            $row->{'branchname'}     = "All Branches" if !$row->{'branchcode'};
             push @opac_news, $row;
         }
         $count++;
@@ -127,17 +177,18 @@ sub get_opac_news {
 
 =head2 GetNewsToDisplay
 
-    $news = &GetNewsToDisplay($lang);
+    $news = &GetNewsToDisplay($lang,$branch);
     C<$news> is a ref to an array which containts
-    all news with expirationdate > today or expirationdate is null.
+    all news with expirationdate > today or expirationdate is null
+    that is applicable for a given branch.
 
 =cut
 
 sub GetNewsToDisplay {
-    my $lang = shift;
+    my ($lang,$branch) = @_;
     my $dbh = C4::Context->dbh;
     # SELECT *,DATE_FORMAT(timestamp, '%d/%m/%Y') AS newdate
-    my $query = "
+    my $query = q{
      SELECT *,timestamp AS newdate
      FROM   opac_news
      WHERE   (
@@ -145,15 +196,20 @@ sub GetNewsToDisplay {
         OR    expirationdate IS NULL
         OR    expirationdate = '00-00-0000'
       )
-      AND   `timestamp` <= CURRENT_DATE()
-      AND   lang = ?
+      AND   `timestamp` < CURRENT_DATE()+1
+      AND   (lang = '' OR lang = ?)
+      AND   (branchcode IS NULL OR branchcode = ?)
       ORDER BY number
-    ";				# expirationdate field is NOT in ISO format?
+    }; # expirationdate field is NOT in ISO format?
+       # timestamp has HH:mm:ss, CURRENT_DATE() generates 00:00:00
+       #           by adding 1, that captures today correctly.
     my $sth = $dbh->prepare($query);
-    $sth->execute($lang);
+    $lang = $lang // '';
+    $branch = $branch // '';
+    $sth->execute($lang,$branch);
     my @results;
     while ( my $row = $sth->fetchrow_hashref ){
-		$row->{newdate} = format_date($row->{newdate});
+        $row->{newdate} = format_date($row->{newdate});
         push @results, $row;
     }
     return \@results;
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 07160c8..93a4770 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -1636,13 +1636,16 @@ CREATE TABLE `old_reserves` ( -- this table holds all holds/reserves that have b
 DROP TABLE IF EXISTS `opac_news`;
 CREATE TABLE `opac_news` ( -- data from the news tool
   `idnew` int(10) unsigned NOT NULL auto_increment, -- unique identifier for the news article
+  `branchcode` varchar(10) NOT NULL default '', -- branch code used to create branch specific news
   `title` varchar(250) NOT NULL default '', -- title of the news article
   `new` text NOT NULL, -- the body of your news article
   `lang` varchar(25) NOT NULL default '', -- location for the article (koha is the staff client, slip is the circulation receipt and language codes are for the opac)
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP, -- pulibcation date and time
   `expirationdate` date default NULL, -- date the article is set to expire or no longer be visible
   `number` int(11) default NULL, -- the order in which this article appears in that specific location
-  PRIMARY KEY  (`idnew`)
+  PRIMARY KEY  (`idnew`),
+  CONSTRAINT opac_news_branchcode_ibfk FOREIGN KEY (branchcode) REFERENCES branches (branchcode)
+    ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 --
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index a9bfbbf..ead36b1 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -7778,6 +7778,21 @@ if(CheckVersion($DBversion)) {
     SetVersion($DBversion);
 }
 
+$DBversion = "3.15.00.XXX";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE opac_news ADD branchcode varchar(10) NULL DEFAULT NULL;
+    });
+    $dbh->do(q{
+                ALTER TABLE opac_news ADD CONSTRAINT opac_news_branchcode_ibfk
+                    FOREIGN KEY(branchcode) REFERENCES branches(branchcode)
+                    ON DELETE CASCADE ON UPDATE CASCADE;
+    });
+    print "Upgrade to $DBversion done (Bug 7567: Add branchcode to opac_news)\n";
+    SetVersion($DBversion);
+}
+
+
 =head1 FUNCTIONS
 
 =head2 TableExists($table)
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt
index b92f63a..93e4d45 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt
@@ -56,8 +56,8 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
 
 [% IF ( add_form ) %]<div id="doc" class="yui-t7">[% ELSE %]<div id="doc3" class="yui-t2">[% END %]
    <div id="bd">
-	<div id="yui-main">
-	<div class="yui-b">
+        <div id="yui-main">
+        <div class="yui-b">
 
 [% UNLESS ( add_form ) %]
 <div id="toolbar" class="btn-toolbar">
@@ -69,31 +69,70 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
         <form name="add_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl" >
             <input type="hidden" name="op" value="[% op %]" />
             <input type="hidden" name="id" value="[% id %]" />
-			<fieldset class="rows">
+                        <fieldset class="rows">
             <legend>OPAC and Koha news</legend>
            <ol> <li>
             <label for="lang">Display location</label>
             <select id="lang" name="lang">
-                <option value="koha">Librarian interface</option>
-                [% IF ( slip ) %]<option value="slip" selected="selected">Slip</option>[% ELSE %]<option value="slip">Slip</option>[% END %]
-                [% FOREACH lang_lis IN lang_list %]
-                    [% IF ( lang_lis.selected ) %]<option value="[% lang_lis.language %]" selected="selected">OPAC ([% lang_lis.language %])</option>[% ELSE %]<option value="[% lang_lis.language %]">OPAC ([% lang_lis.language %])</option>[% END %]
-                [% END %]
+            [% IF ( new_detail.lang == ""     ) %]
+                <option value="" selected>All</option>
+            [% ELSE %]
+                <option value=""         >All</option>
+            [% END %]
+            [% IF ( new_detail.lang == "koha"     ) %]
+                <option value="koha" selected>Librarian interface</option>
+            [% ELSE %]
+                <option value="koha"         >Librarian interface</option>
+            [% END %]
+            [% IF ( new_detail.lang == "slip"     ) %]
+                <option value="slip" selected>Slip</option>
+            [% ELSE %]
+                <option value="slip"         >Slip</option>
+            [% END %]
+            [% FOREACH lang_lis IN lang_list %]
+            [% IF ( lang_lis.language == new_detail.lang ) %]
+                <option value="[% lang_lis.language %]" selected>OPAC ([% lang_lis.language %])</option>
+            [% ELSE %]
+                <option value="[% lang_lis.language %]"         >OPAC ([% lang_lis.language %])</option>
+            [% END %]
+            [% END %]
             </select>
             </li>
             <li>
+                <label for="branch">Branch: </label>
+                <select id="branch" name="branch">
+                [% IF ( new_detail.branchcode == "" ) %]
+                    <option value="" selected>All Branches</option>
+                [% ELSE %]
+                    <option value=""         >All Branches</option>
+                [% END %]
+                [% FOREACH branch_item IN branch_list %]
+                [% IF ( branch_item.value.branchcode ==
+                        new_detail.branchcode ) %]
+                    <option value="[% branch_item.value.branchcode %]"
+                            selected>[% branch_item.value.branchname %]
+                    </option>
+                [% ELSE %]
+                    <option value="[% branch_item.value.branchcode %]"
+                                    >[% branch_item.value.branchname %]
+                    </option>
+                [% END %]
+                [% END %]
+                </select>
+            </li>
+            <li>
                 <label for="title">Title: </label>
                 <input id="title" size="30" type="text" name="title" value="[% new_detail.title %]" />
             </li>
             <li>
                 <label for="from">Publication date: </label>
                 <input id="from" type="text" name="timestamp" size="15" value="[% new_detail.timestamp %]" class="datepickerfrom" />
-				<div class="hint">[% INCLUDE 'date-format.inc' %]</div>
+                                <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
             </li>
             <li>
                 <label for="to">Expiration date: </label>
                 <input id="to" type="text" name="expirationdate" size="15" value="[% new_detail.expirationdate %]" class="datepickerto" />
-				<div class="hint">[% INCLUDE 'date-format.inc' %]</div>
+                                <div class="hint">[% INCLUDE 'date-format.inc' %]</div>
             </li>
             <li>
                 <label for="number">Appear in position: </label>
@@ -106,7 +145,7 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
             <li><label for="new">News: </label>
             <textarea name="new" id="new"  cols="75" rows="10">[% new_detail.new %]</textarea></li>
             </ol>
-			</fieldset>
+                        </fieldset>
   
                 <fieldset class="action"><input class="button" type="submit" value="Submit" /> <a class="cancel" href="/cgi-bin/koha/tools/koha-news.pl">Cancel</a></fieldset>
         </form>
@@ -115,17 +154,46 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
         <form name="add_form" method="post" action="/cgi-bin/koha/tools/koha-news.pl" >
             <label for="lang">Display location:</label>
             <select name="lang" id="lang">
-            <option value="">All</option>
-            <option value="koha">Librarian interface</option>
-	    <option value="slip">Slip</option>
-                [% FOREACH lang_lis IN lang_list %]
-                    [% IF ( lang_lis.selected ) %]
-                        <option value="[% lang_lis.language %]" selected="selected">
-                    [% ELSE %]
-                        <option value="[% lang_lis.language %]">
-                    [% END %]
-                        OPAC ([% lang_lis.language %])
+            [% IF ( lang == ""     ) %]
+                <option value="" selected>All</option>
+            [% ELSE %]
+                <option value=""         >All</option>
+            [% END %]
+            [% IF ( lang == "koha"     ) %]
+                <option value="koha" selected>Librarian interface</option>
+            [% ELSE %]
+                <option value="koha"         >Librarian interface</option>
+            [% END %]
+            [% IF ( lang == "slip"     ) %]
+                <option value="slip" selected>Slip</option>
+            [% ELSE %]
+                <option value="slip"         >Slip</option>
+            [% END %]
+            [% FOREACH lang_lis IN lang_list %]
+            [% IF ( lang_lis.language == lang ) %]
+                <option value="[% lang_lis.language %]" selected>OPAC ([% lang_lis.language %])</option>
+            [% ELSE %]
+                <option value="[% lang_lis.language %]"         >OPAC ([% lang_lis.language %])</option>
+            [% END %]
+            [% END %]
+            </select>
+            <label for="branch">Branch: </label>
+            <select id="branch" name="branch">
+                [% IF ( branchcode == "" ) %]
+                    <option value="" selected>All Branches</option>
+                [% ELSE %]
+                    <option value=""         >All Branches</option>
+                [% END %]
+                [% FOREACH branch_item IN branch_list %]
+                [% IF ( branch_item.value.branchcode == branchcode ) %]
+                    <option value="[% branch_item.value.branchcode %]"
+                            selected>[% branch_item.value.branchname %]
                     </option>
+                [% ELSE %]
+                    <option value="[% branch_item.value.branchcode %]"
+                                    >[% branch_item.value.branchname %]
+                    </option>
+                [% END %]
                 [% END %]
             </select>
             <input type="submit" class="button" value="Filter" />
@@ -137,6 +205,7 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
                    <thead> <tr>
                         <th>&nbsp;</th>
                         <th>Location</th>
+                        <th>Branch</th>
                         <th>Number</th>
                         <th>Creation date</th>
                         <th>Expiration date</th>
@@ -153,17 +222,18 @@ Edit News Item[% ELSE %]Add News Item[% END %][% ELSE %]News[% END %]</div>
                             <td>
                                 <input type="checkbox" name="ids" value="[% opac_new.idnew %]" />
                             </td>
-                            <td>[% IF ( opac_new.lang == 'koha' ) %]
-			            Librarian interface
-                                 [% ELSE %]
-                                    [% IF ( opac_new.lang == 'slip' ) %]
-				        Slip
-                                    [% ELSE %]
-                                        OPAC
-				    [% END %]
-				 [% END %]
-                             </td>
-
+                            <td>[% SWITCH opac_new.lang %]
+                                [%   CASE 'koha' %]
+                                    Librarian interface
+                                [%   CASE 'slip' %]
+                                    Slip
+                                [%   CASE '' %]
+                                    All
+                                [%   CASE %]
+                                    OPAC ([% opac_new.lang %])
+                                [% END %]
+                            </td>
+                            <td>[% opac_new.branchname %]</td>
                             <td>[% opac_new.number %]</td>
                             <td>[% opac_new.newdate %]</td>
                             <td>[% opac_new.expirationdate %] [% IF ( opac_new.expired ) %](<span class="expired">expired</span>)[% END %]</td>
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
index eb1e600..c397451 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
@@ -19,10 +19,10 @@
          [% END %]
      [% ELSE %]
         <div id="notloggedin" class="yui-ge">
-    [% END %]
+     [% END %]
         <div class="yui-u first">
+        <div id="news" class="container">
 	[% IF ( koha_news_count ) %]
-<div id="news" class="container">
     <table>
     [% FOREACH koha_new IN koha_news %]
     <tr><th>[% koha_new.title %]</th></tr>
@@ -30,8 +30,8 @@
                 <p class="newsfooter"><i>(published on [% koha_new.newdate %])</i></p></td></tr>
     [% END %]
     </table>
-</div>
-[% END %]
+        [% END %]
+        </div>
 
       [% IF ( display_daily_quote && daily_quote ) %]
     <div id="daily-quote" class="container"><h1>Quote of the Day</h1><div><span id="daily-quote-text">[% daily_quote.text %]</span><span id="daily-quote-sep"> ~ </span><span id="daily-quote-source">[% daily_quote.source %]</span></div></div>
diff --git a/mainpage.pl b/mainpage.pl
index 4159618..51fbc97 100755
--- a/mainpage.pl
+++ b/mainpage.pl
@@ -42,7 +42,11 @@ my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
     }
 );
 
-my $all_koha_news   = &GetNewsToDisplay("koha");
+my $homebranch;
+if (C4::Context->userenv) {
+    $homebranch = C4::Context->userenv->{'branch'};
+}
+my $all_koha_news   = &GetNewsToDisplay("koha",$homebranch);
 my $koha_news_count = scalar @$all_koha_news;
 
 $template->param(
diff --git a/opac/opac-main.pl b/opac/opac-main.pl
index 7c6ee36..6ee0246 100755
--- a/opac/opac-main.pl
+++ b/opac/opac-main.pl
@@ -16,12 +16,11 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 
-use strict;
-use warnings;
+use Modern::Perl;
 use CGI;
 use C4::Auth;    # get_template_and_user
 use C4::Output;
-use C4::NewsChannels;    # get_opac_news
+use C4::NewsChannels;    # GetNewsToDisplay
 use C4::Languages qw(getTranslatedLanguages accept_language);
 use C4::Koha qw( GetDailyQuote );
 
@@ -48,7 +47,11 @@ $template->param(
 # use cookie setting for language, bug default to syspref if it's not set
 my ($theme, $news_lang, $availablethemes) = C4::Templates::themelanguage(C4::Context->config('opachtdocs'),'opac-main.tt','opac',$input);
 
-my $all_koha_news   = &GetNewsToDisplay($news_lang);
+my $homebranch;
+if (C4::Context->userenv) {
+    $homebranch = C4::Context->userenv->{'branch'} // '';
+}
+my $all_koha_news   = &GetNewsToDisplay($news_lang,$homebranch);
 my $koha_news_count = scalar @$all_koha_news;
 
 my $quote = GetDailyQuote();   # other options are to pass in an exact quote id or select a random quote each pass... see perldoc C4::Koha
diff --git a/t/NewsChannels.t b/t/NewsChannels.t
deleted file mode 100755
index bbcaab1..0000000
--- a/t/NewsChannels.t
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/perl
-#
-# This Koha test module is a stub!  
-# Add more tests here!!!
-
-use strict;
-use warnings;
-
-use Test::More tests => 1;
-
-BEGIN {
-        use_ok('C4::NewsChannels');
-}
-
diff --git a/t/db_dependent/NewsChannels.t b/t/db_dependent/NewsChannels.t
new file mode 100755
index 0000000..8c417c5
--- /dev/null
+++ b/t/db_dependent/NewsChannels.t
@@ -0,0 +1,120 @@
+#!/usr/bin/perl
+#
+# This Koha test module is a stub!
+# Add more tests here!!!
+
+use Modern::Perl;
+use C4::Dates qw(format_date);
+use C4::Branch qw(GetBranchName);
+use Test::More tests => 8;
+
+BEGIN {
+        use_ok('C4::NewsChannels');
+}
+
+
+my $dbh = C4::Context->dbh;
+
+# Start transaction
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+
+# Add LIB1, if it doesn't exist.
+my $addbra = 'LIB1';
+$dbh->do(q{
+    INSERT INTO branches (branchcode,branchname) VALUES (?,?)
+          }, undef,      ($addbra,   "$addbra branch")
+        ) unless GetBranchName($addbra);
+
+# Test add_opac_new
+my $timestamp = '2000-01-01';
+my $hashref_entry1 = {
+  'title'          => 'News Title',
+  'new'            => '<p>We have some exciting news!</p>',
+  'lang'           => '',
+  'timestamp'      => $timestamp,
+  'expirationdate' => '2999-12-30',
+  'number'         => 1,
+  'branchcode'     => 'LIB1',
+                  };
+my $rv = add_opac_new( $hashref_entry1 );
+ok($rv==1,"Successfully added the first dummy news item!");
+
+my $hashref_entry2 = {
+  "title"          => 'News Title2',
+  "new"            => '<p>We have some exciting news!</p>',
+  "lang"           => '',
+  "timestamp"      => $timestamp,
+  "expirationdate" => '2999-12-31',
+  "number"         => 1,
+  "branchcode"     => 'LIB1',
+                     };
+$rv = add_opac_new( $hashref_entry2 );
+ok($rv==1,"Successfully added the second dummy news item!");
+
+# We need to determine the idnew in a non-MySQLism way.
+# This should be good enough.
+my $sth = $dbh->prepare(q{
+  SELECT idnew from opac_news
+  WHERE timestamp='2000-01-01' AND
+        expirationdate='2999-12-30' AND
+        branchcode='LIB1';
+                        });
+$sth->execute();
+my $idnew1 = $sth->fetchrow;
+$sth = $dbh->prepare(q{
+  SELECT idnew from opac_news
+  WHERE timestamp='2000-01-01' AND
+        expirationdate='2999-12-31' AND
+        branchcode='LIB1';
+                        });
+$sth->execute();
+my $idnew2 = $sth->fetchrow;
+
+# Test upd_opac_new
+$hashref_entry2->{new} = '<p>Update! There is no news!</p>';
+$hashref_entry2->{idnew} = $idnew2;
+$rv = upd_opac_new($hashref_entry2);
+ok($rv==1,"Successfully updated second dummy news item!");
+
+# Test get_opac_new (single news item)
+$hashref_entry1->{timestamp} =
+  format_date( $hashref_entry1->{timestamp} );
+$hashref_entry1->{expirationdate} =
+  format_date( $hashref_entry1->{expirationdate} );
+$hashref_entry2->{timestamp} =
+  format_date( $hashref_entry2->{timestamp} );
+$hashref_entry2->{expirationdate} =
+  format_date( $hashref_entry2->{expirationdate} );
+my $hashref_check = get_opac_new($idnew1);
+my $failure = 0;
+foreach my $key (keys %{$hashref_entry1}) {
+    if ($hashref_entry1->{$key} ne $hashref_check->{$key}) {
+        $failure = 1;
+        print STDERR "\nKey mismatch: " . $hashref_entry1->{$key} . " vs ";
+        print STDERR $hashref_check->{$key} . "\n";
+    }
+}
+ok($failure==0,"Successfully tested get_opac_new id1!");
+
+# Test get_opac_new (single news item)
+$hashref_check = get_opac_new($idnew2);
+$failure = 0;
+foreach my $key (keys %{$hashref_entry2}) {
+    if ($hashref_entry2->{$key} ne $hashref_check->{$key}) {
+        $failure = 1;
+        print STDERR "\nKey mismatch: " . $hashref_entry1->{$key} . " vs ";
+        print STDERR $hashref_check->{$key} . "\n";
+    }
+}
+ok($failure==0,"Successfully tested get_opac_new id2!");
+
+# Test get_opac_news (multiple news items)
+my ($opac_news_count, $arrayref_opac_news) = get_opac_news(0,'','LIB1');
+ok($opac_news_count>=2,"Successfully tested get_opac_news for LIB1!");
+
+# Test GetNewsToDisplay
+($opac_news_count, $arrayref_opac_news) = GetNewsToDisplay('','LIB1');
+ok($opac_news_count>=2,"Successfully tested GetNewsToDisplay for LIB1!");
+
+$dbh->rollback;
diff --git a/tools/koha-news.pl b/tools/koha-news.pl
index 4dd07a9..7ce26db 100755
--- a/tools/koha-news.pl
+++ b/tools/koha-news.pl
@@ -32,6 +32,7 @@ use C4::Output;
 use C4::NewsChannels;
 use C4::Languages qw(getTranslatedLanguages);
 use Date::Calc qw/Date_to_Days Today/;
+use C4::Branch qw/GetBranches/;
 
 my $cgi = new CGI;
 
@@ -42,6 +43,11 @@ my $expirationdate = format_date_in_iso($cgi->param('expirationdate'));
 my $timestamp      = format_date_in_iso($cgi->param('timestamp'));
 my $number         = $cgi->param('number');
 my $lang           = $cgi->param('lang');
+my $branchcode     = $cgi->param('branch');
+# Foreign Key constraints work with NULL, not ''
+# NULL = All branches.
+$branchcode = undef if (defined($branchcode) && $branchcode eq '');
+my $hashref_entry;
 
 my $new_detail = get_opac_new($id);
 
@@ -67,9 +73,13 @@ foreach my $language ( @$tlangs ) {
       };
 }
 
-$template->param( lang_list => \@lang_list );
+my $branches = GetBranches;
 
-my $op = $cgi->param('op');
+$template->param( lang_list   => \@lang_list,
+                  branch_list => $branches,
+                  branchcode => $branchcode );
+
+my $op = $cgi->param('op') // '';
 
 if ( $op eq 'add_form' ) {
     $template->param( add_form => 1 );
@@ -86,11 +96,30 @@ if ( $op eq 'add_form' ) {
     }
 }
 elsif ( $op eq 'add' ) {
-    add_opac_new( $title, $new, $lang, $expirationdate, $timestamp, $number );
+    $hashref_entry = {
+                    "title"          => $title,
+                    "new"            => $new,
+                    "lang"           => $lang,
+                    "timestamp"      => $timestamp,
+                    "expirationdate" => $expirationdate,
+                    "number"         => $number,
+                    "branchcode"     => $branchcode,
+                  };
+    add_opac_new( $hashref_entry );
     print $cgi->redirect("/cgi-bin/koha/tools/koha-news.pl");
 }
 elsif ( $op eq 'edit' ) {
-    upd_opac_new( $id, $title, $new, $lang, $expirationdate, $timestamp ,$number );
+    $hashref_entry = {
+                    "idnew"          => $id,
+                    "title"          => $title,
+                    "new"            => $new,
+                    "lang"           => $lang,
+                    "timestamp"      => $timestamp,
+                    "expirationdate" => $expirationdate,
+                    "number"         => $number,
+                    "branchcode"     => $branchcode,
+                  };
+    upd_opac_new( $hashref_entry );
     print $cgi->redirect("/cgi-bin/koha/tools/koha-news.pl");
 }
 elsif ( $op eq 'del' ) {
@@ -101,7 +130,7 @@ elsif ( $op eq 'del' ) {
 
 else {
 
-    my ( $opac_news_count, $opac_news ) = &get_opac_news( undef, $lang );
+    my ( $opac_news_count, $opac_news ) = &get_opac_news( 0, $lang, $branchcode );
     
     foreach my $new ( @$opac_news ) {
         next unless $new->{'expirationdate'};
@@ -113,9 +142,9 @@ else {
     }
     
     $template->param(
-        $lang           => 1,
         opac_news       => $opac_news,
         opac_news_count => $opac_news_count,
 		);
+    $template->param( lang => $lang );
 }
 output_html_with_http_headers $cgi, $cookie, $template->output;
-- 
1.7.9.5