Merge remote-tracking branch 'origin/new/bug_6199'
authorPaul Poulain <paul.poulain@biblibre.com>
Wed, 28 Mar 2012 15:54:55 +0000 (17:54 +0200)
committerPaul Poulain <paul.poulain@biblibre.com>
Wed, 28 Mar 2012 15:54:55 +0000 (17:54 +0200)
449 files changed:
C4/Accounts.pm
C4/Acquisition.pm
C4/Auth.pm
C4/Auth_with_cas.pm
C4/Biblio.pm
C4/Branch.pm
C4/Circulation.pm
C4/Context.pm
C4/ILSDI/Services.pm
C4/Installer/PerlDependencies.pm
C4/Items.pm
C4/Members.pm
C4/Members/AttributeTypes.pm
C4/Members/Attributes.pm
C4/Overdues.pm
C4/SIP/ILS/Patron.pm
C4/SIP/ILS/Transaction/Checkout.pm
C4/SIP/ILS/Transaction/Renew.pm
C4/SIP/ILS/Transaction/RenewAll.pm
C4/SIP/Sip.pm
C4/SocialData.pm [new file with mode: 0644]
C4/VirtualShelves.pm
C4/VirtualShelves/Page.pm
Koha/Calendar.pm [new file with mode: 0644]
Koha/DateUtils.pm [new file with mode: 0644]
Koha/Template/Plugin/KohaDates.pm
acqui/addorderiso2709.pl
acqui/basketgroup.pl
acqui/booksellers.pl
acqui/check_uniqueness.pl [new file with mode: 0755]
acqui/neworderempty.pl
acqui/orderreceive.pl
acqui/supplier.pl
acqui/z3950_search.pl
admin/authorised_values.pl
admin/branches.pl
admin/currency.pl
admin/item_circulation_alerts.pl
admin/marc_subfields_structure.pl
admin/marctagstructure.pl
admin/matching-rules.pl
admin/patron-attr-types.pl
admin/smart-rules.pl
admin/z3950servers.pl
catalogue/detail.pl
catalogue/issuehistory.pl
catalogue/moredetail.pl
catalogue/search.pl
cataloguing/addbiblio.pl
cataloguing/additem.pl
cataloguing/value_builder/dateaccessioned.pl
cataloguing/z3950_search.pl
circ/branchoverdues.pl
circ/circulation.pl
circ/overdue.pl
circ/returns.pl
installer/data/mysql/atomicupdate/hourlyloans.sql [new file with mode: 0644]
installer/data/mysql/atomicupdate/issuedate_times.pl [new file with mode: 0644]
installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql
installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.txt
installer/data/mysql/kohastructure.sql
installer/data/mysql/nb-NO/2-Valgfritt/z3950servers.sql
installer/data/mysql/sysprefs.sql
installer/data/mysql/updatedatabase.pl
koha-tmpl/intranet-tmpl/prog/en/columns.def
koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css
koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/en/includes/patron-toolbar.inc
koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc
koha-tmpl/intranet-tmpl/prog/en/js/additem.js
koha-tmpl/intranet-tmpl/prog/en/modules/about.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/addorderiso2709.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroup.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketheader.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderbiblio.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty_duplicate.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/newordersuggestion.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/ordered.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/spent.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/supplier.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/uncertainprice.tt
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudget_owner_search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqcontract.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqplan.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_subfields_structure.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_tag_structure.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/authorised_values.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/authtypes.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/biblio_framework.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/categorie.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/checkmarc.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/cities.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/classsources.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/currency.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/fieldmapping.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/item_circulation_alerts.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/koha2marclinks.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/marc_subfields_structure.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/marctagstructure.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/matching-rules.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/oai_set_mappings.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/oai_sets.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/patron-attr-types.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/serials.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/printers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/roadtype.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/stopwords.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/systempreferences.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/z3950servers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/auth_finder.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/detail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/searchresultlist-auth.tt
koha-tmpl/intranet-tmpl/prog/en/modules/authorities/searchresultlist.tt
koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tt
koha-tmpl/intranet-tmpl/prog/en/modules/basket/downloadcart.tt
koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasketform.tt
koha-tmpl/intranet-tmpl/prog/en/modules/batch/print-notices.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detailprint.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/issuehistory.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/labeledMARCdetail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/showmarc.tt
koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/subject.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbooks.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/linkitem.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/moveitem.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/labs_theses.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/macles.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_field_006.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_field_007.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_field_008.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_field_008_authorities.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_leader.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_leader_authorities.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_leader_book.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/marc21_leader_computerfile.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/normarc_field_007.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/normarc_field_008.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/normarc_leader.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_100.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_105.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_106.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_110.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_115a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_115b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_116.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_117.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_120.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_121a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_121b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_122.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_123a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_123d.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_123e.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_123f.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_123g.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124c.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124d.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124e.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124f.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_124g.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_125a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_125b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_126a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_126b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_127.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_128a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_128b.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_128c.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_130.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_135a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_140.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_141.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_210c.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_210c_bis.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_225a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_4XX.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_686a.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_field_700-4.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/unimarc_leader.tt
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/billing.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/bookcount.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchoverdues.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/branchtransfers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/overdue.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingreserves.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/printslip.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/reserveratios.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/selectbranchprinter.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/transfer-slip.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/view_holdsqueue.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/waitingreserves.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/400.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/401.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/402.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/403.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/404.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/405.tt
koha-tmpl/intranet-tmpl/prog/en/modules/errors/500.tt
koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/marc_subfields_structure.tt
koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-bib-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-profile.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-template.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-manage.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-print.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/result.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/spinelabel-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/labels/spinelabel-print.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/deletemem.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/guarantor_search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/mancredit.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/maninvoice.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/member-flags.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-brief.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-print.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-receipt.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/notices.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/printfeercpt.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/printinvoice.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/update-child.tt
koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt
koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/card-print.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-batch.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-layout.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-profile.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/edit-template.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/image-manage.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/manage.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/members-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/print.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/acquisitions_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/bor_issues_top.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/borrowers_out.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/borrowers_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/cat_issues_top.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_out.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/catalogue_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/dictionary.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_avg_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_by_borrower_category.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemtypes.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/reservereport.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/reserves_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/serials_stats.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reports/stats_screen.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt
koha-tmpl/intranet-tmpl/prog/en/modules/reviews/reviewswaiting.tt
koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/editCollections.tt
koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/rotatingCollections.tt
koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/transferCollection.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/acqui-search-result.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/acqui-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/checkexpiration.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/claims.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/member-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/result.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/routing-preview-slip.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/routing-preview.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/routing.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues-full.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-collection.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-edit.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-recieve.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-bib-search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-renew.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/viewalerts.tt
koha-tmpl/intranet-tmpl/prog/en/modules/services/itemrecorddisplay.tt [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/en/modules/sms/sms-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/suggestion/suggestion.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tags/list.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tags/review.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-del.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod-edit.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/batchMod.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/cleanborrowers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/csv-profiles.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/holidays.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/import_borrowers.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/koha-news.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/picture-upload.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/scheduler.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt
koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/addbybiblionumber.tt
koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/downloadshelf.tt
koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/sendshelfform.tt
koha-tmpl/intranet-tmpl/prog/en/modules/virtualshelves/shelves.tt
koha-tmpl/intranet-tmpl/prog/en/modules/z3950/searchresult.tt
koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl
koha-tmpl/opac-tmpl/prog/en/css/opac.css
koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc
koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc
koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.tools.min.js [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/en/modules/opac-account.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-addbybiblionumber.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-readingrecord.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-shelves.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews-rss.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-showreviews.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-tags.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt
koha-tmpl/opac-tmpl/prog/en/modules/opac-userupdate.tt
koha-tmpl/opac-tmpl/prog/en/modules/sco/sco-main.tt
koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACDetail.xsl
koha-tmpl/opac-tmpl/prog/en/xslt/NORMARCslim2OPACDetail.xsl
koha-tmpl/opac-tmpl/prog/images/Star0.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/Star1.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/Star2.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/Star3.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/Star4.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/Star5.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/bonus.png [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/socnet/delicious16.gif [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/socnet/facebook16.png [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/socnet/linkedin16.png [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/socnet/mailto16.png [new file with mode: 0644]
koha-tmpl/opac-tmpl/prog/images/socnet/twitter16.png [new file with mode: 0644]
kohaversion.pl
labels/label-edit-layout.pl
members/deletemem.pl
members/memberentry.pl
members/moremember.pl
members/pay.pl
members/readingrec.pl
misc/cronjobs/advance_notices.pl
misc/cronjobs/fines.pl
misc/cronjobs/overdue_notices.pl
misc/cronjobs/social_data/get_report_social_data.pl [new file with mode: 0644]
misc/cronjobs/social_data/update_social_data.pl [new file with mode: 0644]
misc/translator/LangInstaller.pm
misc/translator/tmpl_process3.pl
misc/translator/translate
opac/opac-account.pl
opac/opac-addbybiblionumber.pl
opac/opac-detail.pl
opac/opac-ics.pl
opac/opac-readingrecord.pl
opac/opac-reserve.pl
opac/opac-search.pl
opac/opac-shelves.pl
opac/opac-showreviews.pl
opac/opac-tags.pl
opac/opac-user.pl
opac/opac-userupdate.pl
opac/sco/sco-main.pl
reports/acquisitions_stats.pl
reports/bor_issues_top.pl
reports/borrowers_out.pl
reports/borrowers_stats.pl
reports/cat_issues_top.pl
reports/catalogue_out.pl
reports/catalogue_stats.pl
reports/issues_avg_stats.pl
reports/issues_stats.pl
reports/reserves_stats.pl
reports/serials_stats.pl
reserve/renewscript.pl
reserve/request.pl
serials/serials-home.pl
serials/subscription-add.pl
services/itemrecorddisplay.pl [new file with mode: 0755]
suggestion/suggestion.pl
t/00-testcritic.t
t/DateUtils.t [new file with mode: 0755]
t/Heading_MARC21.t
t/Kalendar.t [new file with mode: 0755]
t/db_dependent/VirtualShelves.t
t/db_dependent/rollingloans.t [new file with mode: 0644]
tools/cleanborrowers.pl
tools/letter.pl
tools/manage-marc-import.pl
tools/upload-file.pl
virtualshelves/addbybiblionumber.pl

index c3d121d..b7aef01 100644 (file)
@@ -33,12 +33,20 @@ BEGIN {
        require Exporter;
        @ISA    = qw(Exporter);
        @EXPORT = qw(
-               &recordpayment &makepayment &manualinvoice
-               &getnextacctno &reconcileaccount &getcharges &ModNote &getcredits
-               &getrefunds &chargelostitem
+               &recordpayment
+               &makepayment
+               &manualinvoice
+               &getnextacctno
+               &reconcileaccount
+               &getcharges
+               &ModNote
+               &getcredits
+               &getrefunds
+               &chargelostitem
                &ReversePayment
-        makepartialpayment
-        recordpayment_selectaccts
+                &makepartialpayment
+                &recordpayment_selectaccts
+                &WriteOffFee
        );
 }
 
@@ -756,7 +764,51 @@ sub makepartialpayment {
     return;
 }
 
+=head2 WriteOff
 
+  WriteOff( $borrowernumber, $accountnum, $itemnum, $accounttype, $amount, $branch );
+
+Write off a fine for a patron.
+C<$borrowernumber> is the patron's borrower number.
+C<$accountnum> is the accountnumber of the fee to write off.
+C<$itemnum> is the itemnumber of of item whose fine is being written off.
+C<$accounttype> is the account type of the fine being written off.
+C<$amount> is a floating-point number, giving the amount that is being written off.
+C<$branch> is the branchcode of the library where the writeoff occurred.
+
+=cut
+
+sub WriteOffFee {
+    my ( $borrowernumber, $accountnum, $itemnum, $accounttype, $amount, $branch ) = @_;
+    $branch ||= C4::Context->userenv->{branch};
+    my $manager_id = 0;
+    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
+
+    # if no item is attached to fine, make sure to store it as a NULL
+    $itemnum ||= undef;
+
+    my ( $sth, $query );
+    my $dbh = C4::Context->dbh();
+
+    $query = "
+        UPDATE accountlines SET amountoutstanding = 0
+        WHERE accountno = ? AND borrowernumber = ?
+    ";
+    $sth = $dbh->prepare( $query );
+    $sth->execute( $accountnum, $borrowernumber );
+
+    $query ="
+        INSERT INTO accountlines
+        ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id )
+        VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ? )
+    ";
+    $sth = $dbh->prepare( $query );
+    my $acct = getnextacctno($borrowernumber);
+    $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id );
+
+    UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
+
+}
 
 END { }    # module clean-up code here (global destructor)
 
index 15a68ea..4fd5cc2 100644 (file)
@@ -44,6 +44,7 @@ BEGIN {
         &GetBasket &NewBasket &CloseBasket &DelBasket &ModBasket
        &GetBasketAsCSV
         &GetBasketsByBookseller &GetBasketsByBasketgroup
+        &GetBasketsInfosByBookseller
 
         &ModBasketHeader
 
@@ -464,6 +465,39 @@ sub GetBasketsByBookseller {
     return $results
 }
 
+=head3 GetBasketsInfosByBookseller
+
+    my $baskets = GetBasketsInfosByBookseller($supplierid);
+
+Returns in a arrayref of hashref all about booksellers baskets, plus:
+    total_biblios: Number of distinct biblios in basket
+    total_items: Number of items in basket
+    expected_items: Number of non-received items in basket
+
+=cut
+
+sub GetBasketsInfosByBookseller {
+    my ($supplierid) = @_;
+
+    return unless $supplierid;
+
+    my $dbh = C4::Context->dbh;
+    my $query = qq{
+        SELECT aqbasket.*,
+          SUM(aqorders.quantity) AS total_items,
+          COUNT(DISTINCT aqorders.biblionumber) AS total_biblios,
+          SUM(IF(aqorders.datereceived IS NULL, aqorders.quantity, 0)) AS expected_items
+        FROM aqbasket
+          LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno
+        WHERE booksellerid = ?
+        GROUP BY aqbasket.basketno
+    };
+    my $sth = $dbh->prepare($query);
+    $sth->execute($supplierid);
+    return $sth->fetchall_arrayref({});
+}
+
+
 #------------------------------------------------------------#
 
 =head3 GetBasketsByBasketgroup
index f74fc84..0b737e7 100644 (file)
@@ -164,19 +164,13 @@ sub get_template_and_user {
         $template->param( loggedinusername => $user );
         $template->param( sessionID        => $sessionID );
 
-        my ($total, $pubshelves, $barshelves) = C4::Context->get_shelves_userenv();
-        if (defined($pubshelves)) {
-            $template->param( pubshelves     => scalar @{$pubshelves},
-                              pubshelvesloop => $pubshelves,
-            );
-            $template->param( pubtotal   => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar @{$pubshelves});
-        }
-        if (defined($barshelves)) {
-            $template->param( barshelves      => scalar @{$barshelves},
-                              barshelvesloop  => $barshelves,
-            );
-            $template->param( bartotal  => $total->{'bartotal'}, ) if ($total->{'bartotal'} > scalar @{$barshelves});
-        }
+        my ($total, $pubshelves, $barshelves) = C4::VirtualShelves::GetSomeShelfNames($borrowernumber, 'MASTHEAD');
+        $template->param(
+            pubshelves     => $total->{pubtotal},
+            pubshelvesloop => $pubshelves,
+            barshelves      => $total->{bartotal},
+            barshelvesloop  => $barshelves,
+        );
 
         require C4::Members;
         my ( $borr ) = C4::Members::GetMemberDetails( $borrowernumber );
@@ -284,14 +278,11 @@ sub get_template_and_user {
 
         $template->param( sessionID        => $sessionID );
         
-        my ($total, $pubshelves) = C4::Context->get_shelves_userenv();  # an anonymous user has no 'barshelves'...
-        if (defined $pubshelves) {
-            $template->param(   pubshelves      => scalar @{$pubshelves},
-                                pubshelvesloop  => $pubshelves,
-                            );
-            $template->param(   pubtotal        => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar @{$pubshelves});
-        }
-
+        my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD');
+       $template->param(
+           pubshelves     => $total->{pubtotal},
+           pubshelvesloop => $pubshelves,
+       );
     }
        # Anonymous opac search history
        # If opac search history is enabled and at least one search has already been performed
@@ -900,22 +891,6 @@ sub checkauth {
                     $session->param('emailaddress'), $session->param('branchprinter')
                 );
 
-                # Grab borrower's shelves and public shelves and add them to the session
-                # $row_count determines how many records are returned from the db query
-                # and the number of lists to be displayed of each type in the 'Lists' button drop down
-                my $row_count = 10; # FIXME:This probably should be a syspref
-                my ($total, $totshelves, $barshelves, $pubshelves);
-                ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $borrowernumber);
-                $total->{'bartotal'} = $totshelves;
-                ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef);
-                $total->{'pubtotal'} = $totshelves;
-                $session->param('barshelves', $barshelves);
-                $session->param('pubshelves', $pubshelves);
-                $session->param('totshelves', $total);
-
-                C4::Context::set_shelves_userenv('bar',$barshelves);
-                C4::Context::set_shelves_userenv('pub',$pubshelves);
-                C4::Context::set_shelves_userenv('tot',$total);
             }
                else {
                if ($userid) {
@@ -929,16 +904,6 @@ sub checkauth {
             # anonymous sessions are created only for the OPAC
                        $debug and warn "Initiating an anonymous session...";
 
-                       # Grab the public shelves and add to the session...
-                       my $row_count = 20; # FIXME:This probably should be a syspref
-                       my ($total, $totshelves, $pubshelves);
-                       ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef);
-                       $total->{'pubtotal'} = $totshelves;
-                       $session->param('pubshelves', $pubshelves);
-                       $session->param('totshelves', $total);
-                       C4::Context::set_shelves_userenv('pub',$pubshelves);
-                       C4::Context::set_shelves_userenv('tot',$total);
-
                        # setting a couple of other session vars...
                        $session->param('ip',$session->remote_addr());
                        $session->param('lasttime',time());
index b096232..e00e3a4 100644 (file)
@@ -66,7 +66,7 @@ sub getMultipleAuth {
 # Logout from CAS
 sub logout_cas {
     my ($query) = @_;
-    my $uri = $ENV{'SCRIPT_URI'};
+    my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name();
     my $casparam = $query->param('cas');
     # FIXME: This should be more generic and handle whatever parameters there might be
     $uri .= "?cas=" . $casparam if (defined $casparam);
@@ -78,7 +78,7 @@ sub logout_cas {
 # Login to CAS
 sub login_cas {
     my ($query) = @_;
-    my $uri = $ENV{'SCRIPT_URI'};
+    my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name();
     my $casparam = $query->param('cas');
     # FIXME: This should be more generic and handle whatever parameters there might be
     $uri .= "?cas=" . $casparam if (defined $casparam);
@@ -91,7 +91,7 @@ sub login_cas {
 sub login_cas_url {
 
     my ($query, $key) = @_;
-    my $uri = $ENV{'SCRIPT_URI'};
+    my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name();
     my $casparam = $query->param('cas');
     # FIXME: This should be more generic and handle whatever parameters there might be
     $uri .= "?cas=" . $casparam if (defined $casparam);
@@ -107,7 +107,7 @@ sub checkpw_cas {
     $debug and warn "checkpw_cas";
     my ($dbh, $ticket, $query) = @_;
     my $retnumber;
-    my $uri = $ENV{'SCRIPT_URI'};
+    my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name();
     my $casparam = $query->param('cas');
     # FIXME: This should be more generic and handle whatever parameters there might be
     $uri .= "?cas=" . $casparam if (defined $casparam);
@@ -157,7 +157,7 @@ sub check_api_auth_cas {
     $debug and warn "check_api_auth_cas";
     my ($dbh, $PT, $query) = @_;
     my $retnumber;
-    my $url = $query->url();
+    my $url = C4::Context->preference('OPACBaseURL') . $query->script_name();
 
     my $casparam = $query->param('cas');
     $casparam = $defaultcasserver if (not defined $casparam);
index 9c2f94f..56cd94e 100644 (file)
@@ -1081,7 +1081,7 @@ sub GetMarcStructure {
     }
 
     $sth = $dbh->prepare(
-        "SELECT tagfield,tagsubfield,liblibrarian,libopac,tab,mandatory,repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link,defaultvalue 
+        "SELECT tagfield,tagsubfield,liblibrarian,libopac,tab,mandatory,repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link,defaultvalue,maxlength
          FROM   marc_subfield_structure 
          WHERE  frameworkcode=? 
          ORDER BY tagfield,tagsubfield
@@ -1100,10 +1100,12 @@ sub GetMarcStructure {
     my $isurl;
     my $link;
     my $defaultvalue;
+    my $maxlength;
 
     while (
         (   $tag,          $subfield,      $liblibrarian, $libopac, $tab,    $mandatory, $repeatable, $authorised_value,
-            $authtypecode, $value_builder, $kohafield,    $seealso, $hidden, $isurl,     $link,       $defaultvalue
+            $authtypecode, $value_builder, $kohafield,    $seealso, $hidden, $isurl,     $link,       $defaultvalue,
+            $maxlength
         )
         = $sth->fetchrow
       ) {
@@ -1120,6 +1122,7 @@ sub GetMarcStructure {
         $res->{$tag}->{$subfield}->{isurl}            = $isurl;
         $res->{$tag}->{$subfield}->{'link'}           = $link;
         $res->{$tag}->{$subfield}->{defaultvalue}     = $defaultvalue;
+        $res->{$tag}->{$subfield}->{maxlength}        = $maxlength;
     }
 
     $marc_structure_cache->{$forlibrarian}->{$frameworkcode} = $res;
@@ -1686,7 +1689,7 @@ sub GetMarcSubjects {
 
             # ignore $9
             my @this_link_loop = @link_loop;
-            push @subfields_loop, { code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $subject_subfield->[0] eq 9 );
+            push @subfields_loop, { code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $subject_subfield->[0] eq 9 || $subject_subfield->[0] eq '0' );
             $counter++;
         }
 
@@ -1770,7 +1773,7 @@ sub GetMarcAuthors {
                 link_loop => \@this_link_loop,
                 separator => $separator
               }
-              unless ( $authors_subfield->[0] eq '9' );
+              unless ( $authors_subfield->[0] eq '9' || $authors_subfield->[0] eq '0');
             $count_auth++;
         }
         push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop };
index 7bd0326..2153028 100644 (file)
@@ -204,8 +204,8 @@ sub ModBranch {
             (branchcode,branchname,branchaddress1,
             branchaddress2,branchaddress3,branchzip,branchcity,branchstate,
             branchcountry,branchphone,branchfax,branchemail,
-            branchurl,branchip,branchprinter,branchnotes)
-            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
+            branchurl,branchip,branchprinter,branchnotes,opac_info)
+            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
         ";
         my $sth    = $dbh->prepare($query);
         $sth->execute(
@@ -217,7 +217,7 @@ sub ModBranch {
             $data->{'branchphone'},      $data->{'branchfax'},
             $data->{'branchemail'},      $data->{'branchurl'},
             $data->{'branchip'},         $data->{'branchprinter'},
-            $data->{'branchnotes'},
+            $data->{'branchnotes'},      $data->{opac_info},
         );
         return 1 if $dbh->err;
     } else {
@@ -227,7 +227,7 @@ sub ModBranch {
                 branchaddress2=?,branchaddress3=?,branchzip=?,
                 branchcity=?,branchstate=?,branchcountry=?,branchphone=?,
                 branchfax=?,branchemail=?,branchurl=?,branchip=?,
-                branchprinter=?,branchnotes=?
+                branchprinter=?,branchnotes=?,opac_info=?
             WHERE branchcode=?
         ";
         my $sth    = $dbh->prepare($query);
@@ -240,7 +240,7 @@ sub ModBranch {
             $data->{'branchphone'},      $data->{'branchfax'},
             $data->{'branchemail'},      $data->{'branchurl'},
             $data->{'branchip'},         $data->{'branchprinter'},
-            $data->{'branchnotes'},
+            $data->{'branchnotes'},      $data->{opac_info},
             $data->{'branchcode'},
         );
     }
index b6e86e0..9c43f36 100644 (file)
@@ -21,6 +21,7 @@ package C4::Circulation;
 
 use strict;
 #use warnings; FIXME - Bug 2505
+use DateTime;
 use C4::Context;
 use C4::Stats;
 use C4::Reserves;
@@ -28,28 +29,18 @@ use C4::Biblio;
 use C4::Items;
 use C4::Members;
 use C4::Dates;
-use C4::Calendar;
+use C4::Dates qw(format_date);
 use C4::Accounts;
 use C4::ItemCirculationAlertPreference;
-use C4::Dates qw(format_date);
 use C4::Message;
 use C4::Debug;
-use Date::Calc qw(
-  Today
-  Today_and_Now
-  Add_Delta_YM
-  Add_Delta_DHMS
-  Date_to_Days
-  Day_of_Week
-  Add_Delta_Days       
-  check_date
-  Delta_Days
-);
-use POSIX qw(strftime);
 use C4::Branch; # GetBranches
 use C4::Log; # logaction
 
 use Data::Dumper;
+use Koha::DateUtils;
+use Koha::Calendar;
+use Carp;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
@@ -442,7 +433,7 @@ sub TooMany {
     my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower);
     if (defined($branch_borrower_circ_rule->{maxissueqty})) {
         my @bind_params = ();
-        my $branch_count_query = "SELECT COUNT(*) FROM issues 
+        my $branch_count_query = "SELECT COUNT(*) FROM issues
                                   JOIN items USING (itemnumber)
                                   WHERE borrowernumber = ? ";
         push @bind_params, $borrower->{borrowernumber};
@@ -691,21 +682,28 @@ sub CanBookBeIssued {
     #
     # DUE DATE is OK ? -- should already have checked.
     #
+    if ($duedate && ref $duedate ne 'DateTime') {
+        $duedate = dt_from_string($duedate);
+    }
+    my $now = DateTime->now( time_zone => C4::Context->tz() );
     unless ( $duedate ) {
-        my $issuedate = strftime( "%Y-%m-%d", localtime );
+        my $issuedate = $now->clone();
 
         my $branch = _GetCircControlBranch($item,$borrower);
         my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'};
-        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower );
+        $duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower );
 
         # Offline circ calls AddIssue directly, doesn't run through here
         #  So issuingimpossible should be ok.
     }
     if ($duedate) {
-        $needsconfirmation{INVALID_DATE} = $duedate->output('syspref')
-          unless $duedate->output('iso') ge C4::Dates->today('iso');
+        my $today = $now->clone();
+        $today->truncate( to => 'minutes');
+        if (DateTime->compare($duedate,$today) == -1 ) { # duedate cannot be before now
+            $needsconfirmation{INVALID_DATE} = output_pref($duedate);
+        }
     } else {
-        $issuingimpossible{INVALID_DATE} = $duedate->output('syspref');
+            $issuingimpossible{INVALID_DATE} = output_pref($duedate);
     }
 
     #
@@ -726,13 +724,25 @@ sub CanBookBeIssued {
     if ( $borrower->{flags}->{'DBARRED'} ) {
         $issuingimpossible{DEBARRED} = 1;
     }
-    if ( $borrower->{'dateexpiry'} eq '0000-00-00') {
+    if ( !defined $borrower->{dateexpiry} || $borrower->{'dateexpiry'} eq '0000-00-00') {
         $issuingimpossible{EXPIRED} = 1;
     } else {
-        my @expirydate=  split /-/,$borrower->{'dateexpiry'};
-        if($expirydate[0]==0 || $expirydate[1]==0|| $expirydate[2]==0 ||
-            Date_to_Days(Today) > Date_to_Days( @expirydate )) {
-            $issuingimpossible{EXPIRED} = 1;                                   
+        my ($y, $m, $d) =  split /-/,$borrower->{'dateexpiry'};
+        if ($y && $m && $d) { # are we really writing oinvalid dates to borrs
+            my $expiry_dt = DateTime->new(
+                year => $y,
+                month => $m,
+                day   => $d,
+                time_zone => C4::Context->tz,
+            );
+            $expiry_dt->truncate( to => 'days');
+            my $today = $now->clone()->truncate(to => 'days');
+            if (DateTime->compare($today, $expiry_dt) == 1) {
+                $issuingimpossible{EXPIRED} = 1;
+            }
+        } else {
+            carp("Invalid expity date in borr");
+            $issuingimpossible{EXPIRED} = 1;
         }
     }
     #
@@ -741,7 +751,7 @@ sub CanBookBeIssued {
 
     # DEBTS
     my ($amount) =
-      C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->output('iso') );
+      C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->ymd() );
     my $amountlimit = C4::Context->preference("noissuescharge");
     my $allowfineoverride = C4::Context->preference("AllowFineOverride");
     my $allfinesneedoverride = C4::Context->preference("AllFinesNeedOverride");
@@ -783,7 +793,7 @@ sub CanBookBeIssued {
     #
        my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item );
     # if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book
-    if ($max_loans_allowed eq 0) {
+    if (defined $max_loans_allowed && $max_loans_allowed == 0) {
         $needsconfirmation{PATRON_CANT} = 1;
     } else {
         if($max_loans_allowed){
@@ -958,13 +968,20 @@ sub AddIssue {
     my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_;
     my $dbh = C4::Context->dbh;
        my $barcodecheck=CheckValidBarcode($barcode);
+    if ($datedue && ref $datedue ne 'DateTime') {
+        $datedue = dt_from_string($datedue);
+    }
     # $issuedate defaults to today.
     if ( ! defined $issuedate ) {
-        $issuedate = strftime( "%Y-%m-%d", localtime );
-        # TODO: for hourly circ, this will need to be a C4::Dates object
-        # and all calls to AddIssue including issuedate will need to pass a Dates object.
+        $issuedate = DateTime->now(time_zone => C4::Context->tz());
     }
-       if ($borrower and $barcode and $barcodecheck ne '0'){
+    else {
+        if ( ref $issuedate ne 'DateTime') {
+            $issuedate = dt_from_string($issuedate);
+
+        }
+    }
+       if ($borrower and $barcode and $barcodecheck ne '0'){#??? wtf
                # find which item we issue
                my $item = GetItem('', $barcode) or return undef;       # if we don't get an Item, abort.
                my $branch = _GetCircControlBranch($item,$borrower);
@@ -979,12 +996,12 @@ sub AddIssue {
                # check if we just renew the issue.
                #
                if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) {
-                       $datedue = AddRenewal(
-                               $borrower->{'borrowernumber'},
-                               $item->{'itemnumber'},
-                               $branch,
-                               $datedue,
-                $issuedate, # here interpreted as the renewal date
+                   $datedue = AddRenewal(
+                       $borrower->{'borrowernumber'},
+                       $item->{'itemnumber'},
+                       $branch,
+                       $datedue,
+                       $issuedate, # here interpreted as the renewal date
                        );
                }
                else {
@@ -999,7 +1016,6 @@ sub AddIssue {
                        }
 
             MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve );
-
                        # Starting process for transfer job (checking transfert and validate it if we have one)
             my ($datesent) = GetTransfers($item->{'itemnumber'});
             if ($datesent) {
@@ -1018,23 +1034,23 @@ sub AddIssue {
         # Record in the database the fact that the book was issued.
         my $sth =
           $dbh->prepare(
-                "INSERT INTO issues 
+                "INSERT INTO issues
                     (borrowernumber, itemnumber,issuedate, date_due, branchcode)
                 VALUES (?,?,?,?,?)"
           );
         unless ($datedue) {
             my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'};
-            $datedue = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower );
+            $datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower );
 
         }
+        $datedue->truncate( to => 'minutes');
         $sth->execute(
             $borrower->{'borrowernumber'},      # borrowernumber
             $item->{'itemnumber'},              # itemnumber
-            $issuedate,                         # issuedate
-            $datedue->output('iso'),            # date_due
+            $issuedate->strftime('%Y-%m-%d %H:%M:00'), # issuedate
+            $datedue->strftime('%Y-%m-%d %H:%M:00'),   # date_due
             C4::Context->userenv->{'branch'}    # branchcode
         );
-        $sth->finish;
         if ( C4::Context->preference('ReturnToShelvingCart') ) { ## ReturnToShelvingCart is on, anything issued should be taken off the cart.
           CartToShelf( $item->{'itemnumber'} );
         }
@@ -1048,8 +1064,8 @@ sub AddIssue {
         ModItem({ issues           => $item->{'issues'},
                   holdingbranch    => C4::Context->userenv->{'branch'},
                   itemlost         => 0,
-                  datelastborrowed => C4::Dates->new()->output('iso'),
-                  onloan           => $datedue->output('iso'),
+                  datelastborrowed => DateTime->now(time_zone => C4::Context->tz())->ymd(),
+                  onloan           => $datedue->ymd(),
                 }, $item->{'biblionumber'}, $item->{'itemnumber'});
         ModDateLastSeen( $item->{'itemnumber'} );
 
@@ -1111,53 +1127,57 @@ sub GetLoanLength {
     my $dbh = C4::Context->dbh;
     my $sth =
       $dbh->prepare(
-"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"
+'select issuelength, lengthunit from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null'
       );
 # warn "in get loan lenght $borrowertype $itemtype $branchcode ";
 # try to find issuelength & return the 1st available.
 # check with borrowertype, itemtype and branchcode, then without one of those parameters
     $sth->execute( $borrowertype, $itemtype, $branchcode );
     my $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( $borrowertype, "*", $branchcode );
+    $sth->execute( $borrowertype, '*', $branchcode );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( "*", $itemtype, $branchcode );
+    $sth->execute( '*', $itemtype, $branchcode );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( "*", "*", $branchcode );
+    $sth->execute( '*', '*', $branchcode );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( $borrowertype, $itemtype, "*" );
+    $sth->execute( $borrowertype, $itemtype, '*' );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( $borrowertype, "*", "*" );
+    $sth->execute( $borrowertype, '*', '*' );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( "*", $itemtype, "*" );
+    $sth->execute( '*', $itemtype, '*' );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
-    $sth->execute( "*", "*", "*" );
+    $sth->execute( '*', '*', '*' );
     $loanlength = $sth->fetchrow_hashref;
-    return $loanlength->{issuelength}
-      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
+    return $loanlength
+      if defined($loanlength) && $loanlength->{issuelength};
 
     # if no rule is set => 21 days (hardcoded)
-    return 21;
+    return {
+        issuelength => 21,
+        lengthunit => 'days',
+    };
+
 }
 
 
@@ -1178,43 +1198,43 @@ sub GetHardDueDate {
       );
     $sth->execute( $borrowertype, $itemtype, $branchcode );
     my $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( $borrowertype, "*", $branchcode );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( "*", $itemtype, $branchcode );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( "*", "*", $branchcode );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( $borrowertype, $itemtype, "*" );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( $borrowertype, "*", "*" );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( "*", $itemtype, "*" );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     $sth->execute( "*", "*", "*" );
     $results = $sth->fetchrow_hashref;
-    return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
-      if defined($results) && $results->{hardduedate} ne 'NULL';
+    return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare})
+      if defined($results) && $results->{hardduedate};
 
     # if no rule is set => return undefined
     return (undef, undef);
@@ -1581,7 +1601,8 @@ sub AddReturn {
             # define circControlBranch only if dropbox mode is set
             # don't allow dropbox mode to create an invalid entry in issues (issuedate > today)
             # FIXME: check issuedate > returndate, factoring in holidays
-            $circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );;
+            #$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );;
+            $circControlBranch = _GetCircControlBranch($item,$borrower);
         }
 
         if ($borrowernumber) {
@@ -1718,27 +1739,27 @@ routine in C<C4::Accounts>.
 sub MarkIssueReturned {
     my ( $borrowernumber, $itemnumber, $dropbox_branch, $returndate, $privacy ) = @_;
     my $dbh   = C4::Context->dbh;
-    my $query = "UPDATE issues SET returndate=";
+    my $query = 'UPDATE issues SET returndate=';
     my @bind;
     if ($dropbox_branch) {
-        my $calendar = C4::Calendar->new( branchcode => $dropbox_branch );
-        my $dropboxdate = $calendar->addDate( C4::Dates->new(), -1 );
-        $query .= " ? ";
-        push @bind, $dropboxdate->output('iso');
+        my $calendar = Koha::Calendar->new( branchcode => $dropbox_branch );
+        my $dropboxdate = $calendar->addDate( DateTime->now( time_zone => C4::Context->tz), -1 );
+        $query .= ' ? ';
+        push @bind, $dropboxdate->strftime('%Y-%m-%d %H:%M');
     } elsif ($returndate) {
-        $query .= " ? ";
+        $query .= ' ? ';
         push @bind, $returndate;
     } else {
-        $query .= " now() ";
+        $query .= ' now() ';
     }
-    $query .= " WHERE  borrowernumber = ?  AND itemnumber = ?";
+    $query .= ' WHERE  borrowernumber = ?  AND itemnumber = ?';
     push @bind, $borrowernumber, $itemnumber;
     # FIXME transaction
     my $sth_upd  = $dbh->prepare($query);
     $sth_upd->execute(@bind);
-    my $sth_copy = $dbh->prepare("INSERT INTO old_issues SELECT * FROM issues 
+    my $sth_copy = $dbh->prepare('INSERT INTO old_issues SELECT * FROM issues
                                   WHERE borrowernumber = ?
-                                  AND itemnumber = ?");
+                                  AND itemnumber = ?');
     $sth_copy->execute($borrowernumber, $itemnumber);
     # anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber
     if ( $privacy == 2) {
@@ -1772,18 +1793,16 @@ Internal function, called only by AddReturn that calculate and update the user f
 
 sub _FixFineDaysOnReturn {
     my ( $borrower, $item, $datedue ) = @_;
-
-    if ($datedue) {
-        $datedue = C4::Dates->new( $datedue, "iso" );
-    } else {
-        return;
-    }
+    return unless ($datedue);
+    
+    my $dt_due =  dt_from_string( $datedue );
+    my $dt_today = DateTime->now( time_zone => C4::Context->tz() );
 
     my $branchcode = _GetCircControlBranch( $item, $borrower );
-    my $calendar = C4::Calendar->new( branchcode => $branchcode );
-    my $today = C4::Dates->new();
+    my $calendar = Koha::Calendar->new( branchcode => $branchcode );
 
-    my $deltadays = $calendar->daysBetween( $datedue, C4::Dates->new() );
+    # $deltadays is a DateTime::Duration object
+    my $deltadays = $calendar->days_between( $dt_due, $dt_today );
 
     my $circcontrol = C4::Context::preference('CircControl');
     my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
@@ -1791,22 +1810,22 @@ sub _FixFineDaysOnReturn {
 
     # exit if no finedays defined
     return unless $finedays;
-    my $grace = $issuingrule->{firstremind};
-
-    if ( $deltadays - $grace > 0 ) {
-        my @newdate = Add_Delta_Days( Today(), $deltadays * $finedays );
-        my $isonewdate = join( '-', @newdate );
-        my ( $deby, $debm, $debd ) = split( /-/, $borrower->{debarred} );
-        if ( check_date( $deby, $debm, $debd ) ) {
-            my @olddate = split( /-/, $borrower->{debarred} );
-
-            if ( Delta_Days( @olddate, @newdate ) > 0 ) {
-                C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate );
-                return $isonewdate;
+    my $grace = DateTime::Duration->new( days => $issuingrule->{firstremind} );
+
+    if ( ( $deltadays - $grace )->is_positive ) { # you can't compare DateTime::Durations with logical operators
+        my $new_debar_dt = $dt_today->clone()->add_duration( $deltadays * $finedays );
+        my $borrower_debar_dt = dt_from_string( $borrower->{debarred} );
+        # check to see if the current debar date is a valid date
+        if ( $borrower->{debarred} && $borrower_debar_dt ) {
+        # if so, is it before the new date?  update only if true
+            if ( DateTime->compare( $borrower_debar_dt, $new_debar_dt ) == -1 ) {
+                C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+                return $new_debar_dt->ymd();
             }
+        # if the borrower's debar date is not set or valid, debar them
         } else {
-            C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate );
-            return $isonewdate;
+            C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+            return $new_debar_dt->ymd();
         }
     }
 }
@@ -2024,14 +2043,19 @@ sub GetItemIssue {
     return unless $itemnumber;
     my $sth = C4::Context->dbh->prepare(
         "SELECT *
-        FROM issues 
+        FROM issues
         LEFT JOIN items ON issues.itemnumber=items.itemnumber
         WHERE issues.itemnumber=?");
     $sth->execute($itemnumber);
     my $data = $sth->fetchrow_hashref;
     return unless $data;
-    $data->{'overdue'} = ($data->{'date_due'} lt C4::Dates->today('iso')) ? 1 : 0;
-    return ($data);
+    $data->{issuedate} = dt_from_string($data->{issuedate}, 'sql');
+    $data->{issuedate}->truncate(to => 'minutes');
+    $data->{date_due} = dt_from_string($data->{date_due}, 'sql');
+    $data->{date_due}->truncate(to => 'minutes');
+    my $dt = DateTime->now( time_zone => C4::Context->tz)->truncate( to => 'minutes');
+    $data->{'overdue'} = DateTime->compare($data->{'date_due'}, $dt ) == -1 ? 1 : 0;
+    return $data;
 }
 
 =head2 GetOpenIssue
@@ -2073,14 +2097,15 @@ Returns reference to an array of hashes
 sub GetItemIssues {
     my ( $itemnumber, $history ) = @_;
     
-    my $today = C4::Dates->today('iso');  # get today date
-    my $sql = "SELECT * FROM issues 
+    my $today = DateTime->now( time_zome => C4::Context->tz);  # get today date
+    $today->truncate( to => 'minutes' );
+    my $sql = "SELECT * FROM issues
               JOIN borrowers USING (borrowernumber)
               JOIN items     USING (itemnumber)
               WHERE issues.itemnumber = ? ";
     if ($history) {
         $sql .= "UNION ALL
-                 SELECT * FROM old_issues 
+                 SELECT * FROM old_issues
                  LEFT JOIN borrowers USING (borrowernumber)
                  JOIN items USING (itemnumber)
                  WHERE old_issues.itemnumber = ? ";
@@ -2094,7 +2119,10 @@ sub GetItemIssues {
     }
     my $results = $sth->fetchall_arrayref({});
     foreach (@$results) {
-        $_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0;
+        my $date_due = dt_from_string($_->{date_due},'sql');
+        $date_due->truncate( to => 'minutes' );
+
+        $_->{overdue} = (DateTime->compare($date_due, $today) == -1) ? 1 : 0;
     }
     return $results;
 }
@@ -2224,7 +2252,7 @@ sub CanBookBeRenewed {
                    SELECT 
                     borrowers.categorycode, biblioitems.itemtype, issues.renewals, renewalsallowed, $controlbranch
                    FROM  issuingrules, 
-                   issues 
+                   issues
                    LEFT JOIN items USING (itemnumber) 
                    LEFT JOIN borrowers USING (borrowernumber) 
                    LEFT JOIN biblioitems USING (biblioitemnumber)
@@ -2295,7 +2323,7 @@ sub AddRenewal {
     my $itemnumber      = shift or return undef;
     my $branch          = shift;
     my $datedue         = shift;
-    my $lastreneweddate = shift || C4::Dates->new()->output('iso');
+    my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz)->ymd();
     my $item   = GetItem($itemnumber) or return undef;
     my $biblio = GetBiblioFromItemNumber($itemnumber) or return undef;
 
@@ -2309,9 +2337,9 @@ sub AddRenewal {
     $sth->execute( $borrowernumber, $itemnumber );
     my $issuedata = $sth->fetchrow_hashref;
     $sth->finish;
-    if($datedue && ! $datedue->output('iso')){
-        warn "Invalid date passed to AddRenewal.";
-        return undef;
+    if(defined $datedue && ref $datedue ne 'DateTime' ) {
+        carp 'Invalid date passed to AddRenewal.';
+        return;
     }
     # If the due date wasn't specified, calculate it by adding the
     # book's loan length to today's date or the current due date
@@ -2322,8 +2350,8 @@ sub AddRenewal {
         my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'};
 
         $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
-                                        C4::Dates->new($issuedata->{date_due}, 'iso') :
-                                        C4::Dates->new();
+                                        $issuedata->{date_due} :
+                                        DateTime->now( time_zone => C4::Context->tz());
         $datedue =  CalcDateDue($datedue,$itemtype,$issuedata->{'branchcode'},$borrower);
     }
 
@@ -2334,12 +2362,13 @@ sub AddRenewal {
                             WHERE borrowernumber=? 
                             AND itemnumber=?"
     );
-    $sth->execute( $datedue->output('iso'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
+
+    $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
     $sth->finish;
 
     # Update the renewal count on the item, and tell zebra to reindex
     $renews = $biblio->{'renewals'} + 1;
-    ModItem({ renewals => $renews, onloan => $datedue->output('iso') }, $biblio->{'biblionumber'}, $itemnumber);
+    ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber);
 
     # Charge a new rental fee, if applicable?
     my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
@@ -2357,7 +2386,6 @@ sub AddRenewal {
         $sth->execute( $borrowernumber, $accountno, $charge, $manager_id,
             "Renewal of Rental Item $item->{'title'} $item->{'barcode'}",
             'Rent', $charge, $itemnumber );
-        $sth->finish;
     }
     # Log the renewal
     UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber);
@@ -2767,88 +2795,89 @@ C<$borrower> = Borrower object
 
 =cut
 
-sub CalcDateDue { 
-       my ($startdate,$itemtype,$branch,$borrower) = @_;
-       my $datedue;
-        my $loanlength = GetLoanLength($borrower->{'categorycode'},$itemtype, $branch);
+sub CalcDateDue {
+    my ( $startdate, $itemtype, $branch, $borrower ) = @_;
 
-       # if globalDueDate ON the datedue is set to that date
-       if ( C4::Context->preference('globalDueDate')
-             && ( C4::Context->preference('globalDueDate') =~ C4::Dates->regexp('syspref') ) ) {
-            $datedue = C4::Dates->new( C4::Context->preference('globalDueDate') );
-       } else {
-       # otherwise, calculate the datedue as normal
-               if(C4::Context->preference('useDaysMode') eq 'Days') {  # ignoring calendar
-                       my $timedue = time + ($loanlength) * 86400;
-               #FIXME - assumes now even though we take a startdate 
-                       my @datearr  = localtime($timedue);
-                       $datedue = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso');
-               } else {
-                       my $calendar = C4::Calendar->new(  branchcode => $branch );
-                       $datedue = $calendar->addDate($startdate, $loanlength);
-               }
-       }
+    # loanlength now a href
+    my $loanlength =
+      GetLoanLength( $borrower->{'categorycode'}, $itemtype, $branch );
 
-       # if Hard Due Dates are used, retreive them and apply as necessary
-        my ($hardduedate, $hardduedatecompare) = GetHardDueDate($borrower->{'categorycode'},$itemtype, $branch);
-       if ( $hardduedate && $hardduedate->output('iso') && $hardduedate->output('iso') ne '0000-00-00') {
-            # if the calculated due date is after the 'before' Hard Due Date (ceiling), override
-            if ( $datedue->output( 'iso' ) gt $hardduedate->output( 'iso' ) && $hardduedatecompare == -1) {
-                $datedue = $hardduedate;
-            # if the calculated date is before the 'after' Hard Due Date (floor), override
-            } elsif ( $datedue->output( 'iso' ) lt $hardduedate->output( 'iso' ) && $hardduedatecompare == 1) {
-                $datedue = $hardduedate;               
-            # if the hard due date is set to 'exactly', overrride
-            } elsif ( $hardduedatecompare == 0) {
-                $datedue = $hardduedate;
-            }
-            # in all other cases, keep the date due as it is
-       }
+    my $datedue;
 
-       # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate
-       if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) {
-           $datedue = C4::Dates->new( $borrower->{dateexpiry}, 'iso' );
-       }
-
-       return $datedue;
-}
-
-=head2 CheckValidDatedue
-
-  $newdatedue = CheckValidDatedue($date_due,$itemnumber,$branchcode);
+    # if globalDueDate ON the datedue is set to that date
+    if (C4::Context->preference('globalDueDate')
+        && ( C4::Context->preference('globalDueDate') =~
+            C4::Dates->regexp('syspref') )
+      ) {
+        $datedue = dt_from_string(
+            C4::Context->preference('globalDueDate'),
+            C4::Context->preference('dateformat')
+        );
+    } else {
 
-This function does not account for holiday exceptions nor does it handle the 'useDaysMode' syspref .
-To be replaced by CalcDateDue() once C4::Calendar use is tested.
+        # otherwise, calculate the datedue as normal
+        if ( C4::Context->preference('useDaysMode') eq 'Days' )
+        {    # ignoring calendar
+            my $dt =
+              DateTime->now( time_zone => C4::Context->tz() )
+              ->truncate( to => 'minute' );
+            if ( $loanlength->{lengthunit} eq 'hours' ) {
+                $dt->add( hours => $loanlength->{issuelength} );
+                return $dt;
+            } else {    # days
+                $dt->add( days => $loanlength->{issuelength} );
+                $dt->set_hour(23);
+                $dt->set_minute(59);
+                return $dt;
+            }
+        } else {
+            my $dur;
+            if ($loanlength->{lengthunit} eq 'hours') {
+                $dur = DateTime::Duration->new( hours => $loanlength->{issuelength});
+            }
+            else { # days
+                $dur = DateTime::Duration->new( days => $loanlength->{issuelength});
+            }
+            if (ref $startdate ne 'DateTime' ) {
+                $startdate = dt_from_string($startdate);
+            }
+            my $calendar = Koha::Calendar->new( branchcode => $branch );
+            $datedue = $calendar->addDate( $startdate, $dur, $loanlength->{lengthunit} );
+            if ($loanlength->{lengthunit} eq 'days') {
+                $datedue->set_hour(23);
+                $datedue->set_minute(59);
+            }
+        }
+    }
 
-this function validates the loan length against the holidays calendar, and adjusts the due date as per the 'useDaysMode' syspref.
-C<$date_due>   = returndate calculate with no day check
-C<$itemnumber>  = itemnumber
-C<$branchcode>  = location of issue (affected by 'CircControl' syspref)
-C<$loanlength>  = loan length prior to adjustment
+    # if Hard Due Dates are used, retreive them and apply as necessary
+    my ( $hardduedate, $hardduedatecompare ) =
+      GetHardDueDate( $borrower->{'categorycode'}, $itemtype, $branch );
+    if ($hardduedate) {    # hardduedates are currently dates
+        $hardduedate->truncate( to => 'minute' );
+        $hardduedate->set_hour(23);
+        $hardduedate->set_minute(59);
+        my $cmp = DateTime->compare( $hardduedate, $datedue );
+
+# if the calculated due date is after the 'before' Hard Due Date (ceiling), override
+# if the calculated date is before the 'after' Hard Due Date (floor), override
+# if the hard due date is set to 'exactly', overrride
+        if ( $hardduedatecompare == 0 || $hardduedatecompare == $cmp ) {
+            $datedue = $hardduedate->clone;
+        }
 
-=cut
+        # in all other cases, keep the date due as it is
+    }
 
-sub CheckValidDatedue {
-my ($date_due,$itemnumber,$branchcode)=@_;
-my @datedue=split('-',$date_due->output('iso'));
-my $years=$datedue[0];
-my $month=$datedue[1];
-my $day=$datedue[2];
-# die "Item# $itemnumber ($branchcode) due: " . ${date_due}->output() . "\n(Y,M,D) = ($years,$month,$day)":
-my $dow;
-for (my $i=0;$i<2;$i++){
-    $dow=Day_of_Week($years,$month,$day);
-    ($dow=0) if ($dow>6);
-    my $result=CheckRepeatableHolidays($itemnumber,$dow,$branchcode);
-    my $countspecial=CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode);
-    my $countspecialrepeatable=CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode);
-        if (($result ne '0') or ($countspecial ne '0') or ($countspecialrepeatable ne '0') ){
-        $i=0;
-        (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1');
+    # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate
+    if ( C4::Context->preference('ReturnBeforeExpiry') ) {
+        my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'iso' );
+        if ( DateTime->compare( $datedue, $expiry_dt ) == 1 ) {
+            $datedue = $expiry_dt->clone;
         }
     }
-    my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso');
-return $newdatedue;
+
+    return $datedue;
 }
 
 
index 0417c45..67d31ee 100644 (file)
@@ -104,6 +104,7 @@ use XML::Simple;
 use C4::Boolean;
 use C4::Debug;
 use POSIX ();
+use DateTime::TimeZone;
 
 =head1 NAME
 
@@ -384,6 +385,7 @@ sub new {
     $self->{"userenv"} = undef;        # User env
     $self->{"activeuser"} = undef;        # current active user
     $self->{"shelves"} = undef;
+    $self->{tz} = undef; # local timezone object
 
     bless $self, $class;
     return $self;
@@ -1112,6 +1114,24 @@ sub get_versions {
 }
 
 
+=head2 tz
+
+  C4::Context->tz
+
+  Returns a DateTime::TimeZone object for the system timezone
+
+=cut
+
+sub tz {
+    my $self = shift;
+    if (!defined $context->{tz}) {
+        $context->{tz} = DateTime::TimeZone->new(name => 'local');
+    }
+    return $context->{tz};
+}
+
+
+
 1;
 __END__
 
index 067afd7..2940c00 100644 (file)
@@ -33,6 +33,7 @@ use C4::ILSDI::Utility;
 use XML::Simple;
 use HTML::Entities;
 use CGI;
+use DateTime;
 
 =head1 NAME
 
@@ -558,7 +559,7 @@ sub RenewLoan {
     # Hashref building
     my $out;
     $out->{'renewals'} = $issue->{'renewals'};
-    $out->{'date_due'} = $issue->{'date_due'};
+    $out->{date_due}   = $issue->{date_due}->strftime('%Y-%m-%d %H:%S');
     $out->{'success'}  = $renewal[0];
     $out->{'error'}    = $renewal[1];
 
index 0a888a8..ae01208 100644 (file)
@@ -197,7 +197,37 @@ our $PERL_DEPS = {
     'DateTime' => {
         'usage'    => 'Core',
         'required' => '1',
-        'min_ver'  => '0.51'
+        'min_ver'  => '0.58'
+    },
+    'DateTime::TimeZone' => {
+        'usage'    => 'Core',
+        'required' => '1',
+        'min_ver'  => '1.26'
+    },
+    'DateTime::Format::DateParse' => {
+        'usage'    => 'Core',
+        'required' => '1',
+        'min_ver'  => '0.04'
+    },
+    'DateTime::Set' => {
+        'usage'    => 'Core',
+        'required' => '1',
+        'min_ver'  => '0.28'
+    },
+    'DateTime::Event::ICal' => {
+        'usage'    => 'Core',
+        'required' => '1',
+        'min_ver'  => '0.08'
+    },
+    'Readonly' => {
+        'usage'    => 'Core',
+        'required' => '1',
+        'min_ver'  => '1.03'
+    },
+    'Readonly::XS' => {
+        'usage'    => 'Core',
+        'required' => '0',
+        'min_ver'  => '1.02'
     },
     'Graphics::Magick' => {
         'usage'    => 'Patron Card Creator Feature',
index 62fcbae..0b2f99b 100644 (file)
@@ -1189,7 +1189,9 @@ sub GetItemsInfo {
            items.notforloan as itemnotforloan,
            itemtypes.description,
            itemtypes.notforloan as notforloan_per_itemtype,
-           holding.branchurl
+           holding.branchurl,
+           holding.branchname,
+           holding.opac_info as branch_opac_info
      FROM items
      LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode
      LEFT JOIN branches AS home ON items.homebranch=home.branchcode
@@ -2577,6 +2579,7 @@ sub PrepareItemrecordDisplay {
                 $subfield_data{subfield}      = $subfield;
                 $subfield_data{countsubfield} = $cntsubf++;
                 $subfield_data{kohafield}     = $tagslib->{$tag}->{$subfield}->{'kohafield'};
+                $subfield_data{id}            = "tag_".$tag."_subfield_".$subfield."_".int(rand(1000000));
 
                 #        $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib};
                 $subfield_data{marc_lib}   = $tagslib->{$tag}->{$subfield}->{lib};
@@ -2715,8 +2718,6 @@ sub PrepareItemrecordDisplay {
                             my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
                             my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
                             $subfield_data{random}     = int(rand(1000000));    # why do we need 2 different randoms?
-                            my $index_subfield = int(rand(1000000));
-                            $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield;
                             $subfield_data{marc_value} = qq[<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255"
                                 onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');"
                                  onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" />
index 4aa689f..6161ac9 100644 (file)
@@ -35,6 +35,9 @@ use C4::Letters;
 use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
 use C4::Members::Attributes qw(SearchIdMatchingAttribute);
 use C4::NewsChannels; #get slip news
+use DateTime;
+use DateTime::Format::DateParse;
+use Koha::DateUtils;
 
 our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
 
@@ -639,7 +642,7 @@ sub IsMemberBlocked {
         "SELECT COUNT(*) as latedocs
          FROM issues
          WHERE borrowernumber = ?
-         AND date_due < curdate()"
+         AND date_due < now()"
     );
     $sth->execute($borrowernumber);
     my $latedocs = $sth->fetchrow_hashref->{'latedocs'};
@@ -677,7 +680,7 @@ sub GetMemberIssuesAndFines {
     $sth = $dbh->prepare(
         "SELECT COUNT(*) FROM issues 
          WHERE borrowernumber = ? 
-         AND date_due < curdate()"
+         AND date_due < now()"
     );
     $sth->execute($borrowernumber);
     my $overdue_count = $sth->fetchrow_arrayref->[0];
@@ -1032,9 +1035,15 @@ sub GetPendingIssues {
     my $sth = C4::Context->dbh->prepare($query);
     $sth->execute(@borrowernumbers);
     my $data = $sth->fetchall_arrayref({});
-    my $today = C4::Dates->new->output('iso');
+    my $tz = C4::Context->tz();
+    my $today = DateTime->now( time_zone => $tz);
     foreach (@{$data}) {
-        if ($_->{date_due}  and $_->{date_due} lt $today) {
+        if ($_->{issuedate}) {
+            $_->{issuedate} = dt_from_string($_->{issuedate}, 'sql');
+        }
+        $_->{date_due} or next;
+        $_->{date_due} = DateTime::Format::DateParse->parse_datetime($_->{date_due}, $tz->name());
+        if ( DateTime->compare($_->{date_due}, $today) == -1 ) {
             $_->{overdue} = 1;
         }
     }
index e36557b..8c96e54 100644 (file)
@@ -70,7 +70,7 @@ If $all_fields is true, then each hashref also contains the other fields from bo
 
 sub GetAttributeTypes {
     my ($all) = @_;
-    my $select = $all ? '*' : 'code, description';
+    my $select = $all ? '*' : 'code, description, class';
     my $dbh = C4::Context->dbh;
     my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code");
     $sth->execute();
@@ -120,6 +120,9 @@ sub new {
     $self->{'staff_searchable'} = 0;
     $self->{'display_checkout'} = 0;
     $self->{'authorised_value_category'} = '';
+    $self->{'category_code'} = '';
+    $self->{'category_description'} = '';
+    $self->{'class'} = '';
 
     bless $self, $class;
     return $self;
@@ -140,11 +143,15 @@ sub fetch {
     my $self = {};
     my $dbh = C4::Context->dbh();
 
-    my $sth = $dbh->prepare_cached("SELECT * FROM borrower_attribute_types WHERE code = ?");
+    my $sth = $dbh->prepare_cached("
+        SELECT borrower_attribute_types.*, categories.description AS category_description
+        FROM borrower_attribute_types
+        LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode
+        WHERE code =?");
     $sth->execute($code);
     my $row = $sth->fetchrow_hashref;
     $sth->finish();
-    return undef unless defined $row;    
+    return undef unless defined $row;
 
     $self->{'code'}                      = $row->{'code'};
     $self->{'description'}               = $row->{'description'};
@@ -155,6 +162,9 @@ sub fetch {
     $self->{'staff_searchable'}          = $row->{'staff_searchable'};
     $self->{'display_checkout'}          = $row->{'display_checkout'};
     $self->{'authorised_value_category'} = $row->{'authorised_value_category'};
+    $self->{'category_code'}             = $row->{'category_code'};
+    $self->{'category_description'}      = $row->{'category_description'};
+    $self->{'class'}                     = $row->{'class'};
 
     bless $self, $class;
     return $self;
@@ -185,14 +195,16 @@ sub store {
                                          password_allowed = ?,
                                          staff_searchable = ?,
                                          authorised_value_category = ?,
-                                         display_checkout = ?
+                                         display_checkout = ?,
+                                         category_code = ?,
+                                         class = ?
                                      WHERE code = ?");
     } else {
         $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types 
                                         (description, repeatable, unique_id, opac_display, password_allowed,
-                                         staff_searchable, authorised_value_category, display_checkout, code)
+                                         staff_searchable, authorised_value_category, display_checkout, category_code, class, code)
                                         VALUES (?, ?, ?, ?, ?,
-                                                ?, ?, ?, ?)");
+                                                ?, ?, ?, ?, ?, ?)");
     }
     $sth->bind_param(1, $self->{'description'});
     $sth->bind_param(2, $self->{'repeatable'});
@@ -202,7 +214,9 @@ sub store {
     $sth->bind_param(6, $self->{'staff_searchable'});
     $sth->bind_param(7, $self->{'authorised_value_category'});
     $sth->bind_param(8, $self->{'display_checkout'});
-    $sth->bind_param(9, $self->{'code'});
+    $sth->bind_param(9, $self->{'category_code'} || undef);
+    $sth->bind_param(10, $self->{'class'});
+    $sth->bind_param(11, $self->{'code'});
     $sth->execute;
 
 }
@@ -341,6 +355,61 @@ sub authorised_value_category {
     @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'};
 }
 
+=head2 category_code
+
+=over 4
+
+my $category_code = $attr_type->category_code();
+$attr_type->category_code($category_code);
+
+=back
+
+Accessor.
+
+=cut
+
+sub category_code {
+    my $self = shift;
+    @_ ? $self->{'category_code'} = shift : $self->{'category_code'};
+}
+
+=head2 category_description
+
+=over 4
+
+my $category_description = $attr_type->category_description();
+$attr_type->category_description($category_description);
+
+=back
+
+Accessor.
+
+=cut
+
+sub category_description {
+    my $self = shift;
+    @_ ? $self->{'category_description'} = shift : $self->{'category_description'};
+}
+
+=head2 class
+
+=over 4
+
+my $class = $attr_type->class();
+$attr_type->class($class);
+
+=back
+
+Accessor.
+
+=cut
+
+sub class {
+    my $self = shift;
+    @_ ? $self->{'class'} = shift : $self->{'class'};
+}
+
+
 =head2 delete
 
   $attr_type->delete();
index 33affa8..33d2407 100644 (file)
@@ -72,7 +72,7 @@ sub GetBorrowerAttributes {
     my $opac_only = @_ ? shift : 0;
 
     my $dbh = C4::Context->dbh();
-    my $query = "SELECT code, description, attribute, lib, password, display_checkout
+    my $query = "SELECT code, description, attribute, lib, password, display_checkout, category_code, class
                  FROM borrower_attributes
                  JOIN borrower_attribute_types USING (code)
                  LEFT JOIN authorised_values ON (category = authorised_value_category AND attribute = authorised_value)
@@ -90,6 +90,8 @@ sub GetBorrowerAttributes {
             value_description => $row->{'lib'},  
             password          => $row->{'password'},
             display_checkout  => $row->{'display_checkout'},
+            category_code     => $row->{'category_code'},
+            class             => $row->{'class'},
         }
     }
     return \@results;
index 660e10b..7676a87 100644 (file)
@@ -124,7 +124,7 @@ sub Getoverdues {
    SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
-    WHERE date_due < CURDATE() 
+    WHERE date_due < NOW()
 ";
     } else {
         $statement = "
@@ -132,7 +132,7 @@ LEFT JOIN items       USING (itemnumber)
      FROM issues 
 LEFT JOIN items       USING (itemnumber)
 LEFT JOIN biblioitems USING (biblioitemnumber)
-    WHERE date_due < CURDATE() 
+    WHERE date_due < NOW()
 ";
     }
 
@@ -199,7 +199,7 @@ sub checkoverdues {
          LEFT JOIN biblio      ON items.biblionumber     = biblio.biblionumber
          LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
             WHERE issues.borrowernumber  = ?
-            AND   issues.date_due < CURDATE()"
+            AND   issues.date_due < NOW()"
     );
     # FIXME: SELECT * across 4 tables?  do we really need the marc AND marcxml blobs??
     $sth->execute($borrowernumber);
@@ -209,9 +209,9 @@ sub checkoverdues {
 
 =head2 CalcFine
 
-    ($amount, $chargename, $daycount, $daycounttotal) = &CalcFine($item, 
-                                  $categorycode, $branch, $days_overdue, 
-                                  $description, $start_date, $end_date );
+    ($amount, $chargename,  $daycounttotal) = &CalcFine($item,
+                                  $categorycode, $branch,
+                                  $start_dt, $end_dt );
 
 Calculates the fine for a book.
 
@@ -229,13 +229,8 @@ the book.
 
 C<$branchcode> is the library (string) whose issuingrules govern this transaction.
 
-C<$days_overdue> is the number of days elapsed since the book's due date.
-  NOTE: supplying days_overdue is deprecated.
-
-C<$start_date> & C<$end_date> are C4::Dates objects 
+C<$start_date> & C<$end_date> are DateTime objects
 defining the date range over which to determine the fine.
-Note that if these are defined, we ignore C<$difference> and C<$dues> , 
-but retain these for backwards-comptibility with extant fines scripts.
 
 Fines scripts should just supply the date range over which to calculate the fine.
 
@@ -249,8 +244,6 @@ the categoryitem table, whatever that is.
 C<$daycount> is the number of days between start and end dates, Calendar adjusted (where needed), 
 minus any applicable grace period.
 
-C<$daycounttotal> is C<$daycount> without consideration of grace period.
-
 FIXME - What is chargename supposed to be ?
 
 FIXME: previously attempted to return C<$message> as a text message, either "First Notice", "Second Notice",
@@ -259,48 +252,39 @@ or "Final Notice".  But CalcFine never defined any value.
 =cut
 
 sub CalcFine {
-    my ( $item, $bortype, $branchcode, $difference ,$dues , $start_date, $end_date  ) = @_;
-       $debug and warn sprintf("CalcFine(%s, %s, %s, %s, %s, %s, %s)",
-                       ($item ? '{item}' : 'UNDEF'), 
-                       ($bortype    || 'UNDEF'), 
-                       ($branchcode || 'UNDEF'), 
-                       ($difference || 'UNDEF'), 
-                       ($dues       || 'UNDEF'), 
-                       ($start_date ? ($start_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF'), 
-                       (  $end_date ? (  $end_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF')
-       );
+    my ( $item, $bortype, $branchcode, $due_dt, $end_date  ) = @_;
+    my $start_date = $due_dt->clone();
     my $dbh = C4::Context->dbh;
     my $amount = 0;
-       my $daystocharge;
-       # get issuingrules (fines part will be used)
-    $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)", $bortype, $item->{'itemtype'}, $branchcode);
-    my $data = C4::Circulation::GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode);
-       if($difference) {
-               # if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar.
-       # use copy-pasted functions from calendar module.  (deprecated -- these functions will be removed from C4::Overdues ).
-           my $countspecialday    =    &GetSpecialHolidays($dues,$item->{itemnumber});
-           my $countrepeatableday = &GetRepeatableHolidays($dues,$item->{itemnumber},$difference);    
-           my $countalldayclosed  = $countspecialday + $countrepeatableday;
-           $daystocharge = $difference - $countalldayclosed;
-       } else {
-               # if $difference is not supplied, we have C4::Dates objects giving us the date range, and we use the calendar module.
-               if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
-                       my $calendar = C4::Calendar->new( branchcode => $branchcode );
-                       $daystocharge = $calendar->daysBetween( $start_date, $end_date );
-               } else {
-                       $daystocharge = Date_to_Days(split('-',$end_date->output('iso'))) - Date_to_Days(split('-',$start_date->output('iso')));
-               }
-       }
-       # correct for grace period.
-       my $days_minus_grace = $daystocharge - $data->{'firstremind'};
-    if ($data->{'chargeperiod'} > 0 && $days_minus_grace > 0 ) { 
-        $amount = int($daystocharge / $data->{'chargeperiod'}) * $data->{'fine'};
+    my $charge_duration;
+    # get issuingrules (fines part will be used)
+    my $data = C4::Circulation::GetIssuingRule($bortype, $item->{itemtype}, $branchcode);
+    if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') {
+        my $calendar = Koha::Calendar->new( branchcode => $branchcode );
+        $charge_duration = $calendar->days_between( $start_date, $end_date );
+    } else {
+        $charge_duration = $end_date - $start_date;
+    }
+    # correct for grace period.
+    my $fine_unit = $data->{lengthunit};
+    $fine_unit ||= 'days';
+    my $chargeable_units;
+    if ($fine_unit eq 'hours') {
+        $chargeable_units = $charge_duration->hours(); # TODO closed times???
+    }
+    else {
+        $chargeable_units = $charge_duration->days;
+    }
+    my $days_minus_grace = $chargeable_units - $data->{firstremind};
+    if ($data->{'chargeperiod'}  && $days_minus_grace  ) {
+        $amount = int($chargeable_units / $data->{'chargeperiod'}) * $data->{'fine'};# TODO fine calc should be in cents
     } else {
         # a zero (or null)  chargeperiod means no charge.
     }
-       $amount = C4::Context->preference('maxFine') if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine')));
-       $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
-    return ($amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
+    if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))) {
+        $amount = C4::Context->preference('maxFine');
+    }
+    return ($amount, $data->{chargename}, $days_minus_grace);
     # FIXME: chargename is NEVER populated anywhere.
 }
 
@@ -1218,7 +1202,7 @@ sub GetOverduesForBranch {
     WHERE (accountlines.amountoutstanding  != '0.000000')
       AND (accountlines.accounttype         = 'FU'      )
       AND (issues.branchcode =  ?   )
-      AND (issues.date_due  < CURDATE())
+      AND (issues.date_due  < NOW())
     ";
     my @getoverdues;
     my $i = 0;
index 95981fb..99fd6e7 100644 (file)
@@ -17,7 +17,6 @@ use Data::Dumper;
 
 use C4::Debug;
 use C4::Context;
-# use C4::Dates;
 use C4::Koha;
 use C4::Members;
 use C4::Reserves;
index 617a4eb..d483e16 100644 (file)
@@ -122,11 +122,14 @@ sub do_checkout {
        $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, undef, 0)\n"
                # . "w/ \$borrower: " . Dumper($borrower)
                . "w/ C4::Context->userenv: " . Dumper(C4::Context->userenv);
-       my $c4due  = AddIssue($borrower, $barcode, undef, 0);
-       my $due  = $c4due->output('iso') || undef;
-       $debug and warn "Item due: $due";
-       $self->{'due'} = $due;
-       $self->{item}->due_date($due);
+       my $due_dt  = AddIssue($borrower, $barcode, undef, 0);
+    if ($due_dt) {
+        $self->{due} = $due_dt->clone();
+    } else {
+        $self->{due} = undef;
+    }
+
+    #$self->{item}->due_date($due);
        $self->ok(1);
        return $self;
 }
index 73acaa3..d7f949b 100644 (file)
@@ -37,8 +37,7 @@ sub do_renew_for ($$) {
        my $borrower = shift;
        my ($renewokay,$renewerror) = CanBookBeRenewed($borrower->{borrowernumber},$self->{item}->{itemnumber});
        if ($renewokay){
-               my $datedue = AddIssue( $borrower, $self->{item}->id, undef, 0 );
-               $self->{due} = $datedue;
+               $self->{due} = AddIssue( $borrower, $self->{item}->id, undef, 0 );
                $self->renewal_ok(1);
        } else {
                $self->screen_msg(($self->screen_msg || '') . " " . $renewerror);
index 2e49bf7..10fb27d 100644 (file)
@@ -53,8 +53,8 @@ sub do_renew_all {
                $self->{item} = $item;
                $self->do_renew_for($borrower);
                if ($self->ok) {
-                       $item->{due_date} = $self->{due};
-            push @{$self->{renewed}  }, $item_id;
+                   $item->{due_date} = $self->{due}->clone();
+                   push @{$self->renewed  }, $item_id;
                } else {
             push @{$self->{unrenewed}}, $item_id;
                }
index 337cc0e..4e3f299 100644 (file)
@@ -50,7 +50,9 @@ our $last_response = '';
 
 sub timestamp {
     my $time = $_[0] || time();
-    if ($time=~m/^(\d{4})\-(\d{2})\-(\d{2})/) {
+    if ( ref $time eq 'DateTime') {
+        return $time->strftime(SIP_DATETIME);
+    } elsif ($time=~m/^(\d{4})\-(\d{2})\-(\d{2})/) {
         # passing a db returned date as is + bogus time
         return sprintf( '%04d%02d%02d    235900', $1, $2, $3);
     }
diff --git a/C4/SocialData.pm b/C4/SocialData.pm
new file mode 100644 (file)
index 0000000..ebf2da6
--- /dev/null
@@ -0,0 +1,148 @@
+package C4::SocialData;
+
+# 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.
+#
+# 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., 59 Temple Place,
+# Suite 330, Boston, MA  02111-1307 USA
+
+use Modern::Perl;
+
+use C4::Context;
+use Business::ISBN;
+use C4::Koha;
+
+=head1 NAME
+
+C4::SocialData - Koha functions for dealing with social datas
+For now used by babeltheque, a french company providing, for books, comments, upload of videos, scoring (star)...
+the social_data table could be used and improved by other provides.
+
+=head1 SYNOPSIS
+
+use C4::SocialData;
+
+=head1 DESCRIPTION
+
+The functions in this module deal with social datas
+
+=head1 FUNCTIONS
+
+=head2 get_data
+
+Get social data from a biblio
+
+params:
+  $isbn = isbn of the biblio (it must be the same in your database, isbn given to babelio)
+
+returns:
+  this function returns an hashref with keys
+
+  isbn = isbn
+  num_critics = number of critics
+  num_critics_pro = number of profesionnal critics
+  num_quotations = number of quotations
+  num_videos = number of videos
+  score_avg = average score
+  num_scores = number of score
+=cut
+
+sub get_data {
+    my ( $isbn ) = @_;
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare( qq{SELECT * FROM social_data WHERE isbn = ? LIMIT 1} );
+    $sth->execute( $isbn );
+    my $results = $sth->fetchrow_hashref;
+
+    return $results;
+}
+
+=head2 update_data
+
+Update Social data
+
+params:
+  $url = url containing csv file with data
+
+data separator : ; (semicolon)
+data order : isbn ; active ; critics number , critics pro number ; quotations number ; videos number ; average score ; scores number
+
+=cut
+
+sub update_data {
+    my ( $output_filepath ) = @_;
+
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare( qq{INSERT INTO social_data (
+            `isbn`, `num_critics`, `num_critics_pro`, `num_quotations`, `num_videos`, `score_avg`, `num_scores`
+        ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
+        ON DUPLICATE KEY UPDATE `num_critics`=?, `num_critics_pro`=?, `num_quotations`=?, `num_videos`=?, `score_avg`=?, `num_scores`=?
+    } );
+
+    open my $file, '<', $output_filepath or die "File $output_filepath can not be read";
+    my $sep = qq{;};
+    my $i = 0;
+    my $unknown = 0;
+    while ( my $line = <$file> ) {
+        my ( $isbn, $active, $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores ) = split $sep, $line;
+        next if not $active;
+        eval {
+            $sth->execute( $isbn, $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores,
+                $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores
+            );
+        };
+        if ( $@ ) {
+            warn "Can't insert $isbn ($@)";
+        } else {
+            $i++;
+        }
+    }
+    say "$i data insered or updated";
+}
+
+=head2 get_report
+
+Get social data report
+
+=cut
+
+sub get_report {
+    my $dbh = C4::Context->dbh;
+
+    my $sth = $dbh->prepare( qq{
+        SELECT biblionumber, isbn FROM biblioitems
+    } );
+    $sth->execute;
+    my %results;
+    while ( my ( $biblionumber, $isbn ) = $sth->fetchrow() ) {
+        push @{ $results{no_isbn} }, { biblionumber => $biblionumber } and next if not $isbn;
+        my $original_isbn = $isbn;
+        $isbn =~ s/^\s*(\S*)\s*$/$1/;
+        $isbn = GetNormalizedISBN( $isbn, undef, undef );
+        $isbn = Business::ISBN->new( $isbn );
+        next if not $isbn;
+        eval{
+            $isbn = $isbn->as_isbn13->as_string;
+        };
+        next if $@;
+        $isbn =~ s/-//g;
+        my $social_datas = C4::SocialData::get_data( $isbn );
+        if ( $social_datas ) {
+            push @{ $results{with} }, { biblionumber => $biblionumber, isbn => $isbn, original => $original_isbn };
+        } else {
+            push @{ $results{without} }, { biblionumber => $biblionumber, isbn => $isbn, original => $original_isbn };
+        }
+    }
+    return \%results;
+}
+
+1;
index c74ecb3..85dbc9f 100644 (file)
@@ -28,24 +28,28 @@ use Carp;
 use C4::Context;
 use C4::Debug;
 
+use constant SHELVES_MASTHEAD_MAX => 10; #number under Lists button in masthead
+use constant SHELVES_COMBO_MAX => 10; #add to combo in search
+use constant SHELVES_MGRPAGE_MAX => 20; #managing page
+use constant SHELVES_POPUP_MAX => 40; #addbybiblio popup
+
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
 
 BEGIN {
-       # set the version for version checking
-       $VERSION = 3.02;
-       require Exporter;
-       @ISA    = qw(Exporter);
-       @EXPORT = qw(
+    # set the version for version checking
+    $VERSION = 3.02;
+    require Exporter;
+    @ISA    = qw(Exporter);
+    @EXPORT = qw(
             &GetShelves &GetShelfContents &GetShelf
             &AddToShelf &AddShelf
             &ModShelf
             &ShelfPossibleAction
             &DelFromShelf &DelShelf
             &GetBibliosShelves
-       );
+    );
         @EXPORT_OK = qw(
-            &GetShelvesSummary &GetRecentShelves &GetAllShelves
-            &RefreshShelvesSummary &SetShelvesLimit
+            &GetAllShelves &ShelvesMax
         );
 }
 
@@ -54,7 +58,7 @@ my $dbh = C4::Context->dbh;
 
 =head1 NAME
 
-C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves
+C4::VirtualShelves - Functions for manipulating Koha virtual shelves
 
 =head1 SYNOPSIS
 
@@ -62,21 +66,24 @@ C4::VirtualShelves - Functions for manipulating Koha virtual virtualshelves
 
 =head1 DESCRIPTION
 
-This module provides functions for manipulating virtual virtualshelves,
-including creating and deleting virtualshelves, and adding and removing
-bibs to and from virtualshelves.
+This module provides functions for manipulating virtual shelves,
+including creating and deleting virtual shelves, and adding and removing
+bibs to and from virtual shelves.
 
 =head1 FUNCTIONS
 
 =head2 GetShelves
 
-  ($shelflist, $totshelves) = &GetShelves($mincategory, $row_count, $offset, $owner);
+  ($shelflist, $totshelves) = &GetShelves($category, $row_count, $offset, $owner);
   ($shelfnumber, $shelfhash) = each %{$shelflist};
 
 Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total
-number of shelves that meet the C<$owner> and C<$mincategory> criteria.  C<$mincategory>,
-C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1.
-When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>.
+number of shelves that meet the C<$owner> and C<$category> criteria.  C<$category>,
+C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$category> == 1.
+When C<$category> is 2, supply undef as argument for C<$owner>.
+
+This function is used by shelfpage in VirtualShelves/Page.pm when listing all shelves for lists management in opac or staff client. Order is by shelfname.
+
 C<$shelflist>is a reference-to-hash. The keys are the virtualshelves numbers (C<$shelfnumber>, above),
 and the values (C<$shelfhash>, above) are themselves references-to-hash, with the following keys:
 
@@ -94,35 +101,40 @@ The number of virtuals on that virtualshelves.
 
 =cut
 
-sub GetShelves ($$$$) {
-    my ($mincategory, $row_count, $offset, $owner) = @_;
-       my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count);
-       my @params1 = ($owner, $mincategory);
-       if ($mincategory > 1) {
-               shift @params;
-               shift @params1;
-       }
-       my $total = _shelf_count($owner, $mincategory);
-    # grab only the shelves meeting the row_count/offset spec...
-    my $query = qq(
-        SELECT virtualshelves.shelfnumber, virtualshelves.shelfname,owner,surname,firstname,virtualshelves.category,virtualshelves.sortfield,
-               count(virtualshelfcontents.biblionumber) as count
-        FROM   virtualshelves
-            LEFT JOIN   virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber
-            LEFT JOIN   borrowers ON virtualshelves.owner = borrowers.borrowernumber );
-    $query .= ($mincategory == 1) ? "WHERE  owner=? AND category=?" : "WHERE category>=?";
-       $query .= qq(
-        GROUP BY virtualshelves.shelfnumber
-        ORDER BY virtualshelves.shelfname
-               LIMIT ?, ?);
+sub GetShelves {
+    my ($category, $row_count, $offset, $owner) = @_;
+    my @params;
+    my $total = _shelf_count($owner, $category);
+    my $query = qq{
+        SELECT vs.shelfnumber, vs.shelfname,vs.owner,
+        bo.surname,bo.firstname,vs.category,vs.sortfield,
+        count(vc.biblionumber) as count
+        FROM virtualshelves vs
+        LEFT JOIN borrowers bo ON vs.owner=bo.borrowernumber
+        LEFT JOIN virtualshelfcontents vc USING (shelfnumber) };
+    if($category==1) {
+        $query.= qq{
+            LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
+            AND sh.borrowernumber=?
+        WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
+        @params= ($owner, $owner, $owner, $offset||0, $row_count);
+    }
+    else {
+        $query.= 'WHERE category=2 ';
+        @params= ($offset||0, $row_count);
+    }
+    $query.= qq{
+        GROUP BY vs.shelfnumber
+        ORDER BY vs.shelfname
+        LIMIT ?, ?};
+
     my $sth2 = $dbh->prepare($query);
     $sth2->execute(@params);
     my %shelflist;
-    while ( my ( $shelfnumber, $shelfname, $owner, $surname,
-               $firstname,   $category,  $sortfield, $count ) = $sth2->fetchrow ) {
+    while( my ($shelfnumber, $shelfname, $owner, $surname, $firstname, $category, $sortfield, $count)= $sth2->fetchrow) {
         $shelflist{$shelfnumber}->{'shelfname'} = $shelfname;
         $shelflist{$shelfnumber}->{'count'}     = $count;
-        if($count eq 1){ $shelflist{$shelfnumber}->{'single'} = 1; }
+        $shelflist{$shelfnumber}->{'single'}    = $count==1;
         $shelflist{$shelfnumber}->{'sortfield'} = $sortfield;
         $shelflist{$shelfnumber}->{'category'}  = $category;
         $shelflist{$shelfnumber}->{'owner'}     = $owner;
@@ -132,111 +144,77 @@ sub GetShelves ($$$$) {
     return ( \%shelflist, $total );
 }
 
-=head2 GetShelvesSummary
-
-       ($shelves, $total) = GetShelvesSummary($mincategory, $row_count, $offset, $owner)
-
-Returns the number of shelves specified by C<$row_count> and C<$offset> as well as the total
-number of shelves that meet the C<$owner> and/or C<$mincategory> criteria. C<$mincategory>,
-C<$row_count>, and C<$offset> are required. C<$owner> must be supplied when C<$mincategory> == 1.
-When C<$mincategory> is 2 or 3, supply undef as argument for C<$owner>.
-
-=cut
-
-sub GetShelvesSummary ($$$$) {
-    my ($mincategory, $row_count, $offset, $owner) = @_;
-       my @params = ($owner, $mincategory, ($offset ? $offset : 0), $row_count);
-       my @params1 = ($owner, $mincategory);
-       if ($mincategory > 1) {
-               shift @params;
-               shift @params1;
-       }
-       my $total = _shelf_count($owner, $mincategory);
-    # grab only the shelves meeting the row_count/offset spec...
-       my $query = qq(
-               SELECT
-                       virtualshelves.shelfnumber,
-                       virtualshelves.shelfname,
-                       owner,
-                       CONCAT(firstname, ' ', surname) AS name,
-                       virtualshelves.category,
-                       count(virtualshelfcontents.biblionumber) AS count
-               FROM   virtualshelves
-                       LEFT JOIN  virtualshelfcontents ON virtualshelves.shelfnumber = virtualshelfcontents.shelfnumber
-                       LEFT JOIN             borrowers ON virtualshelves.owner = borrowers.borrowernumber );
-    $query .= ($mincategory == 1) ? "WHERE  owner=? AND category=?" : "WHERE category>=?";
-       $query .= qq(
-               GROUP BY virtualshelves.shelfnumber
-               ORDER BY virtualshelves.category
-               DESC 
-               LIMIT ?, ?);
-       my $sth2 = $dbh->prepare($query);
-       $sth2->execute(@params);
-    my $shelves = $sth2->fetchall_arrayref({});
-    return ($shelves, $total);
-
-       # Probably NOT the final implementation since it is still bulky (repeated hash keys).
-       # might like an array of rows of delimited values:
-       # 1|2||0|blacklist|112
-       # 2|6|Josh Ferraro|51|en_fuego|106
-}
-
-=head2 GetRecentShelves
+=head2 GetAllShelves
 
-       ($shelflist, $total) = GetRecentShelves(1, $limit, $owner)
+    $shelflist = GetAllShelves($category, $owner)
 
-This function returns a reference to an array of hashrefs containing specified shelves sorted
-by the date the shelf was last modified in descending order limited to the number of records
-specified by C<$row_count>. If calling with C<$mincategory> other than 1, use undef as C<$owner>.
+This function returns a reference to an array of hashrefs containing all shelves
+sorted by the shelf name.
 
-This function is intended to return a dataset reflecting the most recently active shelves for
+This function is intended to return a dataset reflecting all the shelves for
 the submitted parameters.
 
 =cut
 
-sub GetRecentShelves {
-    my ($mincategory, $row_count, $owner) = @_;
-    my $total = _shelf_count($owner, $mincategory);
+sub GetAllShelves {
+    my ($category,$owner,$adding_allowed) = @_;
     my @params;
-    my $selection;
-    if (defined $owner) {
-        @params = ($owner, $mincategory);
-        $selection = ' WHERE owner = ? AND category = ?';
-    } else {
-        @params = ( $mincategory);
-        $selection = ' WHERE category >= ? ';
+    my $query = 'SELECT vs.* FROM virtualshelves vs ';
+    if($category==1) {
+        $query.= qq{
+            LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
+            AND sh.borrowernumber=?
+        WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
+        @params = ($owner, $owner, $owner);
     }
-    my $query = 'SELECT * FROM virtualshelves';
-    $query .= $selection;
-    $query .= ' ORDER BY lastmodified DESC';
-    if ($row_count){
-       $query .= ' LIMIT ?';
-       push @params,$row_count;
+    else {
+    $query.='WHERE category=2 ';
+        @params = ();
     }
-    my $sth = $dbh->prepare($query);
+    $query.='AND (allow_add=1 OR owner=?) ' if $adding_allowed;
+    push @params, $owner if $adding_allowed;
+    $query.= 'ORDER BY shelfname ASC';
+    my $sth = $dbh->prepare( $query );
     $sth->execute(@params);
-    my $shelflist = $sth->fetchall_arrayref({});
-    return ( $shelflist, $total );
+    return $sth->fetchall_arrayref({});
 }
 
-=head2 GetAllShelves
+=head2 GetSomeShelfNames
 
-    $shelflist = GetAllShelves($owner)
+Returns shelf names and numbers for Add to combo of search results and Lists button of OPAC header.
 
-This function returns a reference to an array of hashrefs containing all shelves sorted
-by the shelf name.
+=cut
 
-This function is intended to return a dataset reflecting all the shelves for
-the submitted parameters.
+sub GetSomeShelfNames {
+    my ($owner, $purpose, $adding_allowed)= @_;
+    my ($bar, $pub, @params);
 
-=cut
+    my $bquery = 'SELECT vs.shelfnumber, vs.shelfname FROM virtualshelves vs ';
+    my $limit= ShelvesMax($purpose);
 
-sub GetAllShelves {
-    my ($category,$owner) = @_;
-    my $query = 'SELECT * FROM virtualshelves WHERE category = ? AND owner = ? ORDER BY shelfname ASC';
-    my $sth = $dbh->prepare( $query );
-    $sth->execute( $category, $owner );
-    return $sth->fetchall_arrayref({});
+    my $qry1= $bquery."WHERE vs.category=2 ";
+    $qry1.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
+    push @params, $owner||0 if $adding_allowed;
+    $qry1.= "ORDER BY vs.lastmodified DESC LIMIT $limit";
+
+    unless($adding_allowed && (!defined($owner) || $owner<=0)) {
+      #if adding items, user should be known
+      $pub= $dbh->selectall_arrayref($qry1,{Slice=>{}},@params);
+    }
+
+    if($owner) {
+      my $qry2= $bquery. qq{
+        LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber AND sh.borrowernumber=?
+        WHERE vs.category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
+      @params=($owner,$owner,$owner);
+      $qry2.= "AND (allow_add=1 OR owner=?) " if $adding_allowed;
+      push @params, $owner if $adding_allowed;
+      $qry2.= "ORDER BY vs.lastmodified DESC ";
+      $qry2.= "LIMIT $limit";
+      $bar= $dbh->selectall_arrayref($qry2,{Slice=>{}},@params);
+    }
+
+    return ( { bartotal => $bar? scalar @$bar: 0, pubtotal => $pub? scalar @$pub: 0}, $pub, $bar);
 }
 
 =head2 GetShelf
@@ -283,89 +261,93 @@ from C4::Circulation.
 sub GetShelfContents ($;$$$) {
     my ($shelfnumber, $row_count, $offset, $sortfield) = @_;
     my $dbh=C4::Context->dbh();
-       my $sth1 = $dbh->prepare("SELECT count(*) FROM virtualshelfcontents WHERE shelfnumber = ?");
-       $sth1->execute($shelfnumber);
-       my $total = $sth1->fetchrow;
-       if(!$sortfield) {
-               my $sth2 = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?');
-               $sth2->execute($shelfnumber);
-               ($sortfield) = $sth2->fetchrow_array;
-       }
+    my $sth1 = $dbh->prepare("SELECT count(*) FROM virtualshelfcontents WHERE shelfnumber = ?");
+    $sth1->execute($shelfnumber);
+    my $total = $sth1->fetchrow;
+    if(!$sortfield) {
+        my $sth2 = $dbh->prepare('SELECT sortfield FROM virtualshelves WHERE shelfnumber=?');
+        $sth2->execute($shelfnumber);
+        ($sortfield) = $sth2->fetchrow_array;
+    }
     my $query =
        " SELECT vc.biblionumber, vc.shelfnumber, vc.dateadded, itemtypes.*,
             biblio.*, biblioitems.itemtype, biblioitems.publicationyear as year, biblioitems.publishercode, biblioitems.place, biblioitems.size, biblioitems.pages
          FROM   virtualshelfcontents vc
-                LEFT JOIN biblio      ON      vc.biblionumber =      biblio.biblionumber
-                LEFT JOIN biblioitems ON  biblio.biblionumber = biblioitems.biblionumber
-                LEFT JOIN itemtypes   ON biblioitems.itemtype = itemtypes.itemtype
+         LEFT JOIN biblio      ON      vc.biblionumber =      biblio.biblionumber
+         LEFT JOIN biblioitems ON  biblio.biblionumber = biblioitems.biblionumber
+         LEFT JOIN itemtypes   ON biblioitems.itemtype = itemtypes.itemtype
          WHERE  vc.shelfnumber=? ";
-       my @params = ($shelfnumber);
-       if($sortfield) {
-               $query .= " ORDER BY " . $sortfield;
-               $query .= " DESC " if ($sortfield eq 'copyrightdate');
-       }
+    my @params = ($shelfnumber);
+    if($sortfield) {
+        $query .= " ORDER BY " . $sortfield;
+        $query .= " DESC " if ($sortfield eq 'copyrightdate');
+    }
     if($row_count){
-          $query .= " LIMIT ?, ? ";
-          push (@params, ($offset ? $offset : 0));
-          push (@params, $row_count);
+       $query .= " LIMIT ?, ? ";
+       push (@params, ($offset ? $offset : 0));
+       push (@params, $row_count);
     }
     my $sth3 = $dbh->prepare($query);
-       $sth3->execute(@params);
-       return ($sth3->fetchall_arrayref({}), $total);
-       # Like the perldoc says,
-       # returns reference-to-array, where each element is reference-to-hash of the row:
-       #   like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ] 
-       # Suitable for use in TMPL_LOOP.
-       # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
-       # or newer, for your version of DBI.
+    $sth3->execute(@params);
+    return ($sth3->fetchall_arrayref({}), $total);
+    # Like the perldoc says,
+    # returns reference-to-array, where each element is reference-to-hash of the row:
+    #   like [ $sth->fetchrow_hashref(), $sth->fetchrow_hashref() ... ]
+    # Suitable for use in TMPL_LOOP.
+    # See http://search.cpan.org/~timb/DBI-1.601/DBI.pm#fetchall_arrayref
+    # or newer, for your version of DBI.
 }
 
 =head2 AddShelf
 
-  $shelfnumber = &AddShelf( $shelfname, $owner, $category);
+  $shelfnumber = &AddShelf($hashref, $owner);
 
-Creates a new virtual virtualshelves with name C<$shelfname>, owner C<$owner> and category
-C<$category>.
+Creates a new virtual shelf. Params passed in a hash like ModShelf.
 
 Returns a code to know what's happen.
-    * -1 : if this virtualshelves already exist.
+    * -1 : if this virtualshelves already exists.
     * $shelfnumber : if success.
 
 =cut
 
 sub AddShelf {
-    my ( $shelfname, $owner, $category, $sortfield ) = @_;
-    my $query = qq(
-        SELECT *
-        FROM   virtualshelves
-        WHERE  shelfname=? AND owner=?
-    );
+    my ($hashref, $owner)= @_;
+
+    #initialize missing hash values to silence warnings
+    foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
+        $hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': '';
+    }
+
+    return -1 unless _CheckShelfName($hashref->{shelfname}, $hashref->{category}, $owner, 0);
+
+    my $query = qq(INSERT INTO virtualshelves
+        (shelfname,owner,category,sortfield,allow_add,allow_delete_own,allow_delete_other)
+        VALUES (?,?,?,?,?,?,?));
+
     my $sth = $dbh->prepare($query);
-    $sth->execute($shelfname,$owner);
-    ( $sth->rows ) and return (-1);
-    $query = qq(
-        INSERT INTO virtualshelves
-            (shelfname,owner,category,sortfield)
-        VALUES (?,?,?,?)
-    );
-    $sth = $dbh->prepare($query);
-    $sth->execute( $shelfname, $owner, $category, $sortfield );
+    $sth->execute(
+    $hashref->{shelfname},
+    $owner,
+    $hashref->{category},
+    $hashref->{sortfield},
+    $hashref->{allow_add}||0,
+    $hashref->{allow_delete_own}||1,
+    $hashref->{allow_delete_other}||0 );
     my $shelfnumber = $dbh->{'mysql_insertid'};
-    return ($shelfnumber);
+    return $shelfnumber;
 }
 
 =head2 AddToShelf
 
-  &AddToShelf($biblionumber, $shelfnumber);
+  &AddToShelf($biblionumber, $shelfnumber, $borrower);
 
 Adds bib number C<$biblionumber> to virtual virtualshelves number
 C<$shelfnumber>, unless that bib is already on that shelf.
 
 =cut
 
-#'
 sub AddToShelf {
-    my ( $biblionumber, $shelfnumber ) = @_;
+    my ($biblionumber, $shelfnumber, $borrowernumber) = @_;
     return unless $biblionumber;
     my $query = qq(
         SELECT *
@@ -376,68 +358,70 @@ sub AddToShelf {
 
     $sth->execute( $shelfnumber, $biblionumber );
     ($sth->rows) and return undef;     # already on shelf
-       $query = qq(
-               INSERT INTO virtualshelfcontents
-                       (shelfnumber, biblionumber, flags)
-               VALUES
-                       (?, ?, 0)
-       );
-       $sth = $dbh->prepare($query);
-       $sth->execute( $shelfnumber, $biblionumber );
-       $query = qq(UPDATE virtualshelves
-                               SET lastmodified = CURRENT_TIMESTAMP
-                               WHERE shelfnumber = ?);
-       $sth = $dbh->prepare($query);
-       $sth->execute( $shelfnumber );
+    $query = qq(
+        INSERT INTO virtualshelfcontents
+            (shelfnumber, biblionumber, flags, borrowernumber)
+        VALUES (?, ?, 0, ?));
+    $sth = $dbh->prepare($query);
+    $sth->execute( $shelfnumber, $biblionumber, $borrowernumber);
+    $query = qq(UPDATE virtualshelves
+                SET lastmodified = CURRENT_TIMESTAMP
+                WHERE shelfnumber = ?);
+    $sth = $dbh->prepare($query);
+    $sth->execute( $shelfnumber );
 }
 
 =head2 ModShelf
 
-ModShelf($shelfnumber, $hashref)
+my $result= ModShelf($shelfnumber, $hashref)
 
 Where $hashref->{column} = param
 
 Modify the value into virtualshelves table with values given 
 from hashref, which each key of the hashref should be
 the name of a column of virtualshelves.
+Fields like shelfnumber or owner cannot be changed.
+
+Returns 1 if the action seemed to be successful.
 
 =cut
 
 sub ModShelf {
-    my $shelfnumber = shift;
-    my $shelf = shift;
-
-    if (exists $shelf->{shelfnumber}) {
-        carp "Should not use ModShelf to change shelfnumber";
-        return;
-    }
-    unless (defined $shelfnumber and $shelfnumber =~ /^\d+$/) {
-        carp "Invalid shelfnumber passed to ModShelf: $shelfnumber";
-        return;
-    }
+    my ($shelfnumber,$hashref) = @_;
 
-       my $query = "UPDATE virtualshelves SET ";
-    my @bind_params = ();
-    my @set_clauses = ();
+    my $query= "SELECT * FROM virtualshelves WHERE shelfnumber=?";
+    my $sth = $dbh->prepare($query);
+    $sth->execute($shelfnumber);
+    my $oldrecord= $sth->fetchrow_hashref;
+    return 0 unless $oldrecord; #not found?
 
-       foreach my $column (keys %$shelf) {
-        push @set_clauses, "$column = ?";
-        push @bind_params, $shelf->{$column};
+    #initialize missing hash values to silence warnings
+    foreach('shelfname','category', 'sortfield', 'allow_add', 'allow_delete_own', 'allow_delete_other' ) {
+        $hashref->{$_}= exists $hashref->{$_}? $hashref->{$_}||'': '';
     }
 
-    if ($#set_clauses == -1) {
-        carp "No columns to update passed to ModShelf";
-        return;
+    #if name or category changes, the name should be tested
+    if($hashref->{shelfname} || $hashref->{category}) {
+        unless(_CheckShelfName(
+        $hashref->{shelfname}||$oldrecord->{shelfname},
+        $hashref->{category}||$oldrecord->{category},
+        $oldrecord->{owner}, $shelfnumber )) {
+        return 0; #name check failed
+        }
     }
-    $query .= join(", ", @set_clauses);
-
-    $query .= " WHERE shelfnumber = ? ";
-    push @bind_params, $shelfnumber;
 
-    $debug and warn "ModShelf query:\n $query\n",
-                       "ModShelf query args: ", join(',', @bind_params), "\n";
-       my $sth = $dbh->prepare($query);
-       $sth->execute( @bind_params );
+    #only the following fields from the hash may be changed
+    $query= "UPDATE virtualshelves SET shelfname=?, category=?, sortfield=?, allow_add=?, allow_delete_own=?, allow_delete_other=? WHERE shelfnumber=?";
+    $sth = $dbh->prepare($query);
+    $sth->execute(
+    $hashref->{shelfname}||$oldrecord->{shelfname},
+    $hashref->{category}||$oldrecord->{category},
+    $hashref->{sortfield}||$oldrecord->{sortfield},
+    $hashref->{allow_add}||$oldrecord->{allow_add},
+    $hashref->{allow_delete_own}||$oldrecord->{allow_delete_own},
+    $hashref->{allow_delete_other}||$oldrecord->{allow_delete_other},
+    $shelfnumber );
+    return $@? 0: 1;
 }
 
 =head2 ShelfPossibleAction
@@ -446,7 +430,11 @@ ShelfPossibleAction($loggedinuser, $shelfnumber, $action);
 
 C<$loggedinuser,$shelfnumber,$action>
 
-$action can be "view" or "manage".
+$action can be "view", "add", "delete", "manage", "new_public", "new_private".
+Note that add/delete here refers to adding/deleting entries from the list. Deleting the list itself falls under manage.
+new_public and new_private refers to creating a new public or private list.
+The distinction between deleting your own entries from the list or entries from
+others is made in DelFromShelf.
 
 Returns 1 if the user can do the $action in the $shelfnumber shelf.
 Returns 0 otherwise.
@@ -455,75 +443,117 @@ Returns 0 otherwise.
 
 sub ShelfPossibleAction {
     my ( $user, $shelfnumber, $action ) = @_;
-    my $query = qq(
-        SELECT owner,category
-        FROM   virtualshelves
-        WHERE  shelfnumber=?
-    );
+    $action= 'view' unless $action;
+    $user=0 unless $user;
+
+    if($action =~ /^new/) { #no shelfnumber needed
+        if($action eq 'new_private') {
+            return $user>0;
+        }
+        elsif($action eq 'new_public') {
+            return $user>0 && C4::Context->preference('OpacAllowPublicListCreation');
+        }
+        return 0;
+    }
+
+    return 0 unless defined($shelfnumber);
+
+    my $query = qq/
+        SELECT IFNULL(owner,0) AS owner, category, allow_add, allow_delete_own, allow_delete_other, IFNULL(sh.borrowernumber,0) AS borrowernumber
+        FROM virtualshelves vs
+        LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
+        AND sh.borrowernumber=?
+        WHERE vs.shelfnumber=?
+    /;
     my $sth = $dbh->prepare($query);
-    $sth->execute($shelfnumber);
-    my ( $owner, $category ) = $sth->fetchrow;
-    require C4::Members;
-       my $borrower = C4::Members::GetMemberDetails($user);
-       return 0 if not defined($user);
-       return 1 if ( $category >= 3);                                                  # open list
-    return 1 if (($category >= 2) and
-                               defined($action) and $action eq 'view');        # public list, anybody can view
-    return 1 if (($category >= 2) and defined($user) and ($borrower->{authflags}->{superlibrarian} || $user == 0));    # public list, superlibrarian can edit/delete
-    return 1 if (defined($user)  and $owner  eq $user );       # user owns this list.  Check last.
+    $sth->execute($user, $shelfnumber);
+    my $shelf= $sth->fetchrow_hashref;
+
+    return 0 unless $shelf && ($shelf->{category}==2 || $shelf->{owner}==$user || $shelf->{borrowernumber}==$user);
+    if($action eq 'view') {
+    #already handled in the above condition
+    return 1;
+    }
+    elsif($action eq 'add') {
+    return 0 if $user<=0; #should be logged in
+    return 1 if $shelf->{allow_add}==1 || $shelf->{owner}==$user;
+    #owner may always add
+    }
+    elsif($action eq 'delete') {
+        #this answer is just diplomatic: it says that you may be able to delete
+        #some items from that shelf
+        #it does not answer the question about a specific biblio
+        #DelFromShelf checks the situation per biblio
+    return 1 if $user>0 && ($shelf->{allow_delete_own}==1 || $shelf->{allow_delete_other}==1);
+    }
+    elsif($action eq 'manage') {
+    return 1 if $user && $shelf->{owner}==$user;
+    }
     return 0;
 }
 
 =head2 DelFromShelf
 
-  &DelFromShelf( $biblionumber, $shelfnumber);
+    $result= &DelFromShelf( $bibref, $shelfnumber, $user);
 
-Removes bib number C<$biblionumber> from virtual virtualshelves number
-C<$shelfnumber>. If the bib wasn't on that virtualshelves to begin with,
-nothing happens.
+Removes biblionumbers in passed arrayref from shelf C<$shelfnumber>.
+If the bib wasn't on that virtualshelves to begin with, nothing happens.
+
+Returns 0 if no items have been deleted.
 
 =cut
 
-#'
 sub DelFromShelf {
-    my ( $biblionumber, $shelfnumber ) = @_;
-    my $query = qq(
-        DELETE FROM virtualshelfcontents
-        WHERE  shelfnumber=? AND biblionumber=?
-    );
-    my $sth = $dbh->prepare($query);
-    $sth->execute( $shelfnumber, $biblionumber );
+    my ($bibref, $shelfnumber, $user) = @_;
+    my $query = qq(SELECT allow_delete_own, allow_delete_other FROM virtualshelves WHERE shelfnumber=?);
+    my $sth= $dbh->prepare($query);
+    $sth->execute($shelfnumber);
+    my ($del_own, $del_oth)= $sth->fetchrow;
+    my $r; my $t=0;
+
+    if($del_own) {
+        $query = qq(DELETE FROM virtualshelfcontents
+            WHERE shelfnumber=? AND biblionumber=? AND borrowernumber=?);
+        $sth= $dbh->prepare($query);
+    foreach my $biblionumber (@$bibref) {
+            $sth->execute($shelfnumber, $biblionumber, $user);
+        $r= $sth->rows; #Expect -1, 0 or 1 (-1 means Don't know; count as 1)
+        $t+= ($r==-1)? 1: $r;
+    }
+    }
+    if($del_oth) {
+        #includes a check if borrowernumber is null (deleted patron)
+        $query = qq/DELETE FROM virtualshelfcontents
+            WHERE shelfnumber=? AND biblionumber=? AND
+            (borrowernumber IS NULL OR borrowernumber<>?)/;
+        $sth= $dbh->prepare($query);
+    foreach my $biblionumber (@$bibref) {
+            $sth->execute($shelfnumber, $biblionumber, $user);
+        $r= $sth->rows;
+        $t+= ($r==-1)? 1: $r;
+    }
+    }
+    return $t;
 }
 
-=head2 DelShelf (old version)
-
-  ($status, $msg) = &DelShelf($shelfnumber);
-
-Deletes virtual virtualshelves number C<$shelfnumber>. The virtualshelves must
-be empty.
-
-Returns a two-element array, where C<$status> is 0 if the operation
-was successful, or non-zero otherwise. C<$msg> is "Done" in case of
-success, or an error message giving the reason for failure.
-
-=head2 DelShelf (current version)
+=head2 DelShelf
 
   $Number = DelShelf($shelfnumber);
 
 This function deletes the shelf number, and all of it's content.
+Authorization to do so MUST have been checked before calling, while using
+ShelfPossibleAction with manage parameter.
 
 =cut
 
 sub DelShelf {
-       unless (@_) {
-               carp "DelShelf called without valid argument (shelfnumber)";
-               return undef;
-       }
-       my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
-       return $sth->execute(shift);
+    my ($shelfnumber)= @_;
+    return unless $shelfnumber && $shelfnumber =~ /^\d+$/;
+    my $sth = $dbh->prepare("DELETE FROM virtualshelves WHERE shelfnumber=?");
+    return $sth->execute($shelfnumber);
 }
 
-=head2 GetBibShelves
+=head2 GetBibliosShelves
 
 This finds all the public lists that this bib record is in.
 
@@ -536,84 +566,131 @@ sub GetBibliosShelves {
         SELECT vs.shelfname, vs.shelfnumber 
         FROM virtualshelves vs 
         JOIN virtualshelfcontents vc ON (vs.shelfnumber= vc.shelfnumber) 
-        WHERE vs.category != 1 
+        WHERE vs.category=2
         AND vc.biblionumber= ?
     ');
     $sth->execute( $biblionumber );
     return $sth->fetchall_arrayref({});
 }
 
-=head2 RefreshShelvesSummary
+=head2 ShelvesMax
 
-       ($total, $pubshelves, $barshelves) = RefreshShelvesSummary($sessionID, $loggedinuser, $row_count);
+    $howmany= ShelvesMax($context);
 
-Updates the current session and userenv with the most recent shelves
+Tells how much shelves are shown in which context.
+POPUP refers to addbybiblionumber popup, MGRPAGE is managing page (in opac or
+staff), COMBO refers to the Add to-combo of search results. MASTHEAD is the
+main Koha toolbar with Lists button.
 
-Returns the total number of shelves stored in the session/userenv along with two references each to an
-array of hashes, one containing the C<$loggedinuser>'s private shelves and one containing all public/open shelves.
+=cut
 
-This function is used in conjunction with the 'Lists' button in masthead.inc.
+sub ShelvesMax {
+  my $which= shift;
+  return SHELVES_POPUP_MAX if $which eq 'POPUP';
+  return SHELVES_MGRPAGE_MAX if $which eq 'MGRPAGE';
+  return SHELVES_COMBO_MAX if $which eq 'COMBO';
+  return SHELVES_MASTHEAD_MAX if $which eq 'MASTHEAD';
+  return SHELVES_MASTHEAD_MAX;
+}
 
-=cut
+sub HandleDelBorrower {
+#when a member is deleted (DelMember in Members.pm), you should call me first
+#this routine deletes/moves lists and entries for the deleted member/borrower
+#you could just delete everything (and lose more than you want)
+#instead we now try to save all public/shared stuff and keep others happy
+    my ($borrower)= @_;
+    my $query;
+    my $dbh = C4::Context->dbh;
+
+    #Delete shares of this borrower (not lists !)
+    $query="DELETE FROM virtualshelfshares WHERE borrowernumber=?";
+    $dbh->do($query,undef,($borrower));
 
-sub RefreshShelvesSummary ($$$) {
-       require C4::Auth;
-       my ($sessionID, $loggedinuser, $row_count) = @_;
-       my $session = C4::Auth::get_session($sessionID);
-       my ($total, $totshelves, $barshelves, $pubshelves);
+    #Delete private lists without owner that now have no shares anymore
+    $query="DELETE vs.* FROM virtualshelves vs LEFT JOIN virtualshelfshares sh USING (shelfnumber) WHERE category=1 AND vs.owner IS NULL AND sh.shelfnumber IS NULL";
+    $dbh->do($query);
 
-       ($barshelves, $totshelves) = GetRecentShelves(1, $row_count, $loggedinuser);
-       $total->{'bartotal'} = $totshelves;
-       ($pubshelves, $totshelves) = GetRecentShelves(2, $row_count, undef);
-       $total->{'pubtotal'} = $totshelves;
+    #Change owner for private lists which have shares
+    $query="UPDATE virtualshelves LEFT JOIN virtualshelfshares sh USING (shelfnumber) SET owner=NULL where owner=? AND category=1 AND sh.borrowernumber IS NOT NULL";
+    $dbh->do($query,undef,($borrower));
 
-       # Update the current session with the latest shelves...
-       $session->param('barshelves', $barshelves);
-       $session->param('pubshelves', $pubshelves);
-       $session->param('totshelves', $total);
+    #Delete unshared private lists
+    $query="DELETE FROM virtualshelves WHERE owner=? AND category=1";
+    $dbh->do($query,undef,($borrower));
 
-       # likewise the userenv...
-       C4::Context->set_shelves_userenv('bar',$barshelves);
-       C4::Context->set_shelves_userenv('pub',$pubshelves);
-       C4::Context::set_shelves_userenv('tot',$total);
+    #Handle public lists owned by borrower
+    $query="UPDATE virtualshelves SET owner=NULL WHERE owner=? AND category=2";
+    $dbh->do($query,undef,($borrower));
 
-       return ($total, $pubshelves, $barshelves);
+    #Handle entries added by borrower to lists of others
+    $query="UPDATE virtualshelfcontents SET borrowernumber=NULL WHERE borrowernumber=?";
+    $dbh->do($query,undef,($borrower));
 }
 
 # internal subs
 
-sub _shelf_count ($$) {
-       my (@params) = @_;
-       # Find out how many shelves total meet the submitted criteria...
-       my $query = "SELECT count(*) FROM virtualshelves";
-       $query .= ($params[1] > 1) ? " WHERE category >= ?" : " WHERE  owner=? AND category=?";
-       shift @params if $params[1] > 1;
-       my $sth = $dbh->prepare($query);
-       $sth->execute(@params);
-       my $total = $sth->fetchrow;
-       return $total;
+sub _shelf_count {
+    my ($owner, $category) = @_;
+    my @params;
+    # Find out how many shelves total meet the submitted criteria...
+
+    my $query = "SELECT count(*) FROM virtualshelves vs ";
+    if($category==1) {
+        $query.= qq{
+            LEFT JOIN virtualshelfshares sh ON sh.shelfnumber=vs.shelfnumber
+            AND sh.borrowernumber=?
+        WHERE category=1 AND (vs.owner=? OR sh.borrowernumber=?) };
+        @params= ($owner, $owner, $owner);
+    }
+    else {
+    $query.='WHERE category=2';
+        @params= ();
+    }
+    my $sth = $dbh->prepare($query);
+    $sth->execute(@params);
+    my ($total)= $sth->fetchrow;
+    return $total;
 }
 
-sub _biblionumber_sth {
+sub _biblionumber_sth { #only used in obsolete sub below
     my ($shelf) = @_;
     my $query = 'select biblionumber from virtualshelfcontents where shelfnumber = ?';
     my $dbh = C4::Context->dbh;
     my $sth = $dbh->prepare($query)
-       or die $dbh->errstr;
+    or die $dbh->errstr;
     $sth->execute( $shelf )
-       or die $sth->errstr;
+    or die $sth->errstr;
     $sth;
 }
 
-sub each_biblionumbers (&$) {
+sub each_biblionumbers (&$) { #OBSOLETE
     my ($code,$shelf) = @_;
     my $ref =  _biblionumber_sth($shelf)->fetchall_arrayref;
     map {
-       $_=$$_[0];
-       $code->();
+    $_=$$_[0];
+    $code->();
     } @$ref;
 }
 
+sub _CheckShelfName {
+    my ($name, $cat, $owner, $number)= @_;
+
+    my $query = qq(
+        SELECT DISTINCT shelfnumber
+        FROM   virtualshelves
+    LEFT JOIN virtualshelfshares sh USING (shelfnumber)
+        WHERE  shelfname=? AND shelfnumber<>?);
+    if($cat==1) {
+        $query.= ' AND (sh.borrowernumber=? OR owner=?) AND category=1';
+    }
+    else {
+        $query.= ' AND category=2';
+    }
+    my $sth = $dbh->prepare($query);
+    $sth->execute($cat==1? ($name, $number, $owner, $owner): ($name, $number));
+    return $sth->rows>0? 0: 1;
+}
+
 1;
 
 __END__
index 1727389..125a1e6 100644 (file)
@@ -22,8 +22,12 @@ package C4::VirtualShelves::Page;
 
 use strict;
 use warnings;
+
 use CGI;
-use C4::VirtualShelves qw/:DEFAULT RefreshShelvesSummary/;
+use Exporter;
+use Data::Dumper;
+
+use C4::VirtualShelves qw/:DEFAULT ShelvesMax/;
 use C4::Biblio;
 use C4::Items;
 use C4::Koha;
@@ -32,11 +36,11 @@ use C4::Members;
 use C4::Output;
 use C4::Dates qw/format_date/;
 use C4::Tags qw(get_tags);
-use Exporter;
-use Data::Dumper;
 use C4::Csv;
 use C4::XSLT;
 
+use constant VIRTUALSHELVES_COUNT => 20;
+
 use vars qw($debug @EXPORT @ISA $VERSION);
 
 BEGIN {
@@ -51,12 +55,15 @@ our %pages = (
     opac     => { redirect => '/cgi-bin/koha/opac-shelves.pl', },
 );
 
-sub shelfpage ($$$$$) {
+sub shelfpage {
     my ( $type, $query, $template, $loggedinuser, $cookie ) = @_;
     ( $pages{$type} ) or $type = 'opac';
     $query            or die "No query";
     $template         or die "No template";
-    $template->param(  loggedinuser => $loggedinuser  );
+    $template->param(
+    loggedinuser => $loggedinuser,
+    OpacAllowPublicListCreation => C4::Context->preference('OpacAllowPublicListCreation'),
+    );
     my $edit;
     my $shelves;
     my @paramsloop;
@@ -77,7 +84,7 @@ sub shelfpage ($$$$$) {
     }
 
     $shelflimit = ( $type eq 'opac' ? C4::Context->preference('OPACnumSearchResults') : C4::Context->preference('numSearchResults') );
-    $shelflimit = $shelflimit || 20;
+    $shelflimit = $shelflimit || ShelvesMax('MGRPAGE');
     $shelfoffset   = ( $itemoff - 1 ) * $shelflimit;     # Sets the offset to begin retrieving items at
     $shelveslimit  = $shelflimit;                        # Limits number of shelves returned for a given query (row_count)
     $shelvesoffset = ( $shelfoff - 1 ) * $shelflimit;    # Sets the offset to begin retrieving shelves at (offset)
@@ -92,36 +99,51 @@ sub shelfpage ($$$$$) {
     }
     my $op = $query->param('op');
 
-    #    my $imgdir = getitemtypeimagesrc();
-    #    my $itemtypes = GetItemTypes();
-
     # the format of this is unindented for ease of diff comparison to the old script
     # Note: do not mistake the assignment statements below for comparisons!
     if ( $query->param('modifyshelfcontents') ) {
         my ( $shelfnumber, $barcode, $item, $biblio );
         if ( $shelfnumber = $query->param('viewshelf') ) {
-            if ( ShelfPossibleAction( $loggedinuser, $shelfnumber, 'manage' ) ) {
-                if ( $barcode = $query->param('addbarcode') ) {
-                    $item = GetItem( 0, $barcode );
-                    if (defined $item && $item->{'itemnumber'}){
+            #add to shelf
+            if($barcode = $query->param('addbarcode') ) {
+                if(ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add')) {
+                    $item = GetItem( 0, $barcode);
+                    if (defined $item && $item->{'itemnumber'}) {
                         $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'} );
-                        AddToShelf( $biblio->{'biblionumber'}, $shelfnumber )
+                        AddToShelf( $biblio->{'biblionumber'}, $shelfnumber, $loggedinuser)
                           or push @paramsloop, { duplicatebiblio => $barcode };
-                    } else {
+                    }
+                    else {
                         push @paramsloop, { failgetitem => $barcode };
                     }
-                } else {
-                    ( grep { /REM-(\d+)/ } $query->param ) or push @paramsloop, { nobarcode => 1 };
-                    foreach ( $query->param ) {
+                }
+                else {
+                    push @paramsloop, { nopermission => $shelfnumber };
+                }
+            }
+            elsif(grep { /REM-(\d+)/ } $query->param) {
+            #remove item(s) from shelf
+                if(ShelfPossibleAction($loggedinuser, $shelfnumber, 'delete')) {
+                #This is just a general okay; DelFromShelf checks further
+                    my @bib;
+                    foreach($query->param) {
                         /REM-(\d+)/ or next;
-                        $debug and warn "SHELVES: user $loggedinuser removing item $1 from shelf $shelfnumber";
-                        DelFromShelf( $1, $shelfnumber );    # $1 is biblionumber
+                        push @bib, $1; #$1 is biblionumber
+                    }
+                    my $t= DelFromShelf(\@bib, $shelfnumber, $loggedinuser);
+                    if($t==0) {
+                        push @paramsloop, {nothingdeleted => $shelfnumber};
+                    }
+                    elsif($t<@bib) {
+                        push @paramsloop, {somedeleted => $shelfnumber};
                     }
                 }
-            } else {
-                push @paramsloop, { nopermission => $shelfnumber };
+                else {
+                    push @paramsloop, { nopermission => $shelfnumber };
+                }
             }
-        } else {
+        }
+        else {
             push @paramsloop, { noshelfnumber => 1 };
         }
     }
@@ -156,18 +178,24 @@ sub shelfpage ($$$$$) {
 
   SWITCH: {
         if ($op) {
-            unless ($okmanage) {
-                push @paramsloop, { nopermission => $shelfnumber };
-                last SWITCH;
-            }
+        #Saving modified shelf
             if ( $op eq 'modifsave' ) {
+                unless ($okmanage) {
+                        push @paramsloop, { nopermission => $shelfnumber };
+                        last SWITCH;
+                }
                 my $shelf = {
                     'shelfname' => $query->param('shelfname'),
-                    'category'  => $query->param('category'),
                     'sortfield' => $query->param('sortfield'),
                 };
+                if($query->param('category')) { #optional
+                    $shelf->{category}= $query->param('category');
+                }
+                unless(ModShelf($shelfnumber, $shelf )) {
+                  push @paramsloop, {modifyfailure => $shelf->{shelfname}};
+                  last SWITCH;
+                }
 
-                ModShelf( $shelfnumber, $shelf );
                 if($displaymode eq "viewshelf"){
                     print $query->redirect( $pages{$type}->{redirect} . "?viewshelf=$shelfnumber" );
                 } elsif($displaymode eq "publicshelves"){
@@ -176,12 +204,14 @@ sub shelfpage ($$$$$) {
                     print $query->redirect( $pages{$type}->{redirect} . "?display=privateshelves" );
                 }
                 exit;
-
-            } elsif ( $op eq 'modif' ) {
+            }
+        #Editing a shelf
+        elsif ( $op eq 'modif' ) {
                 my ( $shelfnumber2, $shelfname, $owner, $category, $sortfield ) = GetShelf($shelfnumber);
                 my $member = GetMember( 'borrowernumber' => $owner );
                 my $ownername = defined($member) ? $member->{firstname} . " " . $member->{surname} : '';
                 $edit = 1;
+                $sortfield='' unless $sortfield;
                 $template->param(
                     edit                => 1,
                     display             => $displaymode,
@@ -196,6 +226,8 @@ sub shelfpage ($$$$$) {
             }
             last SWITCH;
         }
+
+        #View a shelf
         if ( $shelfnumber = $query->param('viewshelf') ) {
             # explicitly fetch this shelf
             my ($shelfnumber2,$shelfname,$owner,$category,$sorton) = GetShelf($shelfnumber);
@@ -267,21 +299,31 @@ sub shelfpage ($$$$$) {
                     authorsort          => $authorsort,
                     yearsort            => $yearsort,
                     manageshelf         => $manageshelf,
+                    allowremovingitems  => ShelfPossibleAction( $loggedinuser, $shelfnumber, 'delete'),
+                    allowaddingitem     => ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add'),
                     "category$category" => 1,
                     category            => $category,
                     itemsloop           => $items,
+                    showprivateshelves  => $category==1,
                 );
             } else {
                 push @paramsloop, { nopermission => $shelfnumber };
             }
             last SWITCH;
         }
+
         if ( $query->param('shelves') ) {
             my $stay = 1;
+
+        #Add a shelf
             if ( my $newshelf = $query->param('addshelf') ) {
 
                 # note: a user can always add a new shelf
-                my $shelfnumber = AddShelf( $newshelf, $query->param('owner'), $query->param('category'), $query->param('sortfield') );
+                my $shelfnumber = AddShelf( {
+                    shelfname => $newshelf,
+                    sortfield => $query->param('sortfield'),
+                    category => $query->param('category') },
+                    $query->param('owner') );
                 $stay = 1;
                 if ( $shelfnumber == -1 ) {    #shelf already exists.
                     $showadd = 1;
@@ -292,6 +334,8 @@ sub shelfpage ($$$$$) {
                     exit;
                 }
             }
+
+        #Deleting a shelf (asking for confirmation if it has entries)
             foreach ( $query->param() ) {
                 /DEL-(\d+)/ or next;
                 $delflag = 1;
@@ -333,7 +377,6 @@ sub shelfpage ($$$$$) {
                 }
                 push( @paramsloop, { delete_ok => $name } );
 
-                # print $query->redirect($pages{$type}->{redirect}); exit;
                 $stay = 0;
             }
             $showadd = 1;
@@ -343,7 +386,7 @@ sub shelfpage ($$$$$) {
             }
             last SWITCH;
         }
-    }
+    } # end of SWITCH block
 
     (@paramsloop) and $template->param( paramsloop => \@paramsloop );
     $showadd      and $template->param( showadd    => 1 );
@@ -357,7 +400,7 @@ sub shelfpage ($$$$$) {
         my %line;
         $shelflist->{$element}->{shelf} = $element;
         my $category  = $shelflist->{$element}->{'category'};
-        my $owner     = $shelflist->{$element}->{'owner'};
+        my $owner     = $shelflist->{$element}->{'owner'}||0;
         my $canmanage = ShelfPossibleAction( $loggedinuser, $element, 'manage' );
         my $sortfield = $shelflist->{$element}->{'sortfield'};
         if ( $sortfield ){
@@ -369,7 +412,7 @@ sub shelfpage ($$$$$) {
         }
         $shelflist->{$element}->{"viewcategory$category"} = 1;
         $shelflist->{$element}->{manageshelf} = $canmanage;
-        if ( $owner eq $loggedinuser or $canmanage ) {
+        if($canmanage || ($loggedinuser && $owner==$loggedinuser)) {
             $shelflist->{$element}->{'mine'} = 1;
         }
         my $member = GetMember( 'borrowernumber' => $owner );
@@ -413,28 +456,15 @@ sub shelfpage ($$$$$) {
         $template->param( seflag => 1 );
     }
 
-    #FIXME: This refresh really only needs to happen when there is a modification of some sort
-    #       to the shelves, but the above code is so convoluted in its handling of the various
-    #       options, it is easier to do this refresh every time C4::VirtualShelves::Page.pm is
-    #       called
-
-    my ( $total, $pubshelves, $barshelves ) = RefreshShelvesSummary( $query->cookie("CGISESSID"), $loggedinuser, ( $loggedinuser == -1 ? 20 : 10 ) );
-
-    if ( defined $barshelves ) {
-        $template->param(
-            barshelves     => scalar( @{ $barshelves } ),
+#Next call updates the shelves for the Lists button.
+#May not always be needed (when nothing changed), but doesn't take much.
+    my ($total, $pubshelves, $barshelves) = C4::VirtualShelves::GetSomeShelfNames($loggedinuser, 'MASTHEAD');
+    $template->param(
+            barshelves     => $total->{bartotal},
             barshelvesloop => $barshelves,
-        );
-        $template->param( bartotal => $total->{'bartotal'}, ) if ( $total->{'bartotal'} > scalar( @{ $barshelves } ) );
-    }
-
-    if ( defined $pubshelves ) {
-        $template->param(
-            pubshelves     => scalar( @{ $pubshelves } ),
+            pubshelves     => $total->{pubtotal},
             pubshelvesloop => $pubshelves,
-        );
-        $template->param( pubtotal => $total->{'pubtotal'}, ) if ( $total->{'pubtotal'} > scalar( @{ $pubshelves } ) );
-    }
+    );
 
     output_html_with_http_headers $query, $cookie, $template->output;
 }
diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm
new file mode 100644 (file)
index 0000000..1e7299c
--- /dev/null
@@ -0,0 +1,300 @@
+package Koha::Calendar;
+use strict;
+use warnings;
+use 5.010;
+
+use DateTime;
+use DateTime::Set;
+use DateTime::Duration;
+use C4::Context;
+use Carp;
+use Readonly;
+
+sub new {
+    my ( $classname, %options ) = @_;
+    my $self = {};
+    bless $self, $classname;
+    for my $o_name ( keys %options ) {
+        my $o = lc $o_name;
+        $self->{$o} = $options{$o_name};
+    }
+    if ( exists $options{TEST_MODE} ) {
+        $self->_mockinit();
+        return $self;
+    }
+    if ( !defined $self->{branchcode} ) {
+        croak 'No branchcode argument passed to Koha::Calendar->new';
+    }
+    $self->_init();
+    return $self;
+}
+
+sub _init {
+    my $self       = shift;
+    my $branch     = $self->{branchcode};
+    my $dbh        = C4::Context->dbh();
+    my $repeat_sth = $dbh->prepare(
+'SELECT * from repeatable_holidays WHERE branchcode = ? AND ISNULL(weekday) = ?'
+    );
+    $repeat_sth->execute( $branch, 0 );
+    $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ];
+    Readonly::Scalar my $sunday => 7;
+    while ( my $tuple = $repeat_sth->fetchrow_hashref ) {
+        $self->{weekly_closed_days}->[ $tuple->{weekday} ] = 1;
+    }
+    $repeat_sth->execute( $branch, 1 );
+    $self->{day_month_closed_days} = {};
+    while ( my $tuple = $repeat_sth->fetchrow_hashref ) {
+        $self->{day_month_closed_days}->{ $tuple->{day} }->{ $tuple->{month} } =
+          1;
+    }
+    my $special = $dbh->prepare(
+'SELECT day, month, year, title, description FROM special_holidays WHERE ( branchcode = ? ) AND (isexception = ?)'
+    );
+    $special->execute( $branch, 1 );
+    my $dates = [];
+    while ( my ( $day, $month, $year, $title, $description ) =
+        $special->fetchrow ) {
+        push @{$dates},
+          DateTime->new(
+            day       => $day,
+            month     => $month,
+            year      => $year,
+            time_zone => C4::Context->tz()
+          )->truncate( to => 'day' );
+    }
+    $self->{exception_holidays} =
+      DateTime::Set->from_datetimes( dates => $dates );
+    $special->execute( $branch, 1 );
+    $dates = [];
+    while ( my ( $day, $month, $year, $title, $description ) =
+        $special->fetchrow ) {
+        push @{$dates},
+          DateTime->new(
+            day       => $day,
+            month     => $month,
+            year      => $year,
+            time_zone => C4::Context->tz()
+          )->truncate( to => 'day' );
+    }
+    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
+    $self->{days_mode} = C4::Context->preference('useDaysMode');
+    return;
+}
+
+sub addDate {
+    my ( $self, $startdate, $add_duration, $unit ) = @_;
+    my $base_date = $startdate->clone();
+    if ( ref $add_duration ne 'DateTime::Duration' ) {
+        $add_duration = DateTime::Duration->new( days => $add_duration );
+    }
+    $unit ||= q{};    # default days ?
+    my $days_mode = $self->{days_mode};
+    Readonly::Scalar my $return_by_hour => 10;
+    my $day_dur = DateTime::Duration->new( days => 1 );
+    if ( $add_duration->is_negative() ) {
+        $day_dur->inverse();
+    }
+    if ( $days_mode eq 'Datedue' ) {
+
+        my $dt = $base_date + $add_duration;
+        while ( $self->is_holiday($dt) ) {
+
+            # TODOP if hours set to 10 am
+            $dt->add_duration($day_dur);
+            if ( $unit eq 'hours' ) {
+                $dt->set_hour($return_by_hour);    # Staffs specific
+            }
+        }
+        return $dt;
+    } elsif ( $days_mode eq 'Calendar' ) {
+        if ( $unit eq 'hours' ) {
+            $base_date->add_duration($add_duration);
+            while ( $self->is_holiday($base_date) ) {
+                $base_date->add_duration($day_dur);
+
+            }
+
+        } else {
+            my $days = abs $add_duration->in_units('days');
+            while ($days) {
+                $base_date->add_duration($day_dur);
+                if ( $self->is_holiday($base_date) ) {
+                    next;
+                } else {
+                    --$days;
+                }
+            }
+        }
+        if ( $unit eq 'hours' ) {
+            my $dt = $base_date->clone()->subtract( days => 1 );
+            if ( $self->is_holiday($dt) ) {
+                $base_date->set_hour($return_by_hour);    # Staffs specific
+            }
+        }
+        return $base_date;
+    } else {    # Days
+        return $base_date + $add_duration;
+    }
+}
+
+sub is_holiday {
+    my ( $self, $dt ) = @_;
+    my $dow = $dt->day_of_week;
+    if ( $dow == 7 ) {
+        $dow = 0;
+    }
+    if ( $self->{weekly_closed_days}->[$dow] == 1 ) {
+        return 1;
+    }
+    $dt->truncate( to => 'days' );
+    my $day   = $dt->day;
+    my $month = $dt->month;
+    if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) {
+        return 1;
+    }
+    if ( $self->{exception_holidays}->contains($dt) ) {
+        return 1;
+    }
+    if ( $self->{single_holidays}->contains($dt) ) {
+        return 1;
+    }
+
+    # damn have to go to work after all
+    return 0;
+}
+
+sub days_between {
+    my $self     = shift;
+    my $start_dt = shift;
+    my $end_dt   = shift;
+    $start_dt->truncate( to => 'hours' );
+    $end_dt->truncate( to => 'hours' );
+
+    # start and end should not be closed days
+    my $duration = $end_dt - $start_dt;
+    $start_dt->truncate( to => 'days' );
+    $end_dt->truncate( to => 'days' );
+    while ( DateTime->compare( $start_dt, $end_dt ) == -1 ) {
+        $start_dt->add( days => 1 );
+        if ( $self->is_holiday($start_dt) ) {
+            $duration->subtract( days => 1 );
+        }
+    }
+    return $duration;
+
+}
+
+sub _mockinit {
+    my $self = shift;
+    $self->{weekly_closed_days} = [ 1, 0, 0, 0, 0, 0, 0 ];    # Sunday only
+    $self->{day_month_closed_days} = { 6 => { 16 => 1, } };
+    my $dates = [];
+    $self->{exception_holidays} =
+      DateTime::Set->from_datetimes( dates => $dates );
+    my $special = DateTime->new(
+        year      => 2011,
+        month     => 6,
+        day       => 1,
+        time_zone => 'Europe/London',
+    );
+    push @{$dates}, $special;
+    $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates );
+    $self->{days_mode} = 'Calendar';
+    return;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Koha::Calendar - Object containing a branches calendar
+
+=head1 VERSION
+
+This documentation refers to Koha::Calendar version 0.0.1
+
+=head1 SYNOPSIS
+
+  use Koha::Calendat
+
+  my $c = Koha::Calender->new( branchcode => 'MAIN' );
+  my $dt = DateTime->now();
+
+  # are we open
+  $open = $c->is_holiday($dt);
+  # when will item be due if loan period = $dur (a DateTime::Duration object)
+  $duedate = $c->addDate($dt,$dur,'days');
+
+
+=head1 DESCRIPTION
+
+  Implements those features of C4::Calendar needed for Staffs Rolling Loans
+
+=head1 METHODS
+
+=head2 new : Create a calendar object
+
+my $calendar = Koha::Calendar->new( branchcode => 'MAIN' );
+
+The option branchcode is required
+
+
+=head2 addDate
+
+    my $dt = $calendar->addDate($date, $dur, $unit)
+
+C<$date> is a DateTime object representing the starting date of the interval.
+
+C<$offset> is a DateTime::Duration to add to it
+
+C<$unit> is a string value 'days' or 'hours' toflag granularity of duration
+
+Currently unit is only used to invoke Staffs return Monday at 10 am rule this
+parameter will be removed when issuingrules properly cope with that
+
+
+=head2 is_holiday
+
+$yesno = $calendar->is_holiday($dt);
+
+passed at DateTime object returns 1 if it is a closed day
+0 if not according to the calendar
+
+=head2 days_between
+
+$duration = $calendar->days_between($start_dt, $end_dt);
+
+Passed two dates returns a DateTime::Duration object measuring the length between them
+ignoring closed days
+
+=head1 DIAGNOSTICS
+
+Will croak if not passed a branchcode in new
+
+=head1 BUGS AND LIMITATIONS
+
+This only contains a limited subset of the functionality in C4::Calendar
+Only enough to support Staffs Rolling loans
+
+=head1 AUTHOR
+
+Colin Campbell colin.campbell@ptfs-europe.com
+
+=head1 LICENSE AND COPYRIGHT
+
+Copyright (c) 2011 PTFS-Europe Ltd All rights reserved
+
+This program 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.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm
new file mode 100644 (file)
index 0000000..e2e92bd
--- /dev/null
@@ -0,0 +1,187 @@
+package Koha::DateUtils;
+
+# Copyright (c) 2011 PTFS-Europe Ltd.
+# 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.
+#
+# 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., 59 Temple Place,
+# Suite 330, Boston, MA  02111-1307 USA
+
+use strict;
+use warnings;
+use 5.010;
+use DateTime;
+use DateTime::Format::DateParse;
+use C4::Context;
+
+use base 'Exporter';
+use version; our $VERSION = qv('1.0.0');
+
+our @EXPORT = (
+    qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime)
+);
+
+=head1 DateUtils
+
+Koha::DateUtils - Transitional wrappers to ease use of DateTime
+
+=head1 DESCRIPTION
+
+Koha has historically only used dates not datetimes and been content to
+handle these as strings. It also has confused formatting with actual dates
+this is a temporary module for wrappers to hide the complexity of switch to DateTime
+
+=cut
+
+=head2 dt_ftom_string
+
+$dt = dt_from_string($date_string, [$format, $timezone ]);
+
+Passed a date string returns a DateTime object format and timezone default
+to the system preferences. If the date string is empty DateTime->now is returned
+
+=cut
+
+sub dt_from_string {
+    my ( $date_string, $date_format, $tz ) = @_;
+    if ( !$tz ) {
+        $tz = C4::Context->tz;
+    }
+    if ( !$date_format ) {
+        $date_format = C4::Context->preference('dateformat');
+    }
+    if ($date_string) {
+        if ( ref($date_string) eq 'DateTime' ) {    # already a dt return it
+            return $date_string;
+        }
+
+        if ( $date_format eq 'metric' ) {
+            $date_string =~ s#-#/#g;
+            $date_string =~ s/^00/01/;    # system allows the 0th of the month
+            $date_string =~ s#^(\d{1,2})/(\d{1,2})#$2/$1#;
+        } else {
+            if ( $date_format eq 'iso' ) {
+                $date_string =~ s/-00/-01/;
+                if ( $date_string =~ m/^0000-0/ ) {
+                    return;               # invalid date in db
+                }
+            } elsif ( $date_format eq 'us' ) {
+                $date_string =~ s#-#/#g;
+                $date_string =~ s[/00/][/01/];
+            } elsif ( $date_format eq 'sql' ) {
+                $date_string =~
+s/(\d{4})(\d{2})(\d{2})\s+(\d{2})(\d{2})(\d{2})/$1-$2-$3T$4:$5:$6/;
+                $date_string =~ s/00T/01T/;
+            }
+        }
+        return DateTime::Format::DateParse->parse_datetime( $date_string,
+            $tz->name() );
+    }
+    return DateTime->now( time_zone => $tz );
+
+}
+
+=head2 output_pref
+
+$date_string = output_pref($dt, [$format] );
+
+Returns a string containing the time & date formatted as per the C4::Context setting
+
+A second parameter allows overriding of the syspref value. This is for testing only
+In usage use the DateTime objects own methods for non standard formatting
+
+=cut
+
+sub output_pref {
+    my $dt         = shift;
+    my $force_pref = shift;    # if testing we want to override Context
+    my $pref =
+      defined $force_pref ? $force_pref : C4::Context->preference('dateformat');
+    given ($pref) {
+        when (/^iso/) {
+            return $dt->strftime('%Y-%m-%d %H:%M');
+        }
+        when (/^metric/) {
+            return $dt->strftime('%d/%m/%Y %H:%M');
+        }
+        when (/^us/) {
+            return $dt->strftime('%m/%d/%Y %H:%M');
+        }
+        default {
+            return $dt->strftime('%Y-%m-%d %H:%M');
+        }
+
+    }
+    return;
+}
+
+=head2 output_pref_due
+
+$date_string = output_pref_due($dt, [$format] );
+
+Returns a string containing the time & date formatted as per the C4::Context setting
+
+A second parameter allows overriding of the syspref value. This is for testing only
+In usage use the DateTime objects own methods for non standard formatting
+
+This is effectivelyt a wrapper around output_pref for due dates
+the time portion is stripped if it is '23:59'
+
+=cut
+
+sub output_pref_due {
+    my $disp_str = output_pref(@_);
+    $disp_str =~ s/ 23:59//;
+    return $disp_str;
+}
+
+=head2 format_sqldatetime
+
+$string = format_sqldatetime( $string_as_returned_from_db );
+
+a convenience routine for calling dt_from_string and formatting the result
+with output_pref as it is a frequent activity in scripts
+
+=cut
+
+sub format_sqldatetime {
+    my $str        = shift;
+    my $force_pref = shift;    # if testing we want to override Context
+    if ( defined $str && $str =~ m/^\d{4}-\d{2}-\d{2}/ ) {
+        my $dt = dt_from_string( $str, 'sql' );
+        $dt->truncate( to => 'minutes' );
+        return output_pref( $dt, $force_pref );
+    }
+    return q{};
+}
+
+=head2 format_sqlduedatetime
+
+$string = format_sqldatetime( $string_as_returned_from_db );
+
+a convenience routine for calling dt_from_string and formatting the result
+with output_pref_due as it is a frequent activity in scripts
+
+=cut
+
+sub format_sqlduedatetime {
+    my $str        = shift;
+    my $force_pref = shift;    # if testing we want to override Context
+    if ( defined $str && $str =~ m/^\d{4}-\d{2}-\d{2}/ ) {
+        my $dt = dt_from_string( $str, 'sql' );
+        $dt->truncate( to => 'minutes' );
+        return output_pref_due( $dt, $force_pref );
+    }
+    return q{};
+}
+
+1;
index 749f6e2..6a4a882 100644 (file)
@@ -19,6 +19,8 @@ package Koha::Template::Plugin::KohaDates;
 
 use Template::Plugin::Filter;
 use base qw( Template::Plugin::Filter );
+use warnings;
+use strict;
 
 use C4::Dates;
 
index 660d633..8d9c0e3 100755 (executable)
@@ -41,7 +41,6 @@ use C4::Koha;
 use C4::Budgets;
 use C4::Acquisition;
 use C4::Bookseller qw/GetBookSellerFromId/;
-use C4::Dates;
 use C4::Suggestions;    # GetSuggestion
 use C4::Branch;         # GetBranches
 use C4::Members;
@@ -343,11 +342,13 @@ sub import_batches_list {
             # check if there is at least 1 line still staged
             my $stagedList=GetImportBibliosRange($batch->{'import_batch_id'}, undef, undef, 'staged');
             if (scalar @$stagedList) {
+                my ($staged_date, $staged_hour) = split (/ /, $batch->{'upload_timestamp'});
                 push @list, {
                         import_batch_id => $batch->{'import_batch_id'},
                         num_biblios => $batch->{'num_biblios'},
                         num_items => $batch->{'num_items'},
-                        upload_timestamp => $batch->{'upload_timestamp'},
+                        staged_date => $staged_date,
+                        staged_hour => $staged_hour,
                         import_status => $batch->{'import_status'},
                         file_name => $batch->{'file_name'},
                         comments => $batch->{'comments'},
index d2e1856..3300cea 100755 (executable)
@@ -60,7 +60,7 @@ use C4::Members qw/GetMember/;
 
 my $input=new CGI;
 
-my ($template, $loggedinuser, $cookie)
+our ($template, $loggedinuser, $cookie)
     = get_template_and_user({template_name => "acqui/basketgroup.tmpl",
                             query => $input,
                             type => "intranet",
index ac3c557..5a1c248 100755 (executable)
@@ -56,7 +56,7 @@ use C4::Biblio;
 use C4::Output;
 use CGI;
 
-use C4::Dates qw/format_date/;
+use C4::Acquisition qw/ GetBasketsInfosByBookseller /;
 use C4::Bookseller qw/ GetBookSellerFromId GetBookSeller /;
 use C4::Members qw/GetMember/;
 use C4::Context;
@@ -105,25 +105,32 @@ my $userbranch = $userenv->{branch};
 my $loop_suppliers = [];
 
 for my $vendor (@suppliers) {
-    my $baskets = get_vendors_baskets( $vendor->{id} );
+    my $baskets = GetBasketsInfosByBookseller( $vendor->{id} );
 
     my $loop_basket = [];
-    
+
     for my $basket ( @{$baskets} ) {
         my $authorisedby = $basket->{authorisedby};
-        
+        my $basketbranch = ''; # set a blank branch to start with
+        my $member = GetMember( borrowernumber => $authorisedby );
+        if ( $member ) {
+           $basketbranch = $member->{branchcode};
+        }
+
         if ($userenv->{'flags'} & 1 || #user is superlibrarian
                (haspermission( $uid, { acquisition => q{*} } ) && #user has acq permissions and
                    ($viewbaskets eq 'all' || #user is allowed to see all baskets
-                   ($viewbaskets eq 'branch' && $authorisedby && $userbranch eq GetMember( borrowernumber => $authorisedby )->{branchcode}) || #basket belongs to user's branch
-                   ($basket->{authorisedby} &&  $viewbaskets == 'user' && $authorisedby == $loggedinuser) #user created this basket
+                   ($viewbaskets eq 'branch' && $authorisedby && $userbranch eq $basketbranch) || #basket belongs to user's branch
+                   ($basket->{authorisedby} &&  $viewbaskets eq 'user' && $authorisedby == $loggedinuser) #user created this basket
                    ) 
                 ) 
            ) { 
-            for my $date_field (qw( creationdate closedate)) {
-                if ( $basket->{$date_field} ) {
-                    $basket->{$date_field} = format_date( $basket->{$date_field} );
-                }
+            foreach (qw(total_items total_biblios expected_items)) {
+                $basket->{$_} ||= 0;
+            }
+            if($member) {
+                $basket->{authorisedby_firstname} = $member->{firstname};
+                $basket->{authorisedby_surname} = $member->{surname};
             }
             push @{$loop_basket}, $basket; 
         }
@@ -141,21 +148,7 @@ $template->param(
     loop_suppliers => $loop_suppliers,
     supplier       => ( $booksellerid || $supplier ),
     count          => $supplier_count,
+    dateformat     => C4::Context->preference('dateformat'),
 );
 
 output_html_with_http_headers $query, $cookie, $template->output;
-
-sub get_vendors_baskets {
-    my $supplier_id = shift;
-    my $dbh         = C4::Context->dbh;
-    my $sql         = <<'ENDSQL';
-select aqbasket.*, count(*) as total,  borrowers.firstname, borrowers.surname
-from aqbasket left join aqorders on aqorders.basketno = aqbasket.basketno
-left join borrowers on aqbasket.authorisedby = borrowers.borrowernumber
-where booksellerid = ?
-AND ( aqorders.quantity > aqorders.quantityreceived OR quantityreceived IS NULL)
-AND datecancellationprinted IS NULL
-group by basketno
-ENDSQL
-    return $dbh->selectall_arrayref( $sql, { Slice => {} }, $supplier_id );
-}
diff --git a/acqui/check_uniqueness.pl b/acqui/check_uniqueness.pl
new file mode 100755 (executable)
index 0000000..95b1992
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+# Copyright 2011 BibLibre SARL
+#
+# 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.
+#
+# 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.
+
+# This script search in items table if a value for a given field exists.
+# It is used in check_additem (additem.js)
+# Parameters are a list of 'field', which must be field names in items table
+# and a list of 'value', which are the corresponding value to check
+# Eg. @field = ('barcode', 'barcode', 'stocknumber')
+#     @value = ('1234', '1235', 'ABC')
+#     The script will check if there is already an item with barcode '1234',
+#     then an item with barcode '1235', and finally check if there is an item
+#     with stocknumber 'ABC'
+# It returns a JSON string which contains what have been found
+# Eg. { barcode: ['1234', '1235'], stocknumber: ['ABC'] }
+
+use Modern::Perl;
+
+use CGI;
+use JSON;
+use C4::Context;
+use C4::Output;
+use C4::Auth;
+
+my $input = new CGI;
+my @field = $input->param('field');
+my @value = $input->param('value');
+
+my $dbh = C4::Context->dbh;
+
+my $query = "SHOW COLUMNS FROM items";
+my $sth = $dbh->prepare($query);
+$sth->execute;
+my $results = $sth->fetchall_hashref('Field');
+my @columns = keys %$results;
+
+my $r = {};
+my $index = 0;
+for my $f ( @field ) {
+    if(0 < grep /^$f$/, @columns) {
+        $query = "SELECT $f FROM items WHERE $f = ?";
+        $sth = $dbh->prepare( $query );
+        $sth->execute( $value[$index] );
+        my @values = $sth->fetchrow_array;
+
+        if ( @values ) {
+            push @{ $r->{$f} }, $values[0];
+        }
+    }
+    $index++;
+}
+
+output_with_http_headers $input, undef, to_json($r), 'json';
index dbb2cbc..d482554 100755 (executable)
@@ -308,17 +308,15 @@ if ($CGIsort2) {
 }
 
 if (C4::Context->preference('AcqCreateItem') eq 'ordering' && !$ordernumber) {
-    # prepare empty item form
-    my $cell = PrepareItemrecordDisplay('','','','ACQ');
-#     warn "==> ".Data::Dumper::Dumper($cell);
-    unless ($cell) {
-        $cell = PrepareItemrecordDisplay('','','','');
+    # Check if ACQ framework exists
+    my $marc = GetMarcStructure(1, 'ACQ');
+    unless($marc) {
         $template->param('NoACQframework' => 1);
     }
-    my @itemloop;
-    push @itemloop,$cell;
-    
-    $template->param(items => \@itemloop);
+    $template->param(
+        AcqCreateItemOrdering => 1,
+        UniqueItemFields => C4::Context->preference('UniqueItemFields'),
+    );
 }
 # Get the item types list, but only if item_level_itype is YES. Otherwise, it will be in the item, no need to display it in the biblio
 my @itemtypes;
index 659c103..2b59698 100755 (executable)
@@ -117,16 +117,15 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
 # prepare the form for receiving
 if ( $count == 1 ) {
     if (C4::Context->preference('AcqCreateItem') eq 'receiving') {
-        # prepare empty item form
-        my $cell = PrepareItemrecordDisplay('','','','ACQ');
-        unless ($cell) {
-            $cell = PrepareItemrecordDisplay('','','','');
+        # Check if ACQ framework exists
+        my $marc = GetMarcStructure(1, 'ACQ');
+        unless($marc) {
             $template->param('NoACQframework' => 1);
         }
-        my @itemloop;
-        push @itemloop,$cell;
-        
-        $template->param(items => \@itemloop);
+        $template->param(
+            AcqCreateItemReceiving => 1,
+            UniqueItemFields => C4::Context->preference('UniqueItemFields'),
+        );
     }
 
     if ( @$results[0]->{'quantityreceived'} == 0 ) {
index fdeef06..6746d8d 100755 (executable)
@@ -46,7 +46,6 @@ use C4::Auth;
 use C4::Contract qw/GetContract/;
 use C4::Biblio;
 use C4::Output;
-use C4::Dates qw/format_date /;
 use CGI;
 
 use C4::Bookseller qw( GetBookSellerFromId DelBookseller );
@@ -79,11 +78,6 @@ if ( $op eq 'display' ) {
 
     my $contracts = GetContract( { booksellerid => $booksellerid } );
 
-    for ( @{$contracts} ) {
-        $_->{contractstartdate} = format_date( $_->{contractstartdate} );
-        $_->{contractenddate}   = format_date( $_->{contractenddate} );
-    }
-
     $template->param(
         booksellerid  => $booksellerid,
         name          => $supplier->{'name'},
index 80503e0..9dc8b6e 100755 (executable)
@@ -64,7 +64,6 @@ my $op            = $input->param('op');
 my $booksellerid = $input->param('booksellerid');
 my $basketno = $input->param('basketno');
 my $noconnection;
-my $numberpending;
 my $attr = '';
 my $term;
 my $host;
@@ -88,7 +87,7 @@ unless ($random)
     $random = rand(1000000000);
 }
 
-my $DEBUG = 0;    # if set to 1, many debug message are send on syslog.
+my $DEBUG = $ENV{DEBUG} || 0;    # if set to 1, many debug message are send on syslog.
 
 # get framework list
 my $frameworks = getframeworks;
@@ -131,11 +130,12 @@ if ( $op ne "do_search" ) {
         biblionumber => $biblionumber,
     );
     output_html_with_http_headers $input, $cookie, $template->output;
+    exit;
 }
-else {
+
     my @id = $input->param('id');
 
-    if ( not defined @id ) {
+    if ( not @id ) {
         # empty server list -> report and exit
         $template->param( emptyserverlist => 1 );
         output_html_with_http_headers $input, $cookie, $template->output;
@@ -228,7 +228,10 @@ warn "query ".$query  if $DEBUG;
         # $oResult[$z] = $oConnection[$z]->search_pqf($query);
     }
 
-sub displayresults {
+  warn "# nremaining = $nremaining\n" if $DEBUG;
+
+  while ( $nremaining-- ) {
+
     my $k;
     my $event;
     while ( ( $k = ZOOM::event( \@oConnection ) ) != 0 ) {
@@ -241,7 +244,7 @@ sub displayresults {
 
     if ( $k != 0 ) {
         $k--;
-        warn $serverhost[$k] if $DEBUG;
+        warn "event from $k server = ",$serverhost[$k] if $DEBUG;
         my ( $error, $errmsg, $addinfo, $diagset ) =
           $oConnection[$k]->error_x();
         if ($error) {
@@ -252,6 +255,7 @@ sub displayresults {
         }
         else {
             my $numresults = $oResult[$k]->size();
+            warn "numresults = $numresults" if $DEBUG;
             my $i;
             my $result = '';
             if ( $numresults > 0 ) {
@@ -305,20 +309,15 @@ sub displayresults {
             }    #$numresults
         }
     }    # if $k !=0
-    $numberpending = $nremaining - 1;
-    $template->param(
-        breeding_loop => \@breeding_loop,
-        server        => $servername[$k],
-        numberpending => $numberpending,
-        errconn       => \@errconn
-    );
-    output_html_with_http_headers $input, $cookie, $template->output if $numberpending == 0;
-
     #   print  $template->output  if $firstresult !=1;
     $firstresult++;
-}
-displayresults();
-while ( --$nremaining > 0 ) {
-        displayresults();
-    }
-}    ## if op=search
+
+  } # while nremaining
+
+$template->param(
+breeding_loop => \@breeding_loop,
+#server        => $servername[$k],
+numberpending => $nremaining > 0 ? $nremaining : 0,
+errconn       => \@errconn
+);
+output_html_with_http_headers $input, $cookie, $template->output;
index 5282022..1545f0e 100755 (executable)
@@ -45,14 +45,14 @@ sub AuthorizedValuesForCategory {
 my $input = new CGI;
 my $id          = $input->param('id');
 my $op          = $input->param('op')     || '';
-my $offset      = $input->param('offset') || 0;
-my $searchfield = $input->param('searchfield');
+our $offset      = $input->param('offset') || 0;
+our $searchfield = $input->param('searchfield');
 $searchfield = '' unless defined $searchfield;
 $searchfield =~ s/\,//g;
-my $script_name = "/cgi-bin/koha/admin/authorised_values.pl";
-my $dbh = C4::Context->dbh;
+our $script_name = "/cgi-bin/koha/admin/authorised_values.pl";
+our $dbh = C4::Context->dbh;
 
-my ($template, $borrowernumber, $cookie)= get_template_and_user({
+our ($template, $borrowernumber, $cookie)= get_template_and_user({
     template_name => "admin/authorised_values.tmpl",
     authnotrequired => 0,
     flagsrequired => {parameters => 1},
index 12c49e2..c12762d 100755 (executable)
@@ -328,6 +328,7 @@ sub branchinfotable {
         # - branchfax       |
         # - branchemail    /
         # - branchurl      /
+        # - opac_info (can contain HTML)
         # - address-empty-p (1 if no address information, 0 otherwise)
         # - categories      (containing a static error message)
         # - category_list   (loop containing "categoryname")
@@ -343,7 +344,7 @@ sub branchinfotable {
             'branchaddress3', 'branchzip',
             'branchcity', 'branchstate', 'branchcountry',
             'branchphone', 'branchfax',
-            'branchemail', 'branchurl',
+            'branchemail', 'branchurl', 'opac_info',
             'branchip',       'branchprinter', 'branchnotes'
           )
         {
@@ -406,6 +407,7 @@ sub _branch_to_template {
          branchfax      => $data->{'branchfax'},
          branchemail    => $data->{'branchemail'},
          branchurl      => $data->{'branchurl'},
+         opac_info      => $data->{'opac_info'},
          branchip       => $data->{'branchip'},
          branchnotes    => $data->{'branchnotes'}, 
     );
index 1e3f160..e24f6b6 100755 (executable)
@@ -46,14 +46,14 @@ use C4::Dates qw(format_date);
 use C4::Output;
 use C4::Budgets qw/GetCurrency GetCurrencies/;
 
-my $input = CGI->new;
+our $input = CGI->new;
 my $searchfield = $input->param('searchfield') || $input->param('description') || q{};
-my $offset      = $input->param('offset') || 0;
+our $offset      = $input->param('offset') || 0;
 my $op          = $input->param('op')     || q{};
 my $script_name = '/cgi-bin/koha/admin/currency.pl';
-my $pagesize = 20;
+our $pagesize = 20;
 
-my ($template, $loggedinuser, $cookie) = get_template_and_user({
+our ($template, $loggedinuser, $cookie) = get_template_and_user({
     template_name => 'admin/currency.tmpl',
     query => $input,
     type => 'intranet',
@@ -67,7 +67,7 @@ $searchfield=~ s/\,//g;
 $template->param(searchfield => $searchfield,
         script_name => $script_name);
 
-my $dbh = C4::Context->dbh;
+our $dbh = C4::Context->dbh;
 
 if ( $op eq 'add_form' ) {
     add_form($searchfield);
index bba5d60..ee77ae8 100755 (executable)
@@ -33,7 +33,7 @@ use C4::ItemCirculationAlertPreference;
 use C4::Output;
 
 # shortcut for long package name
-my $preferences = 'C4::ItemCirculationAlertPreference';
+our $preferences = 'C4::ItemCirculationAlertPreference';
 
 # utf8 filter
 sub utf8 {
index 2c69733..f837644 100755 (executable)
@@ -179,6 +179,7 @@ if ( $op eq 'add_form' ) {
     while ( $data = $sth->fetchrow_hashref ) {
         my %row_data;    # get a fresh hash for the row data
         $row_data{defaultvalue} = $data->{defaultvalue};
+        $row_data{maxlength} = $data->{maxlength};
         $row_data{tab} = CGI::scrolling_list(
             -name   => 'tab',
             -id     => "tab$i",
@@ -386,11 +387,11 @@ elsif ( $op eq 'add_validate' ) {
 #                                     values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
 #     );
     my $sth_insert = $dbh->prepare(qq{
-        insert into marc_subfield_structure (tagfield,tagsubfield,liblibrarian,libopac,repeatable,mandatory,kohafield,tab,seealso,authorised_value,authtypecode,value_builder,hidden,isurl,frameworkcode, link,defaultvalue)
-        values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
+        insert into marc_subfield_structure (tagfield,tagsubfield,liblibrarian,libopac,repeatable,mandatory,kohafield,tab,seealso,authorised_value,authtypecode,value_builder,hidden,isurl,frameworkcode, link,defaultvalue,maxlength)
+        values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
     });
     my $sth_update = $dbh->prepare(qq{
-        update marc_subfield_structure set tagfield=?, tagsubfield=?, liblibrarian=?, libopac=?, repeatable=?, mandatory=?, kohafield=?, tab=?, seealso=?, authorised_value=?, authtypecode=?, value_builder=?, hidden=?, isurl=?, frameworkcode=?,  link=?, defaultvalue=?
+        update marc_subfield_structure set tagfield=?, tagsubfield=?, liblibrarian=?, libopac=?, repeatable=?, mandatory=?, kohafield=?, tab=?, seealso=?, authorised_value=?, authtypecode=?, value_builder=?, hidden=?, isurl=?, frameworkcode=?,  link=?, defaultvalue=?, maxlength=?
         where tagfield=? and tagsubfield=? and frameworkcode=?
     });
     my @tagsubfield       = $input->param('tagsubfield');
@@ -405,6 +406,7 @@ elsif ( $op eq 'add_validate' ) {
     my @value_builder     = $input->param('value_builder');
     my @link              = $input->param('link');
     my @defaultvalue      = $input->param('defaultvalue');
+    my @maxlength         = $input->param('maxlength');
     
     for ( my $i = 0 ; $i <= $#tagsubfield ; $i++ ) {
         my $tagfield    = $input->param('tagfield');
@@ -425,6 +427,7 @@ elsif ( $op eq 'add_validate' ) {
         my $isurl  = $input->param("isurl$i") ? 1 : 0;
         my $link   = $link[$i];
         my $defaultvalue = $defaultvalue[$i];
+        my $maxlength = $maxlength[$i];
         
         if (defined($liblibrarian) && $liblibrarian ne "") {
             unless ( C4::Context->config('demo') eq 1 ) {
@@ -447,6 +450,7 @@ elsif ( $op eq 'add_validate' ) {
                         $frameworkcode,
                         $link,
                         $defaultvalue,
+                        $maxlength,
                         (
                             $tagfield,
                             $tagsubfield,
@@ -472,6 +476,7 @@ elsif ( $op eq 'add_validate' ) {
                         $frameworkcode,
                         $link,
                         $defaultvalue,
+                        $maxlength,
                     );
                 }
             }
index 92e0d99..a86d788 100755 (executable)
@@ -348,6 +348,7 @@ sub StringSearch  {
 #
 sub duplicate_framework {
        my ($newframeworkcode,$oldframeworkcode) = @_;
+       my $dbh = C4::Context->dbh;
        my $sth = $dbh->prepare("select tagfield,liblibrarian,libopac,repeatable,mandatory,authorised_value from marc_tag_structure where frameworkcode=?");
        $sth->execute($oldframeworkcode);
        my $sth_insert = $dbh->prepare("insert into marc_tag_structure (tagfield, liblibrarian, libopac, repeatable, mandatory, authorised_value, frameworkcode) values (?,?,?,?,?,?,?)");
index e992899..b167026 100755 (executable)
@@ -30,7 +30,7 @@ use C4::Matcher;
 
 my $script_name = "/cgi-bin/koha/admin/matching-rules.pl";
 
-my $input = new CGI;
+our $input = new CGI;
 my $op = $input->param('op') || '';
 
 
index 29a0d90..638456e 100755 (executable)
 use strict;
 use warnings;
 use CGI;
+use List::MoreUtils qw/uniq/;
+
 use C4::Auth;
 use C4::Context;
 use C4::Output;
 use C4::Koha;
+use C4::Members qw/GetBorrowercategoryList/;
 use C4::Members::AttributeTypes;
 
 my $script_name = "/cgi-bin/koha/admin/patron-attr-types.pl";
 
-my $input = new CGI;
+our $input = new CGI;
 my $op = $input->param('op') || '';
 
 
-my ($template, $loggedinuser, $cookie)
+our ($template, $loggedinuser, $cookie)
     = get_template_and_user({template_name => "admin/patron-attr-types.tmpl",
                  query => $input,
                  type => "intranet",
@@ -82,8 +85,10 @@ sub add_attribute_type_form {
     $template->param(
         attribute_type_form => 1,
         confirm_op => 'add_attribute_type_confirmed',
+        categories => GetBorrowercategoryList,
     );
     authorised_value_category_list($template);
+    pa_classes($template);
 }
 
 sub error_add_attribute_type_form {
@@ -110,6 +115,9 @@ sub error_add_attribute_type_form {
         $template->param(display_checkout_checked => 'checked="checked"');
     }
 
+    $template->param( category_code => $input->param('category_code') );
+    $template->param( class => $input->param('class') );
+
     $template->param(
         attribute_type_form => 1,
         confirm_op => 'add_attribute_type_confirmed',
@@ -152,6 +160,8 @@ sub add_update_attribute_type {
     $attr_type->password_allowed($password_allowed);
     my $display_checkout = $input->param('display_checkout');
     $attr_type->display_checkout($display_checkout);
+    $attr_type->category_code($input->param('category_code'));
+    $attr_type->class($input->param('class'));
 
     if ($op eq 'edit') {
         $template->param(edited_attribute_type => $attr_type->code());
@@ -209,6 +219,7 @@ sub edit_attribute_type_form {
 
     $template->param(code => $code);
     $template->param(description => $attr_type->description());
+    $template->param(class => $attr_type->class());
 
     if ($attr_type->repeatable()) {
         $template->param(repeatable_checked => 1);
@@ -231,20 +242,41 @@ sub edit_attribute_type_form {
         $template->param(display_checkout_checked => 'checked="checked"');
     }
     authorised_value_category_list($template, $attr_type->authorised_value_category());
+    pa_classes( $template, $attr_type->class );
+
+    $template->param ( category_code => $attr_type->category_code );
+    $template->param ( category_description => $attr_type->category_description );
 
     $template->param(
         attribute_type_form => 1,
         edit_attribute_type => 1,
         confirm_op => 'edit_attribute_type_confirmed',
+        categories => GetBorrowercategoryList,
     );
 
 }
 
 sub patron_attribute_type_list {
     my $template = shift;
-    
+
     my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes();
-    $template->param(available_attribute_types => \@attr_types);
+    my @classes = uniq( map {$_->{class}} @attr_types );
+    @classes = sort @classes;
+
+    my @attributes_loop;
+    for my $class (@classes) {
+        my @items;
+        for my $attr (@attr_types) {
+            push @items, $attr if $attr->{class} eq $class
+        }
+        my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class;
+        push @attributes_loop, {
+            class => $class,
+            items => \@items,
+            lib   => $lib,
+        };
+    }
+    $template->param(available_attribute_types => \@attributes_loop);
     $template->param(display_list => 1);
 }
 
@@ -261,3 +293,10 @@ sub authorised_value_category_list {
     }
     $template->param(authorised_value_categories => \@list);
 }
+
+sub pa_classes {
+    my $template = shift;
+    my $selected = @_ ? shift : '';
+
+    $template->param(classes_val_loop => GetAuthorisedValues( 'PA_CLASS', $selected ) );
+}
index dcfcfc5..0b8012f 100755 (executable)
@@ -100,9 +100,9 @@ elsif ($op eq 'delete-branch-item') {
 }
 # save the values entered
 elsif ($op eq 'add') {
-    my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?");
-    my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
-    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
+    my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
+    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
+    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
     
     my $br = $branch; # branch
     my $bor  = $input->param('categorycode'); # borrower category
@@ -117,6 +117,7 @@ elsif ($op eq 'add') {
     $maxissueqty =~ s/\s//g;
     $maxissueqty = undef if $maxissueqty !~ /^\d+/;
     my $issuelength  = $input->param('issuelength');
+    my $lengthunit  = $input->param('lengthunit');
     my $hardduedate = $input->param('hardduedate');
     $hardduedate = format_date_in_iso($hardduedate);
     my $hardduedatecompare = $input->param('hardduedatecompare');
@@ -126,9 +127,9 @@ elsif ($op eq 'add') {
     $sth_search->execute($br,$bor,$cat);
     my $res = $sth_search->fetchrow_hashref();
     if ($res->{total}) {
-        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat);
+        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat);
     } else {
-        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
+        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
     }
 } 
 elsif ($op eq "set-branch-defaults") {
index f0a4dbb..14603f6 100755 (executable)
@@ -20,7 +20,7 @@
 #      - we delete the record having primkey=$primkey
 
 use strict;
-#use warnings; FIXME - Bug 2505
+use warnings;
 use CGI;
 use C4::Context;
 use C4::Auth;
@@ -29,16 +29,34 @@ use C4::Output;
 sub StringSearch  {
        my ($searchstring,$type)=@_;
        my $dbh = C4::Context->dbh;
-       $searchstring=~ s/\'/\\\'/g;
-       my @data=split(' ',$searchstring);
-       my $count=@data;
-       my $sth=$dbh->prepare("Select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name like ?) order by rank,name");
-       $sth->execute("$data[0]\%");
+    my @data = ('%');
+    my $count = 1;
+       if ( defined $searchstring ) {
+        $searchstring =~ s/\'/\\\'/g;
+        @data=split(' ',$searchstring);
+        $count=@data;
+    }
+    else {
+        $searchstring = '';
+    }
+
+    my $query    = "SELECT host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout";
+    $query      .= " FROM z3950servers";
+    if ( $searchstring ne '' ) { $query .= " WHERE (name like ?)" }
+    $query      .= " ORDER BY rank,name";
+       my $sth=$dbh->prepare($query);
+
+    if ( $searchstring ne '' ) {
+        $sth->execute("$data[0]\%");
+    }
+    else {
+        $sth->execute;
+    }
+
        my @results;
        while (my $data=$sth->fetchrow_hashref) {
            push(@results,$data);
        }
-       #  $sth->execute;
        $sth->finish;
        $dbh->disconnect;
        return (scalar(@results),\@results);
@@ -46,11 +64,11 @@ sub StringSearch  {
 
 my $input = new CGI;
 my $searchfield=$input->param('searchfield');
-my $offset=$input->param('offset');
+my $offset=$input->param('offset') || 0;
 my $script_name="/cgi-bin/koha/admin/z3950servers.pl";
 
 my $pagesize=20;
-my $op = $input->param('op');
+my $op = $input->param('op') || '';
 
 my ($template, $loggedinuser, $cookie) 
     = get_template_and_user({template_name => "admin/z3950servers.tmpl",
@@ -74,13 +92,13 @@ if ($op eq 'add_form') {
        my $data;
        if ($searchfield) {
                my $dbh = C4::Context->dbh;
-               my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name = ?) order by rank,name");
+               my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout from z3950servers where (name = ?) order by rank,name");
                $sth->execute($searchfield);
                $data=$sth->fetchrow_hashref;
                $sth->finish;
        }
     $template->param( $_ => $data->{$_} ) 
-        for ( qw( host port db userid password checked rank ) );
+        for ( qw( host port db userid password checked rank timeout ) );
     $template->param( $_ . $data->{$_} => 1)
         for ( qw( syntax encoding ) );
                                                                                                        # END $OP eq ADD_FORM
@@ -93,7 +111,7 @@ if ($op eq 'add_form') {
        $sth->execute($input->param('searchfield'));
        my $checked = $input->param('checked') ? 1 : 0;
        if ($sth->rows) {
-               $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=?,syntax=?,encoding=? where name=?");
+               $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=?,syntax=?,encoding=?,timeout=? where name=?");
                $sth->execute($input->param('host'),
                      $input->param('port'),
                      $input->param('db'),
@@ -104,14 +122,15 @@ if ($op eq 'add_form') {
                      $input->param('rank'),
                          $input->param('syntax'),
               $input->param('encoding'),
+              $input->param('timeout'),
                      $input->param('searchfield'),
                      );
        } 
        else {
                $sth=$dbh->prepare(
                  "INSERT INTO z3950servers " .
-                 "(host,port,db,userid,password,name,checked,rank,syntax,encoding) " .
-                 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" );
+                 "(host,port,db,userid,password,name,checked,rank,syntax,encoding,timeout) " .
+                 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" );
         $sth->execute(
             $input->param( 'host' ),
             $input->param( 'port' ),
@@ -119,9 +138,10 @@ if ($op eq 'add_form') {
             $input->param( 'userid' ),
             $input->param( 'password' ),
             $input->param( 'searchfield' ),
-            $input->param( 'checked' ),
+            $checked,
             $input->param( 'rank' ),
             $input->param( 'syntax' ),
+            $input->param( 'timeout' ),
             $input->param( 'encoding' ) );
        }
        $sth->finish;
@@ -132,7 +152,7 @@ if ($op eq 'add_form') {
        $template->param(delete_confirm => 1);
        my $dbh = C4::Context->dbh;
 
-       my $sth2=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name = ?) order by rank,name");
+       my $sth2=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout from z3950servers where (name = ?) order by rank,name");
        $sth2->execute($searchfield);
        my $data=$sth2->fetchrow_hashref;
        $sth2->finish;
@@ -145,6 +165,7 @@ if ($op eq 'add_form') {
                          checked => $data->{'checked'},
                          rank => $data->{'rank'},
                          syntax => $data->{'syntax'},
+                         timeout => $data->{'timeout'},
                          encoding => $data->{'encoding'}            );
 
                                                                                                        # END $OP eq DELETE_CONFIRM
@@ -162,8 +183,8 @@ if ($op eq 'add_form') {
        $template->param(else => 1);
        my ($count,$results)=StringSearch($searchfield,'web');
        my @loop;
+
        for (my $i=$offset; $i < ($offset+$pagesize<$count?$offset+$pagesize:$count); $i++){
-                       
                my $urlsearchfield=$results->[$i]{name};
                $urlsearchfield=~s/ /%20/g;
                my %row = ( name => $results->[$i]{'name'},
@@ -175,7 +196,8 @@ if ($op eq 'add_form') {
                        checked => $results->[$i]{'checked'},
                        rank => $results->[$i]{'rank'},
                        syntax => $results->[$i]{'syntax'},
-      encoding => $results->[$i]{'encoding'});
+                       encoding => $results->[$i]{'encoding'},
+      timeout => $results->[$i]{'timeout'});
                push @loop, \%row;
 
        }
index db38551..da62e07 100755 (executable)
@@ -39,6 +39,7 @@ use C4::Tags qw(get_tags);
 use C4::VirtualShelves;
 use C4::XSLT;
 use C4::Images;
+use Koha::DateUtils;
 
 # use Smart::Comments;
 
@@ -192,9 +193,10 @@ foreach my $item (@items) {
     $item->{imageurl} = defined $item->{itype} ? getitemtypeimagelocation('intranet', $itemtypes->{ $item->{itype} }{imageurl})
                                                : '';
 
-       foreach (qw(datedue datelastseen onloan)) {
+       foreach (qw(datelastseen onloan)) {
                $item->{$_} = format_date($item->{$_});
-       }
+    }
+    $item->{datedue} = format_sqldatetime($item->{datedue});
     # item damaged, lost, withdrawn loops
     $item->{itemlostloop} = GetAuthorisedValues($authvalcode_items_itemlost, $item->{itemlost}) if $authvalcode_items_itemlost;
     if ($item->{damaged}) {
index 3fb936e..288182c 100755 (executable)
@@ -25,8 +25,8 @@ use C4::Output;
 
 use C4::Circulation;    # GetBiblioIssues
 use C4::Biblio;    # GetBiblio GetBiblioFromItemNumber
-use C4::Dates qw/format_date/;
 use C4::Search;                # enabled_staff_search_views
+use Koha::DateUtils;
 
 my $query = new CGI;
 my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
@@ -67,11 +67,11 @@ if ($itemnumber){
                %{$biblio[0]},
        );
 } 
-foreach (@$issues){
-       $_->{date_due}   = format_date($_->{date_due});
-       $_->{issuedate}  = format_date($_->{issuedate});
-       $_->{returndate} = format_date($_->{returndate});
-       $_->{lastreneweddate} = format_date($_->{lastreneweddate});
+foreach (@{$issues}){
+       $_->{date_due}   = format_sqldatetime($_->{date_due});
+       $_->{issuedate}  = format_sqldatetime($_->{issuedate});
+       $_->{returndate} = format_sqldatetime($_->{returndate});
+       $_->{lastreneweddate} = format_sqldatetime($_->{lastreneweddate});
 }
 $template->param(
     total        => scalar @$issues,
index c9d202c..9d5465b 100755 (executable)
@@ -35,6 +35,7 @@ use C4::Circulation;  # to use itemissues
 use C4::Members; # to use GetMember
 use C4::Search;                # enabled_staff_search_views
 use C4::Members qw/GetHideLostItemsPreference/;
+use Koha::DateUtils;
 
 my $query=new CGI;
 
index 235198e..0052f66 100755 (executable)
@@ -147,7 +147,7 @@ use C4::Search;
 use C4::Languages qw(getAllLanguages);
 use C4::Koha;
 use C4::Members qw(GetMember);
-use C4::VirtualShelves qw(GetRecentShelves);
+use C4::VirtualShelves;
 use POSIX qw(ceil floor);
 use C4::Branch; # GetBranches
 
@@ -701,21 +701,13 @@ if ($query_desc || $limit_desc) {
 # VI. BUILD THE TEMPLATE
 
 # Build drop-down list for 'Add To:' menu...
-
-my $row_count = 10; # FIXME:This probably should be a syspref
-my ($pubshelves, $total) = GetRecentShelves(2, $row_count, undef);
-my ($barshelves, $total) = GetRecentShelves(1, $row_count, $borrowernumber);
-
-if (@{$pubshelves}) {
-        $template->param( addpubshelves     => scalar @{$pubshelves});
-        $template->param( addpubshelvesloop => $pubshelves);
-}
-
-if (@{$barshelves}) {
-        $template->param( addbarshelves     => scalar @{$barshelves});
-        $template->param( addbarshelvesloop => $barshelves);
-}
-
-
+my ($totalref, $pubshelves, $barshelves)=
+       C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1);
+$template->param(
+        addbarshelves     => $totalref->{bartotal},
+        addbarshelvesloop => $barshelves,
+       addpubshelves     => $totalref->{pubtotal},
+       addpubshelvesloop => $pubshelves,
+       );
 
 output_html_with_http_headers $cgi, $cookie, $template->output;
index 8e4defd..d5778a4 100755 (executable)
@@ -293,14 +293,6 @@ sub create_input {
 
     $value =~ s/"/&quot;/g;
 
-    # determine maximum length; 9999 bytes per ISO 2709 except for leader and MARC21 008
-    my $max_length = 9999;
-    if ($tag eq '000') {
-        $max_length = 24;
-    } elsif ($tag eq '008' and C4::Context->preference('marcflavour') eq 'MARC21')  {
-        $max_length = 40;
-    }
-
     # if there is no value provided but a default value in parameters, get it
     if ( $value eq '' ) {
         $value = $tagslib->{$tag}->{$subfield}->{defaultvalue};
@@ -335,6 +327,7 @@ sub create_input {
         index          => $index_tag,
         id             => "tag_".$tag."_subfield_".$id_subfield."_".$index_tag."_".$index_subfield,
         value          => $value,
+        maxlength      => $tagslib->{$tag}->{$subfield}->{maxlength},
         random         => CreateKey(),
     );
 
@@ -374,7 +367,7 @@ sub create_input {
                     class=\"input_marceditor readonly\"
                     tabindex=\"1\"
                     size=\"5\"
-                    maxlength=\"$max_length\"
+                    maxlength=\"".$subfield_data{maxlength}."\"
                     readonly=\"readonly\"
                     \/>";
 
@@ -390,7 +383,7 @@ sub create_input {
                     class=\"input_marceditor readonly\"
                     tabindex=\"1\"
                     size=\"67\"
-                    maxlength=\"$max_length\"
+                    maxlength=\"".$subfield_data{maxlength}."\"
                     \/>
                     <span class=\"subfield_controls\"><a href=\"#\" class=\"buttonDot\"
                        onclick=\"openAuth(this.parentNode.parentNode.getElementsByTagName('input')[1].id,'".$tagslib->{$tag}->{$subfield}->{authtypecode}."'); return false;\" tabindex=\"1\" title=\"Tag Editor\"><img src=\"/intranet-tmpl/prog/img/edit-tag.png\" alt=\"Tag Editor\" /></a></span>
@@ -404,7 +397,7 @@ sub create_input {
                     class=\"input_marceditor readonly\"
                     tabindex=\"1\"
                     size=\"67\"
-                    maxlength=\"$max_length\"
+                    maxlength=\"".$subfield_data{maxlength}."\"
                     readonly=\"readonly\"
                     \/><span class=\"subfield_controls\"><a href=\"#\" class=\"buttonDot\"
                         onclick=\"openAuth(this.parentNode.parentNode.getElementsByTagName('input')[1].id,'".$tagslib->{$tag}->{$subfield}->{authtypecode}."'); return false;\" tabindex=\"1\" title=\"Tag Editor\"><img src=\"/intranet-tmpl/prog/img/edit-tag.png\" alt=\"Tag Editor\" /></a></span>
@@ -435,7 +428,7 @@ sub create_input {
                             class=\"input_marceditor\"
                             onfocus=\"Focus$function_name($index_tag)\"
                             size=\"67\"
-                            maxlength=\"$max_length\"
+                            maxlength=\"".$subfield_data{maxlength}."\"
                             onblur=\"Blur$function_name($index_tag); \" \/>
                             <span class=\"subfield_controls\"><a href=\"#\" class=\"buttonDot\" onclick=\"Clic$function_name('$subfield_data{id}'); return false;\" tabindex=\"1\" title=\"Tag Editor\"><img src=\"/intranet-tmpl/prog/img/edit-tag.png\" alt=\"Tag Editor\" /></a></span>
                     $javascript";
@@ -449,7 +442,7 @@ sub create_input {
                         value=\"$value\"
                         tabindex=\"1\"
                         size=\"67\"
-                        maxlength=\"$max_length\"
+                        maxlength=\"".$subfield_data{maxlength}."\"
                         class=\"input_marceditor\"
                 \/>
                 ";
@@ -463,7 +456,7 @@ sub create_input {
                     id=\"".$subfield_data{id}."\"
                     name=\"".$subfield_data{id}."\"
                     size=\"67\"
-                    maxlength=\"$max_length\"
+                    maxlength=\"".$subfield_data{maxlength}."\"
                     value=\"$value\" \/>
             ";
     }
@@ -497,7 +490,7 @@ sub create_input {
                         value=\"$value\"
                         tabindex=\"1\"
                         size=\"67\"
-                        maxlength=\"$max_length\"
+                        maxlength=\"".$subfield_data{maxlength}."\"
                         class=\"input_marceditor\"
                 \/>
                 ";
index 4bf06b5..91dc9e7 100755 (executable)
@@ -120,6 +120,7 @@ sub generate_subfield_form {
         $subfield_data{marc_lib}   ="<span id=\"error$i\" title=\"".$subfieldlib->{lib}."\">".$subfieldlib->{lib}."</span>";
         $subfield_data{mandatory}  = $subfieldlib->{mandatory};
         $subfield_data{repeatable} = $subfieldlib->{repeatable};
+        $subfield_data{maxlength}  = $subfieldlib->{maxlength};
         
         $value =~ s/"/&quot;/g;
         if ( ! defined( $value ) || $value eq '')  {
@@ -150,7 +151,7 @@ sub generate_subfield_form {
            my $input = new CGI;
            $value = $input->param('barcode');
        }
-        my $attributes_no_value = qq(tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" );
+        my $attributes_no_value = qq(tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="$subfield_data{maxlength}" );
         my $attributes          = qq($attributes_no_value value="$value" );
         
         if ( $subfieldlib->{authorised_value} ) {
@@ -308,8 +309,6 @@ my ($template, $loggedinuser, $cookie)
 
 
 my $today_iso = C4::Dates->today('iso');
-$template->param(today_iso => $today_iso);
-
 my $tagslib = &GetMarcStructure(1,$frameworkcode);
 my $record = GetMarcBiblio($biblionumber);
 my $oldrecord = TransformMarcToKoha($dbh,$record);
index af1a285..5e834a4 100755 (executable)
@@ -18,7 +18,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 use strict;
-#use warnings; FIXME - Bug 2505
+use warnings;
 
 =head1
 
@@ -71,14 +71,21 @@ function Focus$function_name(subfield_managed, id, force) {
     //  summary += i + ": " + document.f.tag[i].value + " " + document.f.subfield[i].value + ": " + document.f.field_value[i].value + "\\n"; 
     //}
     //alert("Got focus, subfieldmanaged: " + subfield_managed + "\\n" + summary);
-    set_to_today(id); // defined in additem.pl HEAD
+    set_to_today(id);
     return 0;
 }
 
 function Clic$function_name(id) {
-    set_to_today(id, 1); // defined in additem.pl HEAD
+    set_to_today(id, 1);
     return 0;
 }
+
+function set_to_today(id, force) {
+    if (! id) { alert(_("Bad id ") + id + _(" sent to set_to_today()")); return 0; }
+    if (\$("#" + id).val() == '' || \$("#" + id).val() == '0000-00-00' || force) {
+        \$("#" + id).val("$date");
+    }
+}
 //]]>
 </script>
 END_OF_JS
index b12a9c9..10320e2 100755 (executable)
@@ -179,6 +179,7 @@ warn "query ".$query  if $DEBUG;
             $option1->option('user',         $server->{userid}  ) if $server->{userid};
             $option1->option('password',     $server->{password}) if $server->{password};
             $option1->option('preferredRecordSyntax', $server->{syntax});
+            $option1->option( 'timeout', $server->{timeout} ) if ($server->{timeout});
             $oConnection[$s] = create ZOOM::Connection($option1)
               || $DEBUG
               && warn( "" . $oConnection[$s]->errmsg() );
@@ -222,7 +223,7 @@ warn "query ".$query  if $DEBUG;
           $oConnection[$k]->error_x();
         if ($error) {
             if ($error =~ m/^(10000|10007)$/ ) {
-                push(@errconn, {'server' => $serverhost[$k]});
+                push(@errconn, {'server' => $serverhost[$k], 'error' => $error});
             }
             $DEBUG and warn "$k $serverhost[$k] error $query: $errmsg ($error) $addinfo\n";
         }
index 5c1dcaf..dc89d60 100755 (executable)
@@ -22,12 +22,12 @@ use C4::Context;
 use CGI;
 use C4::Output;
 use C4::Auth;
-use C4::Dates qw/format_date/;
 use C4::Overdues;    # AddNotifyLine
 use C4::Biblio;
 use C4::Koha;
 use C4::Debug;
 use C4::Branch;
+use Data::Dumper;
 
 =head1 branchoverdues.pl
 
@@ -97,7 +97,6 @@ elsif ( $input->param('action') eq 'remove' ) {
 
 my @overduesloop;
 my @getoverdues = GetOverduesForBranch( $default, $location );
-use Data::Dumper;
 $debug and warn "HERE : $default / $location" . Dumper(@getoverdues);
 # search for location authorised value
 my ($tag,$subfield) = GetMarcFromKohaField('items.location','');
@@ -114,7 +113,8 @@ foreach my $num (@getoverdues) {
     if ($record){
         $overdueforbranch{'subtitle'} = GetRecordValue('subtitle',$record,'')->[0]->{subfield};
     }
-    $overdueforbranch{'date_due'}          = format_date( $num->{'date_due'} );
+    my $dt = dt_from_string($num->{date_due}, 'sql');
+    $overdueforbranch{'date_due'}          = output_pref($dt);
     $overdueforbranch{'title'}             = $num->{'title'};
     $overdueforbranch{'description'}       = $num->{'description'};
     $overdueforbranch{'barcode'}           = $num->{'barcode'};
@@ -151,7 +151,6 @@ foreach my $num (@getoverdues) {
 # initiate the templates for the overdueloop
 $template->param(
     overduesloop => \@overduesloop,
-    show_date    => format_date(C4::Dates->today('iso')),
     location     => $location,
 );
 
index 6928966..082b3d4 100755 (executable)
@@ -4,6 +4,7 @@
 
 # Copyright 2000-2002 Katipo Communications
 # copyright 2010 BibLibre
+# Copyright 2011 PTFS-Europe Ltd.
 #
 # This file is part of Koha.
 #
@@ -21,7 +22,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 use strict;
-#use warnings; FIXME - Bug 2505
+use warnings;
 use CGI;
 use C4::Output;
 use C4::Auth qw/:DEFAULT get_session/;
@@ -36,6 +37,7 @@ use C4::Reserves;
 use C4::Context;
 use CGI::Session;
 use C4::Members::Attributes qw(GetBorrowerAttributes);
+use Koha::DateUtils;
 
 use Date::Calc qw(
   Today
@@ -144,14 +146,9 @@ my $duedatespec_allow = C4::Context->preference('SpecifyDueDate');
 if($duedatespec_allow){
     if ($duedatespec) {
         if ($duedatespec =~ C4::Dates->regexp('syspref')) {
-            my $tempdate = C4::Dates->new($duedatespec);
-#           if ($tempdate and $tempdate->output('iso') gt C4::Dates->new()->output('iso')) {
-#               # i.e., it has to be later than today/now
-                $datedue = $tempdate;
-#           } else {
-#               $invalidduedate = 1;
-#               $template->param(IMPOSSIBLE=>1, INVALID_DATE=>$duedatespec);
-#           }
+                $datedue = dt_from_string($duedatespec);
+                $datedue->set_hour(23);
+                $datedue->set_minute(59);
         } else {
             $invalidduedate = 1;
             $template->param(IMPOSSIBLE=>1, INVALID_DATE=>$duedatespec);
@@ -451,9 +448,10 @@ sub build_issue_data {
         $totalprice += $it->{'replacementprice'};
         $it->{'itemtype'} = $itemtypeinfo->{'description'};
         $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
-        $it->{'dd'} = format_date($it->{'date_due'});
-        $it->{'displaydate'} = format_date($it->{'issuedate'});
-        $it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
+        $it->{'dd'} = output_pref($it->{'date_due'});
+        $it->{'displaydate'} = output_pref($it->{'issuedate'});
+        #$it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
+        $it->{'od'} = $it->{'overdue'};
         ($it->{'author'} eq '') and $it->{'author'} = ' ';
         $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}};
 
index c25a1d6..a4cfa7a 100755 (executable)
@@ -28,8 +28,9 @@ use C4::Auth;
 use C4::Branch;
 use C4::Debug;
 use C4::Dates qw/format_date format_date_in_iso/;
-use Date::Calc qw/Today/;
 use Text::CSV_XS;
+use Koha::DateUtils;
+use DateTime;
 
 my $input = new CGI;
 my $order           = $input->param('order') || '';
@@ -42,6 +43,14 @@ my $branchfilter    = $input->param('branch') || '';
 my $op              = $input->param('op') || '';
 my $dateduefrom = format_date_in_iso($input->param( 'dateduefrom' )) || '';
 my $datedueto   = format_date_in_iso($input->param( 'datedueto' )) || '';
+# FIXME This is a kludge to include times
+if ($datedueto) {
+    $datedueto .= ' 23:59';
+}
+if ($dateduefrom) {
+    $dateduefrom .= ' 00:00';
+}
+# kludge end
 my $isfiltered      = $op =~ /apply/i && $op =~ /filter/i;
 my $noreport        = C4::Context->preference('FilterBeforeOverdueReport') && ! $isfiltered && $op ne "csv";
 
@@ -229,7 +238,9 @@ if ($noreport) {
     #  FIX 2: ensure there are indexes for columns participating in the WHERE clauses, where feasible/reasonable
 
 
-    my $todaysdate = sprintf("%-04.4d-%-02.2d-%02.2d", Today());
+    my $today_dt = DateTime->now(time_zone => C4::Context->tz);
+    $today_dt->truncate(to => 'minutes');
+    my $todaysdate = $today_dt->strftime('%Y-%m-%d %H:%M');
 
     $bornamefilter =~s/\*/\%/g;
     $bornamefilter =~s/\?/\_/g;
@@ -318,9 +329,10 @@ if ($noreport) {
             my @displayvalues = map { $_->[1] } @{ $pattrs->{$pattr_filter->{code}} };   # grab second value from each subarray
             push @patron_attr_value_loop, { value => join(', ', sort { lc $a cmp lc $b } @displayvalues) };
         }
+        my $dt = dt_from_string($data->{date_due}, 'sql');
 
         push @overduedata, {
-            duedate                => format_date($data->{date_due}),
+            duedate                => output_pref($dt),
             borrowernumber         => $data->{borrowernumber},
             barcode                => $data->{barcode},
             itemnum                => $data->{itemnumber},
@@ -389,7 +401,7 @@ if ($noreport) {
 
     $template->param(
         csv_param_string        => $csv_param_string,
-        todaysdate              => format_date($todaysdate),
+        todaysdate              => output_pref($today_dt),
         overdueloop             => \@overduedata,
         nnoverdue               => scalar(@overduedata),
         noverdue_is_plural      => scalar(@overduedata) != 1,
index e142117..83817a8 100755 (executable)
@@ -4,6 +4,7 @@
 #           2006 SAN-OP
 #           2007-2010 BibLibre, Paul POULAIN
 #           2010 Catalyst IT
+#           2011 PTFS-Europe Ltd.
 #
 # This file is part of Koha.
 #
@@ -30,13 +31,11 @@ use strict;
 #use warnings; FIXME - Bug 2505
 
 use CGI;
+use DateTime;
 use C4::Context;
 use C4::Auth qw/:DEFAULT get_session/;
 use C4::Output;
 use C4::Circulation;
-use C4::Dates qw/format_date/;
-use Date::Calc qw/Add_Delta_Days/;
-use C4::Calendar;
 use C4::Print;
 use C4::Reserves;
 use C4::Biblio;
@@ -45,6 +44,8 @@ use C4::Members;
 use C4::Branch; # GetBranches GetBranchName
 use C4::Koha;   # FIXME : is it still useful ?
 use C4::RotatingCollections;
+use Koha::DateUtils;
+use Koha::Calendar;
 
 my $query = new CGI;
 
@@ -175,10 +176,9 @@ my $dropboxmode = $query->param('dropboxmode');
 my $dotransfer  = $query->param('dotransfer');
 my $canceltransfer = $query->param('canceltransfer');
 my $dest = $query->param('dest');
-my $calendar    = C4::Calendar->new( branchcode => $userenv_branch );
+my $calendar    = Koha::Calendar->new( branchcode => $userenv_branch );
 #dropbox: get last open day (today - 1)
-my $today       = C4::Dates->new();
-my $today_iso   = $today->output('iso');
+my $today       = DateTime->now( time_zone => C4::Context->tz());
 my $dropboxdate = $calendar->addDate($today, -1);
 if ($dotransfer){
 # An item has been returned to a branch other than the homebranch, and the librarian has chosen to initiate a transfer
@@ -249,13 +249,14 @@ if ($barcode) {
     );
 
     if ($returned) {
-        my $duedate = $issueinformation->{'date_due'};
+        my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minutes');
+        my $duedate = $issueinformation->{date_due}->strftime('%Y-%m-%d %H:%M');
         $returneditems{0}      = $barcode;
         $riborrowernumber{0}   = $borrower->{'borrowernumber'};
         $riduedate{0}          = $duedate;
         $input{borrowernumber} = $borrower->{'borrowernumber'};
         $input{duedate}        = $duedate;
-        $input{return_overdue} = 1 if ($duedate and $duedate lt $today->output('iso'));
+        $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, $time_now) == -1);
         push( @inputloop, \%input );
 
         if ( C4::Context->preference("FineNotifyAtCheckin") ) {
@@ -463,7 +464,7 @@ foreach my $code ( keys %$messages ) {
     elsif ( $code eq 'Wrongbranch' ) {
     }
     elsif ( $code eq 'Debarred' ) {
-        $err{debarred}            = format_date( $messages->{'Debarred'} );
+        $err{debarred}            = $messages->{'Debarred'};
         $err{debarcardnumber}     = $borrower->{cardnumber};
         $err{debarborrowernumber} = $borrower->{borrowernumber};
         $err{debarname}           = "$borrower->{firstname} $borrower->{surname}";
@@ -519,7 +520,7 @@ if ($borrower) {
             {
                 my $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'});
                 push @itemloop, {
-                    duedate   => format_date($item->{'date_due'}),
+                    duedate   => format_sqldatetime($item->{date_due}),
                     biblionum => $biblio->{'biblionumber'},
                     barcode   => $biblio->{'barcode'},
                     title     => $biblio->{'title'},
@@ -545,7 +546,6 @@ if ($borrower) {
         riborfirstname   => $borrower->{'firstname'}
     );
 }
-
 #set up so only the last 8 returned items display (make for faster loading pages)
 my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow') ) ? C4::Context->preference('numReturnedItemsToShow') : 8;
 my $count = 0;
@@ -555,15 +555,16 @@ foreach ( sort { $a <=> $b } keys %returneditems ) {
     my %ri;
     if ( $count++ < $returned_counter ) {
         my $bar_code = $returneditems{$_};
-        my $duedate = $riduedate{$_};
-        if ($duedate) {
-            my @tempdate = split( /-/, $duedate );
-            $ri{year}  = $tempdate[0];
-            $ri{month} = $tempdate[1];
-            $ri{day}   = $tempdate[2];
-            $ri{duedate} = format_date($duedate);
+        if ($riduedate{$_}) {
+            my $duedate = dt_from_string( $riduedate{$_}, 'sql');
+            $ri{year}  = $duedate->year();
+            $ri{month} = $duedate->month();
+            $ri{day}   = $duedate->day();
+            $ri{hour}   = $duedate->hour();
+            $ri{minute}   = $duedate->minute();
+            $ri{duedate} = output_pref($duedate);
             my ($b)      = GetMemberDetails( $riborrowernumber{$_}, 0 );
-            $ri{return_overdue} = 1 if ($duedate lt $today->output('iso'));
+            $ri{return_overdue} = 1 if (DateTime->compare($duedate, DateTime->now()) == -1 );
             $ri{borrowernumber} = $b->{'borrowernumber'};
             $ri{borcnum}        = $b->{'cardnumber'};
             $ri{borfirstname}   = $b->{'firstname'};
@@ -600,7 +601,6 @@ foreach ( sort { $a <=> $b } keys %returneditems ) {
     }
     push @riloop, \%ri;
 }
-
 $template->param(
     riloop         => \@riloop,
     genbrname      => $branches->{$userenv_branch}->{'branchname'},
@@ -610,7 +610,7 @@ $template->param(
     errmsgloop     => \@errmsgloop,
     exemptfine     => $exemptfine,
     dropboxmode    => $dropboxmode,
-    dropboxdate    => $dropboxdate->output(),
+    dropboxdate    => output_pref($dropboxdate),
     overduecharges => $overduecharges,
     soundon        => C4::Context->preference("SoundOn"),
 );
diff --git a/installer/data/mysql/atomicupdate/hourlyloans.sql b/installer/data/mysql/atomicupdate/hourlyloans.sql
new file mode 100644 (file)
index 0000000..664142d
--- /dev/null
@@ -0,0 +1 @@
+alter table issuingrules add column lengthunit varchar(10) default 'days' after issuelength;
diff --git a/installer/data/mysql/atomicupdate/issuedate_times.pl b/installer/data/mysql/atomicupdate/issuedate_times.pl
new file mode 100644 (file)
index 0000000..864109a
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use C4::Context;
+
+my $dbh = C4::Context->dbh;
+
+$dbh->do("ALTER TABLE issues CHANGE date_due date_due datetime");
+$dbh->do("ALTER TABLE issues CHANGE returndate returndate datetime");
+$dbh->do("ALTER TABLE issues CHANGE lastreneweddate lastreneweddate datetime");
+$dbh->do("ALTER TABLE issues CHANGE issuedate issuedate datetime");
+$dbh->do("ALTER TABLE old_issues CHANGE date_due date_due datetime");
+$dbh->do("ALTER TABLE old_issues CHANGE returndate returndate datetime");
+$dbh->do("ALTER TABLE old_issues CHANGE lastreneweddate lastreneweddate datetime");
+$dbh->do("ALTER TABLE old_issues CHANGE issuedate issuedate datetime");
+$dbh->do(q{update issues set date_due = addtime(date_due, '0 23:0:0') where hour(date_due) = 0});
index 4eb1210..1056d14 100644 (file)
@@ -1,20 +1,20 @@
 INSERT IGNORE INTO `letter`
 (module, code, name, title, content)
 VALUES
-('circulation','ODUE','Overdue Notice','Item Overdue','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nAccording to our current records, you have items that are overdue.Your library does not charge late fines, but please return or renew them at the branch below as soon as possible.\n\n<<branches.branchname>>\n<<branches.branchaddress1>>\n<<branches.branchaddress2>> <<branches.branchaddress3>>\nPhone: <<branches.branchphone>>\nFax: <<branches.branchfax>>\nEmail: <<branches.branchemail>>\n\nIf you have registered a password with the library, and you have a renewal available, you may renew online. If an item becomes more than 30 days overdue, you will be unable to use your library card until the item is returned.\n\nThe following item(s) is/are currently overdue:\n\n<item>"<<biblio.title>>" by <<biblio.author>>, <<items.itemcallnumber>>, Barcode: <<items.barcode>> Fine: <fine>GBP</fine></item>\n\nThank-you for your prompt attention to this matter.\n\n<<branches.branchname>> Staff\n'),
-('claimacquisition','ACQCLAIM','Acquisition Claim','Item Not Received','<<aqbooksellers.name>>\r\n<<aqbooksellers.address1>>\r\n<<aqbooksellers.address2>>\r\n<<aqbooksellers.address3>>\r\n<<aqbooksellers.address4>>\r\n<<aqbooksellers.phone>>\r\n\r\n<order>Ordernumber <<aqorders.ordernumber>> (<<biblio.title>>) (<<aqorders.quantity>> ordered) ($<<aqorders.listprice>> each) has not been received.</order>'),
-('serial','RLIST','Routing List','Serial is now available','<<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nThe following issue is now available:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)\r\n\r\nPlease pick it up at your convenience.'),
-('members','ACCTDETAILS','Account Details Template - DEFAULT','Your new Koha account details.','Hello <<borrowers.title>> <<borrowers.firstname>> <<borrowers.surname>>.\r\n\r\nYour new Koha account details are:\r\n\r\nUser:  <<borrowers.userid>>\r\nPassword: <<borrowers.password>>\r\n\r\nIf you have any problems or questions regarding your account, please contact your Koha Administrator.\r\n\r\nThank you,\r\nKoha Administrator\r\nkohaadmin@yoursite.org'),
-('circulation','DUE','Item Due Reminder','Item Due Reminder','Dear <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nThe following item is now due:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)'),
-('circulation','DUEDGST','Item Due Reminder (Digest)','Item Due Reminder','You have <<count>> items due'),
-('circulation','PREDUE','Advance Notice of Item Due','Advance Notice of Item Due','Dear <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nThe following item will be due soon:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)'),
-('circulation','PREDUEDGST','Advance Notice of Item Due (Digest)','Advance Notice of Item Due','You have <<count>> items due soon'),
-('reserves', 'HOLD', 'Hold Available for Pickup', 'Hold Available for Pickup at <<branches.branchname>>', 'Dear <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\nLocation: <<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchaddress3>>'),
-('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup at <<branches.branchname>>', '<<branches.branchname>>\n<<branches.branchaddress1>>\n<<branches.branchaddress2>>\n\n\nChange Service Requested\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>>\n<<borrowers.address>>\n<<borrowers.city>> <<borrowers.zipcode>>\n\n\n\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\n\nYou have a hold available for pickup as of <<reserves.waitingdate>>:\r\n\r\nTitle: <<biblio.title>>\r\nAuthor: <<biblio.author>>\r\nCopy: <<items.copynumber>>\r\n'),
-('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you.'),
-('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<<biblio.title>>\r\n----\r\nThank you for visiting <<branches.branchname>>.'),
-('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <<biblio.title>> (<<biblio.biblionumber>>) by the user <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
-('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
-('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>'),
-('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <<branches.branchemail>>\n\nThank you,\n\n<<branches.branchname>>'),
-('suggestions','REJECTED','Suggestion rejected', 'Purchase suggestion declined','Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\nYou have suggested that the library acquire <<suggestions.title>> by <<suggestions.author>>.\n\nThe library has reviewed your request today, and has decided not to accept the suggestion at this time.\n\nThe reason given is: <<suggestions.reason>>\n\nIf you have any questions, please email us at <<branches.branchemail>>.\n\nThank you,\n\n<<branches.branchname>>');
+('circulation','ODUE','Avis de retard','Document en retard','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\n\nSelon nos informations actuelles, vous avez des documents signalés en retard dans votre compte.La Bibliothèque n\'applique pas les pénalités, mais nous vous invitons Ã  retourner ou renouveler ces documents au plus vite dans la Bibliothèque suivante.\n\n<<branches.branchname>>\n<<branches.branchaddress1>>\n<<branches.branchaddress2>> <<branches.branchaddress3>>\nTéléphone: <<branches.branchphone>>\nFax: <<branches.branchfax>>\nCourriel: <<branches.branchemail>>\n\nSi vous possédez un identifiant et un mot de passe pour vous connecter Ã  notre catalogue en ligne,vous pouvez depuis celui-ci prolonger la durée de prêt des documents. Si les documents ont plus de 3à jours de retard, vous ne pourrez plus utiliser votre carte d\'adhérent tant que les documents ne seront pas rendus.\n\nLe(s) document(s) actuellement en retard:\n\n<item>"<<biblio.title>>" de <<biblio.author>>, <<items.itemcallnumber>>, Code barres: <<items.barcode>> Pénalité: <fine>GBP</fine></item>\n\nAvec nos remerciements.\n\n<<branches.branchname>> La banque de prêt\n'),
+('claimacquisition','ACQCLAIM','Réclamation Acquisitions','Document non reçu','<<aqbooksellers.name>>\r\n<<aqbooksellers.address1>>\r\n<<aqbooksellers.address2>>\r\n<<aqbooksellers.address3>>\r\n<<aqbooksellers.address4>>\r\n<<aqbooksellers.phone>>\r\n\r\n<order>Commande <<aqorders.ordernumber>> (<<biblio.title>>) (<<aqorders.quantity>> ordered) ($<<aqorders.listprice>> each) pas encore reçue.</order>'),
+('serial','RLIST','Liste de routage','Fascicule de périodique disponible','<<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nLe numéro suivant est disponible:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)\r\n\r\nVous pouvez venir le retirer quand vous voulez.'),
+('members','ACCTDETAILS','Nouveau compte adhérent','Votre nouveau compte adhérent.','Bonjour <<borrowers.title>> <<borrowers.firstname>> <<borrowers.surname>>.\r\n\r\nLes informations de votre nouveau compte sont:\r\n\r\nIdentifiant:  <<borrowers.userid>>\r\nMot de passe: <<borrowers.password>>\r\n\r\nSi vous avez des questions au sujet de votre nouveau compte, merci de prendre contact Ã  l\'acceuil de la Bibliothèque.\r\n\r\nMerci,\r\nLa Bibliothèque\r\nkohaadmin@yoursite.org'),
+('circulation','DUE','Document Ã  rendre ','Document Ã  rendre','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nLe document suivant doit Ãªtre rendu aujourd\'hui:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)'),
+('circulation','DUEDGST','Document Ã  rendre (résumé)','Document Ã  rendre','Vous avez <<count>> document(s) Ã  rendre'),
+('circulation','PREDUE','Document Ã  rendre bientôt','Document Ã  rendre bientôt','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nLa date de retour du doucment suivant est proche:\r\n\r\n<<biblio.title>>, <<biblio.author>> (<<items.barcode>>)'),
+('circulation','PREDUEDGST','Document Ã  rendre bientôt (résumé)','Document Ã  rendre bientôt','Vous avez <<count>> document(s) dont la date de retour est proche'),
+('reserves', 'HOLD', 'Réservation disponible pour retrait', 'Réservation disponible Ã  la banque de retrait du site <<branches.branchname>>', 'Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\r\n\r\nVous avez une réservation disponible pour retrait depuis le <<reserves.waitingdate>>:\r\n\r\nTitre: <<biblio.title>>\r\nAuteur: <<biblio.author>>\r\nNuméro de fascicule: <<items.copynumber>>\r\nSite: <<branches.branchname>>\r\n<<branches.branchaddress1>>\r\n<<branches.branchaddress2>>\r\n<<branches.branchaddress3>>'),
+('reserves', 'HOLD_PRINT', 'Réservation disponible pour retrait (papier)', 'Réservation disponible Ã  la banque de retrait du site <<branches.branchname>>', '<<branches.branchname>>\n<<branches.branchaddress1>>\n<<branches.branchaddress2>>\n\n\nLe service des réservations\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>>\n<<borrowers.address>>\n<<borrowers.city>> <<borrowers.zipcode>>\n\n\n\n\n\n\n\n\n\n\n<<borrowers.firstname>> <<borrowers.surname>> <<borrowers.cardnumber>>\n\nVotre réservation est disponible pour retrait depuis le <<reserves.waitingdate>>:\r\n\r\nTitre: <<biblio.title>>\r\nAuteur: <<biblio.author>>\r\nNuméro de fascicule: <<items.copynumber>>\r\n'),
+('circulation','CHECKIN','Document rendu (résumé)','Retours','Les documents suivants ont Ã©té rendus:\r\n----\r\n<<biblio.title>>\r\n----\r\nMerci.'),
+('circulation','CHECKOUT','Document prêté (résumé)','Prêts','Les documents suivants ont Ã©té prêtés:\r\n----\r\n<<biblio.title>>\r\n----\r\nMerci de votre visite <<branches.branchname>>.'),
+('reserves', 'HOLDPLACED', 'Demande de réservation', 'Demande de réservation','Une demande de réservation a Ã©té placée sur le document : <<biblio.title>> (<<biblio.biblionumber>>) par l\'adhérent <<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>).'),
+('suggestions','ACCEPTED','Suggestion accceptée', 'Suggestion acceptée','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\n\nVous avez crée une suggestion d\'achat au sujet du document <<suggestions.title>> de <<suggestions.author>>.\n\nLa Bibliothèque a reçu votre demande ce jour. Nous donnerons suite Ã  votre demande aussi vite que possible. Vous serez averti par courriel dès que la commande sera envoyée,et quand les documents seront arrivés Ã  la Bibliothèque.\n\nSi vous avez des questions, merci de nous contacter Ã  l\'adresse suivante <<branches.branchemail>>.\n\nMerci,\n\n<<branches.branchname>>'),
+('suggestions','AVAILABLE','Suggestion disponible', 'Suggestion d\'achat disponible','cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\n\nVous avez effectué une suggestion d\'achat pour le docuement  <<suggestions.title>> de <<suggestions.author>>.\n\nNous sommes heureux de vous informer que le document que vous aviez demandé est maintenant disponible dans nos collections.\n\nSi vous avez des questions, merci de nous contacter par courriel Ã  l\'adresse <<branches.branchemail>>.\n\nMerci,\n\n<<branches.branchname>>'),
+('suggestions','ORDERED','Suggestion commandée', 'Suggestion commandée','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\n\nVous avez effectué une demande de suggestion d\'achat sur le docuement <<suggestions.title>> de <<suggestions.author>>.\n\nNous sommes heureux de vous informer que le document que vous avez demandé est maintenant en commande. Le document devrait arriver rapidement dans nos collections.\n\nVous serez averti quand le docuement sera disponible.\n\nSi vous avez des questions, merci de nous contacter Ã  l\'adresse <<branches.branchemail>>\n\nMerci,\n\n<<branches.branchname>>'),
+('suggestions','REJECTED','Suggestion rejetée', 'Suggestion d\'achat rejeté','Cher(e) <<borrowers.firstname>> <<borrowers.surname>>,\n\nVous avez fait la demande du document <<suggestions.title>> de <<suggestions.author>>.\n\nla Bibliothèque a examiné votre demande ce jour, et a décidé de ne pas retenir la suggestion pour l\'instant.\n\nLa raison est la suivante: <<suggestions.reason>>\n\nSi vous avez des questions, merci de nous contacter Ã  l\'adresse <<branches.branchemail>>.\n\nMerci,\n\n<<branches.branchname>>');
index e0ce034..26689c6 100644 (file)
@@ -286,6 +286,8 @@ CREATE TABLE `borrower_attribute_types` ( -- definitions for custom patron field
   `staff_searchable` tinyint(1) NOT NULL default 0, -- defines if this field is searchable via the patron search in the staff client (1 for yes, 0 for no)
   `authorised_value_category` varchar(10) default NULL, -- foreign key from authorised_values that links this custom field to an authorized value category
   `display_checkout` tinyint(1) NOT NULL default 0,-- defines if this field displays in checkout screens
+  `category_code` VARCHAR(1) NOT NULL DEFAULT '',-- defines a category for an attribute_type
+  `class` VARCHAR(255) NOT NULL DEFAULT '',-- defines a class for an attribute_type
   PRIMARY KEY  (`code`),
   KEY `auth_val_cat_idx` (`authorised_value_category`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -362,6 +364,7 @@ CREATE TABLE `branches` ( -- information about your libraries or branches are st
   `branchip` varchar(15) default NULL, -- the IP address for your library or branch
   `branchprinter` varchar(100) default NULL, -- unused in Koha
   `branchnotes` mediumtext, -- notes related to your library or branch
+  opac_info text, -- HTML that displays in OPAC
   UNIQUE KEY `branchcode` (`branchcode`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
@@ -953,15 +956,15 @@ DROP TABLE IF EXISTS `issues`;
 CREATE TABLE `issues` ( -- information related to check outs or issues
   `borrowernumber` int(11), -- foreign key, linking this to the borrowers table for the patron this item was checked out to
   `itemnumber` int(11), -- foreign key, linking this to the items table for the item that was checked out
-  `date_due` date default NULL, -- date the item is due (yyyy-mm-dd)
+  `date_due` datetime default NULL, -- datetime the item is due (yyyy-mm-dd hh:mm::ss)
   `branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out
   `issuingbranch` varchar(18) default NULL,
-  `returndate` date default NULL, -- date the item was returned, will be NULL until moved to old_issues
-  `lastreneweddate` date default NULL, -- date the item was last renewed
+  `returndate` datetime default NULL, -- date the item was returned, will be NULL until moved to old_issues
+  `lastreneweddate` datetime default NULL, -- date the item was last renewed
   `return` varchar(4) default NULL,
   `renewals` tinyint(4) default NULL, -- lists the number of times the item was renewed
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched
-  `issuedate` date default NULL, -- date the item was checked out or issued
+  `issuedate` datetime default NULL, -- date the item was checked out or issued
   KEY `issuesborridx` (`borrowernumber`),
   KEY `bordate` (`borrowernumber`,`timestamp`),
   CONSTRAINT `issues_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE RESTRICT ON UPDATE CASCADE,
@@ -1204,6 +1207,7 @@ CREATE TABLE `marc_subfield_structure` (
   `seealso` varchar(1100) default NULL,
   `link` varchar(80) default NULL,
   `defaultvalue` text default NULL,
+  `maxlength` int(4) NOT NULL DEFAULT '9999',
   PRIMARY KEY  (`frameworkcode`,`tagfield`,`tagsubfield`),
   KEY `kohafield_2` (`kohafield`),
   KEY `tab` (`frameworkcode`,`tab`),
@@ -1416,15 +1420,15 @@ DROP TABLE IF EXISTS `old_issues`;
 CREATE TABLE `old_issues` ( -- lists items that were checked out and have been returned
   `borrowernumber` int(11) default NULL, -- foreign key, linking this to the borrowers table for the patron this item was checked out to
   `itemnumber` int(11) default NULL, -- foreign key, linking this to the items table for the item that was checked out
-  `date_due` date default NULL, -- date the item is due (yyyy-mm-dd)
+  `date_due` datetime default NULL, -- date the item is due (yyyy-mm-dd)
   `branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out
   `issuingbranch` varchar(18) default NULL,
-  `returndate` date default NULL, -- date the item was returned
-  `lastreneweddate` date default NULL, -- date the item was last renewed
+  `returndate` datetime default NULL, -- date the item was returned
+  `lastreneweddate` datetime default NULL, -- date the item was last renewed
   `return` varchar(4) default NULL,
   `renewals` tinyint(4) default NULL, -- lists the number of times the item was renewed
   `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched
-  `issuedate` date default NULL, -- date the item was checked out or issued
+  `issuedate` datetime default NULL, -- date the item was checked out or issued
   KEY `old_issuesborridx` (`borrowernumber`),
   KEY `old_issuesitemidx` (`itemnumber`),
   KEY `old_bordate` (`borrowernumber`,`timestamp`),
@@ -2055,11 +2059,15 @@ DROP TABLE IF EXISTS `virtualshelves`;
 CREATE TABLE `virtualshelves` ( -- information about lists (or virtual shelves) 
   `shelfnumber` int(11) NOT NULL auto_increment, -- unique identifier assigned by Koha
   `shelfname` varchar(255) default NULL, -- name of the list
-  `owner` varchar(80) default NULL, -- foriegn key linking to the borrowers table (using borrowernumber) for the creator of this list
-  `category` varchar(1) default NULL, -- type of list (public [2], private [1] or open [3])
+  `owner` int default NULL, -- foreign key linking to the borrowers table (using borrowernumber) for the creator of this list (changed from varchar(80) to int)
+  `category` varchar(1) default NULL, -- type of list (private [1], public [2])
   `sortfield` varchar(16) default NULL, -- the field this list is sorted on
   `lastmodified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- date and time the list was last modified
-  PRIMARY KEY  (`shelfnumber`)
+  `allow_add` tinyint(1) default 0, -- permission for adding entries to list
+  `allow_delete_own` tinyint(1) default 1, -- permission for deleting entries frm list that you added yourself
+  `allow_delete_other` tinyint(1) default 0, -- permission for deleting entries from list that another person added
+  PRIMARY KEY  (`shelfnumber`),
+  CONSTRAINT `virtualshelves_ibfk_1` FOREIGN KEY (`owner`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL -- no cascaded delete, please see HandleDelBorrower in VirtualShelves.pm
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 --
@@ -2072,10 +2080,27 @@ CREATE TABLE `virtualshelfcontents` ( -- information about the titles in a list
   `biblionumber` int(11) NOT NULL default 0, -- foreign key linking to the biblio table, defines the bib record that has been added to the list
   `flags` int(11) default NULL,
   `dateadded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- date and time this bib record was added to the list
+  `borrowernumber` int, -- borrower number that created this list entry (only the first one is saved: no need for use in/as key)
   KEY `shelfnumber` (`shelfnumber`),
   KEY `biblionumber` (`biblionumber`),
   CONSTRAINT `virtualshelfcontents_ibfk_1` FOREIGN KEY (`shelfnumber`) REFERENCES `virtualshelves` (`shelfnumber`) ON DELETE CASCADE ON UPDATE CASCADE,
-  CONSTRAINT `shelfcontents_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE
+  CONSTRAINT `shelfcontents_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `shelfcontents_ibfk_3` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL -- no cascaded delete, please see HandleDelBorrower in VirtualShelves.pm
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `virtualshelfshares`
+--
+
+DROP TABLE IF EXISTS `virtualshelfshares`;
+CREATE TABLE `virtualshelfshares` ( -- shared private lists
+  `id` int AUTO_INCREMENT PRIMARY KEY,  -- unique key
+  `shelfnumber` int NOT NULL,  -- foreign key for virtualshelves
+  `borrowernumber` int,  -- borrower that accepted access to this list
+  `invitekey` varchar(10), -- temporary string used in accepting the invitation to access thist list; not-empty means that the invitation has not been accepted yet
+  `sharedate` datetime,  -- date of invitation or acceptance of invitation
+  CONSTRAINT `virtualshelfshares_ibfk_1` FOREIGN KEY (`shelfnumber`) REFERENCES `virtualshelves` (`shelfnumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `virtualshelfshares_ibfk_2` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL -- no cascaded delete, please see HandleDelBorrower in VirtualShelves.pm
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 --
@@ -2094,6 +2119,7 @@ CREATE TABLE `z3950servers` ( -- connection information for the Z39.50 targets u
   `checked` smallint(6) default NULL, -- whether this target is checked by default  (1 for yes, 0 for no)
   `rank` int(11) default NULL, -- where this target appears in the list of targets
   `syntax` varchar(80) default NULL, -- marc format provided by this target
+  `timeout` int(11) NOT NULL DEFAULT '0',
   `icon` text, -- unused in Koha
   `position` enum('primary','secondary','') NOT NULL default 'primary',
   `type` enum('zed','opensearch') NOT NULL default 'zed',
@@ -2763,6 +2789,22 @@ CREATE TABLE `biblioimages` (
  CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
+--
+-- Table structure for table `social_data`
+--
+
+DROP TABLE IF EXISTS `social_data`;
+CREATE TABLE IF NOT EXISTS `social_data` (
+  `isbn` VARCHAR(30),
+  `num_critics` INT,
+  `num_critics_pro` INT,
+  `num_quotations` INT,
+  `num_videos` INT,
+  `score_avg` DECIMAL(5,2),
+  `num_scores` INT,
+  PRIMARY KEY  (`isbn`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
 /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
index cb0ce50..1deca7a 100644 (file)
@@ -1,6 +1,6 @@
-INSERT INTO `z3950servers` VALUES 
-('z3950.loc.gov',7090,'Voyager','','','LIBRARY OF CONGRESS',1,0,0,'USMARC',NULL,'primary','zed','MARC-8',''),
-('z3950.bibsys.no',2100,'BIBSYS','','','BIBSYS',12,1,1,'NORMARC',NULL,'primary','zed','ISO_6937',''),
-('z3950.nb.no',2100,'Norbok','','','NORBOK',13,0,0,'NORMARC',NULL,'primary','zed','ISO_6937',''),
-('z3950.nb.no',2100,'Sambok','','','SAMBOK',14,0,0,'NORMARC',NULL,'primary','zed','ISO_6937',''),
-('z3950.deich.folkebibl.no',210,'data','','','DEICHMAN',15,0,0,'NORMARC',NULL,'primary','zed','ISO_6937','');
\ No newline at end of file
+INSERT INTO z3950servers (host, port, db, userid, password, name, id, checked, rank, syntax, timeout, icon, position, type, encoding, description) VALUES
+('z3950.loc.gov',7090,'Voyager','','','LIBRARY OF CONGRESS',1,0,0,'USMARC',0,NULL,'primary','zed','MARC-8',''),
+('z3950.bibsys.no',2100,'BIBSYS','','','BIBSYS',12,1,1,'NORMARC',0,NULL,'primary','zed','ISO_6937',''),
+('z3950.nb.no',2100,'Norbok','','','NORBOK',13,0,0,'NORMARC',0,NULL,'primary','zed','ISO_6937',''),
+('z3950.nb.no',2100,'Sambok','','','SAMBOK',14,0,0,'NORMARC',0,NULL,'primary','zed','ISO_6937',''),
+('z3950.deich.folkebibl.no',210,'data','','','DEICHMAN',15,0,0,'NORMARC',0,NULL,'primary','zed','ISO_6937','');
index fe69552..4a12a17 100644 (file)
@@ -353,3 +353,9 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('
 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RoutingListNote','To change this note edit <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=RoutingListNote#jumped">RoutlingListNote</a> system preference.','Define a note to be shown on all routing lists','70|10','Textarea');
 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('AllowPKIAuth','None','Use the field from a client-side SSL certificate to look a user in the Koha database','None|Common Name|emailAddress','Choice');
 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OAI-PMH:AutoUpdateSets','0','Automatically update OAI sets when a bibliographic record is created or updated','','YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowPublicListCreation',1,'If set, allows opac users to create public lists',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowSharingPrivateLists',0,'If set, allows opac users to share private lists with other patrons',NULL,'YesNo');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_js','','Url for Babeltheque javascript (e.g. http://www.babeltheque.com/bw_XX.js)','','Free');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_update', '', 'Url for Babeltheque update (E.G. http://www.babeltheque.com/.../file.csv.bz2)', '', 'Free');
+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SocialNetworks','1','Enable/Disable social networks links in opac detail pages','','YesNo');
+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('SubscriptionDuplicateDroppedInput','','','List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)','Free');
index eb5f58a..d29c8e4 100755 (executable)
@@ -4932,7 +4932,6 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     SetVersion($DBversion);
 }
 
-
 $DBversion = "3.07.00.029";
 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     my $installer = C4::Installer->new();
@@ -4967,6 +4966,135 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
     SetVersion ($DBversion);
 }
 
+$DBversion = "3.07.00.032";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do("ALTER TABLE virtualshelves MODIFY COLUMN owner int"); #should have been int already (fk to borrowers)
+    $dbh->do("UPDATE virtualshelves vi LEFT JOIN borrowers bo ON bo.borrowernumber=vi.owner SET vi.owner=NULL where bo.borrowernumber IS NULL"); #before adding the constraint on borrowernumber, we need to get rid of deleted owners
+    $dbh->do("DELETE FROM virtualshelves WHERE owner IS NULL and category=1"); #delete private lists without owner (cascades to shelfcontents)
+    $dbh->do("ALTER TABLE virtualshelves ADD COLUMN allow_add tinyint(1) DEFAULT 0, ADD COLUMN allow_delete_own tinyint(1) DEFAULT 1, ADD COLUMN allow_delete_other tinyint(1) DEFAULT 0, ADD CONSTRAINT `virtualshelves_ibfk_1` FOREIGN KEY (`owner`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL");
+    $dbh->do("UPDATE virtualshelves SET allow_add=0, allow_delete_own=1, allow_delete_other=0 WHERE category=1");
+    $dbh->do("UPDATE virtualshelves SET allow_add=0, allow_delete_own=1, allow_delete_other=0 WHERE category=2");
+    $dbh->do("UPDATE virtualshelves SET allow_add=1, allow_delete_own=1, allow_delete_other=1 WHERE category=3");
+    $dbh->do("UPDATE virtualshelves SET category=2 WHERE category=3");
+
+    $dbh->do("ALTER TABLE virtualshelfcontents ADD COLUMN borrowernumber int, ADD CONSTRAINT `shelfcontents_ibfk_3` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL");
+    $dbh->do("UPDATE virtualshelfcontents co LEFT JOIN virtualshelves sh USING (shelfnumber) SET co.borrowernumber=sh.owner");
+
+    $dbh->do("CREATE TABLE virtualshelfshares
+    (id int AUTO_INCREMENT PRIMARY KEY, shelfnumber int NOT NULL,
+    borrowernumber int, invitekey varchar(10), sharedate datetime,
+    CONSTRAINT `virtualshelfshares_ibfk_1` FOREIGN KEY (`shelfnumber`) REFERENCES `virtualshelves` (`shelfnumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+        CONSTRAINT `virtualshelfshares_ibfk_2` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE SET NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+
+    $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowPublicListCreation',1,'If set, allows opac users to create public lists',NULL,'YesNo');");
+    $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowSharingPrivateLists',0,'If set, allows opac users to share private lists with other patrons',NULL,'YesNo');");
+
+    print "Upgrade to $DBversion done (BZ7310: Improving list permissions)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.033";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+    $dbh->do("ALTER TABLE branches ADD opac_info text;");
+    print "Upgrade to $DBversion done add opac_info to branches \n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.034";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+    $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN category_code VARCHAR(10) NULL DEFAULT NULL AFTER `display_checkout`");
+    $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN class VARCHAR(255)  NOT NULL DEFAULT '' AFTER `category_code`");
+    $dbh->do("ALTER TABLE borrower_attribute_types ADD CONSTRAINT category_code_fk FOREIGN KEY (category_code) REFERENCES categories(categorycode)");
+    print "Upgrade to $DBversion done (New fields category_code and class in borrower_attribute_types table)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.035";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do("ALTER TABLE issues CHANGE date_due date_due datetime");
+    $dbh->do("ALTER TABLE issues CHANGE returndate returndate datetime");
+    $dbh->do("ALTER TABLE issues CHANGE lastreneweddate lastreneweddate datetime");
+    $dbh->do("ALTER TABLE issues CHANGE issuedate issuedate datetime");
+    $dbh->do("ALTER TABLE old_issues CHANGE date_due date_due datetime");
+    $dbh->do("ALTER TABLE old_issues CHANGE returndate returndate datetime");
+    $dbh->do("ALTER TABLE old_issues CHANGE lastreneweddate lastreneweddate datetime");
+    $dbh->do("ALTER TABLE old_issues CHANGE issuedate issuedate datetime");
+    $dbh->do("alter table issuingrules add column lengthunit varchar(10) default 'days' after issuelength");
+    print "Upgrade to $DBversion done (Setting up issues tables for hourly loans)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.036";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do(qq{
+       ALTER TABLE z3950servers ADD timeout INT( 11 ) NOT NULL DEFAULT '0' AFTER syntax;
+    });
+    print "Upgrade to $DBversion done (New timeout field in z3950servers)\n";
+}
+
+$DBversion = "3.07.00.037";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do("
+       ALTER TABLE  `marc_subfield_structure` ADD  `maxlength` INT( 4 ) NOT NULL DEFAULT  '9999';
+       ");
+       $dbh->do("
+       UPDATE `marc_subfield_structure` SET maxlength=24 WHERE tagfield='000';
+       ");
+       $dbh->do("
+       UPDATE marc_subfield_structure SET maxlength = IF ((SELECT value FROM systempreferences WHERE variable = 'marcflavour')='MARC21','40','9999') WHERE tagfield='008';
+       ");
+       $dbh->do("
+       UPDATE marc_subfield_structure SET maxlength = IF ((SELECT value FROM systempreferences WHERE variable = 'marcflavour')='UNIMARC','36','9999') WHERE tagfield='100';
+       ");
+    print "Upgrade to $DBversion done (Add new field maxlength to marc_subfield_structure)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.038";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do(qq{
+        INSERT INTO systempreferences(variable,value,explanation,options,type)
+        VALUES('UniqueItemFields', 'barcode', 'Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table', '', 'Free')
+    });
+    print "Upgrade to $DBversion done (Added system preference 'UniqueItemFields')\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.039";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do( qq{INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Babeltheque_url_js','','Url for Babeltheque javascript (e.g. http://www.babeltheque.com/bw_XX.js','','Free')} );
+    $dbh->do( qq{CREATE TABLE IF NOT EXISTS social_data
+      ( isbn VARCHAR(30),
+        num_critics INT,
+        num_critics_pro INT,
+        num_quotations INT,
+        num_videos INT,
+        score_avg DECIMAL(5,2),
+        num_scores INT,
+        PRIMARY KEY  (isbn)
+      ) ENGINE=InnoDB DEFAULT CHARSET=utf8
+    } );
+    $dbh->do( qq{INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('Babeltheque_url_update', '', 'Url for Babeltheque update (E.G. http://www.babeltheque.com/.../file.csv.bz2)', '', 'Free')} );
+    print "Upgrade to $DBversion done (added syspref and table for babeltheque (Babeltheque_url_js, babeltheque))\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "3.07.00.040";
+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
+    $dbh->do( qq{INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('SocialNetworks','0','Enable/Disable social networks links in opac detail','','YesNo')} );
+    print "Upgrade to $DBversion done (added syspref SocialNetworks, to display facebook/ggl+ and other buttons)\n";
+    SetVersion($DBversion);
+}
+
+
+
+$DBversion = "3.07.00.041";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+    $dbh->do("INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('SubscriptionDuplicateDroppedInput','','','List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)','Free')");
+    print "Upgrade to $DBversion done (Add System Preferences SubscriptionDuplicateDroppedInput)\n";
+    SetVersion($DBversion);
+}
+
 =head1 FUNCTIONS
 
 =head2 DropAllForeignKeys($table)
index 3c67949..726ecc6 100644 (file)
-borrowers.borrowernumber       Borrower Number
-borrowers.cardnumber   Card Number
+borrowers.borrowernumber       Borrower number
+borrowers.title        Salutation
 borrowers.surname      Surname
-borrowers.firstname    Firstname
-borrowers.title        Title
-borrowers.othernames Other Names
-borrowers.initials      Initials
-borrowers.streetaddress        Street Address 
-borrowers.suburb       Suburb
-borrowers.city City
-borrowers.phone        Phone
-borrowers.emailaddress Email 
-borrowers.faxnumber    Fax
-borrowers.textmessaging        Opac Message
-borrowers.altstreetaddress      Alternative Street Address
-borrowers.altsuburb    Alternative Suburb
-borrowers.altcity      Alternative City
-borrowers.altphone     Alternative Phone
-borrowers.dateofbirth  Date of Birth
-borrowers.branchcode   Branch Code
-borrowers.categorycode Borrowers Category
-borrowers.dateenrolled Date Enrolled
-borrowers.gonenoaddress        Address Missing
-borrowers.lost Lost Card
-borrowers.debarred     Restricted
-borrowers.studentnumber         Student Id number
-borrowers.school       School
-borrowers.contactname  Contact Name
-borrowers.borrowernotes        Circulation Notes
-borrowers.guarantor    Guarantor(parent)
-borrowers.area Area
-borrowers.ethnicity    Ethnicity
-borrowers.ethnotes     Ethnicity Notes
+borrowers.firstname    First name
+borrowers.dateofbirth  Date of birth
+borrowers.initials     Initials
+borrowers.othernames   Other name
 borrowers.sex  Gender
-borrowers.expiry       Expiry Date
-borrowers.altnotes     Alternative Contact Notes
-borrowers.altrelationship      Relationship of Alternative Contact
-borrowers.streetcity   Streetcity??
-borrowers.phoneday     Work Phone
-borrowers.preferredcont         Preferred method of Contact
-borrowers.physstreet   Physical Street Address
-borrowers.password      Password
-borrowers.flags        Warnings
-borrowers.userid       Login ID
-borrowers.homezipcode  Zip/Post Code
-borrowers.zipcode      Zip/Post Code 2?
-borrowers.sort1        Sorting Column
-borrowers.sort2        Sorting Column 2
-borrowers.cellph       Cellphone number
-borrowers.borlog
-borrowers.checkhist
-items.itemnumber       Item Number (koha internal)
-items.biblionumber     Biblio Number (koha internal)
-items.multivolumepart  Item one part of a Multi volume set
-items.biblioitemnumber Biblioitem Number (koha internal)
+borrowers.relationship Relationship
+borrowers.guarantorid  Guarantor borrower number
+borrowers.streetnumber Street number
+borrowers.streettype   Street type
+borrowers.address      Address
+borrowers.address2     Address 2
+borrowers.city City
+borrowers.state        State
+borrowers.zipcode      Zip/postal code
+borrowers.country      Country
+borrowers.phone        Primary phone
+borrowers.phonepro     Secondary phone
+borrowers.mobile       Other phone
+borrowers.email        Primary email
+borrowers.emailpro     Secondary email
+borrowers.fax  Fax
+borrowers.B_streetnumber       Alternate address: Street number
+borrowers.B_streettype Alternate address: Street type
+borrowers.B_address    Alternate address: Address
+borrowers.B_address2   Alternate address: Address 2
+borrowers.B_city       Alternate address: City
+borrowers.B_state      Alternate address: State
+borrowers.B_zipcode    Alternate address: Zip/postal code
+borrowers.B_country    Alternate address: Country
+borrowers.B_phone      Alternate address: Phone
+borrowers.B_email      Alternate address: Email
+borrowers.contactnote  Alternate contact: Note
+borrowers.altcontactfirstname  Alternate contact: Last name
+borrowers.altcontactsurname    Alternate contact: First name
+borrowers.altcontactaddress1   Alternate contact: Address
+borrowers.altcontactaddress2   Alternate contact: Address 2
+borrowers.altcontactaddress3   Alternate contact: City
+borrowers.contactname  Alternate contact: Surname
+borrowers.contactfirstname     Alternate contact: First name
+borrowers.contacttitle Alternate contact: Title
+borrowers.altcontactstate      Alternate contact: State
+borrowers.altcontactzipcode    Alternate contact: Zip/postal code
+borrowers.altcontactcountry    Alternate contact: Country
+borrowers.altcontactphone      Alternate contact: Phone
+borrowers.cardnumber   Card number
+borrowers.branchcode   Home library
+borrowers.categorycode Category
+borrowers.sort1        Sort 1
+borrowers.sort2        Sort 2
+borrowers.dateenrolled Registration date
+borrowers.dateexpiry   Expiry date
+borrowers.opacnote     OPAC note
+borrowers.borrowernotes        Circulation note
+borrowers.userid       Username
+borrowers.password     Password
+borrowers.flags        System permissions
+borrowers.gonenoaddress        Gone no address flag
+borrowers.lost Lost card flag
+borrowers.debarred     Restricted [until] flag
+borrowers.debarredcomment      Comment
+borrowers.smsalertnumber       Mobile phone number
+borrowers.privacy      Privacy settings
+items.itemnumber       Item number (internal)
+items.biblionumber     Biblio number (internal)
+items.biblioitemnumber Biblioitem number (internal)
 items.barcode  Barcode
-items.dateaccessioned  Accession Date
-items.booksellerid     Supplier ID
-items.homebranch       Home Branch
+items.dateaccessioned  Date acquired
+items.booksellerid     Source of acquisition
+items.homebranch       Permanent library
 items.price    Price
-items.replacementprice Replacement Price
-items.replacementpricedate     Date Replacement Price was set
-items.datelastborrowed Date Item last issued
-items.datelastseen     Date Item was last seen by Koha
-items.multivolume      Volume Number (if part of a multivolume work)
-items.stack    Is the item in the stack?
-items.onloan   On loan
-items.notforloan       Item Not for loan
-items.itemlost Item Lost
-items.wthdrawn Item Cancelled
-items.itemcallnumber   Item Call Number
-items.issues   Issues Count
-items.renewals Renewals Count
-items.reserves Reserves Count
-items.restricted       Item Restricted
-items.binding  Item needs binding
-items.itemnotes        Item Notes
-items.holdingbranch    Holding Branch
-items.paidfor  Has Item been lost and then paid for
+items.replacementprice Replacement price
+items.replacementpricedate     Price effective from
+items.datelastborrowed Date last checked out
+items.datelastseen     Date last seen
+items.stack    Shelving control number
+items.onloan   Due date
+items.cn_source        Source of classification / shelving scheme
+items.cn_sort  Koha normalized classification for sorting
+items.notforloan       Not for loan
+items.itemlost Lost status
+items.wthdrawn Withdrawn status
+items.itemcallnumber   Call number
+items.issues   Total checkouts
+items.renewals Total renewals
+items.reserves Total holds
+items.restricted       Use restrictions
+items.itemnotes        Public note
+items.holdingbranch    Current library
+items.paidfor
 items.timestamp        Timestamp
-items.location Location
-items.ccode    Koha Collection
-items.itype    Item-level Item Type
-items.spystatus
-items.spydescr
-items.itemlog
-items.spycopydata
-statistics.datetime    Statistics Date and Time
-statistics.branch      Branch Code
-statistics.proccode    Type of Procedure
+items.location Shelving location
+items.ccode    Collection code
+items.itype    Koha itemtype
+items.stocknumber      Inventory number
+items.damaged  Damaged status
+items.materials        Materials specified
+items.uri      Uniform Resource Identifier
+items.more_subfields_xml       Additional subfields (XML)
+items.enumchron        Serial enumeraton/chronology
+items.copynumber       Copy number
+statistics.datetime    Statistics date and time
+statistics.branch      Library
+statistics.proccode    Type of procedure
 statistics.value       Value
 statistics.type        Type
 statistics.other
-statistics.usercode    User Code
-statistics.itemnumber  Item Number
-statistics.itemtype    Item Type
-statistics.borrowernumber      Borrower Number
-biblio.frameworkcode   Framework Code
+statistics.usercode    User code
+statistics.itemnumber  Item number
+statistics.itemtype    Itemtype
+statistics.borrowernumber      Borrower number
+biblio.frameworkcode   Framework code
 biblio.author  Author
-biblio.datecreated     Creation Date
-biblio.timestamp       Modification Date
-biblioitems.biblioitemnumber   Biblioitem Number
-biblioitems.biblionumber       Biblio Number
-biblioitems.volume     Volume Number
+biblio.datecreated     Creation date
+biblio.timestamp       Modification date
+biblioitems.biblioitemnumber   Biblioitem number
+biblioitems.biblionumber       Biblio number
+biblioitems.volume     Volume number
 biblioitems.number     Number
 biblioitems.classification     Classification
-biblioitems.itemtype   Biblio-level Item Type
+biblioitems.itemtype   Biblio-level item type
 biblioitems.isbn       ISBN
 biblioitems.issn       ISSN
-biblioitems.dewey      Dewey/Classification
-biblioitems.subclass   Sub Classification
-biblioitems.publicationyear    Publication Date
+biblioitems.dewey      Dewey/classification
+biblioitems.subclass   Sub classification
+biblioitems.publicationyear    Publication date
 biblioitems.publishercode      Publisher
-biblioitems.volumedate Volume Date
-biblioitems.volumeddesc        Volume Information
+biblioitems.volumedate Volume date
+biblioitems.volumedesc Volume information
 biblioitems.timestamp  Timestamp
 biblioitems.illus      Illustrator
-biblioitems.pages      Number of Pages
+biblioitems.pages      Number of pages
 biblioitems.notes      Notes
 biblioitems.size       Size
-biblioitems.place      Place of Publication
+biblioitems.place      Place of publication
 biblioitems.lccn       LCCN
-biblioitems.marc       MARC Blob
+biblioitems.marcxml    MARC blob
 biblioitems.url        URL
index 78dd4f9..fa66dbf 100644 (file)
@@ -82,9 +82,6 @@ h1,h2,h3,h4,h5,h6 {
        margin : .3em 0;
 }
 
-html {
-}
-
 p {
        margin: .5em 0 .5em 0;
 }
@@ -111,9 +108,6 @@ em strong {
     font-style : italic;
 }
 
-#hd {
-}
-
 #navigation {
        border-right : 1px solid #BCBCBC;
 }
@@ -140,12 +134,6 @@ em strong {
        text-decoration : none;
 }
 
-#ft {
-}
-
-.yui-u {
-}
-
 #doc, #doc1, #doc2, #doc3 {
        padding-top : 1em;
 }
@@ -155,10 +143,6 @@ em strong {
        right : .5em;
 }
 
-#login a {
-
-}
-
 ul {
        padding-left : 1.1em;
 }
@@ -449,9 +433,6 @@ ul.toolbar button {
        padding-bottom : 2px;
        font-family: arial, verdana, helvetica, sans-serif;
 }
-.yui-menu-button  {
-       
-}
 
 a.yuimenuitemlabel-disabled, #disabled a {
        color: #999;
@@ -824,10 +805,6 @@ fieldset.rows .inputnote {
        text-decoration : none;
 }
 
-.toptabs .ui-tabs-nav li.ui-tabs-selected  {
-
-}
-
 .toptabs .ui-tabs-nav li.ui-tabs-selected a, .toptabs .ui-tabs-nav li.ui-tabs-selected span.a {
        background-color : #FFF;
        border-bottom : 1px solid #FFF;
@@ -1526,9 +1503,6 @@ html>/**/body #searchheader button, x:-moz-any-link, x:default {
        padding-bottom : 3px;
 }
 
-#searchheader h3 {
-}
-
 #searchheader form {
        float : right;
 }
@@ -1580,9 +1554,6 @@ html>/**/body #searchheader button, x:-moz-any-link, x:default {
        padding : .1em .2em;
 }
 
-#search-facets li li a {
-}
-
 #search-facets li.showmore {
        font-weight : bold;
        text-indent : 1em;
@@ -1767,7 +1738,6 @@ ul#i18nMenu li ul li {
        padding : 0;
  }
  
-               
 ul#i18nMenu li.more a {
        background-image:url(../../img/more-up-arrow.gif);
        background-position:right center;
@@ -1877,7 +1847,6 @@ span.permissiondesc {
        padding : .5em;
 }
 
-
 /* borrower autocomplete */
 #borrowerautocomplete { width: 450px; text-align:left;} /* z-index needed on top instances for ie & sf absolute inside relative issue */
 .autocomplete .yui-ac-highlight ,
@@ -2164,3 +2133,23 @@ a.localimage img {
 div.pager p {
        margin: 0;
 }
+
+div#acqui_order_supplierlist > div.supplier {
+    border: 1px solid #EEEEEE;
+    margin: 0.5em;
+    padding: 1em;
+}
+
+div#acqui_order_supplierlist > div.supplier > span.suppliername {
+    display: inline;
+    font-size: 1.7em;
+    margin-bottom: 0.5em;
+}
+
+div#acqui_order_supplierlist > div.supplier > span.action {
+    margin-left: 5em;
+}
+
+div#acqui_order_supplierlist > div.supplier > div.baskets {
+    margin-top: 0.5em;
+}
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc
new file mode 100644 (file)
index 0000000..5ab37f4
--- /dev/null
@@ -0,0 +1,10 @@
+<script type="text/javascript">
+//<![CDATA[
+var MSG_ADDITEM_JS_EDIT = _("Edit");
+var MSG_ADDITEM_JS_DELETE = _("Delete");
+var MSG_ADDITEM_JS_CLEAR = _("Clear");
+var MSG_ADDITEM_JS_CANT_RECEIVE_MORE_ITEMS = _("You can't receive any more items");
+var MSG_ADDITEM_JS_IS_DUPLICATE = _("is duplicated");
+var MSG_ADDITEM_JS_ALREADY_EXISTS_IN_DB = _("already exists in database");
+//]]>
+</script>
index d07c577..36bb08f 100644 (file)
@@ -39,7 +39,7 @@
 
            new YAHOO.widget.Button({
                type: "menu",
-               label: _("New"),
+               label: _("New patron"),
                name: "newmenubutton",
                menu: newmenu,
                container: "newmenuc"
index 8a739d5..53360b0 100644 (file)
@@ -23,7 +23,7 @@
        <li><a href="/cgi-bin/koha/tools/import_borrowers.pl">Import patrons</a></li>
     [% END %]
     [% IF ( CAN_user_tools_edit_notices ) %]
-       <li><a href="/cgi-bin/koha/tools/letter.pl">Notices</a></li>
+       <li><a href="/cgi-bin/koha/tools/letter.pl">Notices & Slips</a></li>
     [% END %]
     [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
        <li><a href="/cgi-bin/koha/tools/overduerules.pl">Overdue notice/status triggers</a></li>
index 2f6c3fe..859fe02 100644 (file)
-function deleteItemBlock(index) {
-    var aDiv = document.getElementById(index);
-    aDiv.parentNode.removeChild(aDiv);
-    var quantity = document.getElementById('quantity');
-    quantity.setAttribute('value',parseFloat(quantity.getAttribute('value'))-1);
+function addItem( node, unique_item_fields ) {
+    var index = $(node).parent().attr('id');
+    var current_qty = parseInt($("#quantity").val());
+    var max_qty;
+    if($("#quantity_to_receive").length != 0){
+        max_qty = parseInt($("#quantity_to_receive").val());
+    } else  {
+        max_qty = 99999;
+    }
+    if ( $("#items_list table").find('tr[idblock="' + index + '"]').length == 0 ) {
+        if ( current_qty < max_qty ) {
+            if ( current_qty < max_qty - 1 )
+                cloneItemBlock(index, unique_item_fields);
+            addItemInList(index, unique_item_fields);
+            $("#" + index).find("a[name='buttonPlus']").text("Update");
+            $("#quantity").val(current_qty + 1);
+        } else if ( current_qty >= max_qty ) {
+            alert(window.MSG_ADDITEM_JS_CANT_RECEIVE_MORE_ITEMS
+                || "You can't receive any more items.");
+        }
+    } else {
+        if ( current_qty < max_qty )
+            cloneItemBlock(index, unique_item_fields);
+        var tr = constructTrNode(index);
+        $("#items_list table").find('tr[idblock="' + index + '"]:first').replaceWith(tr);
+    }
+    $("#" + index).hide();
+}
+
+function showItem(index) {
+    $("#outeritemblock").children("div").each(function(){
+        if ( $(this).attr('id') == index ) {
+            $(this).show();
+        } else {
+            if ( $("#items_list table").find('tr[idblock="' + $(this).attr('id') + '"]').length == 0 ) {
+                $(this).remove();
+            } else {
+                $(this).hide();
+            }
+        }
+    });
+}
+
+function constructTrNode(index, unique_item_fields) {
+    var fields = ['barcode', 'homebranch', 'holdingbranch', 'notforloan',
+        'restricted', 'location', 'itemcallnumber', 'copynumber',
+        'stocknumber', 'ccode', 'itype', 'materials', 'itemnotes'];
+
+    var result = "<tr idblock='" + index + "'>";
+    var edit_link = "<a href='#itemfieldset' style='text-decoration:none' onclick='showItem(\"" + index + "\");'>"
+        + (window.MSG_ADDITEM_JS_EDIT || "Edit") + "</a>";
+    var del_link = "<a style='cursor:pointer' "
+        + "onclick='deleteItemBlock(this, \"" + index + "\", \"" + unique_item_fields + "\");'>"
+        + (window.MSG_ADDITEM_JS_DELETE || "Delete") + "</a>";
+    result += "<td>" + edit_link + "</td>";
+    result += "<td>" + del_link + "</td>";
+    for(i in fields) {
+        var field = fields[i];
+        var field_elt = $("#" + index)
+            .find("[name='kohafield'][value='items."+field+"']")
+            .prevAll("[name='field_value']")[0];
+        var field_value;
+        if($(field_elt).is('select')) {
+            field_value = $(field_elt).find("option:selected").text();
+        } else {
+            field_value = $(field_elt).val();
+        }
+        result += "<td>" + field_value + "</td>";
+    }
+    result += "</tr>";
+
+    return result;
+}
+
+function addItemInList(index, unique_item_fields) {
+    $("#items_list").show();
+    var tr = constructTrNode(index, unique_item_fields);
+    $("#items_list table tbody").append(tr);
+}
+
+function deleteItemBlock(node_a, index, unique_item_fields) {
+    $("#" + index).remove();
+    var current_qty = parseInt($("#quantity").val());
+    var max_qty;
+    if($("#quantity_to_receive").length != 0) {
+        max_qty = parseInt($("#quantity_to_receive").val());
+    } else {
+        max_qty = 99999;
+    }
+    $("#quantity").val(current_qty - 1);
+    $(node_a).parents('tr').remove();
+    if(current_qty - 1 == 0)
+        $("#items_list").hide();
+
+    if ( $("#quantity").val() <= max_qty - 1) {
+        if ( $("#outeritemblock").children("div :visible").length == 0 ) {
+            $("#outeritemblock").children("div:last").show();
+        }
+    }
+    if ( $("#quantity").val() == 0 && $("#outeritemblock > div").length == 0) {
+        cloneItemBlock(0, unique_item_fields);
+    }
 }
-function cloneItemBlock(index) {    
-    var original = document.getElementById(index); //original <div>
-    var clone = clone_with_selected(original)
+
+function cloneItemBlock(index, unique_item_fields) {
+    var original;
+    if(index) {
+        original = $("#" + index); //original <div>
+    }
+    var dont_copy_fields = new Array();
+    if(unique_item_fields) {
+        var dont_copy_fields = unique_item_fields.split(' ');
+        for(i in dont_copy_fields) {
+            dont_copy_fields[i] = "items." + dont_copy_fields[i];
+        }
+    }
+
     var random = Math.floor(Math.random()*100000); // get a random itemid.
-    // set the attribute for the new 'div' subfields
-    clone.setAttribute('id',index + random);//set another id.
-    var NumTabIndex;
-    NumTabIndex = parseInt(original.getAttribute('tabindex'));
-    if(isNaN(NumTabIndex)) NumTabIndex = 0;
-    clone.setAttribute('tabindex',NumTabIndex+1);
-    var CloneButtonPlus;
-    var CloneButtonMinus;
-  //  try{
-        var jclone = $(clone);
-        CloneButtonPlus = $("a.addItem", jclone).get(0);
-        CloneButtonPlus.setAttribute('onclick',"cloneItemBlock('" + index + random + "')");
-    CloneButtonMinus = $("a.delItem", jclone).get(0);
-    CloneButtonMinus.setAttribute('onclick',"deleteItemBlock('" + index + random + "')");
-    CloneButtonMinus.setAttribute('style',"display:inline");
-    // change itemids of the clone
-    var elems = clone.getElementsByTagName('input');
-    for( i = 0 ; elems[i] ; i++ )
-    {
-        if(elems[i].name.match(/^itemid/)) {
-            elems[i].value = random;
+    var clone = $("<div id='itemblock"+random+"'></div>")
+    $.ajax({
+        url: "/cgi-bin/koha/services/itemrecorddisplay.pl",
+        dataType: 'html',
+        data: {
+            frameworkcode: 'ACQ'
+        },
+        success: function(data, textStatus, jqXHR) {
+            /* Create the item block */
+            $(clone).append(data);
+            /* Change all itemid fields value */
+            $(clone).find("input[name='itemid']").each(function(){
+                $(this).val(random);
+            });
+            /* Add buttons + and Clear */
+            var buttonPlus = '<a name="buttonPlus" style="cursor:pointer; margin:0 1em;" onclick="addItem(this,\'' + unique_item_fields + '\')">Add</a>';
+            var buttonClear = '<a name="buttonClear" style="cursor:pointer;" onclick="clearItemBlock(this)">' + (window.MSG_ADDITEM_JS_CLEAR || 'Clear') + '</a>';
+            $(clone).append(buttonPlus).append(buttonClear);
+            /* Copy values from the original block (input) */
+            $(original).find("input[name='field_value']").each(function(){
+                var kohafield = $(this).siblings("input[name='kohafield']").val();
+                if($(this).val() && dont_copy_fields.indexOf(kohafield) == -1) {
+                    $(this).parent("div").attr("id").match(/^(subfield.)/);
+                    var id = RegExp.$1;
+                    var value = $(this).val();
+                    $(clone).find("div[id^='"+id+"'] input[name='field_value']").val(value);
+                }
+            });
+            /* Copy values from the original block (select) */
+            $(original).find("select[name='field_value']").each(function(){
+                var kohafield = $(this).siblings("input[name='kohafield']").val();
+                if($(this).val() && dont_copy_fields.indexOf(kohafield) == -1) {
+                    $(this).parent("div").attr("id").match(/^(subfield.)/);
+                    var id = RegExp.$1;
+                    var value = $(this).val();
+                    $(clone).find("div[id^='"+id+"'] select[name='field_value']").val(value);
+                }
+            });
+
+            $("#outeritemblock").append(clone);
         }
-    }    
-   // }
-    //catch(e){        // do nothig if ButtonPlus & CloneButtonPlus don't exist.
-    //}
-    // insert this line on the page    
-    original.parentNode.insertBefore(clone,original.nextSibling);
-    var quantity = document.getElementById('quantity');
-    quantity.setAttribute('value',parseFloat(quantity.getAttribute('value'))+1);
+    });
 }
-function check_additem() {
-       var     barcodes = document.getElementsByName('barcode');
-       var success = true;
-       for(i=0;i<barcodes.length;i++){
-               for(j=0;j<barcodes.length;j++){
-                       if( (i > j) && (barcodes[i].value == barcodes[j].value) && barcodes[i].value !='') {
-                               barcodes[i].className='error';
-                               barcodes[j].className='error';
-                               success = false;
-                       }
-               }
-       }
-       // TODO : Add AJAX function to test against barcodes already in the database, not just 
-       // duplicates within the form.  
-       return success;
+
+function clearItemBlock(node) {
+    var index = $(node).parent().attr('id');
+    var block = $("#"+index);
+    $(block).find("input[type='text']").each(function(){
+        $(this).val("");
+    });
+    $(block).find("select").each(function(){
+        $(this).find("option:first").attr("selected", true);
+    });
+}
+
+function check_additem(unique_item_fields) {
+    var success = true;
+    var data = new Object();
+    data['field'] = new Array();
+    data['value'] = new Array();
+    var array_fields = unique_item_fields.split(' ');
+    $(".error").empty(); // Clear error div
+
+    // Check if a value is duplicated in form
+    for ( field in array_fields ) {
+        var fieldname = array_fields[field];
+        var values = new Array();
+        $("[name='kohafield'][value=items."+array_fields[field]+"]").each(function(){
+            var input = $(this).prevAll("input[name='field_value']")[0];
+            if($(input).val()) {
+                values.push($(input).val());
+                data['field'].push(fieldname);
+                data['value'].push($(input).val());
+            }
+        });
+
+        var sorted_arr = values.sort();
+        for (var i = 0; i < sorted_arr.length - 1; i += 1) {
+            if (sorted_arr[i + 1] == sorted_arr[i]) {
+                $(".error").append(
+                    fieldname + " '" + sorted_arr[i] + "' "
+                    + (window.MSG_ADDITEM_JS_IS_DUPLICATE || "is duplicated")
+                    + "<br/>");
+                success = false;
+            }
+        }
+    }
+
+    // If there is a duplication, we raise an error
+    if ( success == false ) {
+        $(".error").show();
+        return false;
+    }
+
+    $.ajax({
+        url: '/cgi-bin/koha/acqui/check_uniqueness.pl',
+        async: false,
+        dataType: 'json',
+        data: data,
+        success: function(data) {
+            for (field in data) {
+                success = false;
+                for (var i=0; i < data[field].length; i++) {
+                    var value = data[field][i];
+                    $(".error").append(
+                        field + " '" + value + "' "
+                        + (window.MSG_ADDITEM_JS_ALREADY_EXISTS_IN_DB
+                            || "already exists in database")
+                        + "<br />"
+                    );
+                }
+            }
+        }
+    });
+
+    if ( success == false ) {
+        $(".error").show();
+    }
+    return success;
 }
 
-function clone_with_selected (node) {
-          var origin = node.getElementsByTagName("select");
-          var tmp = node.cloneNode(true)
-          var selectelem = tmp.getElementsByTagName("select");
-          for (var i=0; i<origin.length; i++) {
-              selectelem[i].selectedIndex = origin[i].selectedIndex;
-          }
-          origin = null;
-          selectelem = null;
-          return tmp;
-       }
-
-$(document).ready(function(){
-       $(".cloneItemBlock").click(function(){
-               var clonedRow = $(this).parent().parent().clone(true);
-               clonedRow.insertAfter($(this).parent().parent()).find("a.deleteItemBlock").show();
-               // find ID of cloned row so we can increment it for the clone
-               var count = $("input[id^=volinf]",clonedRow).attr("id");
-               var current = Number(count.replace("volinf",""));
-               var increment = current + 1;
-               // loop over inputs
-               var inputs = ["volinf","barcode"];
-               jQuery.each(inputs,function() {
-                       // increment IDs of labels and inputs in the clone
-                       $("label[for="+this+current+"]",clonedRow).attr("for",this+increment);
-                       $("input[name="+this+"]",clonedRow).attr("id",this+increment);
-               });
-               // loop over selects
-               var selects = ["homebranch","location","itemtype","ccode"];
-               jQuery.each(selects,function() {
-                       // increment IDs of labels and selects in the clone
-                       $("label[for="+this+current+"]",clonedRow).attr("for",this+increment);
-                       $("input[name="+this+"]",clonedRow).attr("id",this+increment);
-                       $("select[name="+this+"]",clonedRow).attr("id",this+increment);
-                       // find the selected option and select it in the clone
-                       var selectedVal = $("select#"+this+current).find("option:selected").attr("value");
-                       $("select[name="+this+"] option[value="+selectedVal+"]",clonedRow).attr("selected","selected");
-               });
-               
-               var quantityrec = parseFloat($("#quantityrec").attr("value"));
-               quantityrec++;
-               $("#quantityrec").attr("value",quantityrec);
-               return false;
-       });
-       $(".deleteItemBlock").click(function(){
-               $(this).parent().parent().remove();
-               var quantityrec = parseFloat($("#quantityrec").attr("value"));
-               quantityrec--;
-               $("#quantityrec").attr("value",quantityrec);
-               return false;
-       });
-});
index 8b15b12..302e7bd 100644 (file)
@@ -10,7 +10,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="about_about" class="about">
 [% INCLUDE 'header.inc' %]
 
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; About Koha</div>
index b8e81b7..9acc451 100644 (file)
@@ -23,7 +23,7 @@ $(document).ready(function() {
 </script>
 
 </head>
-<body>
+<body id="acq_acqui-home" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 9b85af3..80f88f9 100644 (file)
@@ -1,3 +1,4 @@
+[% USE KohaDates %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Acquisitions &rsaquo; Order Staged MARC Records
 [% IF ( batch_details ) %]
@@ -21,7 +22,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_addorderiso2709" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/acqui/acqui-home.pl">Acquisitions</a> &rsaquo; <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% booksellerid %]">[% booksellername %]</a> &rsaquo; <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basketno %]">Basket [% basketno %]</a> &rsaquo;  Add orders from iso2709 file</div>
@@ -90,7 +91,7 @@
                         <td>[% batch_lis.file_name %]</td>
                        <td>[% batch_lis.comments %]</td>
                        <td>[% batch_lis.import_status %]</td>
-                       <td>[% batch_lis.upload_timestamp %]</td>
+                       <td>[% batch_lis.staged_date | $KohaDates %] [% batch_lis.staged_hour %]</td>
                        <td>[% batch_lis.num_biblios %]</td>
                        <td><a href="[% batch_lis.scriptname %]?import_batch_id=[% batch_lis.import_batch_id %]&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]">Add orders</a></td>
                      </tr>
index cc64cae..401e484 100644 (file)
@@ -72,7 +72,7 @@
 .sortmsg {font-size: 80%;}
 </style>
 </head>
-<body>
+<body id="acq_basket" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index c651e00..f19b299 100644 (file)
@@ -133,7 +133,7 @@ function yuiToolbar() {
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_basketgroup" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 160c5f6..1ac8d96 100644 (file)
@@ -13,8 +13,8 @@
 // to check if the data are correctly entered.
 function Check(ff) {
     var ok=0;
-    var _alertString="Form not submitted because of the following problem(s)\n";
-    _alertString +="-------------------------------------------------------------------\n\n";
+    var _alertString="Form not submitted because of the following problem(s)";
+    _alertString +="\n-------------------------------------------------------------------\n\n";
     if (!(isNotNull(ff.basketname,0))){
         ok=1;
         _alertString += "- name missing\n";
@@ -84,7 +84,7 @@ li.list2 {
 </style>
 
 </head>
-<body>
+<body id="acq_basketheader" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 1616261..798c2e7 100644 (file)
@@ -1,3 +1,4 @@
+[% USE KohaDates %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Search for vendor [% supplier %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
@@ -6,23 +7,34 @@
        vertical-align: top;
 }
 </style>
-<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
+<link rel="stylesheet" href="[% themelang %]/css/datatables.css" />
+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
+[% INCLUDE 'datatables-strings.inc' %]
+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>
 <script type="text/javascript">
 //<![CDATA[
- $(document).ready(function() {
-        $("#vendorst").tablesorter({
-           headers: { 
-               3: { 
-                   sorter: false 
-               }
-           } 
-       }); 
- }); 
- //]]>
+$(document).ready(function() {
+    [% IF (dateformat == 'metric') %]
+        dt_add_type_uk_date();
+    [% END %]
+    $("table.baskets").dataTable($.extend(true, {}, dataTablesDefaults, {
+        'bPaginate': false,
+        'bFilter': false,
+        'bInfo': false,
+        'aoColumnDefs': [
+            { 'aTargets': [-1], 'bSortable': false }
+        ]
+    }));
+    $("#supplierlist").change(function() {
+        var id = $(this).find("option:selected").val();
+        window.location.href = "#" + id;
+    });
+});
+//]]>
 </script>
 
 </head>
-<body>
+<body id="acq_booksellers" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
 [% ELSE %]
 <h1>You searched on <b>vendor [% supplier %],</b> [% count %] results found</h1>
 [% END %]
-[% IF ( loop_suppliers ) %]
+[% IF ( loop_suppliers.size ) %]
+    [% UNLESS (count == 1) %]
+        <p>Choose a vendor in the list to jump directly to the right place.
+        <select id="supplierlist">
+            [% FOREACH supplier IN loop_suppliers %]
+                <option value="[% supplier.booksellerid %]">[% supplier.name %]</option>
+            [% END %]
+        </select>
+        </p>
+    [% END %]
     <div id="acqui_order_supplierlist">
-        <table id="vendorst">
-       <thead>
-        <tr>
-            <th>Order</th>
-            <th>Order receive</th>
-            <th>Vendor</th>
-            <th>&nbsp;</th>
-        </tr>
-       </thead>
-       <tbody> 
-        [% FOREACH loop_supplier IN loop_suppliers %]
-        [% UNLESS ( loop.odd ) %]
-            <tr class="highlight">
-        [% ELSE %]
-            <tr>
-        [% END %]
-                <td>[% IF ( CAN_user_acquisition_order_manage ) %]
-                    [% IF ( loop_supplier.active ) %]
-                        <a href="basketheader.pl?booksellerid=[% loop_supplier.booksellerid %]&amp;op=add_form">New basket</a>
+        [% FOREACH supplier IN loop_suppliers %]
+            <div class="supplier">
+                <span class="suppliername">
+                    [% IF (supplier.name) %]
+                        <a name="[% supplier.booksellerid %]" href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% supplier.booksellerid %]">[% supplier.name %]</a>
                     [% ELSE %]
-                        Inactive
+                        <a name="[% supplier.booksellerid %]" href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% supplier.booksellerid %]">NO NAME</a>
                     [% END %]
+                </span>
+                <span class="action">
+                    [% IF ( CAN_user_acquisition_order_manage ) %]
+                        [% IF ( supplier.active ) %]
+                            <input type="button" value="New basket" onclick="window.location.href='/cgi-bin/koha/acqui/basketheader.pl?booksellerid=[% supplier.booksellerid %]&amp;op=add_form'" />
+                        [% ELSE %]
+                            (inactive)
+                        [% END %]
                     [% END %]
-                </td>
-                <td>   <a href="parcels.pl?booksellerid=[% loop_supplier.booksellerid %]">Receive shipment</a>
-                </td>
-                [% IF ( loop_supplier.name ) %]
-                <td><a href="supplier.pl?booksellerid=[% loop_supplier.booksellerid %]">[% loop_supplier.name %]</a></td>
-                [% ELSE %]
-                <td><a href="supplier.pl?booksellerid=[% loop_supplier.booksellerid %]">NO NAME</a></td>
-                [% END %]
-                <td>   <table>
-                        [% IF ( loop_supplier.loop_basket ) %]
-                            <tr>
-                                <th>Basket (#)</th>
-                                <th>Items</th>
-                                <th>Created by</th>
-                                <th>Date</th>
-                                <th>&nbsp;</th>
-                            </tr>
-                            [% FOREACH loop_baske IN loop_supplier.loop_basket %]
-                            [% IF ( loop_baske.uncertainprices ) %]
-                                <tr class="problem">
-                            [% ELSE %]
-                            [% UNLESS ( loop.odd ) %]
-                                <tr class="highlight">
-                            [% ELSE %]
+                    <input type="button" value="Receive shipment" onclick="window.location.href='/cgi-bin/koha/acqui/parcels.pl?booksellerid=[% supplier.booksellerid %]'" />
+                </span>
+                <div class="baskets">
+                    [% IF ( supplier.loop_basket.size ) %]
+                        <table class="baskets">
+                            <thead>
                                 <tr>
-                            [% END %]
-                            [% END %]
-                                    <td>[% loop_baske.basketname %] (#[% loop_baske.basketno %])</td>
-                                    <td>[% loop_baske.total %]</td>
-                                    <td>                                               [% loop_baske.firstname %]
-                                            [% loop_baske.surname %]
-                                    </td>
-                                    <td>[% loop_baske.creationdate %]</td>
-                                    <td>                                               [% IF ( loop_baske.closedate ) %]
-                                            closed on [% loop_baske.closedate %]
-                                            <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% loop_baske.basketno %]">View</a>
-                                        [% ELSE %]
-                                            [% IF ( loop_baske.active ) %]
-                                                <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% loop_baske.basketno %]">modify</a>
+                                    <th>Basket (#)</th>
+                                    <th>Item count</th>
+                                    <th>Biblio count</th>
+                                    <th>Items expected</th>
+                                    <th>Created by</th>
+                                    <th>Date</th>
+                                    <th>&nbsp;</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                [% FOREACH basket IN supplier.loop_basket %]
+                                    [% IF ( basket.uncertainprices ) %]
+                                        <tr class="problem">
+                                    [% ELSE %]
+                                        <tr>
+                                    [% END %]
+                                        <td>[% basket.basketname %] (#[% basket.basketno %])</td>
+                                        <td>[% basket.total_items %]</td>
+                                        <td>[% basket.total_biblios %]</td>
+                                        <td>[% basket.expected_items %]</td>
+                                        <td>
+                                            [% basket.authorisedby_firstname %]
+                                            [% basket.authorisedby_surname %]
+                                        </td>
+                                        <td>[% basket.creationdate | $KohaDates %]</td>
+                                        <td>
+                                            [% IF ( basket.closedate ) %]
+                                                closed on [% basket.closedate | $KohaDates %]
+                                                <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno %]">View</a>
                                             [% ELSE %]
-                                                <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% loop_baske.basketno %]">View</a>
+                                                [% IF ( basket.active ) %]
+                                                    <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno %]">Modify</a>
+                                                [% ELSE %]
+                                                    <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno %]">View</a>
+                                                [% END %]
                                             [% END %]
-                                        [% END %]
-                                    </td>
-                                </tr>
-                            [% END %]
-                        [% ELSE %]
-                            <tr><td>No pending baskets</td></tr>
-                        [% END %]
+                                        </td>
+                                    </tr>
+                                [% END %][%# FOREACH basket IN supplier.loop_basket %]
+                            </tbody>
                         </table>
-                </td>
-                </tr>
-            [% END %]
-           </tbody>
-            </table>
-        </div>
-    [% END %]
+                    [% ELSE %]
+                        <p>No pending baskets</p>
+                    [% END %][%# IF ( supplier.loop_basket.size ) %]
+                </div>
+            </div>
+        [% END %][%# FOREACH supplier IN loop_suppliers %]
+    </div>
+[% END %][%# IF ( loop_suppliers.size ) %]
 </div>
 </div>
 <div class="yui-b">
index fb6982d..1d6c242 100644 (file)
@@ -4,7 +4,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="acq_histsearch" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index cdb8711..33473f6 100644 (file)
@@ -19,7 +19,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_lateorders" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index c888ccb..5e1ee9a 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'greybox.inc' %]
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="acq_neworderbiblio" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 9c2d70a..8aec465 100644 (file)
@@ -4,12 +4,28 @@
 [% INCLUDE 'doc-head-close.inc' %]
 
 <script type="text/javascript" src="[% themelang %]/js/acq.js"></script>
+[% INCLUDE 'additem.js.inc' %]
 <script type="text/javascript" src="[% themelang %]/js/additem.js"></script>
 <script type="text/javascript">
 //<![CDATA[
 actTotal = "";
 
 function Check(ff) {
+    [% IF (AcqCreateItemOrdering) %]
+        // Remove last itemblock if it is not in items_list
+        var lastitemblock = $("#outeritemblock > div:last");
+        var tobedeleted = true;
+        var listitems = $("#items_list tr");
+        $(listitems).each(function(){
+            if($(this).attr('idblock') == $(lastitemblock).attr('id')){
+                tobedeleted = false;
+            }
+        });
+        if(tobedeleted){
+            $(lastitemblock).remove();
+        }
+    [% END %]
+
     var ok=0;
     var _alertString= _("Form not submitted because of the following problem(s)")+"\n";
 
@@ -25,7 +41,7 @@ function Check(ff) {
                                        _alertString += "\n- "+ _("You must select a budget");
     }
 
-    if (!(isNum(ff.quantity,0))){
+    if (!(isNum(ff.quantity,0)) || ff.quantity.value == 0){
         ok=1;
                     _alertString += "\n- " + _("Quantity must be greater than '0'");
     }
@@ -47,16 +63,12 @@ function Check(ff) {
     }
 
     if ( ff.field_value ) {
-        var barcodes = [];
         var empty_item_mandatory = 0;
         for (i = 0; i < ff.field_value.length; i++) {
             //alert("i = " + i + " => " + ff.kohafield[i] );
             if (ff.field_value[i].value.length == 0 && ff.mandatory[i].value == 1) {
                 empty_item_mandatory++;
             }
-            if(ff.subfield[i].value === '[% barcode_subfield %]' && ff.field_value[i].value.length != 0) {
-                barcodes.push(ff.field_value[i].value);
-            }
         }
         if (empty_item_mandatory > 0) {
             ok = 1;
@@ -64,56 +76,34 @@ function Check(ff) {
                 "\n- " + empty_item_mandatory + _(" item mandatory fields empty");
         }
 
-        if(barcodes.length > 0) {
-            // Check for duplicate barcodes in the form
-            barcodes = barcodes.sort();
-            for(var i=0; i<barcodes.length-1; i++) {
-                if(barcodes[i] == barcodes[i+1]) {
-                    ok = 1;
-                    _alertString += "\n- " + _("The barcode ") + barcodes[i] + _(" is used more than once in the form. Every barcode must be unique");
-                }
-            }
-
-            // Check for duplicate barcodes in the database via an ajax call
-            $.ajax({
-                url: "/cgi-bin/koha/acqui/check_duplicate_barcode_ajax.pl",
-                async:false,
-                method: "post",
-                data: {barcodes : barcodes},
-                dataType: 'json',
-
-                error: function(xhr) {
-                    alert("Error: \n" + xhr.responseText);
-                },
-                success: function(json) {
-                    switch(json.status) {
-                        case 'UNAUTHORIZED':
-                            ok = 1;
-                            _alertString += "\n- " + _("Error: Duplicate barcode verification failed. Insufficient user permissions.");
-                            break;
-                        case 'DUPLICATES':
-                            ok = 1;
-                            $.each(json.barcodes, function(index, barcode) {
-                                _alertString += "\n- " + _("The barcode ") + barcode + _(" already exists in the database");
-                            });
-                            break;
-                    }
-                },
-            });
-        }
     }
 
     if (ok) {
         alert(_alertString);
+        [% IF (AcqCreateItemOrdering) %]
+            if(tobedeleted) {
+                $(lastitemblock).appendTo('#outeritemblock');
+            }
+        [% END %]
         return false;
     }
 
-    ff.submit();
-
+    [% IF (AcqCreateItemOrdering) %]
+        if(check_additem('[% UniqueItemFields %]') == false) {
+            alert(_('Duplicate values detected. Please correct the errors and resubmit.') );
+            if(tobedeleted) {
+                $(lastitemblock).appendTo('#outeritemblock');
+            }
+            return false;
+        }
+    [% END %]
 }
 
 $(document).ready(function() 
     {
+        [% IF (AcqCreateItemOrdering) %]
+            cloneItemBlock(0, '[% UniqueItemFields %]');
+        [% END %]
         //We apply the fonction only for modify option
         [% IF ( quantityrec ) %]
         $('#quantity').blur(function() 
@@ -148,7 +138,7 @@ $(document).ready(function()
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_neworderempty" class="acq">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
@@ -169,6 +159,8 @@ $(document).ready(function()
     [% END %]
 </h2>
 
+<div class="error" style="display:none"></div>
+
 [% IF ( basketno ) %]
     <div id="acqui_basket_summary"  class="yui-g">
     <fieldset class="rows">
@@ -208,7 +200,7 @@ $(document).ready(function()
     </div>
 [% END %]
 
-<form action="/cgi-bin/koha/acqui/addorder.pl" method="post" id="Aform">
+<form action="/cgi-bin/koha/acqui/addorder.pl" method="post" id="Aform" onsubmit="return Check(this);">
 
 <fieldset class="rows">
         <legend>
@@ -333,41 +325,47 @@ $(document).ready(function()
         </fieldset>
     [% END %]
 
-    [% IF ( items ) %]
-    <fieldset class="rows">
+    [% IF (AcqCreateItemOrdering) %]
+
+    <div id="items_list" style="display:none">
+        <p><b>Items list</b></p>
+        <div style="width:100%;overflow:auto;">
+            <table>
+                <thead>
+                    <tr>
+                        <th>&nbsp;</th>
+                        <th>&nbsp;</th>
+                        <th>Barcode</th>
+                        <th>Home branch</th>
+                        <th>Holding branch</th>
+                        <th>Not for loan</th>
+                        <th>Restricted</th>
+                        <th>Location</th>
+                        <th>Call number</th>
+                        <th>Copy number</th>
+                        <th>Stock number</th>
+                        <th>Collection code</th>
+                        <th>Item type</th>
+                        <th>Materials</th>
+                        <th>Notes</th>
+                    </tr>
+                </thead>
+                <tbody>
+                </tbody>
+            </table>
+        </div>
+    </div>
+
+    <fieldset class="rows" id="itemfieldset">
         <legend>Item</legend>
         [% IF ( NoACQframework ) %]
             <div class="dialog message">No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used</div>
         [% END %]
 
-        [% FOREACH item IN items %]
-        <div id="outeritemblock">
-        <div id="itemblock">
-            <ol>[% FOREACH iteminformatio IN item.iteminformation %]<li style="[% iteminformatio.hidden %];">
-                <div class="subfield_line" id="subfield[% iteminformatio.serialid %][% iteminformatio.countitems %][% iteminformatio.subfield %][% iteminformatio.random %]">
-
-                    <label>[% iteminformatio.subfield %] - [% IF ( iteminformatio.mandatory ) %]<b>[% END %][% iteminformatio.marc_lib %][% IF ( iteminformatio.mandatory ) %] *</b>[% END %]</label>
-                    [% iteminformatio.marc_value %]
-                    <input type="hidden" name="itemid" value="1" />
-                    <input type="hidden" name="kohafield" value="[% iteminformatio.kohafield %]" />
-                    <input type="hidden" name="tag" value="[% iteminformatio.tag %]" />
-                    <input type="hidden" name="subfield" value="[% iteminformatio.subfield %]" />
-                    <input type="hidden" name="mandatory" value="[% iteminformatio.mandatory %]" />
-                    [% IF ( iteminformatio.ITEM_SUBFIELDS_ARE_NOT_REPEATABLE ) %]
-                        <span class="buttonPlus" onclick="CloneSubfield('subfield[% iteminformatio.serialid %][% iteminformatio.countitems %][% iteminformatio.subfield %][% iteminformatio.random %]')">+</span>
-                    [% END %]
-
-                </div></li>
-            [% END %]
-            </ol>
-            <a class="addItem" onclick="cloneItemBlock('itemblock[% item.itemBlockIndex %]')">Add</a>
-            <a class="delItem" style="display:none;" onclick="deleteItemBlock('itemblock[% item.itemBlockIndex %]')">Delete</a>
-        </div><!-- /iteminformation -->
-        </div>
+        <div id="outeritemblock"></div>
 
-        [% END %] <!-- /items -->
     </fieldset>
-    [% END %] <!-- items -->
+    [% END %][%# IF (AcqCreateItemOrdering) %]
     <fieldset class="rows">
         <legend>Accounting Details</legend>
         <ol>
@@ -376,9 +374,9 @@ $(document).ready(function()
             <span class="label required">Quantity: </span>
                     <input type="hidden" size="20" name="quantity" value="[% quantity %]" />[% quantity %]
                 [% ELSE %]
-                <label class="required" for="quantity">Quantity: </label>
-                    [% IF ( items ) %]
-                        <input type="text" readonly="readonly" size="20" id="quantity" name="quantity" value="1" onchange="calcNeworderTotal();" />
+                    <label class="required" for="quantity">Quantity: </label>
+                    [% IF (AcqCreateItemOrdering) %]
+                        <input type="text" readonly="readonly" size="20" id="quantity" name="quantity" value="0" onchange="updateCosts();" />
                     [% ELSE %]
                         <input type="text" size="20" id="quantity" name="quantity" value="[% quantityrec %]" onchange="calcNeworderTotal();" />
                     [% END %]
@@ -530,7 +528,12 @@ $(document).ready(function()
 </ol>
     </fieldset>
     <fieldset class="action">
-        <input type="button" value="Save" onclick="Check(this.form)" /> [% IF ( suggestionid ) %]<a class="cancel" href="/cgi-bin/koha/acqui/newordersuggestion.pl?booksellerid=[% booksellerid %]&amp;basketno=[% basketno %]">Cancel</a>[% ELSE %]<a class="cancel" href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basketno %]">Cancel</a>[% END %]
+        <input type="submit" value="Save" />
+        [% IF (suggestionid) %]
+            <a class="cancel" href="/cgi-bin/koha/acqui/newordersuggestion.pl?booksellerid=[% booksellerid %]&amp;basketno=[% basketno %]">Cancel</a>
+        [% ELSE %]
+            <a class="cancel" href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basketno %]">Cancel</a>
+        [% END %]
     </fieldset>
 </form>
 </div>
index fd990c8..78ad410 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Acquisitions &rsaquo; Basket [% basketno %] &rsaquo; Duplicate warning</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="acq_neworderempty_duplicate" class="acq">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
index 8629e1d..2843ee2 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Acquisitions &rsaquo; Add order from a suggestion</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="acq_newordersuggestion" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'suggestions-add-search.inc' %]
 
index a0cabbc..379d042 100644 (file)
@@ -3,7 +3,7 @@
 <title>Koha &rsaquo; Acquisitions &rsaquo; Ordered</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="acq_ordered" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 3eb3e23..bb706ec 100644 (file)
@@ -1,9 +1,46 @@
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Acquisitions &rsaquo; Receipt summary for : [% name %] [% IF ( invoice ) %]invoice, [% invoice %][% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
+[% INCLUDE 'additem.js.inc' %]
 <script type="text/javascript" src="[% themelang %]/js/additem.js"> </script>
+<script type="text/javascript">
+//<![CDATA[
+    function Check(form) {
+        [% IF (AcqCreateItemReceiving) %]
+            // Remove last itemblock if it is not in items_list
+            var lastitemblock = $("#outeritemblock > div:last");
+            var tobedeleted = true;
+            var listitems = $("#items_list tr");
+            $(listitems).each(function(){
+                if($(this).attr('idblock') == $(lastitemblock).attr('id')){
+                    tobedeleted = false;
+                }
+            });
+            if(tobedeleted){
+                $(lastitemblock).remove();
+            }
+
+            if(check_additem('[% UniqueItemFields %]') == false){
+                alert(_('Duplicate values detected. Please correct the errors and resubmit.') );
+                if(tobedeleted) {
+                    $(lastitemblock).appendTo("#outeritemblock");
+                }
+                return false;
+            };
+        [% END %]
+
+        return true;
+    }
+
+    $(document).ready(function() {
+        [% IF (AcqCreateItemReceiving) %]
+            cloneItemBlock(0, '[% UniqueItemFields %]');
+        [% END %]
+    });
+//]]>
+</script>
 </head>
-<body>
+<body id="acq_orderreceive" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
 <h1>Receive items from : [% name %] [% IF ( invoice ) %][[% invoice %]] [% END %] (order #[% ordernumber %])</h1>
 
 [% IF ( count ) %]
-    <form action="/cgi-bin/koha/acqui/finishreceive.pl" method="post">
+    <form action="/cgi-bin/koha/acqui/finishreceive.pl" method="post" onsubmit="return Check(this);">
 <div class="yui-g">
 <div class="yui-u first">
-    
+    <div class="error" style="display:none"></div>
+
     <fieldset class="rows">
     <legend>Catalog Details</legend>
     <ol><li><span class="label">Title: </span><span class="title">[% title |html %]</span></li>
         </fieldset>
     [% END %]
 
-    [% IF ( items ) %]
-    <fieldset class="rows">
-        <legend>Item</legend>
-        [% IF ( NoACQframework ) %]
-            <p class="required">No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used</p>
-        [% END %]
+    [% IF (AcqCreateItemReceiving) %]
+        <div id="items_list" style="display:none">
+            <p><b>Items list</b></p>
+            <div style="width:100%;overflow:auto;">
+                <table>
+                    <thead>
+                        <tr>
+                            <th>&nbsp;</th>
+                            <th>&nbsp;</th>
+                            <th>Barcode</th>
+                            <th>Home branch</th>
+                            <th>Holding branch</th>
+                            <th>Not for loan</th>
+                            <th>Restricted</th>
+                            <th>Location</th>
+                            <th>Call number</th>
+                            <th>Copy number</th>
+                            <th>Stock number</th>
+                            <th>Collection code</th>
+                            <th>Item type</th>
+                            <th>Materials</th>
+                            <th>Notes</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                    </tbody>
+                </table>
+            </div>
+        </div>
 
-        [% FOREACH item IN items %]
-        <div id="outeritemblock">
-        <div id="itemblock">
-            <ol>[% FOREACH iteminformatio IN item.iteminformation %]<li style="[% iteminformatio.hidden %];">
-                <div class="subfield_line" id="subfield[% iteminformatio.serialid %][% iteminformatio.countitems %][% iteminformatio.subfield %][% iteminformatio.random %]">
-                                
-                    <label>[% iteminformatio.subfield %] - [% IF ( iteminformatio.mandatory ) %]<b>[% END %][% iteminformatio.marc_lib %][% IF ( iteminformatio.mandatory ) %] *</b>[% END %]</label>
-                    [% iteminformatio.marc_value %]
-                    <input type="hidden" name="itemid" value="1" />
-                    <input type="hidden" name="kohafield" value="[% iteminformatio.kohafield %]" />
-                    <input type="hidden" name="tag" value="[% iteminformatio.tag %]" />
-                    <input type="hidden" name="subfield" value="[% iteminformatio.subfield %]" />
-                    <input type="hidden" name="mandatory" value="[% iteminformatio.mandatory %]" />
-                    [% IF ( iteminformatio.ITEM_SUBFIELDS_ARE_NOT_REPEATABLE ) %]
-                        <span class="buttonPlus" onclick="CloneSubfield('subfield[% iteminformatio.serialid %][% iteminformatio.countitems %][% iteminformatio.subfield %][% iteminformatio.random %]')">+</span>
-                    [% END %]
-            
-                </div></li>
+        <fieldset class="rows" id="itemfieldset">
+            <legend>Item</legend>
+            [% IF ( NoACQframework ) %]
+                <p class="required">
+                    No ACQ framework, using default. You should create a
+                    framework with code ACQ, the items framework would be
+                    used
+                </p>
             [% END %]
-            </ol>
-            <a class="addItem" onclick="cloneItemBlock('itemblock[% item.itemBlockIndex %]')">Add</a>
-            <a class="delItem" style="display:none;" onclick="deleteItemBlock('itemblock[% item.itemBlockIndex %]')">Delete</a>
-        </div><!-- /iteminformation -->
-        </div>
-        
-        <input type="hidden" name="moditem" value="" /> 
-        <input type="hidden" name="tag" value="[% item.itemtagfield %]" />
-        <input type="hidden" name="subfield" value="[% item.itemtagsubfield %]" />
-        <input type="hidden" name="serial" value="[% item.serialid %]" />
-        <input type="hidden" name="bibnum" value="[% item.biblionumber %]" />
-        <input type="hidden" name="itemid" value="1" />
-        <input type="hidden" name="field_value" value="[% item.itemnumber %]" />
-        [% END %] <!-- /items -->
-    </fieldset>
-    [% END %] <!-- items -->
+            <div id="outeritemblock"></div>
+        </fieldset>
+    [% END %][%# IF (AcqCreateItemReceiving) %]
     <input type="hidden" name="biblionumber" value="[% biblionumber %]" />
     <input type="hidden" name="ordernumber" value="[% ordernumber %]" />
     <input type="hidden" name="biblioitemnumber" value="[% biblioitemnumber %]" />
        <li><label for="creator">Created by: </label><span> [% IF ( memberfirstname and membersurname ) %][% IF ( memberfirstname ) %][% memberfirstname %][% END %] [% membersurname %][% ELSE %]No name[% END %]</span></li>
        <li><label for="quantityto">Quantity to receive: </label><span class="label">
            [% IF ( edit ) %]
-               <input type="text" name="quantity" value="[% quantity %]" />
+               <input type="text" id="quantity_to_receive" name="quantity" value="[% quantity %]" />
            [% ELSE %]
-               <input type="text" READONLY name="quantity" value="[% quantity %]" />
+               <input type="text" readonly="readonly" id="quantity_to_receive" name="quantity" value="[% quantity %]" />
            [% END %]
            </span></li>
         <li><label for="quantity">Quantity received: </label>
+          [% IF (AcqCreateItemReceiving) %]
+            <input readonly="readonly" type="text" size="20" name="quantityrec" id="quantity" value="0" />
+          [% ELSE %]
             [% IF ( quantityreceived ) %]
                 [% IF ( edit ) %]
                     <input type="text" size="20" name="quantityrec" id="quantity" value="[% quantityreceived %]" />
                 [% END %]
                 <input id="origquantityrec" READONLY type="hidden" name="origquantityrec" value="0" />
             [% END %]
+          [% END %][%# IF (AcqCreateItemReceiving) %]
                </li>
         <li><label for="rrp">Replacement cost: </label><input type="text" size="20" name="rrp" id="rrp" value="[% rrp %]" /></li>
         <li><label for="ecost">Budgeted cost: </label><input type="text" size="20" name="ecost" id="ecost" value="[% ecost %]" /></li>
 
 </div>
 </div><div class="yui-g"><fieldset class="action">
-        <input type="button"  value="Save" onclick="javascript:if(check_additem()) { this.form.submit(); } else { alert( _('Duplicate barcodes detected.  Please correct the errors and resubmit.') ); return false };" /> <a class="cancel" href="/cgi-bin/koha/acqui/parcel.pl?booksellerid=[% booksellerid %]&amp;invoice=[% invoice %]&amp;gst=[% gst %]&amp;freight=[% freight %]">Cancel</a>
+        <input type="submit"  value="Save" />
+        <a class="cancel" href="/cgi-bin/koha/acqui/parcel.pl?booksellerid=[% supplierid %]&amp;invoice=[% invoice %]&amp;gst=[% gst %]&amp;freight=[% freight %]">Cancel</a>
 </fieldset></div>    </form>
 [% ELSE %]
 <div id="acqui_acquire_orderlist">
index 02e1769..4ddfc7d 100644 (file)
 </script>
 
 </head>
-<body>
+<body id="acq_parcel" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
                [% IF ( number.highlight ) %]
                <span class="current">[% number.number %]</span>
                [% ELSE %]
-               <a href="parcel.pl?type=intra&amp;booksellerid=[% booksellerid %]&amp;startfrom=[% number.startfrom %][% IF ( number.datereceived ) %]&amp;datereceived=[% number.datereceived %][% END %][% IF ( number.invoice ) %]&amp;invoice=[% number.invoice %][% END %][% IF ( number.resultsperpage ) %]&amp;resultsperpage=[% number.resultsperpage %][% END %]#resultnumber">[% number.number %]</a>
+               <a href="parcel.pl?type=intra&amp;booksellerid=[% booksellerid %]&amp;startfrom=[% number.startfrom %][% IF ( datereceived ) %]&amp;datereceived=[% datereceived %][% END %][% IF ( invoice ) %]&amp;invoice=[% invoice %][% END %][% IF ( resultsperpage ) %]&amp;resultsperpage=[% resultsperpage %][% END %]#resultnumber">[% number.number %]</a>
                [% END %]
        [% END %]
        [% IF ( displaynext ) %]
index fb937f0..712c472 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="acq_parcels" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index a944419..622604b 100644 (file)
@@ -3,7 +3,7 @@
 <title>Koha &rsaquo; Acquisitions &rsaquo; Spent</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="acq_spent" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 05b7fac..6ace8da 100644 (file)
@@ -1,3 +1,4 @@
+[% USE KohaDates %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Vendor [% bookselname %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
@@ -18,7 +19,7 @@ if (f.company.value == "") {
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_supplier" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
@@ -217,8 +218,8 @@ if (f.company.value == "") {
                             <a href="/cgi-bin/koha/admin/aqcontract.pl?op=add_form&amp;contractnumber=[% contract.contractnumber %]&amp;booksellerid=[% contract.booksellerid %]">[% contract.contractname %]</a>
                         </td>
                         <td>[% contract.contractdescription %]</td>
-                        <td>[% contract.contractstartdate %]</td>
-                        <td>[% contract.contractenddate %]</td>
+                        <td>[% contract.contractstartdate | $KohaDates %]</td>
+                        <td>[% contract.contractenddate | $KohaDates %]</td>
                         <td><a href="/cgi-bin/koha/admin/aqcontract.pl?op=add_form&amp;contractnumber=[% contract.contractnumber %]&amp;booksellerid=[% contract.booksellerid %]">Edit</a></td>
                         <td><a href="/cgi-bin/koha/admin/aqcontract.pl?op=delete_confirm&amp;contractnumber=[% contract.contractnumber %]&amp;booksellerid=[% contract.booksellerid %]">Delete</a></td>
                         </tr>
index 613153c..5717034 100644 (file)
@@ -10,7 +10,7 @@ function check(form) {
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_uncertainprice" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index 2449c8e..176922d 100644 (file)
@@ -59,7 +59,7 @@ $.tablesorter.addParser({
 tr.selected { background-color : #FFFFCC; } tr.selected td { background-color : transparent !important; }
 </style>
 </head>
-<body>
+<body id="acq_z3950_search" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'acquisitions-search.inc' %]
 
index f3f8707..6b339f8 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Administration</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="admin_admin-home" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 5fc623d..84da262 100644 (file)
@@ -20,7 +20,7 @@ function returnOwner(ownerId, ownerName){
 
 
 </head>
-<body>
+<body id="admin_aqbudget_owner_search" class="admin">
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
        <div class="yui-g">
index 29dcf7f..f3c52d5 100644 (file)
 
 </head>
 
-<body>
+<body id="admin_aqbudgetperiods" class="admin">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'budgets-admin-search.inc' %]
index 7fa91f7..cae2306 100644 (file)
 [% END %]
 
 </head>
-<body>
+<body id="admin_aqbudgets" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'budgets-admin-search.inc' %]
 
index 19861b9..9eb9088 100644 (file)
@@ -51,7 +51,7 @@ function Check(ff) {
 //]]>
 </script>
 </head>
-<body>
+<body id="acq_aqcontract" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'contracts-admin-search.inc' %]
 
index 10ca4ce..a836138 100644 (file)
@@ -66,7 +66,7 @@ YAHOO.util.Event.onAvailable("popmenu", function () {
 </script>
 <style type="text/css">td.locked { background-image: url('/intranet-tmpl/prog/img/locked.png'); padding-left : 20px; background-repeat: no-repeat; background-position: 4% 50%; } a.control { font-size:85%;text-decoration:none; }</style>
 </head>
-<body>
+<body id="admin_aqplan" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'budgets-admin-search.inc' %]
 
index a8f2b46..e7ea422 100644 (file)
@@ -22,7 +22,7 @@ function displayMoreConstraint(numlayer){
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_auth_subfields_structure" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <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;
index af03d1c..9347adc 100644 (file)
@@ -65,7 +65,7 @@ return false;
     //]]>
 </script>
 </head>
-<body>
+<body id="admin_auth_tag_structure" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 7e71789..0c806ce 100644 (file)
@@ -29,7 +29,7 @@
        fieldset.rows .ui-tabs-panel { margin-right : 10px; margin-left : 10px;margin-bottom:10px;}
 </style>
 </head>
-<body>
+<body id="admin_authorised_values" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <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 ) %] <a href="/cgi-bin/koha/admin/authorised_values.pl">Authorized Values</a> &rsaquo; [% IF ( action_modify ) %]Modify authorized value[% END %]
index a955374..ef11e9a 100644 (file)
@@ -48,7 +48,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_authtypes" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index cfe657a..234d2d5 100644 (file)
@@ -122,7 +122,7 @@ $(document).ready(function() {
 </script>
 
 </head>
-<body>
+<body id="admin_biblio_framework" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 0e8805e..1fd7816 100644 (file)
@@ -59,7 +59,7 @@
 </script>
 <style type="text/css">td { text-align: center; }</style>
 </head>
-<body>
+<body id="admin_branch_transfer_limits" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index df5e56c..583a7a0 100644 (file)
 [% INCLUDE 'doc-head-close.inc' %]
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.pager.js"></script>
+<script type="text/javascript" src="[% themelang %]/js/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
+<script language="javascript" type="text/javascript">
+tinyMCE.init({
+    mode : "textareas",
+    theme : "advanced",
+    content_css : "[% themelang %]/css/tinymce.css",
+    plugins : "table,save,advhr,advlink,iespell,contextmenu",
+    theme_advanced_buttons1 : "save,|,bold,italic,|,cut,copy,paste,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,|,link,unlink,anchor,cleanup,help,code,advhr,",
+    theme_advanced_buttons2 : "tablecontrols,|,bullist,numlist,|,outdent,indent,|,undo,redo,|,removeformat,|,visualaid,|,sub,sup,|,charmap",
+    theme_advanced_buttons3 : "",
+    theme_advanced_toolbar_location : "top",
+    theme_advanced_toolbar_align : "left",
+    theme_advanced_path_location : "bottom",
+    theme_advanced_resizing : true,
+    apply_source_formatting : true,
+    height : "300",
+    width : "700"
+});
+</script>
 </head>
-<body>
+<body id="admin_branches" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
         <li><label for="branchfax">Fax</label><input type="text" name="branchfax" id="branchfax" value="[% branchfax |html %]" /></li>
         <li><label for="branchemail">Email</label><input type="text" name="branchemail" id="branchemail" value="[% branchemail |html %]" /></li>
         <li><label for="branchurl">url</label><input type="text" name="branchurl" id="branchurl" value="[% branchurl |html %]" /></li>
+        <li><label for="opac_info">OPAC Info</label><textarea name="opac_info" id="opac_info">[% opac_info |html %]</textarea></li>
         <li><label for="branchip">IP</label><input type="text" name="branchip" id="branchip" value="[% branchip |html %]" /> <span class="hint">Can be entered as a single IP, or a subnet such as 192.168.1.*</span></li>
                <!--
         <li><label for="branchprinter">Library Printer</label>
                             <br /><a href="mailto:[% branche.branchemail %]">[% branche.branchemail |html %]</a>[% END %]
                         [% IF ( branche.branchurl ) %]
                             <br /><a href="[% branche.branchurl %]">[% branche.branchurl |html %]</a>[% END %]
+                        [% IF ( branche.opac_info ) %]
+                            <br />OPAC Info: <div>[% branche.opac_info %]</div>[% END %]
                         [% IF ( branche.branchnotes ) %]
                             <br />Notes: [% branche.branchnotes |html %][% END %]
                     [% END %]
index 62322fa..d2c353e 100644 (file)
@@ -89,7 +89,7 @@
 </script>
 <style type="text/css">#enrolmentmessage.hint { display : none; }</style>
 </head>
-<body>
+<body id="admin_categorie" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patrons-admin-search.inc' %]
 
index d339c00..63851bf 100644 (file)
@@ -3,7 +3,7 @@
 [% IF ( total ) %] :[% total %] errors found[% ELSE %] : Configuration OK![% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="admin_checkmarc" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index c1fccde..bd45d57 100644 (file)
@@ -25,7 +25,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_cities" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cities-admin-search.inc' %]
 
index ae1c75f..4dafc16 100644 (file)
@@ -73,7 +73,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_classsources" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 7bbe27b..dfe65fb 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Administration &rsaquo; Issuing Rules &rsaquo; Clone Issuing Rules</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="admin_clone-rules" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index f9f2cb9..bc187ab 100644 (file)
@@ -50,7 +50,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_currency" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'currencies-admin-search.inc' %]
 
index 239fbe7..7355bf0 100644 (file)
@@ -16,7 +16,7 @@ $(document).ready(function() {
 
 </head>
 
-<body>
+<body id="admin_fieldmapping" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <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; Keyword to MARC Mapping</div>
index 9a976a0..a652bc4 100644 (file)
@@ -85,7 +85,7 @@ $(function(){
 }); //]]>
 </script>
 </head>
-<body>
+<body id="admin_item_circulation_alerts" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <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; Item Circulation Alerts </div>
index 13ece6e..8407d09 100644 (file)
@@ -95,7 +95,7 @@ function Check(f) {
        fieldset.rows .ui-tabs-panel { margin-right : 10px; margin-left : 10px;margin-bottom:10px;}
 </style>
 </head>
-<body>
+<body id="admin_itemtypes" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 8eed289..287a581 100644 (file)
@@ -5,7 +5,7 @@
 
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="admin_koha2marclinks" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index c196300..71c83b9 100644 (file)
@@ -5,17 +5,19 @@
 <script type="text/javascript">
 //<![CDATA[
 
-        $(document).ready(function() {
-               $('#subfieldtabs > ul').tabs();
-               $("a.displaymore").click(function(){
-                       $("#"+$(this).attr("href").replace("#","")).toggle();
-                       if($(this).html() == "display more constraints"){
-                               $(this).html("hide constraints");
-                       } else {
-                               $(this).html("display more constraints");
-                       }
-               });
-        });
+$(document).ready(function() {
+    $('#subfieldtabs > ul').tabs();
+        $("a.displaymore").click(function(){
+        var link = $(this);
+        var constraints = $("#"+$(this).attr("href").replace("#",""));
+        constraints.toggle();
+            if($(constraints).is(':visible')){
+                link.html(_("Hide constraints"));
+            } else {
+                link.html(_("Display more constraints"));
+            }
+    });
+});
 
 /*function displayMoreConstraint(numlayer){
     var thisdiv = document.getElementById(numlayer);
@@ -31,7 +33,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_marc_subfields_structure" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
                        </ol>
             </fieldset>
                        
-            <a class="displaymore" href="#more[% loo.urisubfieldcode %]">display more constraints</a>
+            <a class="displaymore" href="#more[% loo.urisubfieldcode %]">Display more constraints</a>
             <div id="more[% loo.urisubfieldcode %]" style="display:none; clear: both">
              <fieldset class="rows" style="float:none;">
                                <legend>Advanced constraints:</legend>
                 <ol><li><label for="defaultvalue[% loo.row %]">Default value:</label>
                     <input type="text" name="defaultvalue" id="defaultvalue[% loo.row %]" value="[% loo.defaultvalue %]" /></li>
+                               <li><label for="maxlength[% loo.row %]">Max length:</label><input type="text" id="maxlength[% loo.row %]" name="maxlength" value="[% loo.maxlength %]" size="4" /> (see online help)</li>
                 <li><label for="hidden[% loo.row %]">hidden</label><input type="text" id="hidden[% loo.row %]" name="hidden" value="[% loo.hidden %]" size="2" /> (see online help)</li>
                 <li><label for="isurl[% loo.row %]">Is a url:</label>[% loo.isurl %] (if checked, it means that the subfield is a url and can be clicked)</li>
                 <li><label for="link[% loo.row %]">Link:</label><input type="text" id="link[% loo.row %]" name="link" value="[% loo.link %]" size="10" maxlength="80" /> (e.g., Title or Local-Number) <span class="error"><em>NOTE: If you change this value you must ask your administrator to run misc/batchRebuildBiblioTables.pl.</em></span></li>
index c889820..ec0a583 100644 (file)
@@ -37,7 +37,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_marctagstructure" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 1c0a009..4e31d4f 100644 (file)
@@ -168,7 +168,7 @@ function CheckRuleForm(f) {
   div.matchgroup { border:1px solid #DDD; border-left-width: 15px; padding:.4em; margin-bottom:.6em;}
 </style>
 </head>
-<body>
+<body id="admin_matching-rules" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 894d7d5..2d438e0 100644 (file)
@@ -25,7 +25,7 @@ function returnToSetsPage() {
 </script>
 </head>
 
-<body>
+<body id="admin_oai_set_mappings" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 444f972..bb53fb8 100644 (file)
@@ -24,7 +24,7 @@ $(document).ready(function() {
 </script>
 </head>
 
-<body>
+<body id="admin_oai_sets" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index b8a8e3e..6fff8ab 100644 (file)
@@ -44,7 +44,7 @@ function CheckAttributeTypeForm(f) {
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_patron-attr-types" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
@@ -186,6 +186,34 @@ function CheckAttributeTypeForm(f) {
                   to be chosen from the authorized value list.  However, an authorized value list is not 
                   enforced during batch patron import.</span>
         </li>
+        <li>
+            <label for="category">Category: </label>
+            <select name="category_code" id="category">
+                <option value=""></option>
+                [% FOREACH cat IN categories %]
+                    [% IF ( cat.categorycode == category_code ) %]<option value="[% cat.categorycode %]" selected="selected">[% cat.description %]</option>[% ELSE %]<option value="[% cat.categorycode %]">[% cat.description %]</option>[% END %]
+                [% END %]
+            </select>
+            <span>Please let blank if you want these attributs to be for all types of patron. Else, select one type.</span>
+        </li>
+        <li>
+            <label for="class">Class: </label>
+            <select name="class">
+                <option value="" />
+                [% FOREACH class IN classes_val_loop %]
+                    [% IF ( class.selected ) %]
+                        <option value="[% class.authorised_value %]" selected="selected">
+                            [% class.lib %]
+                        </option>
+                    [% ELSE %]
+                        <option value="[% class.authorised_value %]" >
+                            [% class.lib %]
+                        </option>
+                    [% END %]
+                [% END %]
+            </select>
+            <span>Group attributes types with a block title (based on Authorised values category 'PA_CLASS')</span>
+        </li>
     </ol>
   </fieldset>
   <fieldset class="action">
@@ -248,23 +276,36 @@ function CheckAttributeTypeForm(f) {
 <div class="dialog message">Could not delete patron attribute type &quot;[% ERROR_delete_not_found %]&quot; 
     &mdash; it was already absent from the database.</div>
 [% END %]
-[% IF ( available_attribute_types ) %]<table>
-  <tr>
-    <th>Code</th>
-    <th>Description</th>
-    <th>Actions</th>
-  </tr>
-  [% FOREACH available_attribute_type IN available_attribute_types %]
-  <tr>
-    <td>[% available_attribute_type.code |html %]</td>
-    <td>[% available_attribute_type.description %]</td>
-    <td>
-      <a href="[% available_attribute_type.script_name %]?op=edit_attribute_type&amp;code=[% available_attribute_type.code |html %]">Edit</a>
-      <a href="[% available_attribute_type.script_name %]?op=delete_attribute_type&amp;code=[% available_attribute_type.code |html %]">Delete</a>
-    </td>
-  </tr>
+[% IF ( available_attribute_types ) %]
+  [% FOREACH attribute IN available_attribute_types %]
+    [% IF attribute.class %]
+        <h4>[% attribute.lib %]</h4>
+    [% END %]
+    <table class="patron_attributes_types">
+      <thead>
+        <tr>
+          <th>Code</th>
+          <th>Description</th>
+          <th>Actions</th>
+        </tr>
+      </thead>
+      <tbody>
+        [% FOREACH item IN attribute.items %]
+          <tr>
+            <td>[% item.code |html %]</td>
+            <td>[% item.description %]</td>
+            <td>
+              <a href="[% item.script_name %]?op=edit_attribute_type&amp;code=[% item.code |html %]">Edit</a>
+              <a href="[% item.script_name %]?op=delete_attribute_type&amp;code=[% item.code |html %]">Delete</a>
+            </td>
+          </tr>
+        [% END %]
+      </tbody>
+    </table>
   [% END %]
-</table>[% ELSE %]<p>There are no saved patron attribute types.</p>[% END %]
+[% ELSE %]
+  <p>There are no saved patron attribute types.</p>
+[% END %]
 
 <div class="pages">[% pagination_bar %]</div>
 
index ed2a964..7fd77be 100644 (file)
@@ -22,7 +22,7 @@
 <script src="[% themelang %]/js/pages/preferences.js" type="text/javascript"></script>
 <script src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js" type="text/javascript"></script>
 </head>
-<body>
+<body id="admin_preferences" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'prefs-admin-search.inc' %]
 
index 4b1e13b..cf8fcf0 100644 (file)
@@ -9,6 +9,9 @@ Acquisitions:
               receiving: receiving an order.
               cataloguing: cataloging the record.
     -
+        - pref: UniqueItemFields
+        - (space-separated list of fields that should be unique for items, must be valid SQL fields of items table)
+    -
         - When closing or reopening a basket,
         - pref: BasketConfirmations
           default: 1
index f5828ae..bb3bc2d 100644 (file)
@@ -103,6 +103,12 @@ Enhanced Content:
                   yes: Do
                   no: "Don't"
             - include information (such as reviews and citations) from Babelthèque in item detail pages on the OPAC.
+        -
+            - pref: Babeltheque_url_js
+            - Defined the url for the Babeltheque javascript file (eg. http://www.babeltheque.com/bw_XX.js)
+        -
+            - pref: Babeltheque_url_update
+            - Defined the url for the Babeltheque update periodically (eq. http://www.babeltheque.com/.../file.csv.bz2).
     Baker and Taylor:
         -
             - pref: BakerTaylorEnabled
index 9224747..ae6b620 100644 (file)
@@ -362,7 +362,7 @@ OPAC:
             - Only allow patrons to renew their own books on the OPAC if they have less than
             - pref: OPACFineNoRenewals
               class: currency
-            - '[% local_currency %] in fines (set a large value to always allow renewal).'
+            - '[% local_currency %] in fines (leave blank to disable).'
         -
             - pref: OPACViewOthersSuggestions
               choices:
@@ -380,7 +380,21 @@ OPAC:
             - pref: OpacHiddenItems
               type: textarea
               class: code
-            - Allows to define custom rules for hiding specific items at opac. See docs/opac/OpacHiddenItems.txt for more informations.
+            - Allows to define custom rules for hiding specific items at opac. See docs/opac/OpacHiddenItems.txt for more informations
+        -
+            - pref: OpacAllowPublicListCreation
+              default: 1
+              choices:
+                  no: "Don't allow"
+                  yes: Allow
+            - opac users to create public lists
+        -
+            - pref: OpacAllowSharingPrivateLists
+              default: 0
+              choices:
+                  no: "Don't allow"
+                  yes: Allow
+            - opac users to share private lists with other patrons. This feature is not active yet but will be released soon
 
     Privacy:
         -
index 3d7dd64..7b5993d 100644 (file)
@@ -76,6 +76,13 @@ Searching:
                   yes: Using
                   no: "Not using"
             - 'ICU Zebra indexing. Please note: This setting will not affect Zebra indexing, it should only be used to tell Koha that you have activated ICU indexing if you have actually done so, since there is no way for Koha to figure this out on its own.'
+        -
+            - pref: SocialNetworks
+              default: 0
+              choices:
+                  yes: Enable
+                  no: Disable
+            - Enable/Disable social network links in opac detail pages
     Search Form:
         -
             - Show tabs in OPAC and staff-side advanced search for limiting searches on the
index 1950ba6..8b23135 100644 (file)
@@ -47,3 +47,6 @@ Serials:
               simplified: a summary
               full: a full list
         - of the serial issues.
+    -
+        - List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)
+        - pref: SubscriptionDuplicateDroppedInput
index 4a551b8..486fc48 100644 (file)
@@ -63,7 +63,7 @@
 </script>
        [% END %]
 </head>
-<body>
+<body id="admin_printers" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'printers-admin-search.inc' %]
 
index 2e6e8a1..bdd3bc1 100644 (file)
@@ -50,7 +50,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_roadtype" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'roadtype-admin-search.inc' %]
 <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 ) %]<a href="/cgi-bin/koha/admin/roadtype.pl">Road Types</a> &rsaquo; [% IF ( roadtypeid ) %] Modify Road Type[% ELSE %] New Road Type[% END %][% ELSE %][% IF ( delete_confirm ) %]<a href="/cgi-bin/koha/admin/roadtype.pl">Road Types</a> &rsaquo; Confirm Deletion of Road Type[% ELSE %] Road Type[% END %][% END %]</div>
index 5d5be3e..7b01ac7 100644 (file)
@@ -19,7 +19,7 @@ $(document).ready(function() {
 <script type="text/javascript" src="[% themelang %]/lib/calendar/calendar-setup.js"></script>
 <!-- End Calendar system additions -->
 </head>
-<body>
+<body id="admin_smart-rules" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
@@ -72,7 +72,8 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                 <th>Patron category</th>
                 <th>Item type</th>
                 <th>Current checkouts allowed</th>
-                <th>Loan period (day)</th>
+                <th>Loan period</th>
+                <th>Unit</th>
                 <th>Hard due date</th>
                 <th>Fine amount</th>
                 <th>Fine charging interval</th>
@@ -80,7 +81,7 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                 <th>Suspension in days (day)</th>
                 <th>Renewals allowed (count)</th>
                 <th>Holds allowed (count)</th>
-                       <th>Rental discount (%)</th>
+               <th>Rental discount (%)</th>
                                <th>&nbsp;</th>
             </tr>
                                [% FOREACH rule IN rules %]
@@ -108,6 +109,9 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                                                                [% END %]
                                                        </td>
                                                        <td>[% rule.issuelength %]</td>
+                                                       <td>
+                                                           [% rule.lengthunit %]
+                                                       </td>
                                                         <td>[% IF ( rule.hardduedate ) %]
                                                                [% IF ( rule.hardduedatebefore ) %]before [% rule.hardduedate %]</td>
                                                                [% ELSE %][% IF ( rule.hardduedateexact ) %]on [% rule.hardduedate %]</td>
@@ -146,6 +150,12 @@ for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde
                     </td>
                     <td><input name="maxissueqty" size="3" /></td>
                     <td><input name="issuelength" size="3" /> </td>
+                    <td>
+                     <select name="lengthunit">
+                       <option value="days" selected>Days</option>
+                       <option value="hours">Hours</option>
+                     </select>
+                   </td>
                     <td><select name="hardduedatecompare">
                            <option value="-1">Before</option>
                            <option value="0">Exactly on</option>
index aceecc0..272d1a0 100644 (file)
@@ -27,7 +27,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="admin_stopwords" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'stopwords-admin-search.inc' %]
 
index d4a7bf3..9e0a976 100644 (file)
@@ -73,7 +73,7 @@
         //]]>
 </script>
 </head>
-<body>
+<body id="admin_systempreferences" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'sysprefs-admin-search.inc' %]
 
index 12585b3..9a4950b 100644 (file)
@@ -65,7 +65,7 @@
 </script>
         [% END %]
 </head>
-<body>
+<body id="admin_z3950servers" class="admin">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'z3950-admin-search.inc' %]
 
 [% END %]
 </select>
 </li>
+    <li><label for="timeout">Timeout (0 its like not set): </label>
+               <input type="text" name="timeout" id="timeout" size="4" value="[% timeout %]" onblur="isNum(this)" /> seconds
+       </li>
 </ol>
         </fieldset>
                
                 <li><strong>Rank: </strong>[% rank %]</li>
                 <li><strong>Syntax: </strong>[% syntax %]</li>
                 <li><strong>Encoding: </strong>[% encoding %]</li>
+                <li><strong>Timeout: </strong>[% timeout %]</li>
        </ul>                <form action="[% script_name %]" method="post"><input type="hidden" name="op" value="delete_confirmed" /><input type="hidden" name="searchfield" value="[% searchfield %]" /><input type="submit" value="Delete this Server" /></form>  <form action="[% script_name %]" method="post"><input type="submit" value="Do Not Delete" /></form>
 
 
                 You searched for [% searchfield %]
         [% END %]              
 <table id="serverst">
-                <thead><tr><th>Target</th><th>Hostname/Port</th><th>Database</th><th>Userid</th><th>Password</th><th>Checked</th><th>Rank</th>                         <th>Syntax</th><th>Encoding</th><th colspan="2">&nbsp;</th>
+                <thead><tr><th>Target</th><th>Hostname/Port</th><th>Database</th><th>Userid</th><th>Password</th><th>Checked</th><th>Rank</th>                         <th>Syntax</th><th>Encoding</th><th>Timeout</th><th colspan="2">&nbsp;</th>
                 </tr></thead>
                 <tbody>[% FOREACH loo IN loop %]
                 [% UNLESS ( loop.odd ) %]
                 [% ELSE %]
                     <tr>
                 [% END %]
-<td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.name |url %]">[% loo.name %]</a></td><td>[% loo.host %]:[% loo.port %]</td><td>[% loo.db %]</td><td>[% loo.userid %]</td><td>[% loo.password %]</td><td>[% IF ( loo.checked ) %]Yes[% ELSE %]No[% END %]</td><td>[% loo.rank %]</td>                     <td>[% loo.syntax %]</td><td>[% loo.encoding %]</td><td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.name |url %]">Edit</a></td><td><a href="[% loo.script_name %]?op=delete_confirm&amp;searchfield=[% loo.name |url %]">Delete</a></td>                </tr>
+<td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.name |url %]">[% loo.name %]</a></td><td>[% loo.host %]:[% loo.port %]</td><td>[% loo.db %]</td><td>[% loo.userid %]</td><td>[% loo.password %]</td><td>[% IF ( loo.checked ) %]Yes[% ELSE %]No[% END %]</td><td>[% loo.rank %]</td>                     <td>[% loo.syntax %]</td><td>[% loo.encoding %]</td><td>[% loo.timeout %]</td><td><a href="[% loo.script_name %]?op=add_form&amp;searchfield=[% loo.name |url %]">Edit</a></td><td><a href="[% loo.script_name %]?op=delete_confirm&amp;searchfield=[% loo.name |url %]">Delete</a></td>                </tr>
                 [% END %]</tbody>
        </table>
 
index 6d86a62..96ed02d 100644 (file)
@@ -8,7 +8,7 @@
 </title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="main_auth" class="main">
 
 <div id="doc" class="yui-t7">
    <div id="bd">
index 4945be4..f0140d9 100644 (file)
@@ -10,7 +10,7 @@
 
 
 </head>
-<body>
+<body id="auth_auth_finder" class="auth">
 <div id="custom-doc" class="yui-t7">
    
    <div id="bd">
index 3b46219..7d138ff 100644 (file)
@@ -22,7 +22,7 @@ function confirm_deletion() {   // not really implemented, but required by phant
 //]]>
 </script>
 </head>
-<body>
+<body id="auth_authorities_home" class="auth">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'authorities-search.inc' %]
 
index 5009bff..b670b4a 100644 (file)
@@ -505,7 +505,7 @@ function searchauthority() {
 </script>
 <link type="text/css" rel="stylesheet" href="[% themelang %]/css/addbiblio.css" />
 </head>
-<body>
+<body id="auth_authorities" class="auth">
 <div id="yui-cms-loading">
       <div id="yui-cms-float">
           Loading, please wait...
index 6c74a3b..41384c5 100644 (file)
@@ -65,7 +65,7 @@ function searchauthority() {
 </script>
  [% END %]
 </head>
-<body>
+<body id="auth_detail" class="auth">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'authorities-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/authorities/authorities-home.pl">Authorities</a> &rsaquo;
index 7a118c9..6c67de7 100644 (file)
@@ -12,7 +12,7 @@ function jumpfull(page)
 }
 </script>
 </head>
-<body>
+<body id="auth_searchresultlist_auth" class="auth">
 <div id="custom-doc" class="yui-t7">
 
    <div id="bd">
@@ -70,13 +70,7 @@ function jumpfull(page)
                         <td>[% resul.summary %]</td>
                         <td>[% resul.used %] times</td>
                         <td>
-                          [% IF ( resul.repets ) %]
-                            [% FOREACH repet IN resul.repets %]
-                              <a href="javascript:jumpfull('blinddetail-biblio-search.pl?authid=[% resul.authid %]&amp;index=[% repet.index %]&amp;repet=[% repet.repet %]')" title="[% repet.value %]">[% repet.repet %]</a>
-                            [% END %]
-                          [% ELSE %]
-                            <a href="javascript:jumpfull('blinddetail-biblio-search.pl?authid=[% resul.authid %]&amp;index=[% index %]')">choose</a>
-                          [% END %]
+                          <a href="javascript:jumpfull('blinddetail-biblio-search.pl?authid=[% resul.authid %]&amp;index=[% index %]')">choose</a>
                         </td>
                         <td><a href="authorities.pl?authid=[% resul.authid %]">Edit authority</a></td>
                     </tr>
index 7bbf052..1131871 100644 (file)
@@ -26,7 +26,7 @@ function searchauthority() {
 //]]>
 </script>
 </head>
-<body>
+<body id="auth_searchresultlist" class="auth">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'authorities-search.inc' %]
 
index 4239b4f..6041e25 100644 (file)
@@ -72,7 +72,7 @@ function placeHold () {
        </script>
        [% END %]
 </head>
-[% IF ( print_basket ) %]<body id="basket" onload="print();history.back();">[% ELSE %]<body id="basket">[% END %]
+[% IF ( print_basket ) %]<body id="cart_basket" class="cart" onload="print();history.back();">[% ELSE %]<body id="cart_basket" class="cart">[% END %]
 
 <div id="doc" class="yui-t7">
 <div class="container">
index f52dd5a..a58699c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Download cart</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body style="padding:1em;" id="cart_downloadcart" class="cart">
 [% IF ( format ) %]
     <p>Your download should begin automatically.</p>
 [% ELSE %]
index 9c9c565..69f01d6 100644 (file)
@@ -2,7 +2,7 @@
 <title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo;  Sending Your Cart</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding: 1em;" id="sendbasket">
+<body style="padding: 1em;" id="cart_sendbasketform" class="cart">
 <div class="container">[% IF ( email_add ) %]
 
        [% IF ( SENT ) %]
index 73f9e61..f8099e5 100644 (file)
@@ -11,7 +11,7 @@
     <link rel="stylesheet" type="text/css" href="[% stylesheet %]">
     [% END %]
 </head>
-<body>
+<body id="batch_print-notices" class="batch">
     [% FOREACH message IN messages %]
     <div class="message">
         <pre>[% message.content %]</pre>
index 1d924ec..33550ac 100644 (file)
@@ -8,7 +8,7 @@
 </title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_ISBDdetail" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index ae86ee0..f9389f2 100644 (file)
@@ -22,7 +22,7 @@ function Changefwk(FwkList) {
 //]]>
 </script>
 </head>
-<body>
+<body id="catalog_MARCdetail" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 28f445c..82ba631 100644 (file)
@@ -19,7 +19,7 @@
        });
 </script>
 </head>
-<body>
+<body id="catalog_advsearch" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; Advanced Search</div>
index 55a3a91..46de77e 100644 (file)
@@ -45,7 +45,7 @@ function verify_images() {
 </script>
 </head>
 
-<body>
+<body id="catalog_detail" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index d59bf83..ae4f91c 100644 (file)
@@ -4,7 +4,7 @@
 <link rel="stylesheet" href="[% themelang %]/css/print.css" type="text/css" />
 </head>
 
-<body>
+<body id="catalog_detailprint" class="catalog">
 
 <!-- main site -->
 <div id="main">
index 794d4ad..60674d0 100644 (file)
@@ -45,7 +45,7 @@ img.thumbnail {
 </style>[% END %]
 </head>
 
-<body>
+<body id="catalog_imageviewer" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index de5db0e..14d823c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Catalog &rsaquo; Checkout History for [% title |html %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_issuehistory" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 983420e..30b8405 100644 (file)
@@ -21,7 +21,7 @@
        </script>
 </head>
 
-<body>
+<body id="catlaog_labeledMARCdetail" class="catalog">
        [% INCLUDE 'header.inc' %]
        [% INCLUDE 'cat-search.inc' %]
 
index 5d2936b..5b9547f 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 <style type="text/css">h3{padding-top: 1em; border-top: 2px solid #CCCCCC;}</style>
 </head>
-<body>
+<body id="catalog_moredetail" class="catalog">
 [% USE KohaDates %]
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 7830902..bed9a84 100644 (file)
@@ -41,6 +41,11 @@ function cartList(){
             Dopop('/cgi-bin/koha/virtualshelves/addbybiblionumber.pl?newshelf=1&' + vShelfAdd());
         }
         return false;
+    } else if($("#addto").find("option:selected").attr("value") == "morelists"){
+        if (vShelfAdd()) {
+            Dopop('/cgi-bin/koha/virtualshelves/addbybiblionumber.pl?' + vShelfAdd());
+        }
+        return false;
     }
     if($("#addto").find("option:selected").attr("value") == "addtocart"){
         addMultiple();
@@ -64,8 +69,11 @@ $(".addtocart").show();
         param1 += "<option id=\"s[% addbarshelvesloo.shelfnumber %]\" value=\"addtolist\">[% addbarshelvesloo.shelfname |html %]<\/option>";[% END %]
         param1 += "<\/optgroup>";[% END %]
         [% IF ( addpubshelves ) %]param1 += "<optgroup label=\""+_("Public Lists:")+"\">"[% FOREACH addpubshelvesloo IN addpubshelvesloop %]+"<option id=\"s[% addpubshelvesloo.shelfnumber %]\" value=\"addtolist\">[% addpubshelvesloo.shelfname |html %]<\/option>"[% END %]
+        param1 += "<\/optgroup>";[% END %]
+        [% IF ( addbarshelvesloop.size>9 || addpubshelvesloop.size>9 ) %]
+            param1 += "<option value=\"morelists\">[ "+_("More Lists")+" ]<\/option>";
         [% END %]
-        param1 +="<\/optgroup><option value=\"newlist\">"+_("[ New List ]")+"<\/option>"
+        param1 +="<option value=\"newlist\">"+_("[ New List ]")+"<\/option>"
         [% END %]
         param1 += "<\/select> <input id=\"cartsubmit\" type=\"submit\" class=\"submit\" value=\""+_("Save")+"\" />";
  $('#sortsubmit').hide();
@@ -220,7 +228,7 @@ YAHOO.util.Event.onContentReady("searchheader", function () {
 //]]>
 </script>
 </head>
-<body>
+<body id="catalog_results" class="catalog">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 30c3af5..a295b29 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha -- Cataloging: MARC Import</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_showmarc" class="catalog">
 <div id="main">
 <pre>[% MARC_FORMATTED %] </pre>
 [% INCLUDE 'intranet-bottom.inc' %]
index 4972431..0bf84e5 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Catalog &rsaquo; Subject Search Results</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_subject" class="catalog">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 62f5d87..839926e 100644 (file)
@@ -639,7 +639,7 @@ function unHideSubfield(index,labelindex) { // FIXME :: is it used ?
 </script>
 <link type="text/css" rel="stylesheet" href="[% themelang %]/css/addbiblio.css" />
 </head>
-<body>
+<body id="cat_addbiblio" class="cat">
 <div id="yui-cms-loading">
       <div id="yui-cms-float">
           Loading, please wait...
index a57da61..8feec5f 100644 (file)
@@ -8,7 +8,7 @@
  });
 </script>
 </head>
-<body>
+<body id="cat_addbooks" class="cat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cataloging-search.inc' %]
 
index 934ae71..26313f9 100644 (file)
@@ -157,18 +157,11 @@ $(document).ready(function() {
         function () {$(this).attr("class",""         );}
     );
 });
-
-function set_to_today(id, force) {
-    if (! id) { alert(_("Bad id ") + id + _(" sent to set_to_today()")); return 0; }
-    if ($("#" + id).val() == '' || $("#" + id).val() == '0000-00-00' || force) {
-        $("#" + id).val("[% today_iso %]");
-    }
-}
 //]]>
 </script>
 <link type="text/css" rel="stylesheet" href="[% themelang %]/css/addbiblio.css" />
 </head>
-<body>
+<body id="cat_additem" class="cat">
 [% INCLUDE 'header.inc' %]
 <div id="breadcrumbs">
           <a href="/cgi-bin/koha/mainpage.pl">Home</a>
index 38114f6..e422d7c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Link to host item</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_linkitem" class="catalog">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/cataloging/addbooks.pl">Cataloging</a>  &rsaquo; Link a host item to <i>[% bibliotitle |html %]</i></div>
index 9235fdd..745680c 100644 (file)
@@ -169,7 +169,7 @@ function changeFramework(fw) {
 //]]>
 </script>
 </head>
-<body>
+<body id="cat_merge" class="cat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cataloging-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/cataloguing/addbooks.pl">Cataloging</a>  &rsaquo; Merging records</div>
index 78b8579..342b3d8 100644 (file)
@@ -2,7 +2,7 @@
 <title>Attach an item to [% bibliotitle |html %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="catalog_moveitem" class="catalog">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/cataloging/addbooks.pl">Cataloging</a>  &rsaquo; Attach an item to <i>[% bibliotitle |html %][% IF ( itemsloo.subtitle ) %][% itemsloo.subtitle %][% END %]</i></div>
index 2fc1b5a..14609cc 100644 (file)
@@ -29,7 +29,7 @@ a.catalogue:hover {
 </style>
 </head>
 
-<body style="padding:1em;">
+<body id="cat_labs_theses" class="cat" style="padding:1em;">
 <div id="mainbloc">
        <h1>Laboratory Search</h1>
        
index 3055445..0afed38 100644 (file)
@@ -14,7 +14,7 @@
 </script>
 </head>
 
-<body  class="yui-skin-sam" onload="Activate(0);load_macles();" >
+<body id="cat_macles" class="yui-skin-sam cat" onload="Activate(0);load_macles();" >
 
 <h1>Gestion des index MACLES</h1>
 <form name="f_pop" action="">
index 66a2a5a..798e7da 100644 (file)
@@ -33,7 +33,7 @@
 </script>
 
 </head>
-<body style="padding:1em;" onload="loadXmlValues()">
+<body id="cat_marc21_field_006" class="cat" style="padding:1em;" onload="loadXmlValues()">
 <h3>006 Fixed-length data elements--Additional material characteristics--General information</h3>
 
 <table border="1">
index 88a1bec..8762b2e 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; 007 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;" onload="RedrawChoices('[% f0 %]');">
+<body id="cat_marc21_field_007" class="cat" style="padding:1em;" onload="RedrawChoices('[% f0 %]');">
 <h3>007 Physical description fixed field--General information</h3>
 <form id="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_field_007.pl" />
index 9561ae5..b292991 100644 (file)
@@ -33,7 +33,7 @@
 </script>
 
 </head>
-<body style="padding:1em;" onload="loadXmlValues()">
+<body id="cat_marc21_field_008" class="cat" style="padding:1em;" onload="loadXmlValues()">
 <h3> 008 Fixed-length data elements--Additional material characteristics--General information</h3>
 
 <table border="1">
index 196d9c1..e3c9447 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Authorities &rsaquo; 008 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_marc21_field_008_authorities" class="cat" style="padding:1em;">
 <h3> 008 Fixed-length data elements</h3>
 <form name="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_field_008_authorities.pl" />
index 1592a60..2f80cfb 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; 000 - Leader builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_marc21_leader" class="cat" style="padding:1em;">
 <form name="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_leader.pl" />
 <h3>000 - Leader</h3>
index 20035d5..abcf570 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Authorities &rsaquo; Leader builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_marc21_leader_authorities" class="cat" style="padding:1em;">
 <h3>000 - Leader</h3>
 <form name="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_leader_authorities.pl" />
index 5905ffe..fe68a8e 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; Leader builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_marc21_leader_book" class="cat" style="padding:1em;">
 <form name="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_leader_book.pl" />
 <table>
index 8ff15b9..71efda8 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; Leader builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_marc21_leader_computerfile" class="cat" style="padding:1em;">
 <h3>000 - Leader</h3>
 <form name="f_pop" onsubmit="report()" action="">
 <input type="hidden" name="plugin_name" value="marc21_leader_computerfile.pl" />
index b959357..503af7a 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; 007 feltbygger</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;" onload="RedrawChoices('[% f0 %]');">
+<body id="cat_normarc_field_007" class="cat" style="padding:1em;" onload="RedrawChoices('[% f0 %]');">
 <h3>007 Fysisk beskrivelse av dokumentet</h3>
 <form id="f_pop" onsubmit="report()">
 <input type="hidden" name="plugin_name" value="normarc_field_007.pl" />
index 5635fe5..cfdba9c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Katalogisering &rsaquo; Feltbygger for 008</title> 
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_normarc_field_008" class="cat" style="padding:1em;">
 <h3>008 Informasjonskoder</h3>
 
 <form>
index 9af6f29..a99d78e 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Cataloging &rsaquo; 000 - Bygging av postens hode</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_normarc_leader" class="cat" style="padding:1em;">
 <form name="f_pop" onsubmit="report()">
 <input type="hidden" name="plugin_name" value="normarc_leader.pl" />
 <h3>000 - Postens hode</h3>
index 4686148..878d7bb 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 100 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_100" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 100 builder</h3>
 <form name="f_pop" action="">
 <table>
index f7e5884..2806de1 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 105 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_105" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 105 builder</h3>
 <form name="f_pop" action="">
 <table>
index 3e129c8..b62b0ad 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 106 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_106" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 106 builder</h3>
 <form name="f_pop" action="">
 <table>
index b661898..c729cd4 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 110 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_110" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 110 builder</h3>
 <form name="f_pop" action="">
 <table>
index 8a7b2eb..5d96588 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 115a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_115a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 115a builder</h3>
 <form name="f_pop" action="">
 <table>
index 49f6ee2..a05004f 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 115b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_115b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 115b builder</h3>
 <form name="f_pop" action="">
 <table>
index 70cd050..fcee6ea 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 116 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_116" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 116 builder</h3>
 <form name="f_pop" action="">
 <table>
index 376641a..71e4adb 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 117 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_117" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 117 builder</h3>
 <form name="f_pop" action="">
 <table>
index 09ac0df..48a46df 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 120 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_120" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 120 builder</h3>
 <form name="f_pop" action="">
 <table>
index 827c506..31384f4 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 121a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_121a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 121a builder</h3>
 <form name="f_pop" action="">
 <table>
index 63394c8..e822179 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 121b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_121b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 121b builder</h3>
 <form name="f_pop" action="">
 <table>
index ece6a4d..d99013d 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 122 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_122" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 122 builder</h3>
 <form name="f_pop" action="">
 <table>
index e4e1c86..a762aea 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 123a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_123a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 123a builder</h3>
 <form name="f_pop" action="">
 <table>
index 649066c..e596ca9 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 123d builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_123d" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 123d builder</h3>
 <form name="f_pop" action="">
 <table>
index 1f7e665..dd3f675 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 123e builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_123e" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 123e builder</h3>
 <form name="f_pop" action="">
 <table>
index cd950a1..aa0594d 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 123f builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_123f" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 123f builder</h3>
 <form name="f_pop" action="">
 <table>
index 1835327..11023fb 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 123g builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_123g" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 123g builder</h3>
 <form name="f_pop" action="">
 <table>
index 2ddf7a1..873a43e 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124a builder</h3>
 <form name="f_pop" action="">
 <table>
index d4fa242..1b05672 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124b builder</h3>
 <form name="f_pop" action="">
 <table>
index fb3ea84..07effa2 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124c builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124c" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124c builder</h3>
 <form name="f_pop" action="">
 <table>
index a0a004c..094f8cc 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124d builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124d" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124d builder</h3>
 <form name="f_pop" action="">
 <table>
index 090b049..7af2bb8 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124e builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124e" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124e builder</h3>
 <form name="f_pop" action="">
 <table>
index 7ed3dc0..5ed6a48 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124f builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124f" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124f builder</h3>
 <form name="f_pop" action="">
 <table>
index 476292b..053f645 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 124g builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_124g" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 124g builder</h3>
 <form name="f_pop" action="">
 <table>
index 94bf3f9..871b0a8 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 125a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_125a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 125a builder</h3>
 <form name="f_pop" action="">
 <table>
index 7bee0bf..ec867c7 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 125b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="unimarc_field_125b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 125b builder</h3>
 <form name="f_pop" action="">
 <table>
index 959e4a8..159eed8 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 126a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_126a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 126a builder</h3>
 <form name="f_pop" action="">
 <table>
index 69464f8..de252b0 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 126b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_126b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 126b builder</h3>
 <form name="f_pop" action="">
 <table>
index c2e538a..b3cf23f 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 127 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_127" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 127 builder</h3>
 <form name="f_pop" action="">
 <table>
index f4006a7..0634d72 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 128a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_128a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 128a builder</h3>
 <form name="f_pop" action="">
 <table>
index 5751b2d..44f85b6 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 128b builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_128b" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 128b builder</h3>
 <form name="f_pop" action="">
 <table>
index d8012dd..869f0c8 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 128c builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_128c" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 128c builder</h3>
 <form name="f_pop" action="">
 <table>
index 6edba01..2f1a816 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 130 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_130" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 130 builder</h3>
 <form name="f_pop" action="">
 <table>
index 152c6f5..0a33091 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 135a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_135a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 135a builder</h3>
 <form name="f_pop" action="">
 <table>
index 689e775..3868621 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 140 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_140" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 140 builder</h3>
 <form name="f_pop" action="">
 <table>
index d3587bf..bcf62d4 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 141 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_141" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 141 builder</h3>
 <form name="f_pop" action="">
 <table>
index 3e61f92..a5fd3d4 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 210c builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_210c" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 210c builder</h3>
     <h4>Search for authority type: EDITORS</h4>
         <form name="f" method="post" action="plugin_launcher.pl">
index 2a68566..5ef3a1f 100644 (file)
@@ -10,7 +10,7 @@
     <link rel="stylesheet" type="text/css" href="[% themelang %]/css/staff-global.css" />
 
 </head>
-<body>
+<body id="cat_unimarc_field_210c_bis" class="cat">
 <div id="header_search">
 <script type="text/javascript">
 //<![CDATA[
index e85312c..3ab2393 100644 (file)
@@ -2,7 +2,7 @@
     <title>UNIMARC Field 225a builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_225a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 225a builder</h3>
     <div id="mainbloc">
         <form name="f_pop" onsubmit="report()" action="">
index 04adbc3..df79c94 100644 (file)
@@ -78,7 +78,7 @@
 </script>
 
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_4XX" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 4XX builder</h3>
 [% ELSE %]
                <script type="text/javascript">
index b51cfad..3151789 100644 (file)
@@ -5,7 +5,7 @@
 #custom-doc { width:51.46em;*width:50.17em;min-width:675px; margin:auto; text-align:left; }
 </style>
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_686a" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 686a builder</h3>
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
index 37e0987..d977be1 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Field 700-4 builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_field_700-4" class="cat" style="padding:1em;">
 <h3>UNIMARC Field 700-4 builder</h3>
 <p>Sélectionnez la valeur pour le champ 700 $4. Elle sera automatiquement reportée dans la zone 700 $8 qui suit.</p>
 <form name="f_pop" onsubmit="report()" action="">
index 6e53881..0890b33 100644 (file)
@@ -2,7 +2,7 @@
 <title>UNIMARC Leader builder</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="cat_unimarc_leader" class="cat" style="padding:1em;">
 <h3>UNIMARC Leader builder</h3>
 <form name="f_pop" action="">
 <table>
index 7775f1f..3a981e6 100644 (file)
@@ -75,7 +75,7 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
           #custom-doc { width:53em;*width:51.72em;min-width:689px; margin:auto; text-align:left; }
    </style>
 </head>
-<body>
+<body id="cat_z3950_search" class="cat">
 
 <div id="custom-doc" class="yui-t7">
 [% ELSE %]
@@ -166,7 +166,8 @@ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color :
             <div class="dialog alert">
                 <ul>
                 [% FOREACH errcon IN errconn %]
-                    <li>Connection failed to [% errcon.server %]</li>
+                    [% IF ( errcon.error == '10000' ) %]<li>Connection failed to [% errcon.server %]</li>
+                    [% ELSIF ( errcon.error == '10007' ) %]<li>Connection timeout to [% errcon.server %]</li>[% END %]
                 [% END %]
                 </ul>
             </div>
index a24c99a..f1f1d82 100644 (file)
@@ -8,7 +8,7 @@
 <script type="text/javascript" src="[% themelang %]/lib/calendar/calendar-setup.js"></script>
 <!-- End of additions -->
 </head>
-<body>
+<body id="circ_billing" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 43ef0c9..bd1764b 100644 (file)
@@ -8,7 +8,7 @@ $(document).ready(function(){
 });
 </script>
 </head>
-<body>
+<body id="circ_bookcount" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index a8a8912..87eeac6 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Circulation &rsaquo; Overdues at [% LoginBranchname %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="circ_branchoverdues" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 097089a..a8fc073 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Circulation &rsaquo; Transfers</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="circ_branchtransfers" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 6e7ae45..bdd735d 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Circulation</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="circ_circulation-home" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 1d0e07a..eaa4a8d 100644 (file)
@@ -157,7 +157,7 @@ function refocus(calendar) {
 </script>
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="circ_circulation" class="circ">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
index fec6e82..c230e76 100644 (file)
@@ -24,7 +24,9 @@
 
                        var attrcode = $("script", clone).attr("x-code");
                        var newsuffix = parts[1] + appendid;
-                       create_auto_completion_responder(newsuffix,attrcode);
+            [% IF ( CircAutocompl ) %]
+                create_auto_completion_responder(newsuffix,attrcode);
+            [% END %]
                }
 
         parent.parentNode.insertBefore(clone, parent.nextSibling);
@@ -33,6 +35,7 @@
         var parent = node.parentNode;
         parent.parentNode.removeChild(parent);
     }
+    [% IF ( CircAutocompl ) %]
        function create_auto_completion_responder(uniqueid,attrcode) {
                YAHOO.util.Event.onContentReady("pattrodue-getready-"+uniqueid, function() {
                        new function() {
@@ -64,6 +67,7 @@
                        }
                });
        }
+    [% END %]
 //]]>
 </script>
 <style type="text/css">
@@ -71,7 +75,7 @@
 </style>
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="circ_overdue" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
                <!-- domid cgivalue ismany isclone ordinal code description repeatable authorised_value_category -->
                <li>
                        <label>[% patron_attr_filter_loo.description %]:</label>
-                       [% IF ( patron_attr_filter_loo.authorised_value_category ) %]
-                               <script type="text/JavaScript" language="JavaScript" x-code="[% patron_attr_filter_loo.code |html %]">create_auto_completion_responder([% patron_attr_filter_loo.domid %],"[% patron_attr_filter_loo.code |html %]");</script>
+            [% IF ( patron_attr_filter_loo.authorised_value_category AND CircAutocompl) %]
+                <script type="text/JavaScript" language="JavaScript" x-code="[% patron_attr_filter_loo.code |html %]">create_auto_completion_responder([% patron_attr_filter_loo.domid %],"[% patron_attr_filter_loo.code |html %]");</script>
                                <span id="pattrodue-getready-[% patron_attr_filter_loo.domid %]">
                                                <div class="pattrodue-autocomplete">
                                                        <input autocomplete="off" id="pattrodue-input-[% patron_attr_filter_loo.domid %]" name="patron_attr_filter_[% patron_attr_filter_loo.code |html %]" value="[% patron_attr_filter_loo.cgivalue |html %]"  class="pattrodue-input" type="text" />
index 634bab9..426f06d 100644 (file)
@@ -46,7 +46,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="circ_pendingreserves" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index a790069..3e60d73 100644 (file)
@@ -14,7 +14,7 @@
     }
 </script>
 </head>
-<body onload="printThenClose();">
+<body id="circ_printslip" class="circ" onload="printThenClose();">
 <div id="receipt">
 
 [% IF plain %]
index 8fe571b..da6292d 100644 (file)
@@ -40,7 +40,7 @@ $.tablesorter.addParser({
     .ratiolimit { color: blue; cursor: pointer; }
 </style>
 </head>
-<body>
+<body id="circ_reserveratios" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 65ce0f6..c51fed1 100644 (file)
@@ -1,3 +1,4 @@
+[% USE KohaDates %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Circulation &rsaquo; Check In [% title |html %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
@@ -41,7 +42,7 @@ function Dopop(link) {
 //]]>
 </script>
 </head>
-<body>
+<body id="circ_returns" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'checkin-search.inc' %]
 
@@ -331,7 +332,7 @@ function Dopop(link) {
                         <p class="problem">Item is withdrawn.</p>
                     [% END %]
                     [% IF ( errmsgloo.debarred ) %]
-                        <p class="problem"><a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% errmsgloo.debarborrowernumber %]">[% errmsgloo.debarname %]([% errmsgloo.debarcardnumber %])</a> is now debarred until [% errmsgloo.debarred %] </p>
+                        <p class="problem"><a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% errmsgloo.debarborrowernumber %]">[% errmsgloo.debarname %]([% errmsgloo.debarcardnumber %])</a> is now debarred until [% errmsgloo.debarred | $KohaDates %] </p>
                     [% END %]
             [% END %]
 [% IF ( soundon ) %]
index 9b77e68..2f842bc 100644 (file)
@@ -5,7 +5,7 @@
     .noshow {display: none;}
 </style>
 </head>
-<body>
+<body id="circ_selectbranchprinter" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 880a096..d62c1af 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Circulation &rsaquo; Statistics</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="circ_stats" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 9d9ac99..d448186 100644 (file)
@@ -9,7 +9,8 @@ window.close();
 }
 </script>
 </head>
-<body onload="printandclose();"><div id="main">
+<body id="circ_transfer-slip" class="circ" onload="printandclose();">
+<div id="main">
 
 <h5>Date: [% pulldate %]</h5>
 <h3>Transfer to [% branchname %]</h3>
index 2c84d5d..1b9bac6 100644 (file)
@@ -23,7 +23,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="circ_transferstoreceive" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index d9ba8fc..09a8ac0 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 <style type="text/css"> p { margin-top: 0; }</style>
 </head>
-<body>
+<body id="circ_view_holdsqueue" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 0de1f0f..d4b88a4 100644 (file)
@@ -23,7 +23,7 @@ $.tablesorter.addParser({
 //]]>
 </script>
 </head>
-<body>
+<body id="circ_waitingreserves" class="circ">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index d93383b..b82ae04 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_400" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 584ba59..3097a9e 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 401</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_401" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index ef93027..20c9032 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 402</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_402" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index c56a441..4f8e68a 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 403</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_403" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index d762143..7416333 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 404</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_404" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 36e99df..88e0693 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 405</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_405" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 6b96116..7cc7b57 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Error 500</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="err_500" class="err">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
index 2a8801c..0fba909 100644 (file)
@@ -84,6 +84,13 @@ To edit the subfields associated with the tag, click 'Subfields' to the right of
 </li>
 </ul>
 <ul>
+       <li>Max length
+<ul>
+       <li>Define the max characters to fill.</li>
+</ul>
+</li>
+</ul>
+<ul>
        <li>Is a url
 <ul>
        <li>if checked, it means that the subfield is a url and can be clicked</li>
index a4377df..1afa5b0 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 <style type="text/css"> #koha-news { border: 1px solid #EEEEEE; margin: .2em;} #koha-news h3 {background-color: #EEEEEE; padding : .3em; margin: 0;} .newsitem {margin: .3em; border-bottom: 1px solid #EEE;} .newsitem:last-child {border-bottom : 0;} .newsfooter {font-size: 80%; color: #CCCCCC;} </style>
 </head>
-<body>
+<body id="main_intranet-main" class="main">
 [% INCLUDE 'header.inc' %]
 [% IF ( koha_news_count ) %]<div id="doc3" class="yui-t3">[% ELSE %]<div id="doc3" class="yui-t7">[% END %]
 <div id="bd">
index fdfc71d..131f085 100644 (file)
@@ -1,6 +1,6 @@
 [% INCLUDE 'doc-head-open.inc' %]Koha &rsaquo; Tools &rsaquo; Labels &rsaquo;: Search[% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="labels_label-bib-search" class="tools labels">
 <div id="main-compact">
 
 <h1>Search</h1>
index 1da5830..2ef4aec 100644 (file)
@@ -20,7 +20,7 @@
     //]]>
     </script>
 </head>
-<body onload="dofocus();">
+<body id="labels_label-edit-batch" class="tools labels" onload="dofocus();">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index cd799a8..9b8a57a 100644 (file)
@@ -19,7 +19,7 @@
         //]]>
     </script>
 </head>
-<body>
+<body id="labels_label-edit-layout" class="tools labels">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index d9576e7..88243b2 100644 (file)
@@ -36,7 +36,7 @@
         //]]>
        </script>
 </head>
-<body>
+<body id="labels_label-edit-profile" class="tools labels">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index feefe53..6c96bab 100644 (file)
@@ -36,7 +36,7 @@
         //]]>
        </script>
 </head>
-<body>
+<body id="labels_label-edit-template" class="tools labels">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 2f9fa69..5c21837 100644 (file)
@@ -3,7 +3,7 @@
     [% INCLUDE 'doc-head-close.inc' %]
     <link rel="stylesheet" type="text/css" href="[% themelang %]/css/label.css" />
 </head>
-<body>
+<body id="labels_label-home" class="tools labels">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 2e6bbd7..3f88920 100644 (file)
@@ -79,7 +79,7 @@
         //]]>
     </script>
 </head>
-<body>
+<body id="labels_label-manage" class="tools labels">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 91f5d41..59c1fed 100644 (file)
@@ -11,7 +11,7 @@
     <style type="text/css">#custom-doc {width:47.23em; *width:46.04em; min-width:610px; margin:auto; margin-top:0.4em;}</style>
     <style type="text/css">table {border-collapse: separate; border-spacing: 0; border: hidden none;} .header {cursor: auto; background-position: center center; background-repeat: repeat;}</style>
 </head>
-<body>
+<body id="labels_label-print" class="tools labels">
     <div id="custom-doc" class="yui-t2">
         <div id="bd">
             [% IF ( batches ) %]
index f8d7286..d272f01 100644 (file)
@@ -41,7 +41,7 @@
             //]]>
     </script>
 </head>
-<body>
+<body id="labels_result" class="tools labels">
     <div id="custom-doc" class="yui-t7">
         <div id="bd">
             <h1>Search results</h1>
index 1cd7aef..1d9d45d 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'calendar.inc' %]
 <style type="text/css">#custom-doc { width:47.23em;*width:46.04em;min-width:610px; margin:auto;margin-top: .4em; text-align:left; }</style>
 </head>
-<body>
+<body id="labels_search" class="tools labels">
 
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
index 3384af5..e324db5 100644 (file)
@@ -1,7 +1,7 @@
 [% INCLUDE 'doc-head-open.inc' %]<title>Koha &rsaquo; Tools &rsaquo; Quick spine label creator</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="labels_spinelabel-home" class="tools labels">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 598eed8..3df9cd0 100644 (file)
        </style>
 </head>
        [% IF ( BarcodeNotFound ) %]
-               <body>
+               <body id="labels_spinelabel-print" class="tools labels">
                        <p>The barcode [% Barcode %] was not found.</p>
                        <p><a href="spinelabel-home.pl">Return To Spine Label Printer</a></p>
                </body>
        [% ELSE %]
                [% IF ( autoprint ) %]
-                       <body onLoad="window.print()">
+                       <body id="labels_spinelabel-print" class="tools labels" onLoad="window.print()">
                [% ELSE %]      
                        <body>
                [% END %] 
index 4e053e2..995ea8c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Patrons &rsaquo; Account for [% INCLUDE 'patron-title.inc' %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="pat_borraccount" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 49c4ad2..5bd0a92 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Can't Delete Patron</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="pat_deletemem" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index bf30f9f..c79cbf9 100644 (file)
@@ -55,7 +55,7 @@
         // -->
     </script>
 </head>
-
+<body id="pat_guarantor_search" class="pat">
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
        <div class="yui-g">
index f783350..f8d242b 100644 (file)
@@ -9,7 +9,7 @@ $(document).ready(function(){
 //]]>
 </script>
 </head>
-<body>
+<body id="pat_mancredit" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 318bd59..62045a9 100644 (file)
@@ -9,7 +9,7 @@ $(document).ready(function(){
 //]]>
 </script>
 </head>
-<body>
+<body id="pat_maninvoice" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 32a8421..f04a620 100644 (file)
@@ -68,7 +68,7 @@
 
 </script>
 </head>
-<body>
+<body id="pat_member-flags" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 1269270..4eaef3f 100644 (file)
@@ -21,7 +21,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="pat_member-password" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index c3f3909..9fd7b5c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Patrons [% IF ( searching ) %]&rsaquo; Search Results[% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="pat_member" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 814bd55..8a31738 100644 (file)
             document.form.state.value=RegExp.$3;
             document.form.country.value=RegExp.$4;
         });
+
+        [% IF categorycode %]
+            update_category_code( "[% categorycode %]" );
+        [% ELSE %]
+            if ( $("#categorycode").length > 0 ){
+                var category_code = $("#categorycode").find("option:selected").val();
+                update_category_code( category_code );
+            }
+        [% END %]
+
     });
 
     function clear_entry(node) {
         $("select#patron_attr_" + newId, clone).attr('value','');
         original.parentNode.insertBefore(clone, original.nextSibling);
     }
+
+    function update_category_code(category_code) {
+        if ( $(category_code).is("select") ) {
+            category_code = $("#categorycode").find("option:selected").val();
+        }
+        var mytables = $(".attributes_table>tbody");
+
+        mytables.find("tr").each(function(){
+            $(this).hide()
+        });
+
+        mytables.find("tr[data-category_code="+category_code+"]").each(function(){
+            $(this).show();
+        });
+        mytables.find("tr[data-category_code='']").each(function(){
+            $(this).show();
+        });
+
+    }
+
                var MSG_SEPARATOR = _("Separator must be / in field ");
         var MSG_INCORRECT_DAY = _("Invalid day entered in field ");
         var MSG_INCORRECT_MONTH = _("Invalid month entered in field ");
@@ -65,7 +95,7 @@
 </script>
 <script type="text/javascript" src="[% themelang %]/js/members.js"></script>
 </head>
-<body>
+<body id="pat_memberentrygen" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
         [% END %]
     <li>
         <label for="categorycode">Category: </label>
-        <select id="categorycode" name="categorycode">
+        <select id="categorycode" name="categorycode" onchange="update_category_code(this);">
         [% FOREACH typeloo IN typeloop %]
-                       [% FOREACH categoryloo IN typeloo.categoryloop %]
-                               [% IF ( loop.first ) %]
-                                       [% IF ( typeloo.typename_C ) %]<optgroup label="Child">[% END %]
-                                       [% IF ( typeloo.typename_A ) %]<optgroup label="Adult">[% END %]
-                                       [% IF ( typeloo.typename_S ) %]<optgroup label="Staff">[% END %]
-                                       [% IF ( typeloo.typename_I ) %]<optgroup label="Organization">[% END %]
-                                       [% IF ( typeloo.typename_P ) %]<optgroup label="Professional">[% END %]
-                                       [% IF ( typeloo.typename_X ) %]<optgroup label="Statistical">[% END %]
-                           [% END %]
-                               [% IF ( categoryloo.categorycodeselected ) %]
-               <option value="[% categoryloo.categorycode %]" selected="selected">[% categoryloo.categoryname %]</option>
-                               [% ELSE %]
-<option value="[% categoryloo.categorycode %]">[% categoryloo.categoryname %]</option>
-                               [% END %]
-                               [% IF ( loop.last ) %]
-                               </optgroup>
-                               [% END %]
+            [% FOREACH categoryloo IN typeloo.categoryloop %]
+                [% IF ( loop.first ) %]
+                    [% IF ( typeloo.typename_C ) %]<optgroup label="Child"        value="C">[% END %]
+                    [% IF ( typeloo.typename_A ) %]<optgroup label="Adult"        value="A">[% END %]
+                    [% IF ( typeloo.typename_S ) %]<optgroup label="Staff"        value="S">[% END %]
+                    [% IF ( typeloo.typename_I ) %]<optgroup label="Organization" value="I">[% END %]
+                    [% IF ( typeloo.typename_P ) %]<optgroup label="Professional" value="P">[% END %]
+                    [% IF ( typeloo.typename_X ) %]<optgroup label="Statistical"  value="X">[% END %]
+                [% END %]
+                [% IF ( categoryloo.categorycodeselected ) %]
+                    <option value="[% categoryloo.categorycode %]" selected="selected" data-typename="[% typeloo.typename %]">[% categoryloo.categoryname %]</option>
+                [% ELSE %]
+                    <option value="[% categoryloo.categorycode %]" data-typename="[% typeloo.typename %]">[% categoryloo.categoryname %]</option>
+                [% END %]
+                [% IF ( loop.last ) %]
+                    </optgroup>
+                [% END %]
             [% END %]
        [% END %]
        </select>
   <fieldset class="rows" id="memberentry_patron_attributes">
     <input type="hidden" name="setting_extended_patron_attributes" value="1" />
     <legend>Additional attributes and identifiers</legend>
-    <table>
-        <tr>
-            <th>Type</th>
-            <th colspan="2">Value</th>
-        </tr>
-        [% FOREACH patron_attribute IN patron_attributes %]
-        <tr>
-            <td>[% patron_attribute.code %] ([% patron_attribute.description %])
-            </td>
-            <td>
-                <input type="hidden" id="[% patron_attribute.form_id %]_code" name="[% patron_attribute.form_id %]_code" value="[% patron_attribute.code |html %]" />
-                [% IF ( patron_attribute.use_dropdown ) %]
-                    <select id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]">
-                        <option value="" />
-                        [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %]
-                            [% IF ( auth_val_loo.selected ) %]
-                                <option value="[% auth_val_loo.authorised_value %]" selected="selected">
-                                    [% auth_val_loo.lib %]
-                                </option>
+    [% FOREACH pa_loo IN patron_attributes %]
+        [% IF pa_loo.class %]
+            <h4>[% pa_loo.lib %]</h4>
+            <table id=aai_[% pa_loo.class %] class="attributes_table">
+        [% ELSE %]
+            <table id="aai" class="attributes_table">
+        [% END %]
+        <thead>
+            <tr>
+                <th>Type</th>
+                <th colspan="2">Value</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOREACH patron_attribute IN pa_loo.items %]
+                <tr data-category_code="[% patron_attribute.category_code %]">
+                    <td>
+                        [% patron_attribute.code %] ([% patron_attribute.description %])
+                    </td>
+                    <td>
+                        <input type="hidden" id="[% patron_attribute.form_id %]_code" name="[% patron_attribute.form_id %]_code" value="[% patron_attribute.code |html %]" />
+                        [% IF ( patron_attribute.use_dropdown ) %]
+                            <select id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]">
+                                <option value="" />
+                                [% FOREACH auth_val_loo IN patron_attribute.auth_val_loop %]
+                                    [% IF ( auth_val_loo.selected ) %]
+                                        <option value="[% auth_val_loo.authorised_value %]" selected="selected">
+                                            [% auth_val_loo.lib %]
+                                        </option>
+                                    [% ELSE %]
+                                        <option value="[% auth_val_loo.authorised_value %]" >
+                                            [% auth_val_loo.lib %]
+                                        </option>
+                                    [% END %]
+                                [% END %]
+                            </select>
+                        [% ELSE %]
+                            [% IF ( opduplicate ) %]
+                            <input type="text" maxlength="64" value="[% patron_attribute.value %]"
+                                   id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" onclick="this.value=''" />
                             [% ELSE %]
-                                <option value="[% auth_val_loo.authorised_value %]" >
-                                    [% auth_val_loo.lib %]
-                                </option>
+                            <input type="text" maxlength="64" value="[% patron_attribute.value %]"
+                                   id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" />
                             [% END %]
                         [% END %]
-                    </select>
-                [% ELSE %]
-                    [% IF ( opduplicate ) %]
-                    <input type="text" maxlength="64" value="[% patron_attribute.value %]"
-                           id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" onclick="this.value=''" />
-                    [% ELSE %]
-                    <input type="text" maxlength="64" value="[% patron_attribute.value %]"
-                           id="[% patron_attribute.form_id %]" name="[% patron_attribute.form_id %]" />
-                    [% END %]
-                [% END %]
-                [% IF ( patron_attribute.password_allowed ) %]
-                    (Password: <input type="password" maxlength="64" value="[% patron_attribute.password %]"
-                           id="[% patron_attribute.form_id %]_password" name="[% patron_attribute.form_id %]_password" />)
-                [% END %]
-            </td>
-            <td>
-                <a href="#" onclick="clear_entry(this); return false;">Clear</a>
-                [% IF ( patron_attribute.repeatable ) %]
-                <a href="#" onclick="clone_entry(this); return false;">New</a>
-                [% END %]
-            </td>
-        </tr>
-        [% END %]
-    </table>
+                        [% IF ( patron_attribute.password_allowed ) %]
+                            (Password: <input type="password" maxlength="64" value="[% patron_attribute.password %]"
+                                   id="[% patron_attribute.form_id %]_password" name="[% patron_attribute.form_id %]_password" />)
+                        [% END %]
+                    </td>
+                    <td>
+                        <a href="#" onclick="clear_entry(this); return false;">Clear</a>
+                        [% IF ( patron_attribute.repeatable ) %]
+                        <a href="#" onclick="clone_entry(this); return false;">New</a>
+                        [% END %]
+                    </td>
+                </tr>
+            [% END %]
+        </tbody>
+        </table>
+    [% END %]
   </fieldset>
 [% END %][% END %][% END %]
 
index f7ca5ff..efe7f20 100644 (file)
@@ -5,7 +5,7 @@
                #custom-doc { width:44.23em;*width:43.12em;min-width:491px; margin:auto; text-align:left; } 
        </style>
 </head>
-<body style="padding:.5em;">
+<body id="pat_moremember-brief" class="pat" style="padding:.5em;">
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
        <h3>[% UNLESS ( I ) %]
index f84052b..7cf6bd5 100644 (file)
@@ -9,7 +9,7 @@
         window.close();
     }
 </script>
-<body onload="printThenClose();">
+<body id="pat_moremember-print" class="pat" onload="printThenClose();">
 
 </head>
 <body>
index 4a85ccb..6674e5c 100644 (file)
@@ -11,7 +11,7 @@
     }
 </script>
 </head>
-<body onload="printThenClose();">
+<body id="pat_moremember-receipt" class="pat" onload="printThenClose();">
 
 <div id="receipt">
 
index bd19584..7a62b00 100644 (file)
@@ -118,7 +118,7 @@ function validate1(date) {
 </script>
 
 </head>
-<body>
+<body id="pat_moremember" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
@@ -285,22 +285,35 @@ function validate1(date) {
 [% UNLESS ( no_patron_attribute_types ) %]
 <div id="patron-extended-attributes" style="padding-top: 1em;">
 <h3>Additional attributes and identifiers</h3>
-<table>
-    <tr>
-        <th>Type</th>
-        <th>Value</th>
-    </tr>
-    [% FOREACH extendedattribute IN extendedattributes %]
-    <tr>
-        <td>[% extendedattribute.code %] ([% extendedattribute.description %])</td>
-        <td>[% extendedattribute.value %]
-            [% IF ( extendedattribute.value_description ) %]
-                ([% extendedattribute.value_description %])
-            [% END %]
-        </td>
-    </tr>
+[% FOREACH attribute IN attributes_loop %]
+    [% IF attribute.class %]
+        <h4>[% attribute.lib %]</h4>
+        <table id=aai_[% attribute.class %]>
+    [% ELSE %]
+        <table id="aai">
     [% END %]
-</table>
+        <thead>
+            <tr>
+                <th>Type</th>
+                <th>Description</th>
+                <th>Value</th>
+            </tr>
+        </thead>
+        <tbody>
+        [% FOREACH item IN attribute.items %]
+            <tr>
+                <td>[% item.code %]</td>
+                <td>[% item.description %]</td>
+                <td>[% item.value %]
+                    [% IF ( item.value_description ) %]
+                        ([% item.value_description %])
+                    [% END %]
+                </td>
+            </tr>
+        [% END %]
+        </tbody>
+    </table>
+[% END %]
 </div>
 <div class="action"><a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=4">Edit</a></div>
 [% END %]
@@ -396,8 +409,8 @@ function validate1(date) {
 
 <div id="finesholdsissues" class="toptabs">
        <ul>
-               <li><a href="/cgi-bin/koha/members/moremember.pl#checkedout">[% issuecount %] Checkout(s)</a></li>
-    [% IF ( relissuecount ) %]
+               <li><a href="/cgi-bin/koha/members/moremember.pl#checkedout">[% issueloop.size %] Checkout(s)</a></li>
+    [% IF relissueloop.size %]
         <li><a href="/cgi-bin/koha/members/moremember.pl#relissues">Relatives' Checkouts</a></li>
     [% END %]
                <li><a href="/cgi-bin/koha/members/moremember.pl#finesandcharges">Fines &amp; Charges</a></li>
@@ -528,7 +541,7 @@ function validate1(date) {
 </div>
 
 
-[% IF ( relissuecount ) %]
+[% IF relissueloop %]
 <div id="relissues">
  <table id="relissuest">
     <thead>
index 5b49c48..bd345b8 100644 (file)
@@ -25,7 +25,7 @@
     a.message-title { font-weight: bold; display: block; }
 </style>
 </head>
-<body>
+<body id="pat_notices" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index d883958..4aaca9b 100644 (file)
@@ -14,7 +14,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="pat_pay" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index c3bdc1e..b38fc01 100644 (file)
@@ -54,7 +54,7 @@ function moneyFormat(textObj) {
 //]]>
 </script>
 </head>
-<body>
+<body id="pat_paycollect" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; <a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]">Pay Fines for [% borrower.firstname %] [% borrower.surname %]</a> &rsaquo; [% IF ( pay_individual ) %]Pay an individual fine[% ELSIF ( writeoff_individual ) %]Write off an individual fine[% ELSE %][% IF ( selected_accts ) %]Pay an amount toward selected fines[% ELSE %]Pay an amount toward all fines[% END %][% END %]</div>
index 7625260..12ac15e 100644 (file)
@@ -10,7 +10,7 @@
     }
 </script>
 </head>
-<body onload="printThenClose();">
+<body id="pat_printfeercpt" class="pat" onload="printThenClose();">
 
 <div id="receipt">
 <!-- The table with the account items -->
index a712e83..a1fe56a 100644 (file)
@@ -10,7 +10,7 @@
     }
 </script>
 </head>
-<body onload="printThenClose();">
+<body id="printinvoice" class="pat" onload="printThenClose();">
 
 <div id="receipt">
 <!-- The table with the account items -->
index 0b31878..82858be 100644 (file)
@@ -13,7 +13,7 @@
  });
 }); </script>
 </head>
-<body>
+<body id="pat_readingrec" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index 81fa3b6..8413468 100644 (file)
@@ -15,7 +15,7 @@
           #custom-doc { width:29em;*width:28.3em;min-width:377px; margin:auto; text-align:left; } 
 </style> 
 </head>
-<body>
+<body id="pat_update-child" class="pat">
 
 <div id="custom-doc" class="yui-t7">
 <div id="bd">
index e286cc8..07d7cf0 100644 (file)
@@ -54,7 +54,7 @@
     //]]>
     </script>
 </head>
-<body>
+<body id="ocirc_list" class="circ ocirc">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'circ-search.inc' %]
 
index 6a66b6a..80ef54f 100644 (file)
@@ -34,7 +34,7 @@ function CheckForm(f) {
        #fileuploadprogress,#jobprogress{ width:200px;height:10px;border:1px solid #666;background:url('/intranet-tmpl/prog/img/progress.png') -300px 0px no-repeat; }
 </style>
 </head>
-<body>
+<body id="ocirc_process_koc" class="circ ocirc">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index a7422cc..2c48f36 100644 (file)
@@ -11,7 +11,7 @@
     <style type="text/css">#custom-doc {width:47.23em; *width:46.04em; min-width:610px; margin:auto; margin-top:0.4em;}</style>
     <style type="text/css">table {border-collapse: separate; border-spacing: 0; border: hidden none;} .header {cursor: auto; background-position: center center; background-repeat: repeat;}</style>
 </head>
-<body>
+<body id="pcard_card-print" class="tools pcard">
     <div id="custom-doc" class="yui-t2">
         <div id="bd">
             [% IF ( batches ) %]
index 4eab7b2..0767628 100644 (file)
@@ -19,7 +19,7 @@
         };
     </script>
 </head>
-<body>
+<body id="pcard_edit-batch" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index b8b0942..0a5fcde 100644 (file)
         };
     </script>
 </head>
-<body>
+<body id="pcard_edit-layout" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 7060146..b5a3997 100644 (file)
@@ -63,7 +63,7 @@
         };
     </script>
 </head>
-<body>
+<body id="pcard_edit-profile" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 0532b26..e568204 100644 (file)
@@ -63,7 +63,7 @@
         };
     </script>
 </head>
-<body>
+<body id="pcard_edit-template" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 25c0e13..459f71e 100644 (file)
@@ -3,7 +3,7 @@
     [% INCLUDE 'doc-head-close.inc' %]
     <link rel="stylesheet" type="text/css" href="[% themelang %]/css/card.css" />
 </head>
-<body>
+<body id="pcard_home" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index 642de1d..fb7b6bc 100644 (file)
@@ -89,7 +89,7 @@
         }
     </script>
 </head>
-<body>
+<body id="pcard_image-manage" class="tools pcard">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <div id="breadcrumbs">
index 0185d47..c8edf68 100644 (file)
         };
     </script>
 </head>
-<body>
+<body id="pcard_manage" class="tools pcard">
     [% INCLUDE 'header.inc' %]
     [% INCLUDE 'cat-search.inc' %]
     <div id="breadcrumbs">
index cbd1db5..2412c2b 100644 (file)
@@ -40,7 +40,7 @@ function add_item(borrowernum,batch_id,type_id){
 //]]>
 </script>
 </head>
-<body>
+<body id="pcard_members-search" class="tools pcard">
 
 <div id="custom-doc" class="yui-t7">
   <div id="bd">
index e7ca17a..74f0dd0 100644 (file)
@@ -10,7 +10,7 @@
     </script>
     <style type="text/css">#custom-doc {width:47.23em; *width:46.04em; min-width:610px; margin:auto; margin-top:0.4em;}</style>
 </head>
-<body>
+<body id="pcard_print" class="tools pcard">
     <div id="custom-doc" class="yui-t2">
         <div id="bd">
             [% IF ( batches ) %]
index 5c1a85a..56121db 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="rep_acquisitions_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index b309d94..e6fdb85 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="rep_bor_issues_top" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 3604e30..47a4f6c 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="rep_borrowers_out" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index c22395c..dabd316 100644 (file)
@@ -7,7 +7,7 @@
        .debug {display:none;}
 </style>
 </head>
-<body>
+<body id="rep_borrowers_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index cbff833..641cefa 100644 (file)
@@ -10,7 +10,7 @@ function Dopop(link) {
 </script>
 [% END %]
 </head>
-<body>
+<body id="rep_cat_issues_top" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index d751fc0..1d67e2c 100644 (file)
@@ -5,7 +5,7 @@
        .sql {display: none;}
 </style>
 </head>
-<body>
+<body id="rep_catalogue_out" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index d04d4f7..9bbf03c 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Reports [% IF ( do_it ) %]&rsaquo; Catalog statistics &rsaquo; Results[% ELSE %]&rsaquo; Catalog statistics[% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rep_catalogue_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index e11b598..5c0da1e 100644 (file)
@@ -4,7 +4,7 @@
 [% INCLUDE 'calendar.inc' %]
 <style type="text/css">fieldset.rows table { clear: none; margin: 0;}</style>
 </head>
-<body>
+<body id="rep_dictionary" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 8dbbb03..ea933aa 100644 (file)
@@ -60,7 +60,7 @@ $(document).ready(function(){
 //]]>
 </script>
 </head>
-<body>
+<body id="rep_guided_reports_start" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
@@ -269,7 +269,7 @@ canned reports and writing custom SQL reports.</p>
 <optgroup label="[% column.table %]">
 [% ELSE %]
 <option value="[% column.name %]">
-[% IF ( column.description ) %][% column.description %]
+[% IF ( column.description ) %][% column.description %] &nbsp; / &nbsp; [% column.name %]
 [% ELSE %]
 [% column.name %]
 [% END %]
index 166e4b0..311e355 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="rep_issues_avg_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 679d22b..e2cecb6 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="rep_issues_by_borrower_category" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 4b7a668..1ff9016 100644 (file)
@@ -6,7 +6,7 @@
        .sql {display:none;}
 </style>
 </head>
-<body>
+<body id="rep_issues_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index ebafbaa..d21bec4 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Reports &rsaquo; Lost Items</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rep_itemslost" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 26199e6..307eefc 100644 (file)
@@ -10,7 +10,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="rep_itemtypes" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index e8bb4d5..9f9d532 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Reports</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rep_reports-home" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 2467b5f..3abe04e 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Hold Report &rsaquo; All Holds</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rep_reservereport" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index f5d03f5..0fe8c07 100644 (file)
@@ -6,7 +6,7 @@
        .sql {display:none;}
 </style>
 </head>
-<body>
+<body id="rep_reserve_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index b07dc5e..10df0cf 100644 (file)
@@ -15,7 +15,7 @@
        //]]>
 </script>
 </head>
-<body>
+<body id="rep_serials_stats" class="rep">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 7809766..3c6f9cb 100644 (file)
@@ -3,9 +3,9 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %] 
 
-</head>    
-<body>   
-[% INCLUDE 'header.inc' %]                                    
+</head>
+<body id="rep_stats_screen" class="rep">
+[% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a> &rsaquo; Till Reconciliation
 </div>
index 2771c6f..a257e2e 100644 (file)
@@ -134,7 +134,7 @@ function checkMultiHold() {
 // ]]>
 </script>
 </head>
-<body>
+<body id="circ_request" class="catalog">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 1283a78..c4e0cea 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools &rsaquo; Comments &rsaquo; [% IF ( status ) %] Approved comments[% ELSE %] Comments awaiting moderation[% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="tools_reviewswaiting" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 6c63cfb..4c41462 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools &rsaquo; Rotating Collections &rsaquo; Edit Collections</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rcoll_editCollections" class="tools rcoll">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 911f2dd..a041e7b 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools &rsaquo; Rotating Collections</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rcoll_rotatingCollections" class="tools rcoll">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index cabe604..afc0258 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools &rsaquo; Rotating Collections &rsaquo; Transfer Collection</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="rcoll_transferCollection" class="tools rcoll">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 2a29f72..361e852 100644 (file)
@@ -11,7 +11,7 @@ function GetIt(aqbooksellerid,name)
 }
 </script>
 </head>
-<body>
+<body id="ser_acqui-search-result" class="ser">
 
 <div id="doc" class="yui-t7">
    <div id="bd">
index f0b77ef..9fea3ed 100644 (file)
@@ -12,7 +12,7 @@ function GetIt(aqbooksellerid,name)
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_acqui-search" class="ser">
 
 <div id="doc" class="yui-t7">
    <div id="bd">
index 246eb49..e9909c0 100644 (file)
@@ -27,7 +27,7 @@
 </script>
 <!-- End of additions -->
 </head>
-<body>
+<body id="ser_checkexpiration" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index 506ece1..f6acf09 100644 (file)
 </script>
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="ser_claims" class="ser">
     [% INCLUDE 'header.inc' %]
 [% UNLESS ( preview ) %]
     [% INCLUDE 'serials-search.inc' %]
index 91172be..aae4e0b 100644 (file)
@@ -15,7 +15,7 @@ function add_member(subscriptionid,borrowernumber){
    #custom-doc { width:36.46em;*width:35.53em;min-width:430px; margin:auto; text-align:left; padding: 1em; }
    </style>
 </head>
-<body>
+<body id="ser_member-search" class="ser">
 <div id="custom-doc" class="yui-t7">
    
 <div id="bd">
index 54b4497..9eef84f 100644 (file)
@@ -13,7 +13,7 @@ function GetIt(bibno,title)
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_result" class="ser">
 
 <div id="doc" class="yui-t7">
    <div id="bd">
index f4200e5..5a23158 100644 (file)
@@ -9,7 +9,7 @@
    .yui-t7, #custom-doc { min-width:0; width:auto; }
 </style>
 </head>
-<body>
+<body id="ser_routing-preview-slip" class="ser">
 
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
index b48e902..2995cba 100644 (file)
@@ -12,7 +12,7 @@ function print_slip(subscriptionid,issue){
 //-->
 </script>
 </head>
-<body>
+<body id="ser_routing-preview" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index 9851ebf..c443e03 100644 (file)
@@ -16,7 +16,7 @@ function search_member(subscriptionid){
 //-->
 </script>
 </head>
-<body>
+<body id="ser_routing" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index cddf760..9d1fe7d 100644 (file)
@@ -19,7 +19,7 @@ function active(numlayer)
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_serial-issues-full" class="ser">
 
 [% UNLESS ( popup ) %]
 [% INCLUDE 'header.inc' %]
index 8c8af64..a22b97b 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Serials &rsaquo; Subscription information for [% bibliotitle %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="ser_serial-issues" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index 1293f56..414cf3b 100644 (file)
@@ -48,7 +48,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body class="yui-skin-sam">
+<body id="ser_serials-collection" class="yui-skin-sam ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
@@ -238,7 +238,7 @@ $(document).ready(function() {
                 </td>
                 [% IF ( routing ) %]
                 <td>
-                    <a href="" onclick="print_slip([% serial.subscriptionid |html %], '[% serial.serialseq |html %]'); return false" >Print list</a>
+                    <a href="" onclick="print_slip([% serial.subscriptionid |html %], '[% serial.serialseq |html %] ([% serial.planneddate %])'); return false" >Print list</a>
                 </td>
                 [% END %]
             [% IF ( CAN_user_serials_receive_serials ) %]
index 083580b..36374ba 100644 (file)
@@ -164,7 +164,7 @@ $(document).ready(function() {
        width : auto;
 }</style>
 </head>
-<body>
+<body id="ser_serials-edit" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
@@ -185,7 +185,7 @@ $(document).ready(function() {
 [% IF ( Errors ) %]
 <div class="dialog alert">
 <ul>
-[% IF ( barcode_not_unique ) %]<li>Error : Barcode Not Unique For [% FOREACH errse IN errseq %]serialseq [% errse.serialseq %]<br/>[% END %]</li>[% END %]
+[% IF ( barcode_not_unique ) %]<li>Error: Barcode not unique for [% FOREACH errse IN errseq %]serialseq [% errse.serialseq %]<br/>[% END %]</li>[% END %]
 </ul>
 </div>
 [% END %]
index bb0f9d3..defdd69 100644 (file)
@@ -20,7 +20,7 @@
  //]]>
 </script>
 </head>
-<body
+<body id="ser_serials-home" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
@@ -117,7 +117,7 @@ Serials updated :
                 [% IF ( subscription.internalnotes ) %]([% subscription.internalnotes %])[% END %]
                 </td>
                 <td>
-                [% IF ( subscription.branchcode ) %][% subscription.branchcode %][% END %]
+                [% IF ( subscription.branchname ) %][% subscription.branchname %][% END %]
                 [% IF ( subscription.callnumber ) %]([% subscription.callnumber %])[% END %]
                 </td>
                 [% IF ( routing && CAN_user_serials_routing ) %]
index f45ffeb..ce43eb2 100644 (file)
@@ -40,7 +40,7 @@ function barcode_check(){
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_serials-recieve" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index 5301ce3..6474b16 100644 (file)
@@ -944,11 +944,21 @@ $(document).ready(function() {
     $('#numberpattern').change( function() { 
         reset_num_pattern(); 
     });
+
+    var node;
+    [% FOREACH field IN dont_export_field_loop %]
+        node = $("#[% field.fieldid %]");
+        if ( $(node).is('input') || $(node).is('textarea') ) {
+            $(node).val("");
+        } else if ( $(node).is('select') ) {
+            $(node).find("option:first").attr('selected','selected');
+        }
+    [% END %]
 });
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_subscription-add" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
@@ -1333,7 +1343,7 @@ $(document).ready(function() {
                                        [% IF ( subtype_numberlength ) %]<option value="numberlength" selected="selected">[% ELSE %]<option value="numberlength">[% END %] Number of issues</option>                                    
                                        [% IF ( subtype_weeklength ) %]<option value="weeklength" selected="selected">[% ELSE %]<option value="weeklength">[% END %] Number of weeks</option>                                   
                 </select>
-                <input type="text" name="sublength" value="[% sublength %]" size="3" onkeypress="return check_input(event)" /> (enter amount in numerals)
+                <input type="text" id="numberlength" name="sublength" value="[% sublength %]" size="3" onkeypress="return check_input(event)" /> (enter amount in numerals)
             <span class="required">Required</span>
         </li>
         <li>
index b27e6c1..9cb35f4 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Serials &rsaquo; Catalog search</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="ser_subscription-bib-search" class="ser">
 
 <div id="doc" class="yui-t7">
    <div id="bd">
index 6e66728..e9475f3 100644 (file)
@@ -38,7 +38,7 @@ $(document).ready(function() {
 //]]>
 </script>
 </head>
-<body>
+<body id="ser_subscription-detail" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
index b2290c2..c7f18c2 100644 (file)
@@ -5,7 +5,7 @@
    #custom-doc { width:39.85em;*width:38.86em;min-width:531px; margin:auto; text-align:left; }
    </style>
 </head>
-<body>
+<body id="ser_subscription-renew" class="ser">
 
 <div id="custom-doc" class="yui-t7">
 [% IF ( renew ) %]
index 9c3f83f..c1ad589 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Serials &rsaquo; Alert subscribers for [% bibliotitle %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="ser_viewalerts" class="ser">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'serials-search.inc' %]
 
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/services/itemrecorddisplay.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/services/itemrecorddisplay.tt
new file mode 100644 (file)
index 0000000..6790b3d
--- /dev/null
@@ -0,0 +1,24 @@
+<ol>
+  [% FOREACH iteminfo IN iteminformation %]
+    <li>
+      <div class="subfield_line" style="[% iteminfo.hidden %];" id="subfield[% iteminfo.serialid %][% iteminfo.countitems %][% iteminfo.subfield %][% iteminfo.random %]">
+        <label>
+            [% iteminfo.subfield %] -
+            [% IF ( iteminfo.mandatory ) %]
+                <b>
+            [% END %]
+            [% iteminfo.marc_lib %]
+            [% IF ( iteminfo.mandatory ) %]
+                *</b>
+            [% END %]
+        </label>
+        [% iteminfo.marc_value %]
+        <input type="hidden" name="itemid" value="1" />
+        <input type="hidden" name="kohafield" value="[% iteminfo.kohafield %]" />
+        <input type="hidden" name="tag" value="[% iteminfo.tag %]" />
+        <input type="hidden" name="subfield" value="[% iteminfo.subfield %]" />
+        <input type="hidden" name="mandatory" value="[% iteminfo.mandatory %]" />
+      </div>
+    </li>
+  [% END %]
+</ol>
index 2c30450..9ad3cc9 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools &rsaquo; Send SMS Message</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="sms_sms-home" class="pat">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 91c5a8f..47b98d0 100644 (file)
@@ -102,7 +102,7 @@ $(document).ready(function() { calcNewsuggTotal(); });
 [% END %]
 <script type="text/javascript" src="[% themelang %]/js/acq.js"></script>
 </head>
-<body>
+<body id="acq_suggestion" class="acq">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 <div id="breadcrumbs">
index 05fd452..55bf16a 100644 (file)
@@ -29,7 +29,7 @@
 <style type="text/css">
 tr.selected { background-color : #FFFFCC; } tr.selected td { background-color : transparent; }</style>
 </head>
-<body>
+<body id="tags_list" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 843f7ca..822187c 100644 (file)
@@ -135,7 +135,7 @@ td input,td input[type="submit"] { font-size: 85%; padding: 1px; }
 //]]>
 </script>
 </head>
-<body>
+<body id="tags_review" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 3f0f4b9..c71ab9a 100644 (file)
@@ -23,7 +23,7 @@ for( x=0; x<allColumns.length; x++ ){
 <style type="text/css">#selections { display: none; }</style>
 <![endif]-->
 </head>
-<body>
+<body id="tools_batchMod-del" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 540b141..a1b63d9 100644 (file)
@@ -45,7 +45,7 @@ $("input[name='disable_input']").click(function() {
 <![endif]-->
 <link type="text/css" rel="stylesheet" href="[% themelang %]/css/addbiblio.css" />
 </head>
-<body>
+<body id="tools_batchMod-edit" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 5410bcd..df6fa57 100644 (file)
@@ -11,7 +11,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="tools_batchMod" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 3d0fd2a..16176df 100644 (file)
@@ -37,7 +37,7 @@
 </script>
 
 </head>
-<body>
+<body id="tools_cleanborrowers" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index f3c5192..3623096 100644 (file)
@@ -12,7 +12,7 @@ function reloadPage(p) {
 </script>
 </head>
 
-<body>
+<body id="tools_csv-profiles" class="tools">
        [% INCLUDE 'header.inc' %]
        [% INCLUDE 'cat-search.inc' %]
 
index 0412a81..14e87bc 100644 (file)
@@ -6,7 +6,7 @@
 <script type="text/javascript" src="[% themelang %]/lib/calendar/calendar-en.js"></script>
 <script type="text/javascript" src="[% themelang %]/lib/calendar/calendar-setup.js"></script>
 </head>
-<body>
+<body id="tools_export" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 55db32d..f597f82 100644 (file)
 #showHoliday { margin : .5em 0; } h1 select { width: 20em; } div.yui-b fieldset.brief ol { font-size:100%; } div.yui-b fieldset.brief li, div.yui-b fieldset.brief li.radio  { padding:0.2em 0; } .help { margin:.3em 0;border:1px solid #EEE;padding:.3em .7em; font-size : 90%; } #holidayweeklyrepeatable, #holidaysyearlyrepeatable, #holidaysunique, #holidayexceptions { font-size : 90%; margin-bottom : 1em;} .calendar td, .calendar th, .calendar .button, .calendar tbody .day { padding : .7em; font-size: 110%; } .calendar { width: auto; border : 0; }
 </style>
 </head>
-<body>
+<body id="tools_holidays" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 756e086..9fa7049 100644 (file)
@@ -7,7 +7,7 @@
     code { background-color: yellow; }
 </style>
 </head>
-<body>
+<body id="tools_import_borrowers" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
 
index e3071a2..824b3ff 100644 (file)
@@ -28,7 +28,7 @@ $(document).ready(function(){
 //]]>
 </script>
 </head>
-<body>
+<body id="tools_inventory" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index dfee834..06e6461 100644 (file)
@@ -35,7 +35,7 @@ tinyMCE.init({
 });
 </script>
 </head>
-<body>
+<body id="tools_koha-news" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index fd0aa92..aa1301b 100644 (file)
@@ -117,7 +117,7 @@ $(document).ready(function() {
                //]]>
                </script>
 </head>
-<body>
+<body id="tools_letter" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'letters-search.inc' %]
 
index 3890efe..0750b2c 100644 (file)
@@ -28,7 +28,7 @@ $(document).ready(function(){
        #jobstatus { margin:.4em; }
        #jobprogress{ width:200px;height:10px;border:1px solid #666;background:url('/intranet-tmpl/prog/img/progress.png') -300px 0px no-repeat; } span.change-status { font-style:italic; color:#666; display:none; }</style>
 </head>
-<body>
+<body id="tools_manage-marc-import" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index c3ad0c9..ab69533 100644 (file)
@@ -15,7 +15,7 @@ $(document).ready(function() {
 </script>
 
 </head>
-<body>
+<body id="tools_overduerules" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 2050828..bb59a7d 100644 (file)
@@ -12,7 +12,7 @@
 });
 </script>
 </head>
-<body>
+<body id="tools_picture-upload" class="tools">
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'patron-search.inc' %]
index 09c943a..6085550 100644 (file)
@@ -3,7 +3,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body id="tools_scheduler" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'circ-search.inc' %]
 
index 0f9568e..af15194 100644 (file)
@@ -24,7 +24,7 @@ function CheckForm(f) {
 //]]>
 </script>
 </head>
-<body>
+<body id="tools_stage-marc-import" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 5cc3bbf..0cd163d 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Tools</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body>
+<body id="tools_tools-home" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 6108b3d..b909cc8 100644 (file)
@@ -30,7 +30,7 @@ function CheckForm(f) {
 //]]>
 </script>
 </head>
-<body>
+<body id="tools_upload-images" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index b2ab90f..8449341 100644 (file)
@@ -10,7 +10,7 @@
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
 </head>
-<body>
+<body class="tools_viewlog" class="tools">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
index 77468cc..b062980 100644 (file)
@@ -5,8 +5,15 @@
    #custom-doc { width:34.62em;*width:33.78em;min-width:450px; margin:auto; margin-top: .4em;text-align:left; }
    </style>
 </head>
-<body>
+<body id="lists_addbybiblionumber" class="lists">
 
+[% UNLESS (authorized) %]
+    <p align="center">
+        [% IF (errcode==1) %]Could not make new shelf. Please check the name.<br/>[% END %]
+        [% IF (errcode==2) %]Sorry, you do not have permission to add items to this list.<br/>[% END %]
+        <a href="javascript:self.close();">Close this window.</a>
+    </p>
+[% ELSE %]
 <div id="custom-doc" class="yui-t7">
    <div id="bd">
                 [% IF ( multiple ) %]
 
 [% UNLESS ( shelfnumber ) %]
 
-[% IF ( CGIvirtualshelves ) %]    [% UNLESS ( newshelf ) %]
+[% UNLESS ( newshelf ) %]
      <fieldset class="rows">
        <legend>Select an existing list</legend>
        <ol>
-           <li><label>Choose list</label>[% CGIvirtualshelves %]</li>
+           <li>
+               <label>Choose list</label>
+               <select name="shelfnumber" id="shelfnumber">
+               [% IF ( privatevirtualshelves ) %]
+               <optgroup label="Private Lists">
+               [% FOREACH privatevirtualshelve IN privatevirtualshelves %]
+               <option value="[% privatevirtualshelve.shelfnumber %]">[% privatevirtualshelve.shelfname %]</option>
+               [% END %]
+               </optgroup>
+               [% END %]
+               [% IF ( publicvirtualshelves ) %]
+               <optgroup label="Public Lists">
+               [% FOREACH publicvirtualshelve IN publicvirtualshelves %]
+               <option value="[% publicvirtualshelve.shelfnumber %]">[% publicvirtualshelve.shelfname %]</option>
+               [% END %]
+               </optgroup>
+               [% END %]
+               </select>
+           </li>
        </ol>
        [% FOREACH biblio IN biblios %]<input type="hidden" name="biblionumber" value="[% biblio.biblionumber %]" />[% END %]
        [% UNLESS ( biblionumbers ) %]
@@ -43,9 +68,8 @@
        [% END %]
        </fieldset>
 
-       <p>... or...</p> [% END %]
-
-    [% END %]
+       <p>... or...</p>
+[% END %]
 
     <fieldset class="rows"><legend>Add to a new list:</legend>
        <ol><li>
@@ -66,7 +90,6 @@
            <select name="category" id="category">
                <option value="1">Private</option>
                <option value="2">Public</option>
-               <option value="3">Open</option>
            </select>
        </li></ol>
     </fieldset>
 </div>
 
 [% INCLUDE 'intranet-bottom.inc' %]
+[% END %]
index 357ebe4..e2b1ed5 100644 (file)
@@ -2,7 +2,7 @@
 <title>Koha &rsaquo; Download shelf</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding:1em;">
+<body id="lists_downloadshelf" class="lists" style="padding:1em;">
 [% IF ( format ) %]
     <p>Your download should begin automatically.</p>
 [% ELSE %]
index 9bd1097..e38a071 100644 (file)
@@ -1,7 +1,7 @@
 [% INCLUDE 'doc-head-open.inc' %]<title>Koha &rsaquo; Lists &rsaquo;  Sending your list</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
-<body style="padding: 1em;" id="sendbasket">
+<body id="lists_sendshelfform" class="lists" style="padding: 1em;">
 <div class="container">[% IF ( email ) %]
 
     [% IF ( SENT ) %]
index b054e09..96b00a5 100644 (file)
@@ -24,7 +24,7 @@ $(document).ready(function(){
 
        function confirmDelete(message){
                if (window.confirm(message)) {
-                   location.href="/cgi-bin/koha/virtualshelves/shelves.pl?[% IF ( showprivateshelves ) %] display=privateshelves&[% END %]shelves=1&DEL-[% shelfnumber %]=1&shelfoff=[% shelfoff %]";
+                   location.href="/cgi-bin/koha/virtualshelves/shelves.pl?[% IF ( showprivateshelves ) %]display=privateshelves&[% END %]shelves=1&DEL-[% shelfnumber %]=1&shelfoff=[% shelfoff %]";
                } else { 
                        return false;
                }
@@ -111,7 +111,7 @@ function placeHold () {
 //]]>
 </script>
 </head>
-<body>
+<body id="lists_shelves" class="lists">
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'cat-search.inc' %]
 
@@ -146,7 +146,13 @@ function placeHold () {
                [% END %] 
                [% IF ( paramsloo.duplicatebiblio ) %]
                <div class="dialog alert">A record matching barcode <b>[% paramsloo.duplicatebiblio %]</b> has already been added.</div>
-               [% END %] 
+               [% END %]
+                [% IF ( paramsloo.nothingdeleted) %]
+                      <div class="dialog message">Warning: You could not delete any selected items from this shelf.</div>
+                [% END %]
+                [% IF ( paramsloo.somedeleted) %]
+                      <div class="dialog message">Warning: You could not delete all selected items from this shelf.</div>
+                [% END %]
        </div>
 </div>
 [% END %]
@@ -162,7 +168,7 @@ function placeHold () {
  <fieldset>
   <legend>Contents of <i>[% shelfname | html %]</i></legend>
    
- [% IF ( manageshelf ) %]
+ [% IF ( itemsloop ) %]
      <p><span class="checkall"></span> |
      <span class="clearall"></span></p>
  [% END %]
@@ -170,7 +176,7 @@ function placeHold () {
  <div class="pages">[% pagination_bar %]</div>
     <table>
             <tr>
-                [% IF ( manageshelf ) %]<th class="checkall">&nbsp;</th>[% END %]
+                [% IF ( itemsloop ) %]<th class="checkall">&nbsp;</th>[% END %]
                 [% UNLESS ( item_level_itypes ) %]<th>Item Type</th>[% END %]
                 <th>Title</th>
                 <th>Author</th>
@@ -183,7 +189,7 @@ function placeHold () {
                        [% ELSE %]
                        <tr>
                        [% END %]
-                       [% IF ( manageshelf ) %]
+                       [% IF ( itemsloop ) %]
                        <td>
                                [% IF ( itemsloo.confirm ) %]
                                <input type="hidden"   name="CONFIRM-[% itemsloo.confirm %]" />
@@ -210,9 +216,9 @@ function placeHold () {
                        </tr>
                [% END %]<!-- /itemsloop -->
     </table><fieldset class="action">
-        [% IF ( manageshelf ) %]
+        [% IF ( itemsloop ) %]
             <input type="button" id="placehold" style="display:none" onclick="placeHold(); return false;" value="Place Holds" />
-            <input type="submit" value="Remove selected records" onclick="return confirm(_('Are you sure you want to remove these records from the shelf?'));" />
+            [% IF ( allowremovingitems ) %]<input type="submit" value="Remove selected records" onclick="return confirm(_('Are you sure you want to remove these records from the shelf?'));" />[% END %]
             <input type="submit" value="Merge selected records" onclick="return MergeItems();" />
         [% END %]
  </fieldset>
@@ -223,7 +229,7 @@ function placeHold () {
    </div>
 [% END %]<!-- /viewshelf -->
 
-[% IF ( manageshelf ) %]
+[% IF ( allowaddingitem ) %]
 <div class="yui-g">
 <form action="/cgi-bin/koha/virtualshelves/shelves.pl" method="post">
  <fieldset class="brief">
@@ -240,7 +246,7 @@ function placeHold () {
  </fieldset>
 </form>
 </div>
-[% END %]<!-- /manageshelf -->
+[% END %]<!-- /allowaddingitem -->
 
 [% IF ( debug ) %]
   [% IF ( edit ) %]<div>Edit is on ([% shelfname | html %])</div>[% END %]
@@ -269,7 +275,6 @@ function placeHold () {
                        <select name="category" id="category">
                   <option value="1">Private</option>
                   <option value="2">Public</option>
-                  <option value="3">Open</option>
                        </select></li></ol>
     [% END %]
 
@@ -299,11 +304,6 @@ function placeHold () {
                        [% ELSE %]
                                <option value="2">Public</option>
                        [% END %]
-                       [% IF ( category3 ) %]
-                               <option value="3" selected="selected">Open</option>
-                       [% ELSE %]
-                               <option value="3">Open</option>
-                       [% END %]
                        </select></li></ol>
        [% END %]
 
@@ -317,8 +317,8 @@ function placeHold () {
         <div class="help"><ul>
             <li>A <b>Private</b> List is managed by you and can be seen only by you.</li>
             <li> A <b>Public</b> List can be seen by everybody, but managed only by you.</li>
-            <li> A <b>Open</b> List can be seen and managed by everybody.</li>
-        </ul></div>
+        </ul>
+        </div>
     </div>
 </div>
 [% END %]<!-- /seflag -->
@@ -354,7 +354,6 @@ function placeHold () {
         <td>[% IF ( shelveslooppri.authorsort ) %]Author[% ELSIF ( shelveslooppri.yearsort ) %]Year[% ELSE %]Title[% END %]</td>
         <td>[% IF ( shelveslooppri.viewcategory1 ) %]Private[% END %]
                        [% IF ( shelveslooppri.viewcategory2 ) %]Public[% END %]
-                       [% IF ( shelveslooppri.viewcategory3 ) %]Open[% END %]
                </td>
         <td>
             [% IF ( shelveslooppri.mine ) %]
@@ -387,7 +386,7 @@ function placeHold () {
                 [% END %]
         </table>
             [% ELSE %]
-            <p>No Private Lists.</p>
+            <p>No private lists.</p>
             [% END %]<!-- /shelveslooppriv -->
                </div><!-- /privateshelves -->
 
@@ -408,7 +407,6 @@ function placeHold () {
         <td>[% IF ( shelvesloo.authorsort ) %]Author[% ELSIF ( shelvesloo.yearsort ) %]Year[% ELSE %]Title[% END %]</td>
         <td>[% IF ( shelvesloo.viewcategory1 ) %]Private[% END %]
                        [% IF ( shelvesloo.viewcategory2 ) %]Public[% END %]
-                       [% IF ( shelvesloo.viewcategory3 ) %]Open[% END %]
                </td>
         <td>
             [% IF ( shelvesloo.manageshelf ) %]
@@ -436,7 +434,7 @@ function placeHold () {
             [% END %]
         </table>
         [% ELSE %]
-               [% IF ( showpublicshelves ) %]No Public Lists.[% END %]
+            [% IF ( showpublicshelves ) %]<p>No public lists.</p>[% END %]
         [% END %]<!-- /shelvesloop -->
         </div><!-- /publicshelves -->
                </div>
index e316229..a9d514e 100644 (file)
@@ -11,7 +11,7 @@
 //]]>
 </script>
 </head>
-<body>
+<body id="cat_searchresult" class="cat">
 
     <h2>Z3950 Search Results</h2>
     
index 157aab7..a1dca4f 100644 (file)
             <xsl:when test="$TraceSubjectSubdivisions='1'">
                 <xsl:attribute name="href">/cgi-bin/koha/catalogue/search.pl?q=<xsl:call-template name="subfieldSelect">
                         <xsl:with-param name="codes">abcdfgklmnopqrstvxyz</xsl:with-param>
-                        <xsl:with-param name="delimeter"> and </xsl:with-param>
+                        <xsl:with-param name="delimeter"> AND </xsl:with-param>
                         <xsl:with-param name="prefix">(su<xsl:value-of select="$SubjectModifier"/>:<xsl:value-of select="$TracingQuotesLeft"/></xsl:with-param>
                         <xsl:with-param name="suffix"><xsl:value-of select="$TracingQuotesRight"/>)</xsl:with-param>
                     </xsl:call-template>
index 3011e58..c10e08d 100644 (file)
@@ -2365,3 +2365,153 @@ span.sep {
        padding: 0 .2em;
        text-shadow: 1px 1px 0 #FFF;
 }
+
+/* ## BABELTHEQUE ## */
+/* Uncomment if babeltheque configuration no contains these lines */
+/*
+#BW_etiquettes {
+  clear :left;
+  border: 1px solid #E8E8E8;
+  margin-top: 10px;
+  width: 49%;
+  float: left;
+  visibility: hidden;
+  visibility: visible\9;
+}
+#BW_etiquettes:not(:empty) {
+  visibility: visible;
+}
+
+#BW_etiquettes h2 {
+  clear:left;
+  background-color: #E8E8E8;
+  margin: 5px 10px;
+  padding: 0 5px;
+}
+
+#BW_ulEti {max-width:100%;}
+
+#BW_ulEti ul  {
+  margin:0;
+  padding:0 15px;
+  list-style-type: none;
+}
+
+#BW_ulEti a {
+  text-decoration: none;
+}
+
+#BW_ulEti a.tag_s0  {font-weight: 120;font-size:0.8em;}
+#BW_ulEti a.tag_s1  {font-weight: 150;font-size:0.9em;}
+#BW_ulEti a.tag_s2  {font-weight: 180;font-size:1.0em;}
+#BW_ulEti a.tag_s3  {font-weight: 200;font-size:1.2em;}
+#BW_ulEti a.tag_s4  {font-weight: 220;font-size:1.4em;}
+#BW_ulEti a.tag_s5  {font-weight: 230;font-size:1.5em;}
+#BW_ulEti a.tag_s6  {font-weight: 320;font-size:1.6em;}
+#BW_ulEti a.tag_s7  {font-weight: 350;font-size:1.7em;}
+#BW_ulEti a.tag_s8  {font-weight: 400;font-size:1.8em;}
+#BW_ulEti { padding: 0px; line-height: 2em; text-align: center;}
+#BW_ulEti a { padding: 2px; }
+#BW_ulEti { margin: 0px; }
+
+#BW_ulEti ol {
+  float:left;
+  display: inline;
+  margin: 0 10px;
+}
+
+#BW_suggestions {
+  border: 1px solid #E8E8E8;
+  margin-top: 10px;
+  float: right;
+  width: 49%;
+  visibility: hidden;
+  visibility: visible\9;
+}
+#BW_suggestions:not(:empty) {
+  visibility: visible;
+}
+#BW_suggestions h2 {
+  background-color: #E8E8E8;
+  margin: 5px 10px;
+  padding: 0 5px;
+}
+#BW_suggestions .BW_livres_tag_page {
+  padding: 0 15px;
+}
+#BW_suggestions .BW_livres_tag_page:before {
+  content : '> ';
+}
+#BW_droite .BW_livres_tag:before {
+  content : '> ';
+}
+
+#BW_videos {
+  clear : both;
+  border: 1px solid #E8E8E8;
+  padding-bottom: 140px;
+  margin-top: 10px;
+  max-width: 100%;
+  visibility: hidden;
+  visibility: visible\9;
+}
+
+#BW_videos:not(:empty) {
+  visibility: visible;
+}
+
+#BW_videos h2 {
+  background-color: #E8E8E8;
+  margin: 5px 10px;
+  padding: 0 5px;
+}
+#BW_videos .BW_bloc_vid {
+  clear: both;
+  padding: 0 15px;
+}
+.BW_vignette_vid {
+  border: 1px solid #DFD9CE;
+  float: left;
+  height: 141px;
+  margin: 5px;
+  min-height: 141px;
+  padding: 5px;
+  white-space: nowrap;
+}
+
+#BW_notes {clear :left;}
+#BW_notes h2 {font-size:85%;}
+
+#BW_citations {}
+#BW_citations h2 {font-size:85%;}
+
+#BW_critiques {}
+#BW_critiques h2 {font-size:85%;}
+
+#BW_critiques_pro {}
+#BW_critiques_pro h2 {font-size:85%;}
+
+#BW_citations,#BW_critiques,#BW_critiques_pro {
+  background: -moz-linear-gradient(center top , #3399FF, #3333FF) repeat scroll 0 0 transparent;
+  background: -webkit-gradient(linear, center top, center bottom, from(#3399FF), to(#3333FF));
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3399FF', endColorstr='#3333FF');
+  border: 1px solid #B7B7B7;
+  border-radius: 5px 5px 5px 5px;
+  color: #FFFFCC;
+  display: inline-block;
+  float: left;
+  font-weight: bold;
+  margin: 15px 20px 15px 0;
+  min-width: 150px;
+  padding: 0 15px 8px;
+  position: relative;
+  text-align: center;
+  text-shadow: 1px 1px 1px #777777;
+  white-space: nowrap;
+}
+
+#BW_citations a,#BW_critiques a,#BW_critiques_pro a {
+  color: #FFFFCC;
+}
+
+*/
index ef94cd1..c3a6c95 100644 (file)
                        [% FOREACH pubshelvesloo IN pubshelvesloop %]
                        <li class="yuimenuitem"><a href="/cgi-bin/koha/opac-shelves.pl?viewshelf=[% pubshelvesloo.shelfnumber %]&amp;sortfield=[% pubshelvesloo.sortfield %]">[% pubshelvesloo.shelfname |html %]</a></li>
                        [% END %]
+                       <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl?display=publicshelves">[View All]</a></li>
                        </ul>   
                [% ELSE %]
                        No Public Lists
                [% END %]
-               [% IF ( pubtotal ) %]
-                       <ul class="second-of-type">
-            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl?display=publicshelves">View all [% pubtotal %] public lists</a></li>
-                       </ul>
-               [% END %]
   [% IF ( opacuserlogin ) %]
-    [% IF ( loggedinusername ) %]
-<h4>Your Lists</h4>
+       <h4>Your Lists</h4>
+       [% IF ( loggedinusername ) %]
                [% IF ( barshelves ) %]
                        <ul class="first-of-type">
                        [% FOREACH barshelvesloo IN barshelvesloop %]
                        <li class="yuimenuitem"><a href="/cgi-bin/koha/opac-shelves.pl?viewshelf=[% barshelvesloo.shelfnumber %]&amp;sortfield=[% barshelvesloo.sortfield %]">[% barshelvesloo.shelfname |html %]</a></li>
                        [% END %]
+                       <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves">[View All]</a></li>
                        </ul>   
                [% ELSE %]
-                       No Private Lists
-               [% END %]
-               [% IF ( bartotal ) %]
-                       <ul class="second-of-type">
-            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves">View all [% bartotal %] of your private lists</a></li>
-                       </ul>
+                       <ul class="first-of-type">
+                       <li>No Private Lists</li>
+                       <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves">[New List]</a></li></ul>
                [% END %]
-               <ul class="second-of-type">
-        <li class="yuimenuitem"><a class="yuimenuitemlabel" href="/cgi-bin/koha/opac-shelves.pl">Manage Lists</a></li>
-        </ul>
-    [% ELSE %]<ul class="first-of-type"><li><a href="/cgi-bin/koha/opac-user.pl">Log in to Create Your Own Lists</a></li></ul>
-    [% END %]
+       [% ELSE %]
+               <ul class="first-of-type"><li><a href="/cgi-bin/koha/opac-user.pl">Log in to Create Your Own Lists</a></li></ul>
+       [% END %]
   [% END %]
          </div>
 </div><!-- /listmenu /virtualshelves -->
index 46e195d..66e26c1 100644 (file)
@@ -55,9 +55,5 @@
 
 [% END %]
 
-[% IF ( Babeltheque ) %]
-<script type="text/javascript" src="http://www.babeltheque.com/bw_30.js"></script>
-[% END %]
-
 </body>
 </html>
diff --git a/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.tools.min.js b/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.tools.min.js
new file mode 100644 (file)
index 0000000..d55c776
--- /dev/null
@@ -0,0 +1,11 @@
+/*!
+ * jQuery Tools v1.2.6 - The missing UI library for the Web
+ *
+ * tooltip/tooltip.js
+ *
+ * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
+ *
+ * http://flowplayer.org/tools/
+ *
+ */
+(function(a){a.tools=a.tools||{version:"v1.2.6"},a.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,fadeIE:!1,position:["top","center"],offset:[0,0],relative:!1,cancelDefault:!0,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave",tooltip:"mouseenter,mouseleave"},layout:"<div/>",tipClass:"tooltip"},addEffect:function(a,c,d){b[a]=[c,d]}};var b={toggle:[function(a){var b=this.getConf(),c=this.getTip(),d=b.opacity;d<1&&c.css({opacity:d}),c.show(),a.call()},function(a){this.getTip().hide(),a.call()}],fade:[function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeTo(c.fadeInSpeed,c.opacity,b):(this.getTip().show(),b())},function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeOut(c.fadeOutSpeed,b):(this.getTip().hide(),b())}]};function c(b,c,d){var e=d.relative?b.position().top:b.offset().top,f=d.relative?b.position().left:b.offset().left,g=d.position[0];e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());var h=c.outerHeight()+b.outerHeight();g=="center"&&(e+=h/2),g=="bottom"&&(e+=h),g=d.position[1];var i=c.outerWidth()+b.outerWidth();g=="center"&&(f-=i/2),g=="left"&&(f-=i);return{top:e,left:f}}function d(d,e){var f=this,g=d.add(f),h,i=0,j=0,k=d.attr("title"),l=d.attr("data-tooltip"),m=b[e.effect],n,o=d.is(":input"),p=o&&d.is(":checkbox, :radio, select, :button, :submit"),q=d.attr("type"),r=e.events[q]||e.events[o?p?"widget":"input":"def"];if(!m)throw"Nonexistent effect \""+e.effect+"\"";r=r.split(/,\s*/);if(r.length!=2)throw"Tooltip: bad events configuration for "+q;d.bind(r[0],function(a){clearTimeout(i),e.predelay?j=setTimeout(function(){f.show(a)},e.predelay):f.show(a)}).bind(r[1],function(a){clearTimeout(j),e.delay?i=setTimeout(function(){f.hide(a)},e.delay):f.hide(a)}),k&&e.cancelDefault&&(d.removeAttr("title"),d.data("title",k)),a.extend(f,{show:function(b){if(!h){l?h=a(l):e.tip?h=a(e.tip).eq(0):k?h=a(e.layout).addClass(e.tipClass).appendTo(document.body).hide().append(k):(h=d.next(),h.length||(h=d.parent().next()));if(!h.length)throw"Cannot find tooltip for "+d}if(f.isShown())return f;h.stop(!0,!0);var o=c(d,h,e);e.tip&&h.html(d.data("title")),b=a.Event(),b.type="onBeforeShow",g.trigger(b,[o]);if(b.isDefaultPrevented())return f;o=c(d,h,e),h.css({position:"absolute",top:o.top,left:o.left}),n=!0,m[0].call(f,function(){b.type="onShow",n="full",g.trigger(b)});var p=e.events.tooltip.split(/,\s*/);h.data("__set")||(h.unbind(p[0]).bind(p[0],function(){clearTimeout(i),clearTimeout(j)}),p[1]&&!d.is("input:not(:checkbox, :radio), textarea")&&h.unbind(p[1]).bind(p[1],function(a){a.relatedTarget!=d[0]&&d.trigger(r[1].split(" ")[0])}),e.tip||h.data("__set",!0));return f},hide:function(c){if(!h||!f.isShown())return f;c=a.Event(),c.type="onBeforeHide",g.trigger(c);if(!c.isDefaultPrevented()){n=!1,b[e.effect][1].call(f,function(){c.type="onHide",g.trigger(c)});return f}},isShown:function(a){return a?n=="full":n},getConf:function(){return e},getTip:function(){return h},getTrigger:function(){return d}}),a.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(b,c){a.isFunction(e[c])&&a(f).bind(c,e[c]),f[c]=function(b){b&&a(f).bind(c,b);return f}})}a.fn.tooltip=function(b){var c=this.data("tooltip");if(c)return c;b=a.extend(!0,{},a.tools.tooltip.conf,b),typeof b.position=="string"&&(b.position=b.position.split(/,?\s/)),this.each(function(){c=new d(a(this),b),a(this).data("tooltip",c)});return b.api?c:this}})(jQuery);
index 8b9d84b..9549ea2 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo; Your fines and charges
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
@@ -35,7 +37,7 @@
             <tbody>
                 [% FOREACH ACCOUNT_LINE IN ACCOUNT_LINES %]
                     [% IF ( ACCOUNT_LINE.odd ) %]<tr class="highlight">[% ELSE %]<tr>[% END %]
-                        <td>[% ACCOUNT_LINE.date %]</td>
+                        <td>[% ACCOUNT_LINE.date | $KohaDates %]</td>
                         <td>[% ACCOUNT_LINE.description %]
                         [% IF ( ACCOUNT_LINE.title ) %][% ACCOUNT_LINE.title |html %][% END %]</td>
                         [% IF ( ACCOUNT_LINE.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% ACCOUNT_LINE.amount %]</td>
index f6479f9..e9370c8 100644 (file)
@@ -64,7 +64,9 @@
                <li><label for="category">Category:</label>
                <select name="category" id="category">
                <option value="1">Private</option>
-               <option value="2">Public</option>
+               [% IF (OpacAllowPublicListCreation) %]
+                       <option value="2">Public</option>
+               [% END %]
                </select></li></ol></fieldset>
                [% FOREACH biblio IN biblios %] <input type="hidden" name="biblionumber" value="[% biblio.biblionumber | html%]" />[% END %]
                <fieldset class="action"><input type="submit" value="Save" class="submit" /> <a class="close cancel" href="#">Cancel</a></fieldset>
        [% END %]
 [% ELSE %]
        <p align="center">
-               This is not an open list.
-               Items cannot be added to it.
+       [% IF (errcode==1) %]
+       Could not create new list. Please check if the name is unique.
+       [% ELSE %]
+       Sorry, you cannot add items to this list.
+       [% END %]
        </p>
 [% END %]
 <p align="center">
index aace3e3..53215f7 100644 (file)
@@ -1,6 +1,14 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo; Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield |html %][% END %]
 [% INCLUDE 'doc-head-close.inc' %]
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tools.min.js"></script>
+[% IF ( SocialNetworks ) %]
+    <script type="text/javascript" src="https://apis.google.com/js/plusone.js">
+      {lang: '[% lang %]'}
+    </script>
+[% END %]
 <script type="text/JavaScript" language="JavaScript">
 //<![CDATA[
     [% IF ( busc ) %]
@@ -74,6 +82,7 @@
         });
         [% END %]
 
+        $(".branch-info-tooltip-trigger").tooltip({delay: 100, position: "top right"});
 });
 
 
@@ -212,6 +221,14 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 [% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( TagsEnabled ) %]<style type="text/css">
     #addtagl { display: none; }
 </style>[% END %][% END %][% END %]
+<style type="text/css">
+.branch-info-tooltip {
+  display: none;
+  padding: 20px;
+  background: #fff;
+  border: 1px solid black;
+}
+</style>
 
 </head>
 <body id="opac-detail">
@@ -486,6 +503,15 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
        [% END %]
     [% END %]
 
+    [% IF ( Babeltheque ) %]
+        <input type="hidden" name="BW_id_isbn" id="BW_id_isbn" value="[% normalized_isbn %]"/>
+
+        <div id="BW_notes"></div>
+        <div id="BW_critiques"></div>
+        <div id="BW_critiques_pro"></div>
+        <div id="BW_citations"></div>
+    [% END %]
+
 </div>
 
 <div id="bibliodescriptions" class="toptabs">
@@ -540,7 +566,6 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
     [% IF ( OPACFRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#editions">Editions</a></li>[% END %][% END %]
     
     [% IF ( OPACAmazonEnabled ) %][% IF ( OPACAmazonReviews ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#amazonreviews">Amazon Reviews</a></li>[% END %][% END %]
-    [% IF ( Babeltheque ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#babeltheque">Babelthèque</a></li>[% END %]
 
     [% IF ( serialcollection ) %]
                [% IF ( defaulttab == 'serialcollection' ) %]<li class="ui-tabs-selected">
@@ -592,7 +617,19 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
            </tr></thead>
            <tbody>[% FOREACH ITEM_RESULT IN ITEM_RESULTS %]
            <tr>[% IF ( item_level_itypes ) %]<td>[% UNLESS ( noItemTypeImages ) %][% IF ( ITEM_RESULT.imageurl ) %]<img src="[% ITEM_RESULT.imageurl %]" title="[% ITEM_RESULT.description %]" alt="[% ITEM_RESULT.description %]" />[% END %][% END %] [% ITEM_RESULT.description %]</td>[% END %]
-               <td>[% UNLESS ( singleBranchMode ) %][% IF ( ITEM_RESULT.branchurl ) %]<a href="[% ITEM_RESULT.branchurl %]">[% ITEM_RESULT.branchname %]</a>[% ELSE %][% ITEM_RESULT.branchname %][% END %][% END %] <span class="shelvingloc">[% ITEM_RESULT.location_description %]</span> </td>
+               <td>
+    [% UNLESS ( singleBranchMode ) %]
+        <span class="[% ITEM_RESULT.branch_opac_info ? 'branch-info-tooltip-trigger' : '' %]">
+        [% IF ( ITEM_RESULT.branchurl ) %]
+        <a href="[% ITEM_RESULT.branchurl %]">[% ITEM_RESULT.branchname %]</a>
+        [% ELSE %]
+        [% ITEM_RESULT.branchname %]
+        [% END %]
+        </span>
+        <div class="branch-info-tooltip">[% ITEM_RESULT.branch_opac_info %]</div>
+    [% END %]
+    <span class="shelvingloc">[% ITEM_RESULT.location_description %]</span>
+    </td>
                [% IF ( itemdata_ccode ) %]<td>[% ITEM_RESULT.ccode %]</td>[% END %]
                <td>[% IF ( ITEM_RESULT.itemcallnumber ) %] [% ITEM_RESULT.itemcallnumber %][% IF ( OPACShelfBrowser ) %] (<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% ITEM_RESULT.biblionumber %]&amp;shelfbrowse_itemnumber=[% ITEM_RESULT.itemnumber %]#shelfbrowser">Browse Shelf</a>)[% END %][% END %]</td>
                [% IF ( itemdata_enumchron ) %]<td>[% ITEM_RESULT.enumchron %]</td>[% END %]
@@ -600,7 +637,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
                [% IF ( itemdata_copynumber ) %]<td>[% ITEM_RESULT.copynumber %]</td>[% END %]
                <td>[% INCLUDE 'item-status.inc' item = ITEM_RESULT %]</td>
                [% IF ( itemdata_itemnotes ) %]<td>[% ITEM_RESULT.itemnotes %]</td>[% END %]
-               <td>[% ITEM_RESULT.datedue %]</td>
+               <td>[% ITEM_RESULT.datedue | $KohaDates %]</td>
            </tr>
            [% END %]</tbody>
        </table>
@@ -782,7 +819,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
     [% IF ( subscription.branchname ) %]<h3>At library: [% subscription.branchname %]</h3>[% ELSE %]
     [% IF ( subscription.branchcode ) %]<h3>At library: [% subscription.branchcode %]</h3>[% END %][% END %]
     [% IF ( subscription.subscriptionnotes ) %]<p>[% subscription.subscriptionnotes %] </p>[% END %]
-    <p>Subscription from: [% subscription.histstartdate %]  to:[% IF ( subscription.histenddate ) %] [% subscription.histenddate %] [% ELSE %] now (current)[% END %]</p>
+    <p>Subscription from: [% subscription.histstartdate | $KohaDates %] to:[% IF ( subscription.histenddate ) %] [% subscription.histenddate | $KohaDates %] [% ELSE %] now (current)[% END %]</p>
     [% IF ( subscription.missinglist ) %]<p>Missing issues: [% subscription.missinglist %] </p>[% END %]
     [% IF ( subscription.opacnote ) %]<p>([% subscription.opacnote %])</p>[% END %]
 [% IF ( subscription.latestserials ) %]
@@ -864,7 +901,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
             <h5>
                 Your Comment
             </h5>
-            <small>[% review.datereviewed %]</small>
+            <small>[% review.datereviewed | $KohaDates %]</small>
         <p>
           [% FILTER html_break %]
           [% review.review |html %]
@@ -889,9 +926,9 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
                     [% CASE 'username' %]
                         <h5>Comment by [% review.userid %]</h5>
                     [% END %]
-                <small>[% review.datereviewed %]</small>
+                <small>[% review.datereviewed | $KohaDates %]</small>
             [% ELSIF ( ShowReviewer == "none") %]
-                <h5>Patron comment on [% review.datereviewed %]</h5>
+                <h5>Patron comment on [% review.datereviewed | $KohaDates %]</h5>
             [% END %]
         <p>
           [% FILTER html_break %]
@@ -915,15 +952,6 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 </div>
 [% END %]
 
-[% IF ( Babeltheque ) %]
-<div id="babeltheque">
-  <div id="BW_notes"></div>
-  <div id="BW_critiques"></div>
-  <div id="BW_citations"></div>
-  <div id="BW_etiquettes"></div>
-</div>
-[% END %]
-
 [% IF ( OPACFRBRizeEditions ) %][% IF ( XISBNS ) %]
 <div id="editions">
 
@@ -980,7 +1008,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 
         [% FOREACH AMAZON_CUSTOMER_REVIEW IN AMAZON_CUSTOMER_REVIEWS %]
             <div class="content_set">
-            <div class="clearfix" style="margin: .5em 0;"><h4 style="float: left;">[% AMAZON_CUSTOMER_REVIEW.Summary |html %]</h4>  <span class="starMT" style="float: left;"><span class="starFull" style="float: left; width:[% Rating * 10 %]px"></span></span> </div>  [% AMAZON_CUSTOMER_REVIEW.Date %]
+            <div class="clearfix" style="margin: .5em 0;"><h4 style="float: left;">[% AMAZON_CUSTOMER_REVIEW.Summary |html %]</h4>  <span class="starMT" style="float: left;"><span class="starFull" style="float: left; width:[% Rating * 10 %]px"></span></span> </div>  [% AMAZON_CUSTOMER_REVIEW.Date | $KohaDates %]
             [% IF ( AMAZON_CUSTOMER_REVIEW.Content ) %]
                 <p style="margin-left: .2em;">[% AMAZON_CUSTOMER_REVIEW.Content |html %]</p>
             [% END %]
@@ -1017,6 +1045,16 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 </div>
 [% END %][% END %]
 </div>
+
+[% IF ( Babeltheque ) %]
+    <div>
+        <div id="BW_etiquettes"></div>
+        <div id="BW_suggestions"></div>
+    </div>
+    <div class="clearfix"></div>
+    <div id="BW_videos"></div>
+[% END %]
+
 </div>
 
 
@@ -1045,7 +1083,6 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 [% END %]
 
 [% INCLUDE 'opac-detail-sidebar.inc' %]
-
         [% IF ( NovelistSelectProfile ) %] [% IF ( NovelistSelectView == 'right') %]
          <div id="NovelistSelect">
             <h4>Novelist Select</h4>
@@ -1053,6 +1090,25 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
          </div>
         [% END %] [% END %]
 
+[% IF ( Babeltheque ) %]
+    <div class="babeltheque_adds">
+        <div id="BW_critiques_aj"></div>
+        <div id="BW_citations_aj"></div>
+    </div>
+[% END %]
+
+[% IF ( SocialNetworks ) %]
+    <div class="social_networks">
+        <span>Share</span>
+        <a href="http://www.facebook.com/sharer.php?u=[% current_url |url %]&t=[% title |url %]" title="Share on Facebook"><img alt="Share on Facebook" src="/opac-tmpl/prog/images/socnet/facebook16.png" /></a>
+        <a href="http://twitter.com/share" title="Share on Twitter"><img alt="Share on Twitter" src="/opac-tmpl/prog/images/socnet/twitter16.png" /></a>
+        <a href="http://www.linkedin.com/shareArticle?mini=true&url=[% current_url |url %]&title=[% title |url %]" title="Share on LinkedIn"><img alt="Share on LinkedIn" src="/opac-tmpl/prog/images/socnet/linkedin16.png" /></a>
+        <a href="http://www.delicious.com/save?url=[% current_url |url %]&title=[% title |url %]" title="Share on Delicious"><img alt="Share on Delicious" src="/opac-tmpl/prog/images/socnet/delicious16.gif" /></a>
+        <g:plusone size="small"></g:plusone>
+        <a href="mailto:ADRESSE?subject=TO READ : [% title %]>&body=[% title %]> [% current_url |url %]" title="Share by email"><img alt="Share by email" src="/opac-tmpl/prog/images/socnet/mailto16.png" /></a>
+    </div>
+[% END %]
+
 </div>
 </div>
 </div>
@@ -1076,4 +1132,9 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
 [% IF ( NovelistSelectProfile ) %]
 <script type="text/javascript" src="http://imageserver.ebscohost.com/novelistselect/ns2init.js"></script>
 [% END %]
+
+[% IF ( Babeltheque ) %]
+    <script type="text/javascript" src="[% Babeltheque_url_js %]"></script>
+[% END %]
+
 [% INCLUDE 'opac-bottom.inc' %]
index fc5be4c..5941369 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% LibraryNameTitle or "Koha Online" %] Catalog &rsaquo; Your checkout history
 [% INCLUDE 'doc-head-close.inc' %]
 <style type="text/css">ul.ui-tabs-nav li a, ul.ui-tabs-nav li span.a  { padding:0.6em 1em; }</style>
@@ -82,7 +84,7 @@ You have never borrowed anything from this library.
                     </span></td>
 <td>[% UNLESS ( noItemTypeImages ) %][% IF ( READING_RECOR.imageurl ) %]<img src="[% READING_RECOR.imageurl %]" alt="" />[% END %][% END %] [% READING_RECOR.description %]</td>
 <td>[% READING_RECOR.itemcallnumber %]</td>
-<td>[% IF ( READING_RECOR.returndate ) %][% READING_RECOR.returndate %][% ELSE %]<em>(Checked out)</em>[% END %]</td>
+<td>[% IF ( READING_RECOR.returndate ) %][% READING_RECOR.returndate | $KohaDates %][% ELSE %]<em>(Checked out)</em>[% END %]</td>
 </tr>
 
 [% END %]
index 60f1ae8..eda2015 100644 (file)
@@ -105,10 +105,12 @@ $(document).ready(function(){
     [% END %][% IF ( virtualshelves ) %][% IF ( loggedinusername ) %][% IF ( addbarshelves ) %]
     param1 += "<optgroup label=\""+_("Your Lists:")+"\">";[% FOREACH addbarshelvesloo IN addbarshelvesloop %]
     param1 += "<option id=\"s[% addbarshelvesloo.shelfnumber %]\" value=\"addtolist\">[% addbarshelvesloo.shelfname |html %]<\/option>";[% END %]
-    [% IF ( bartotal ) %]param1 += "<option value=\"morelists\">[ "+_("More lists")+" ]<\/option>";[% END %]
     param1 += "<\/optgroup>";[% END %]
-    [% IF ( addpubshelves ) %]param1 += "<optgroup label=\""+_("Public Lists:")+"\">"[% FOREACH addpubshelvesloo IN addpubshelvesloop %]+"<option id=\"s[% addpubshelvesloo.shelfnumber %]\" value=\"addtolist\">[% addpubshelvesloo.shelfname |html %]<\/option>"[% END %];[% END %]
-    param1 += "<\/optgroup>";
+    [% IF ( addpubshelves ) %]param1 += "<optgroup label=\""+_("Public Lists:")+"\">"[% FOREACH addpubshelvesloo IN addpubshelvesloop %]+"<option id=\"s[% addpubshelvesloo.shelfnumber %]\" value=\"addtolist\">[% addpubshelvesloo.shelfname |html %]<\/option>"[% END %];
+    param1 += "<\/optgroup>";[% END %]
+    [% IF ( addbarshelvesloop.size>9 || addpubshelvesloop.size>9 ) %]
+        param1 += "<option value=\"morelists\">[ "+_("More Lists")+" ]<\/option>";
+    [% END %]
     param1 += "<option value=\"newlist\">[ "+_("New List")+" ]<\/option>";
     [% END %]
     [% END %]
@@ -390,6 +392,9 @@ $(document).ready(function(){
                 [% IF ( SEARCH_RESULT.imageurl ) %]
                 <img src="[% SEARCH_RESULT.imageurl %]" title="[% SEARCH_RESULT.description %]" alt="[% SEARCH_RESULT.description %]" />
                 [% END %]
+                [% IF ( SEARCH_RESULT.score_avg ) %]
+                    <img src="[% themelang %]/../images/bonus.png" title="bonus" style="max-height: 35px;"/>
+                [% END %]
                 </td>
                 [% END %]
                 [% END %]
@@ -478,6 +483,23 @@ $(document).ready(function(){
                 </span>
 
                 [% END %]
+                [% IF ( SEARCH_RESULT.score_avg ) %]
+                    <span class="result_summary">
+                        <img src="[% themelang %]/../images/Star[% SEARCH_RESULT.score_int %].gif" title="" style="max-height: 15px;"/> <span style="font-size: 85%;">[% SEARCH_RESULT.score_avg %] / 5 (on [% SEARCH_RESULT.num_scores %] rates)</span>
+                        [% IF ( SEARCH_RESULT.num_critics ) %]
+                            <span class="social_data">[% SEARCH_RESULT.num_critics %] Internet user critics</span>
+                        [% END %]
+                        [% IF ( SEARCH_RESULT.num_critics_pro ) %]
+                            <span class="social_data">[% SEARCH_RESULT.num_critics_pro %] Professional critics</span>
+                        [% END %]
+                        [% IF ( SEARCH_RESULT.num_videos ) %]
+                            <span class="social_data">[% SEARCH_RESULT.num_videos %] Video extracts</span>
+                        [% END %]
+                        [% IF ( SEARCH_RESULT.num_quotations ) %]
+                            <span class="social_data">[% SEARCH_RESULT.num_quotations %] Quotations</span>
+                        [% END %]
+                    </span>
+                [% END %]
                 [% IF ( LibraryThingForLibrariesID ) %]<div class="ltfl_reviews"></div>[% END %]
                 [% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %]
                                 [% IF ( TagsShowOnList ) %]
index d783852..a1d865d 100644 (file)
@@ -131,7 +131,7 @@ $(function() {
             });
         [% END %]
         [% END %][% END %][% END %]
-  [% IF ( loggedinusername && manageshelf ) %]
+  [% IF ( loggedinusername && allowremovingitems ) %]
   $("#myform").submit(function(){
     var checkedBoxes = $(".checkboxed input:checkbox:checked");
     if ($(checkedBoxes).size()) {
@@ -210,6 +210,15 @@ $(function() {
                     [% IF ( paramsloo.unrecognized ) %]
                       <div class="dialog message">ERROR: List number [% paramsloo.unrecognized %] unrecognized.</div>
                     [% END %]
+                    [% IF ( paramsloo.modifyfailure) %]
+                      <div class="dialog message">ERROR: Shelf could not be renamed to [% paramsloo.modifyfailure %]. This name may not be unique for this type of list. Please check.</div>
+                    [% END %]
+                    [% IF ( paramsloo.nothingdeleted) %]
+                      <div class="dialog message">Warning: You could not delete any selected items from this shelf.</div>
+                    [% END %]
+                    [% IF ( paramsloo.somedeleted) %]
+                      <div class="dialog message">Warning: You could not delete all selected items from this shelf.</div>
+                    [% END %]
                   </div>
                 </div>
               [% END %]<!-- /paramsloop -->
@@ -235,7 +244,7 @@ $(function() {
                       <form method="post" action="opac-shelves.pl">
                         <input type="hidden" value="1" name="shelves"/>
                          <input type="hidden" value="1" name="DEL-[% shelfnumber %]"/>
-                         <input type="submit" class="deleteshelf" value="Delete List" onclick="return confirmDelete(MSG_CONFIRM_DELETE_LIST);"/>
+                         [% IF ( showprivateshelves ) %]<input type="hidden" name="display" value="privateshelves"/>[% END %]<input type="submit" class="deleteshelf" value="Delete List" onclick="return confirmDelete(MSG_CONFIRM_DELETE_LIST);"/>
                       </form> [% END %]
 
 
@@ -257,7 +266,7 @@ $(function() {
                                           </span>
                                         [% END %]
                                       [% END %]
-                    [% IF ( loggedinusername && manageshelf ) %]<span id="removeitems"></span>[% END %]</span>
+                    [% IF ( loggedinusername && allowremovingitems ) %]<span id="removeitems"></span>[% END %]</span>
                   </div>
                   <form action="/cgi-bin/koha/opac-shelves.pl" method="post" id="myform" name="myform" class="checkboxed">
                 [% IF ( manageshelf ) %]
@@ -394,21 +403,20 @@ $(function() {
             [% END %]<!-- /viewshelf -->
 
 
-            [% IF ( manageshelf ) %]
-              <!-- Editing shelf -->
-              [% IF ( itemsloop ) %]
+            [% IF ( itemsloop && allowremovingitems ) %]
+                <form method="post" action="opac-shelves.pl">
                 <input type="hidden" name="shelfnumber" value="[% shelfnumber %]" />
                 <input type="hidden" name="modifyshelfcontents" value="1" />
-                <input type="hidden" name="viewshelf" value="[% shelfnumber %]" /><input type="submit" value="Remove Selected Items" class="icon delete" />
-              [% ELSE %]
+                <input type="hidden" name="viewshelf" value="[% shelfnumber %]" /><input type="submit" value="Remove Selected Items" class="icon delete"/>
+                </form>
+            [% ELSIF ( !itemsloop && manageshelf ) %]
                 <form method="post" action="opac-shelves.pl">
                   <input type="hidden" name="DEL-[% shelfnumber %]" value="1" />
                   <input type="hidden" name="shelves" value="1" />
                  <input type="hidden" name="shelfoff" value="[% shelfoff %]" />
                   <input type="submit" class="icon delete" value="Delete this List" onclick="return confirmDelete(MSG_CONFIRM_DELETE_LIST)" />
-              [% END %]
-            [% END %]
                 </form>
+            [% END %]
 
             
             [% IF ( edit ) %]
@@ -429,11 +437,13 @@ $(function() {
                         </select>
                       </li>
                       <li>
+                       [% IF (OpacAllowPublicListCreation) %]
                         <label for="category">Category:</label>
                         <select name="category" id="category">
                           [% IF ( category1 ) %]<option value="1" selected="selected">Private</option>[% ELSE %]<option value="1">Private</option>[% END %]
                           [% IF ( category2 ) %]<option value="2" selected="selected">Public</option>[% ELSE %]<option value="2">Public</option>[% END %]
                         </select>
+                       [% END %]
                       </li>
                     </ol>
                   </fieldset>
@@ -489,7 +499,6 @@ $(function() {
                               <td>
                                 [% IF ( shelveslooppri.viewcategory1 ) %]Private[% END %]
                                 [% IF ( shelveslooppri.viewcategory2 ) %]Public[% END %]
-                                [% IF ( shelveslooppri.viewcategory3 ) %]Open[% END %]
                               </td>
                               <td>
                               [% IF ( shelveslooppri.mine ) %]
@@ -556,7 +565,6 @@ $(function() {
                           <td>
                             [% IF ( shelvesloo.viewcategory1 ) %]Private[% END %]
                             [% IF ( shelvesloo.viewcategory2 ) %]Public[% END %]
-                            [% IF ( shelvesloo.viewcategory3 ) %]Open[% END %]
                              </td>
                           <td>
                                                        [% IF ( shelvesloo.mine ) %]
@@ -620,7 +628,9 @@ $(function() {
                         <label for="category">Category:</label>
                         <select name="category" id="category">
                           <option value="1">Private</option>
+                         [% IF (OpacAllowPublicListCreation) %]
                           <option value="2">Public</option>
+                         [% END %]
                         </select>
                       </li>
                     </ol>
index 42e0fc0..7e9cc24 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 <?xml version="1.0" encoding="utf-8"?>
 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
 <channel>
@@ -26,7 +28,7 @@
                         [% IF ( review.notes ) %], [% review.notes |html %][% END %]
                         [% IF ( review.size ) %] [% review.size |html %]. [% END %]
                         [% IF ( review.isbn ) %] [% review.isbn |html %][% END %] </p>
-<p>[% IF ( review.borrowernumber && ShowReviewer ) %][% review.firstname %] [% review.surname %] commented[% ELSE %]Comment[% END %] on [% review.datereviewed %]: [% review.review |html %]</p>
+<p>[% IF ( review.borrowernumber && ShowReviewer ) %][% review.firstname %] [% review.surname %] commented[% ELSE %]Comment[% END %] on [% review.datereviewed | $KohaDates %]: [% review.review |html %]</p>
                                                ]]></description>
        <guid>[% OPACBaseURL %]/cgi-bin/koha/opac-detail.pl?biblionumber=[% review.biblionumber %]&amp;reviewid=[% review.reviewid %]</guid>
        <pubDate>[% review.timestamp %]</pubDate>
index d096ea6..c132d15 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo; Recent Comments
 [% INCLUDE 'doc-head-close.inc' %]
 <link rel="alternate" type="application/rss+xml" title="[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog Recent Comments" href="[% OPACBaseURL %]/cgi-bin/koha/opac-showreviews.pl?format=rss" />
@@ -53,7 +55,7 @@ $(document).ready(function(){
             [% FILTER html_break %]
             [% review.review |html %]
             [% END %]
-            <span style="font-size:87%;font-color:#CCC;">Added [% review.datereviewed %] [% IF ( review.your_comment ) %] by <strong>you</strong>[% ELSE %]
+            <span style="font-size:87%;font-color:#CCC;">Added [% review.datereviewed | $KohaDates %] [% IF ( review.your_comment ) %] by <strong>you</strong>[% ELSE %]
             [% IF ( review.borrowernumber && ShowReviewer != "none" ) %] by
                 [% SWITCH ShowReviewer %]
                 [% CASE 'full' %]
index e93e00a..c1ec044 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo; Tags
 [% INCLUDE 'doc-head-close.inc' %]
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
                        </td>
                        <td><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% MY_TAG.biblionumber %]">
                                [% MY_TAG.bib_summary |html %]</a></td>
-                       <td>[% MY_TAG.date_created_display %]</td>
+                       <td>[% MY_TAG.date_created | $KohaDates %]</td>
                        <td><input type="submit" name="del[% MY_TAG.tag_id %]" value="Delete" /></td>
                </tr>
        [% END %]</tbody>
index 8fc13d9..19b7389 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %]
 [% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo; Your library home
 [% INCLUDE 'doc-head-close.inc' %]
@@ -62,7 +64,7 @@ $.tablesorter.addParser({
                               [% FOREACH bor_messages_loo IN bor_messages_loop %]
                                        <li>
                                                <strong>[% bor_messages_loo.message %]</strong><br>
-                                               &nbsp;&nbsp;&nbsp;<i>Written on [% bor_messages_loo.message_date_formatted %] by [% bor_messages_loo.branchname %]</i>
+                            &nbsp;&nbsp;&nbsp;<i>Written on [% bor_messages_loo.message_date | $KohaDates %] by [% bor_messages_loo.branchname %]</i>
                                        </li>
                                [% END %]
 
@@ -89,7 +91,7 @@ $.tablesorter.addParser({
                <div class="dialog alert">
         <ul>
             [% IF ( userdebarred ) %]
-                <li><strong>Please note:</strong> Your account has been frozen[% IF ( BORROWER_INF.userdebarreddate ) %] until [% BORROWER_INF.userdebarreddate %][% END %][% IF ( BORROWER_INF.debarredcomment ) %] with the comment "[% BORROWER_INF.debarredcomment %]"[% END %]. Usually the reason for freezing an account is old overdues or damage fees. If <a href="/cgi-bin/koha/opac-user.pl">your account page</a> shows your account to be clear, please contact the library.</li>
+                <li><strong>Please note:</strong> Your account has been frozen[% IF ( BORROWER_INF.userdebarreddate ) %] until [% BORROWER_INF.userdebarreddate | $KohaDates %][% END %][% IF ( BORROWER_INF.debarredcomment ) %] with the comment "[% BORROWER_INF.debarredcomment %]"[% END %]. Usually the reason for freezing an account is old overdues or damage fees. If <a href="/cgi-bin/koha/opac-user.pl">your account page</a> shows your account to be clear, please contact the library.</li>
             [% END %]
             [% IF ( BORROWER_INF.gonenoaddress ) %]
                 <li><strong>Please note:</strong> According to our records, we don't have up-to-date [% UNLESS ( BORROWER_INF.OPACPatronDetails ) %]<a href="/cgi-bin/koha/opac-userupdate.pl">contact information</a>[% ELSE %]contact information[% END %] on file.  Please contact the library[% IF ( BORROWER_INF.OPACPatronDetails ) %] or use the <a href="/cgi-bin/koha/opac-userupdate.pl">online update form</a> to submit current information (<em>Please note:</em> there may be a delay in restoring your account if you submit online)[% END %].</li>
@@ -169,7 +171,7 @@ $.tablesorter.addParser({
                         </a><span class="item-details">
                             [% WAITIN.author %]
                         </span></td>
-                    <td>[% WAITIN.reservedate %]</td>
+                    <td>[% WAITIN.reservedate | $KohaDates %]</td>
                     <td>[% IF ( WAITIN.atdestination ) %]<strong>Waiting</strong> at [% WAITIN.branch %]
                         [% ELSE %]
                         In transit from [% WAITIN.holdingbranch %] to [% WAITIN.branch %]
@@ -234,9 +236,9 @@ $.tablesorter.addParser({
                         [% ISSUE.author %]
                     </span></td>
                 [% IF ( ISSUE.overdue ) %]
-                    <td class="overdue">[% ISSUE.date_due %]</td>
+                    <td class="overdue">[% ISSUE.date_due | $KohaDates %]</td>
                 [% ELSE %]
-                    <td>[% ISSUE.date_due %]</td>
+                    <td>[% ISSUE.date_due | $KohaDates %]</td>
                 [% END %]
                 [% UNLESS ( item_level_itypes ) %]<td>[% IF ( ISSUE.imageurl ) %]<img src="[% ISSUE.imageurl %]" title="[% ISSUE.description %]" alt="[% ISSUE.description %]" />[% END %] [% ISSUE.description %]</td>[% END %]
                 [% IF ( show_barcode ) %]<td>[% ISSUE.barcode %]</td>[% END %]
@@ -320,7 +322,7 @@ $.tablesorter.addParser({
 [% UNLESS ( item_level_itypes ) %]<td>[% IF ( OVERDUE.imageurl ) %]<img src="[% OVERDUE.imageurl %]" title="[% OVERDUE.description %]" alt="[% OVERDUE.description %]" />[% END %] [% OVERDUE.description %]</td>[% END %]
 [% IF ( show_barcode ) %]<td>[% OVERDUE.barcode %]</td>[% END %]
 <td>[% OVERDUE.itemcallnumber %]</td>
-<td>[% OVERDUE.date_due %]</td>
+<td>[% OVERDUE.date_due | $KohaDates %]</td>
                 [% IF ( OpacRenewalAllowed ) %]
 <td>
 [% IF ( OVERDUE.debarred ) %]Account Frozen
@@ -373,8 +375,8 @@ $.tablesorter.addParser({
                 <td><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% RESERVE.biblionumber %]">[% RESERVE.reserves_title %]</a>
                     [% RESERVE.author %]
                 </td>
-                <td>[% RESERVE.reservedate %]</td>
-               <td>[% IF ( RESERVE.expirationdate ) %][% RESERVE.expirationdate %][% ELSE %]Never Expires[% END %]</td>
+                <td>[% RESERVE.reservedate | $KohaDates %]</td>
+               <td>[% IF ( RESERVE.expirationdate ) %][% RESERVE.expirationdate | $KohaDates %][% ELSE %]Never Expires[% END %]</td>
                 <td>[% RESERVE.branch %]</td>
                                [% IF ( showpriority ) %]
                                <td>[% RESERVE.priority %] </td>
@@ -383,7 +385,7 @@ $.tablesorter.addParser({
                     [% IF ( RESERVE.wait ) %]
                         [% IF ( RESERVE.atdestination ) %]
                             [% IF ( RESERVE.found ) %]
-                            Item waiting at <b> [% RESERVE.wbrname %]</b>[% IF ( RESERVE.formattedwaitingdate ) %] since [% RESERVE.formattedwaitingdate %][% END %]
+                            Item waiting at <b> [% RESERVE.wbrname %]</b>[% IF ( RESERVE.waitingdate ) %] since [% RESERVE.waitingdate | $KohaDates %][% END %]
                             <input type="hidden" name="pickup" value="[% RESERVE.wbrcd %]" />
                             [% ELSE %]
                             Item waiting to be pulled from <b> [% RESERVE.wbrname %]</b>
@@ -394,7 +396,7 @@ $.tablesorter.addParser({
                     [% ELSE %]
                             [% IF ( RESERVE.intransit ) %]
                                 Item in transit from <b> [% RESERVE.frombranch %]</b> since 
-                                [% RESERVE.datesent %]
+                                [% RESERVE.datesent | $KohaDates %]
                             [% ELSE %]
                                 Pending
                             [% END %]
index 58badfd..3a7fb9d 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %][% ELSE %]Koha Online[% END %] Catalog &rsaquo;  Your personal details
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
@@ -68,7 +70,7 @@
 </fieldset>
 <fieldset class="brief">
 <ol>
-<li><label for="dob">Date of Birth: </label> <input id="dob" type="text" size="10" value="[% BORROWER_INF.dateofbirth %]" name="dateofbirth" /></li>
+<li><label for="dob">Date of Birth: </label> <input id="dob" type="text" size="10" value="[% BORROWER_INF.dateofbirth | $KohaDates %]" name="dateofbirth" /></li>
 <li><label for="sex">Gender: </label> <select name="sex" id="sex"><option></option>
 [% IF ( BORROWER_INF.sex == 'F' ) %]<option value="F" selected="selected">Female</option>[% ELSE %]<option value="F">Female</option>[% END %]
 [% IF ( BORROWER_INF.sex == 'M' ) %]<option value="M" selected="selected">Male</option>[% ELSE %]<option value="M">Male</option>[% END %]
@@ -81,8 +83,8 @@
     <li><label for="branchname">Home library:</label><input type="text" id="branchname" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.branchname %]" /></li>
        <li><label for="borrowernumber">Patron Number:</label><input type="text" id="borrowernumber" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.borrowernumber %]" /></li>
        <li><label for="categorycode">Patron Category:</label><input type="text" id="categorycode" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.description %] ([% BORROWER_INF.categorycode %])" /></li>
-       <li><label for="dateenrolled">Joined: </label><input type="text" id="dateenrolled" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.dateenrolled %]" /></li>
-       <li><label for="dateexpiry">Expires: </label><input type="text" id="dateexpiry" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.dateexpiry %]" /></li>
+       <li><label for="dateenrolled">Joined: </label><input type="text" id="dateenrolled" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.dateenrolled | $KohaDates %]" /></li>
+       <li><label for="dateexpiry">Expires: </label><input type="text" id="dateexpiry" disabled="disabled" readonly="readonly" value="[% BORROWER_INF.dateexpiry | $KohaDates %]" /></li>
    [% IF ( BORROWER_INF.ExtendedPatronAttributes ) %]
     [% FOREACH patron_attribute IN BORROWER_INF.patron_attributes %]
         <li><label>[% patron_attribute.description %]</label>
 <fieldset class="rows">
 <legend>Personal Information</legend>
 <ol>
-<li><span class="label">Date of Birth:</span> [% BORROWER_INF.dateofbirth %]</li>
+<li><span class="label">Date of Birth:</span> [% BORROWER_INF.dateofbirth | $KohaDates %]</li>
 <li><span class="label">Gender:</span>
 [% IF ( sex == 'F' ) %]Female[% END %]
 [% IF ( sex == 'M' ) %]Male[% END %]
 <li><span class="label">Home library:</span> [% BORROWER_INF.branchname %]</li>
 <li><span class="label">Patron Number:</span> [% BORROWER_INF.borrowernumber %]</li>
 <li><span class="label">Patron Category:</span> [% BORROWER_INF.description %] ([% BORROWER_INF.categorycode %])</li>
-<li><span class="label">Joined:</span> [% BORROWER_INF.dateenrolled %]</li>
-<li><span class="label">Expires:</span> [% BORROWER_INF.dateexpiry %]</li>
+<li><span class="label">Joined:</span> [% BORROWER_INF.dateenrolled | $KohaDates %]</li>
+<li><span class="label">Expires:</span> [% BORROWER_INF.dateexpiry | $KohaDates %]</li>
    [% IF ( BORROWER_INF.ExtendedPatronAttributes ) %]
     [% FOREACH patron_attribute IN BORROWER_INF.patron_attributes %]
         <li><span class="label">[% patron_attribute.description %]</span>
index f7d2c4f..9f8f634 100644 (file)
@@ -1,3 +1,5 @@
+[% USE KohaDates %]
+
 [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha [% END %] &rsaquo; Self Checkout </title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="Koha [% Version %]" /> <!-- leave this for stats -->
@@ -210,7 +212,7 @@ Sorry, This Self-Checkout Station has lost authentication.  Please contact the a
        <td>[% UNLESS ( ISSUE.noitemlinks ) %]<a href="/cgi-bin/koha/opac-detail.pl?bib=[% ISSUE.biblionumber %]">[% ISSUE.title |html %]</a>[% ELSE %]<strong>[% ISSUE.title |html %]</strong>[% END %]<span class="item-details">
        [% ISSUE.author %]</span> ([% ISSUE.barcode %])</td>
        <td>[% ISSUE.itemcallnumber %]</td>
-       [% IF ( ISSUE.overdue ) %]<td class="overdue">[% ISSUE.date_due_display %]</td>[% ELSE %]<td>[% ISSUE.date_due_display %]</td>[% END %]
+       [% IF ( ISSUE.overdue ) %]<td class="overdue">[% ISSUE.date_due | $KohaDates %]</td>[% ELSE %]<td>[% ISSUE.date_due | $KohaDates %]</td>[% END %]
        <td>
     <form action="/cgi-bin/koha/sco/sco-main.pl" method="post">
     <input type="hidden" name="op" value="checkout" />
index 80fb6ac..189bffe 100644 (file)
             <xsl:when test="$TraceSubjectSubdivisions='1'">
                 <xsl:attribute name="href">/cgi-bin/koha/opac-search.pl?q=<xsl:call-template name="subfieldSelect">
                         <xsl:with-param name="codes">abcdfgklmnopqrstvxyz</xsl:with-param>
-                        <xsl:with-param name="delimeter"> and </xsl:with-param>
+                        <xsl:with-param name="delimeter"> AND </xsl:with-param>
                         <xsl:with-param name="prefix">(su<xsl:value-of select="$SubjectModifier"/>:<xsl:value-of select="$TracingQuotesLeft"/></xsl:with-param>
                         <xsl:with-param name="suffix"><xsl:value-of select="$TracingQuotesRight"/>)</xsl:with-param>
                     </xsl:call-template>
index 19cee91..2538106 100644 (file)
         </h5>
         </xsl:when>
         </xsl:choose>
-        <div id="views">
-        <span class="view"><span id="Normalview">Normal visning</span> </span>
-        <span class="view"><a id="MARCviewPop" href="/cgi-bin/koha/opac-showmarc.pl?id={marc:datafield[@tag=999]/marc:subfield[@code='c']}" title="MARC" rel="gb_page_center[600,500]">MARC-visning</a></span>
-        <span class="view"><a id="MARCview" href="/cgi-bin/koha/opac-MARCdetail.pl?biblionumber={marc:datafield[@tag=999]/marc:subfield[@code='c']}" title="MARC">Utvidet MARC-visning</a></span>
-        <span class="view"><a id="ISBDview" href="/cgi-bin/koha/opac-ISBDdetail.pl?biblionumber={marc:datafield[@tag=999]/marc:subfield[@code='c']}">Kortvisning (ISBD)</a></span>
-        </div> 
 
     <xsl:if test="$DisplayOPACiconsXSLT!='0'">
         <xsl:if test="$materialTypeCode!=''">
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star0.gif b/koha-tmpl/opac-tmpl/prog/images/Star0.gif
new file mode 100644 (file)
index 0000000..44ffdf4
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star0.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star1.gif b/koha-tmpl/opac-tmpl/prog/images/Star1.gif
new file mode 100644 (file)
index 0000000..2038638
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star1.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star2.gif b/koha-tmpl/opac-tmpl/prog/images/Star2.gif
new file mode 100644 (file)
index 0000000..2b60940
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star2.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star3.gif b/koha-tmpl/opac-tmpl/prog/images/Star3.gif
new file mode 100644 (file)
index 0000000..3ff6739
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star3.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star4.gif b/koha-tmpl/opac-tmpl/prog/images/Star4.gif
new file mode 100644 (file)
index 0000000..473cb32
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star4.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/Star5.gif b/koha-tmpl/opac-tmpl/prog/images/Star5.gif
new file mode 100644 (file)
index 0000000..0a61173
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/Star5.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/bonus.png b/koha-tmpl/opac-tmpl/prog/images/bonus.png
new file mode 100644 (file)
index 0000000..663a31d
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/bonus.png differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/socnet/delicious16.gif b/koha-tmpl/opac-tmpl/prog/images/socnet/delicious16.gif
new file mode 100644 (file)
index 0000000..11682e8
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/socnet/delicious16.gif differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/socnet/facebook16.png b/koha-tmpl/opac-tmpl/prog/images/socnet/facebook16.png
new file mode 100644 (file)
index 0000000..1176590
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/socnet/facebook16.png differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/socnet/linkedin16.png b/koha-tmpl/opac-tmpl/prog/images/socnet/linkedin16.png
new file mode 100644 (file)
index 0000000..2a195c2
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/socnet/linkedin16.png differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/socnet/mailto16.png b/koha-tmpl/opac-tmpl/prog/images/socnet/mailto16.png
new file mode 100644 (file)
index 0000000..d8e4a5a
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/socnet/mailto16.png differ
diff --git a/koha-tmpl/opac-tmpl/prog/images/socnet/twitter16.png b/koha-tmpl/opac-tmpl/prog/images/socnet/twitter16.png
new file mode 100644 (file)
index 0000000..ccb1b61
Binary files /dev/null and b/koha-tmpl/opac-tmpl/prog/images/socnet/twitter16.png differ
index 12e3257..66faab4 100644 (file)
@@ -16,7 +16,7 @@ the kohaversion is divided in 4 parts :
 use strict;
 
 sub kohaversion {
-    our $VERSION = '3.07.00.031';
+    our $VERSION = '3.07.00.041';
     # version needs to be set this way
     # so that it can be picked up by Makefile.PL
     # during install
index 5a45d5c..db3d32c 100755 (executable)
@@ -44,7 +44,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
 my $op = $cgi->param('op') || $ARGV[0] || '';
 my $layout_id = $cgi->param('layout_id') || $cgi->param('element_id') || $ARGV[1] || '';
 my $layout_choice = $cgi->param('layout_choice') || '';
-my $layout = '';
+our $layout = '';
 
 sub _set_selected {
     my ($type_list, $object, $data_type) = @_;
index 924245a..a813cd6 100755 (executable)
@@ -30,6 +30,7 @@ use C4::Output;
 use C4::Auth;
 use C4::Members;
 use C4::Branch; # GetBranches
+use C4::VirtualShelves (); #no import
 
 my $input = new CGI;
 
@@ -117,6 +118,7 @@ output_html_with_http_headers $input, $cookie, $template->output;
 
 } else {
     MoveMemberToDeleted($member);
+    C4::VirtualShelves::HandleDelBorrower($member);
     DelMember($member);
     print $input->redirect("/cgi-bin/koha/members/members-home.pl");
 }
index d53f7f1..2d8cace 100755 (executable)
@@ -25,6 +25,7 @@ use warnings;
 # external modules
 use CGI;
 # use Digest::MD5 qw(md5_base64);
+use List::MoreUtils qw/uniq/;
 
 # internal modules
 use C4::Auth;
@@ -423,6 +424,9 @@ if ($op eq 'add'){
 if ($op eq "modify")  {
     $template->param( updtype => 'M',modify => 1 );
     $template->param( step_1=>1, step_2=>1, step_3=>1, step_4=>1, step_5 => 1, step_6 => 1) unless $step;
+    if ( $step == 4 ) {
+        $template->param( categorycode => $borrower_data->{'categorycode'} );
+    }
 }
 if ( $op eq "duplicate" ) {
     $template->param( updtype => 'I' );
@@ -764,6 +768,8 @@ sub patron_attributes_form {
         return;
     }
     my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber);
+    my @classes = uniq( map {$_->{class}} @$attributes );
+    @classes = sort @classes;
 
     # map patron's attributes into a more convenient structure
     my %attr_hash = ();
@@ -773,14 +779,17 @@ sub patron_attributes_form {
 
     my @attribute_loop = ();
     my $i = 0;
+    my %items_by_class;
     foreach my $type_code (map { $_->{code} } @types) {
         my $attr_type = C4::Members::AttributeTypes->fetch($type_code);
         my $entry = {
+            class             => $attr_type->class(),
             code              => $attr_type->code(),
             description       => $attr_type->description(),
             repeatable        => $attr_type->repeatable(),
             password_allowed  => $attr_type->password_allowed(),
             category          => $attr_type->authorised_value_category(),
+            category_code     => $attr_type->category_code(),
             password          => '',
         };
         if (exists $attr_hash{$attr_type->code()}) {
@@ -795,8 +804,7 @@ sub patron_attributes_form {
                 }
                 $i++;
                 $newentry->{form_id} = "patron_attr_$i";
-                #use Data::Dumper; die Dumper($entry) if  $entry->{use_dropdown};
-                push @attribute_loop, $newentry;
+                push @{$items_by_class{$attr_type->class()}}, $newentry;
             }
         } else {
             $i++;
@@ -806,9 +814,18 @@ sub patron_attributes_form {
                 $newentry->{auth_val_loop} = GetAuthorisedValues($attr_type->authorised_value_category());
             }
             $newentry->{form_id} = "patron_attr_$i";
-            push @attribute_loop, $newentry;
+            push @{$items_by_class{$attr_type->class()}}, $newentry;
+        }
+    }
+    while ( my ($class, @items) = each %items_by_class ) {
+        my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class;
+        push @attribute_loop, {
+            class => $class,
+            items => @items,
+            lib   => $lib,
         }
     }
+
     $template->param(patron_attributes => \@attribute_loop);
 
 }
index 5a988f9..a83bce9 100755 (executable)
@@ -56,6 +56,8 @@ use C4::Members::Attributes qw(GetBorrowerAttributes);
 
 #use Smart::Comments;
 #use Data::Dumper;
+use DateTime;
+use Koha::DateUtils;
 
 use vars qw($debug);
 
@@ -65,7 +67,7 @@ BEGIN {
 
 my $dbh = C4::Context->dbh;
 
-my $input = new CGI;
+my $input = CGI->new;
 $debug or $debug = $input->param('debug') || 0;
 my $print = $input->param('print');
 my $override_limit = $input->param("override_limit") || 0;
@@ -247,86 +249,15 @@ my $relissue    = [];
 if ( @borrowernumbers ) {
     $relissue    = GetPendingIssues(@borrowernumbers);
 }
-my $issuecount     = @{$issue};
-my $relissuecount  = @{$relissue};
 my $roaddetails = &GetRoadTypeDetails( $data->{'streettype'} );
-my $today       = POSIX::strftime("%Y-%m-%d", localtime);      # iso format
-my @issuedata;
+my $today       = DateTime->now( time_zone => C4::Context->tz);
+$today->truncate(to => 'days');
 my @borrowers_with_issues;
 my $overdues_exist = 0;
 my $totalprice = 0;
 
-my @issuedata = build_issue_data($issue, $issuecount);
-my @relissuedata = build_issue_data($relissue, $relissuecount);
-
-sub build_issue_data {
-    my $issue = shift;
-    my $issuecount = shift;
-
-    my $localissue;
-
-    for ( my $i = 0 ; $i < $issuecount ; $i++ ) {
-        my $datedue = $issue->[$i]{'date_due'};
-        my $issuedate = $issue->[$i]{'issuedate'};
-        $issue->[$i]{'date_due'}  = C4::Dates->new($issue->[$i]{'date_due'}, 'iso')->output('syspref');
-        $issue->[$i]{'issuedate'} = C4::Dates->new($issue->[$i]{'issuedate'},'iso')->output('syspref');
-        my $biblionumber = $issue->[$i]{'biblionumber'};
-        $issue->[$i]{'issuingbranchname'} = GetBranchName($issue->[$i]{'branchcode'});
-        my %row = %{ $issue->[$i] };
-        $totalprice += $issue->[$i]{'replacementprice'};
-        $row{'replacementprice'} = $issue->[$i]{'replacementprice'};
-        # item lost, damaged loops
-        if ($row{'itemlost'}) {
-            my $fw = GetFrameworkCode($issue->[$i]{'biblionumber'});
-            my $category = GetAuthValCode('items.itemlost',$fw);
-            my $lostdbh = C4::Context->dbh;
-            my $sth = $lostdbh->prepare("select lib from authorised_values where category=? and authorised_value =? ");
-            $sth->execute($category, $row{'itemlost'});
-            my $loststat = $sth->fetchrow;
-            if ($loststat) {
-               $row{'itemlost'} = $loststat;
-            }
-        }
-        if ($row{'damaged'}) {
-            my $fw = GetFrameworkCode($issue->[$i]{'biblionumber'});
-            my $category = GetAuthValCode('items.damaged',$fw);
-            my $damageddbh = C4::Context->dbh;
-            my $sth = $damageddbh->prepare("select lib from authorised_values where category=? and authorised_value =? ");
-            $sth->execute($category, $row{'damaged'});
-            my $damagedstat = $sth->fetchrow;
-            if ($damagedstat) {
-               $row{'itemdamaged'} = $damagedstat;
-            }
-        }
-        # end lost, damaged
-        if ( $datedue lt $today ) {
-            $overdues_exist = 1;
-            $row{'red'} = 1;
-        }
-         if ( $issuedate eq $today ) {
-            $row{'today'} = 1; 
-         }
-
-        #find the charge for an item
-        my ( $charge, $itemtype ) =
-          GetIssuingCharges( $issue->[$i]{'itemnumber'}, $issue->[$i]{'borrowernumber'} );
-
-        my $itemtypeinfo = getitemtypeinfo($itemtype);
-        $row{'itemtype_description'} = $itemtypeinfo->{description};
-        $row{'itemtype_image'}       = $itemtypeinfo->{imageurl};
-
-        $row{'charge'} = sprintf( "%.2f", $charge );
-
-        my ( $renewokay,$renewerror ) = CanBookBeRenewed( $issue->[$i]{'borrowernumber'}, $issue->[$i]{'itemnumber'}, $override_limit );
-        $row{'norenew'} = !$renewokay;
-        $row{'can_confirm'} = ( !$renewokay && $renewerror ne 'on_reserve' );
-        $row{"norenew_reason_$renewerror"} = 1 if $renewerror;
-        $row{'renew_failed'}  = $renew_failed{ $issue->[$i]{'itemnumber'} };
-        $row{'return_failed'} = $return_failed{$issue->[$i]{'barcode'}};   
-        push( @$localissue, \%row );
-    }
-    return $localissue;
-}
+my @issuedata = build_issue_data($issue);
+my @relissuedata = build_issue_data($relissue);
 
 
 ### ###############################################################################
@@ -431,11 +362,29 @@ my $branch=C4::Context->userenv->{'branch'};
 $template->param(%$data);
 
 if (C4::Context->preference('ExtendedPatronAttributes')) {
-    my $attributes = GetBorrowerAttributes($borrowernumber);
+    my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber);
+    my @classes = uniq( map {$_->{class}} @$attributes );
+    @classes = sort @classes;
+
+    my @attributes_loop;
+    for my $class (@classes) {
+        my @items;
+        for my $attr (@$attributes) {
+            push @items, $attr if $attr->{class} eq $class
+        }
+        my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class;
+        push @attributes_loop, {
+            class => $class,
+            items => \@items,
+            lib   => $lib,
+        };
+    }
+
     $template->param(
         ExtendedPatronAttributes => 1,
-        extendedattributes => $attributes
+        attributes_loop => \@attributes_loop
     );
+
     my @types = C4::Members::AttributeTypes::GetAttributeTypes();
     if (scalar(@types) == 0) {
         $template->param(no_patron_attribute_types => 1);
@@ -468,8 +417,6 @@ $template->param(
     totaldue_raw    => $total,
     issueloop       => @issuedata,
     relissueloop    => @relissuedata,
-       issuecount      => $issuecount,
-    relissuecount   => $relissuecount,
     overdues_exist  => $overdues_exist,
     error           => $error,
     $error          => 1,
@@ -484,3 +431,89 @@ $template->param(
 );
 
 output_html_with_http_headers $input, $cookie, $template->output;
+
+sub build_issue_data {
+    my $issues = shift;
+
+    my $localissue;
+
+    foreach my $issue ( @{$issues} ) {
+
+        # Getting borrower details
+        my $memberdetails = GetMemberDetails( $issue->{borrowernumber} );
+        $issue->{borrowername} =
+          $memberdetails->{firstname} . ' ' . $memberdetails->{surname};
+        $issue->{cardnumber} = $memberdetails->{cardnumber};
+        my $issuedate;
+        if ($issue->{issuedate} ) {
+           $issuedate = $issue->{issuedate}->clone();
+        }
+
+        $issue->{date_due}  = output_pref( $issue->{date_due} );
+        $issue->{issuedate} = output_pref( $issue->{issuedate} ) if defined $issue->{issuedate};
+        my $biblionumber = $issue->{biblionumber};
+        my %row          = %{$issue};
+        $totalprice += $issue->{replacementprice};
+
+        # item lost, damaged loops
+        if ( $row{'itemlost'} ) {
+            my $fw       = GetFrameworkCode( $issue->{biblionumber} );
+            my $category = GetAuthValCode( 'items.itemlost', $fw );
+            my $lostdbh  = C4::Context->dbh;
+            my $sth      = $lostdbh->prepare(
+"select lib from authorised_values where category=? and authorised_value =? "
+            );
+            $sth->execute( $category, $row{'itemlost'} );
+            my $loststat = $sth->fetchrow;
+            if ($loststat) {
+                $row{'itemlost'} = $loststat;
+            }
+        }
+        if ( $row{'damaged'} ) {
+            my $fw         = GetFrameworkCode( $issue->{biblionumber} );
+            my $category   = GetAuthValCode( 'items.damaged', $fw );
+            my $damageddbh = C4::Context->dbh;
+            my $sth        = $damageddbh->prepare(
+"select lib from authorised_values where category=? and authorised_value =? "
+            );
+            $sth->execute( $category, $row{'damaged'} );
+            my $damagedstat = $sth->fetchrow;
+            if ($damagedstat) {
+                $row{'itemdamaged'} = $damagedstat;
+            }
+        }
+
+        # end lost, damaged
+        if ( $issue->{overdue} ) {
+            $overdues_exist = 1;
+            $row{red} = 1;
+        }
+        if ($issuedate) {
+            $issuedate->truncate( to => 'days' );
+            if ( DateTime->compare( $issuedate, $today ) == 0 ) {
+                $row{today} = 1;
+            }
+        }
+
+        #find the charge for an item
+        my ( $charge, $itemtype ) =
+          GetIssuingCharges( $issue->{itemnumber}, $borrowernumber );
+
+        my $itemtypeinfo = getitemtypeinfo($itemtype);
+        $row{'itemtype_description'} = $itemtypeinfo->{description};
+        $row{'itemtype_image'}       = $itemtypeinfo->{imageurl};
+
+        $row{'charge'} = sprintf( "%.2f", $charge );
+
+        my ( $renewokay, $renewerror ) =
+          CanBookBeRenewed( $borrowernumber, $issue->{itemnumber},
+            $override_limit );
+        $row{'norenew'} = !$renewokay;
+        $row{'can_confirm'} = ( !$renewokay && $renewerror ne 'on_reserve' );
+        $row{"norenew_reason_$renewerror"} = 1 if $renewerror;
+        $row{renew_failed}  = $renew_failed{ $issue->{itemnumber} };
+        $row{return_failed} = $return_failed{ $issue->{barcode} };
+        push( @{$localissue}, \%row );
+    }
+    return $localissue;
+}
index e3377bf..fe1dc8c 100755 (executable)
@@ -43,7 +43,7 @@ use C4::Members::Attributes qw(GetBorrowerAttributes);
 
 my $input = CGI->new;
 
-my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     {   template_name   => 'members/pay.tmpl',
         query           => $input,
         type            => 'intranet',
@@ -53,9 +53,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     }
 );
 
-my $writeoff_sth;
-my $add_writeoff_sth;
-
 my @names = $input->param;
 
 my $borrowernumber = $input->param('borrowernumber');
@@ -89,8 +86,8 @@ if ($writeoff_all) {
     my $accountno    = $input->param('accountno');
     my $itemno       = $input->param('itemnumber');
     my $account_type = $input->param('accounttype');
-    my $amount       = $input->param('amount');
-    writeoff( $accountno, $itemno, $account_type, $amount );
+    my $amount       = $input->param('amountoutstanding');
+    WriteOffFee( $borrowernumber, $accountno, $itemno, $account_type, $amount, $branch );
 }
 
 for (@names) {
@@ -109,23 +106,6 @@ add_accounts_to_template();
 
 output_html_with_http_headers $input, $cookie, $template->output;
 
-sub writeoff {
-    my ( $accountnum, $itemnum, $accounttype, $amount ) = @_;
-    my $manager_id = 0;
-    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
-
-    # if no item is attached to fine, make sure to store it as a NULL
-    $itemnum ||= undef;
-    get_writeoff_sth();
-    $writeoff_sth->execute( $accountnum, $borrowernumber );
-
-    my $acct = getnextacctno($borrowernumber);
-    $add_writeoff_sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id );
-
-    UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
-
-    return;
-}
 
 sub add_accounts_to_template {
 
@@ -202,9 +182,9 @@ sub writeoff_all {
 
             #    my $borrowernum    = $input->param("borrowernumber$value");
             my $itemno    = $input->param("itemnumber$value");
-            my $amount    = $input->param("amount$value");
+            my $amount    = $input->param("amountoutstanding$value");
             my $accountno = $input->param("accountno$value");
-            writeoff( $accountno, $itemno, $accounttype, $amount );
+            WriteOffFee( $borrowernumber, $accountno, $itemno, $accounttype, $amount, $branch );
         }
     }
 
@@ -270,23 +250,3 @@ sub payselected {
     print $input->redirect($redirect);
     return;
 }
-
-sub get_writeoff_sth {
-
-    # lets prepare these statement handles only once
-    if ($writeoff_sth) {
-        return;
-    } else {
-        my $dbh = C4::Context->dbh;
-
-        # Do we need to validate accounttype
-        my $sql = 'Update accountlines set amountoutstanding=0 '
-          . 'WHERE accountno=? and borrowernumber=?';
-        $writeoff_sth = $dbh->prepare($sql);
-        my $insert =
-q{insert into accountlines (borrowernumber,accountno,itemnumber,date,amount,description,accounttype,manager_id)}
-          . q{values (?,?,?,now(),?,'Writeoff','W',?)};
-        $add_writeoff_sth = $dbh->prepare($insert);
-    }
-    return;
-}
index d4ecf65..2645eda 100755 (executable)
@@ -30,6 +30,7 @@ use C4::Output;
 use C4::Members;
 use C4::Branch;
 use List::MoreUtils qw/any uniq/;
+use Koha::DateUtils;
 
 use C4::Dates qw/format_date/;
 use C4::Members::Attributes qw(GetBorrowerAttributes);
@@ -75,9 +76,9 @@ foreach my $issue (@{$issues}){
        $line{title}           = $issue->{'title'};
        $line{author}          = $issue->{'author'};
        $line{classification}  = $issue->{'classification'} || $issue->{'itemcallnumber'};
-       $line{date_due}        = format_date($issue->{'date_due'});
-       $line{returndate}      = format_date($issue->{'returndate'});
-       $line{issuedate}       = format_date($issue->{'issuedate'});
+       $line{date_due}        = format_sqldatetime($issue->{date_due});
+       $line{returndate}      = format_sqldatetime($issue->{returndate});
+       $line{issuedate}       = format_sqldatetime($issue->{issuedate});
        $line{issuingbranch}   = GetBranchName($issue->{'branchcode'});
        $line{renewals}        = $issue->{'renewals'};
        $line{barcode}         = $issue->{'barcode'};
index 09c4017..de00846 100755 (executable)
@@ -54,7 +54,7 @@ use C4::Letters;
 use C4::Members;
 use C4::Members::Messaging;
 use C4::Overdues;
-use C4::Dates qw/format_date/;
+use Koha::DateUtils;
 
 
 # These are defaults for command line options.
@@ -347,6 +347,12 @@ sub parse_letter {
     );
 }
 
+sub format_date {
+    my $date_string = shift;
+    my $dt=dt_from_string($date_string);
+    return output_pref($dt);
+}
+
 1;
 
 __END__
index 73cdf9f..5124f3c 100755 (executable)
@@ -9,6 +9,7 @@
 #  This script is meant to be run nightly out of cron.
 
 # Copyright 2000-2002 Katipo Communications
+# Copyright 2011 PTFS-Europe Ltd
 #
 # This file is part of Koha.
 #
 # with Koha; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-
-# FIXME: use FinesMode as described or change syspref description
 use strict;
-#use warnings; FIXME - Bug 2505
-
-BEGIN {
-    # find Koha's Perl modules
-    # test carefully before changing this
-    use FindBin;
-    eval { require "$FindBin::Bin/kohalib.pl" };
-}
-
-use Date::Calc qw/Date_to_Days/;
+use warnings;
+use 5.010;
 
 use C4::Context;
-use C4::Circulation;
 use C4::Overdues;
-use C4::Calendar qw();  # don't need any exports from Calendar
-use C4::Biblio;
-use C4::Debug;  # supplying $debug and $cgi_debug
 use Getopt::Long;
+use Carp;
+use File::Spec;
+
+use Koha::Calendar;
+use Koha::DateUtils;
 
-my $help = 0;
-my $verbose = 0;
+my $help;
+my $verbose;
 my $output_dir;
 
-GetOptions( 'h|help'    => \$help,
-            'v|verbose' => \$verbose,
-            'o|out:s'   => \$output_dir,
-       );
+GetOptions(
+    'h|help'    => \$help,
+    'v|verbose' => \$verbose,
+    'o|out:s'   => \$output_dir,
+);
 my $usage = << 'ENDUSAGE';
 
 This script calculates and charges overdue fines
@@ -70,102 +63,111 @@ This script has the following parameters :
 
 ENDUSAGE
 
-die $usage if $help;
-
-use vars qw(@borrower_fields @item_fields @other_fields);
-use vars qw($fldir $libname $control $mode $delim $dbname $today $today_iso $today_days);
-use vars qw($filename);
-
-CHECK {
-    @borrower_fields = qw(cardnumber categorycode surname firstname email phone address citystate);
-        @item_fields = qw(itemnumber barcode date_due);
-       @other_fields = qw(type days_overdue fine);
-    $libname = C4::Context->preference('LibraryName');
-    $control = C4::Context->preference('CircControl');
-    $mode    = C4::Context->preference('finesMode');
-    $dbname  = C4::Context->config('database');
-    $delim   = "\t"; # ?  C4::Context->preference('delimiter') || "\t";
-
+if ($help) {
+    print $usage;
+    exit;
 }
 
-INIT {
-    $debug and print "Each line will contain the following fields:\n",
-        "From borrowers : ", join(', ', @borrower_fields), "\n",
-        "From items : ", join(', ', @item_fields), "\n",
-        "Per overdue: ", join(', ', @other_fields), "\n",
-        "Delimiter: '$delim'\n";
-}
+my @borrower_fields =
+  qw(cardnumber categorycode surname firstname email phone address citystate);
+my @item_fields  = qw(itemnumber barcode date_due);
+my @other_fields = qw(type days_overdue fine);
+my $libname      = C4::Context->preference('LibraryName');
+my $control      = C4::Context->preference('CircControl');
+my $mode         = C4::Context->preference('finesMode');
+my $delim = "\t";    # ?  C4::Context->preference('delimiter') || "\t";
+
+my %is_holiday;
+my $today = DateTime->now( time_zone => C4::Context->tz() );
+my $filename = get_filename($output_dir);
+
+open my $fh, '>>', $filename or croak "Cannot write file $filename: $!";
+print {$fh} join $delim, ( @borrower_fields, @item_fields, @other_fields );
+print {$fh} "\n";
+
+my $counted  = 0;
+my $overdues = Getoverdues();
+for my $overdue ( @{$overdues} ) {
+    if ( !defined $overdue->{borrowernumber} ) {
+        carp
+"ERROR in Getoverdues : issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
+        next;
+    }
+    my $borrower = BorType( $overdue->{borrowernumber} );
+    my $branchcode =
+        ( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch}
+      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
+      :                                     $overdue->{branchcode};
+
+# In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here).
+    if ( !exists $is_holiday{$branchcode} ) {
+        $is_holiday{$branchcode} = set_holiday( $branchcode, $today );
+    }
 
-my $data = Getoverdues();
-my $overdueItemsCounted = 0;
-my %calendars = ();
-$today = C4::Dates->new();
-$today_iso = $today->output('iso');
-$today_days = Date_to_Days(split(/-/,$today_iso));
-if($output_dir){
-    $fldir = $output_dir if( -d $output_dir );
-} else {
-    $fldir = $ENV{TMPDIR} || "/tmp";
-}
-if (!-d $fldir) {
-    warn "Could not write to $fldir ... does not exist!";
-}
-$filename = $dbname;
-$filename =~ s/\W//;
-$filename = $fldir . '/'. $filename . '_' .  $today_iso . ".log";
-print "writing to $filename\n" if $verbose;
-open (FILE, ">$filename") or die "Cannot write file $filename: $!";
-print FILE join $delim, (@borrower_fields, @item_fields, @other_fields);
-print FILE "\n";
-
-for (my $i=0; $i<scalar(@$data); $i++) {
-    my $datedue = C4::Dates->new($data->[$i]->{'date_due'},'iso');
-    my $datedue_days = Date_to_Days(split(/-/,$datedue->output('iso')));
-    my $due_str = $datedue->output();
-    unless (defined $data->[$i]->{'borrowernumber'}) {
-        print STDERR "ERROR in Getoverdues line $i: issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
-        next;   # Note: this doesn't solve everything.  After NULL borrowernumber, multiple issues w/ real borrowernumbers can pile up.
+    my $datedue = dt_from_string( $overdue->{date_due} );
+    if ( DateTime->compare( $datedue, $today ) == 1 ) {
+        next;    # not overdue
     }
-    my $borrower = BorType($data->[$i]->{'borrowernumber'});
-    my $branchcode = ($control eq 'ItemHomeLibrary') ? $data->[$i]->{homebranch} :
-                     ($control eq 'PatronLibrary'  ) ?   $borrower->{branchcode} :
-                                                       $data->[$i]->{branchcode} ;
-    # In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here).
-    my $calendar;
-    unless (defined ($calendars{$branchcode})) {
-        $calendars{$branchcode} = C4::Calendar->new(branchcode => $branchcode);
+    ++$counted;
+
+    my ( $amount, $type, $daycounttotal ) =
+      CalcFine( $overdue, $borrower->{categorycode},
+        $branchcode, $datedue, $today );
+
+    $type ||= q{};
+
+    # Don't update the fine if today is a holiday.
+    # This ensures that dropbox mode will remove the correct amount of fine.
+    if ( $mode eq 'production' && !$is_holiday{$branchcode} ) {
+        if ( $amount > 0 ) {
+            UpdateFine(
+                $overdue->{itemnumber},
+                $overdue->{borrowernumber},
+                $amount, $type, output_pref($datedue)
+            );
+        }
     }
-    $calendar = $calendars{$branchcode};
-    my $isHoliday = $calendar->isHoliday(split '/', $today->output('metric'));
-      
-    ($datedue_days <= $today_days) or next; # or it's not overdue, right?
-
-    $overdueItemsCounted++;
-    my ($amount,$type,$daycounttotal,$daycount)=
-               CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,undef,undef, $datedue, $today);
-        # FIXME: $type NEVER gets populated by anything.
-    (defined $type) or $type = '';
-       # Don't update the fine if today is a holiday.  
-       # This ensures that dropbox mode will remove the correct amount of fine.
-       if ($mode eq 'production' and  ! $isHoliday) {
-               UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due_str) if( $amount > 0 ) ;
-       }
-    my @cells = ();
-    push @cells, map {$borrower->{$_}} @borrower_fields;
-    push @cells, map {$data->[$i]->{$_}} @item_fields;
+    my @cells;
+    push @cells,
+      map { defined $borrower->{$_} ? $borrower->{$_} : q{} } @borrower_fields;
+    push @cells, map { $overdue->{$_} } @item_fields;
     push @cells, $type, $daycounttotal, $amount;
-    print FILE join($delim, @cells), "\n";
+    say {$fh} join $delim, @cells;
 }
+close $fh;
 
-my $numOverdueItems = scalar(@$data);
 if ($verbose) {
-   print <<EOM;
-Fines assessment -- $today_iso -- Saved to $filename
+    my $overdue_items = @{$overdues};
+    print <<'EOM';
+Fines assessment -- $today->ymd() -- Saved to $filename
 Number of Overdue Items:
-     counted $overdueItemsCounted
-    reported $numOverdueItems
+     counted $overdue_items
+    reported $counted
 
 EOM
 }
 
-close FILE;
+sub set_holiday {
+    my ( $branch, $dt ) = @_;
+
+    my $calendar = Koha::Calendar->new( branchcode => $branch );
+    return $calendar->is_holiday($dt);
+}
+
+sub get_filename {
+    my $directory = shift;
+    if ( !$directory ) {
+        $directory = File::Spec->tmpdir();
+    }
+    if ( !-d $directory ) {
+        carp "Could not write to $directory ... does not exist!";
+    }
+    my $name = C4::Context->config('database');
+    $name =~ s/\W//;
+    $name .= join q{}, q{_}, $today->ymd(), '.log';
+    $name = File::Spec->catfile( $directory, $name );
+    if ($verbose) {
+        say "writing to $name";
+    }
+    return $name;
+}
index af3790d..cb9ffa2 100755 (executable)
@@ -323,7 +323,7 @@ if (@branchcodes) {
 # these are the fields that will be substituted into <<item.content>>
 my @item_content_fields = split( /,/, $itemscontent );
 
-binmode STDOUT, ':encoding(UTF-8)';
+binmode( STDOUT, ':encoding(UTF-8)' );
 
 
 our $csv;       # the Text::CSV_XS object
@@ -350,8 +350,8 @@ if ( defined $htmlfilename ) {
   if ( $htmlfilename eq '' ) {
     $html_fh = *STDOUT;
   } else {
-    my $today = C4::Dates->new();
-    open $html_fh, ">",File::Spec->catdir ($htmlfilename,"notices-".$today->output('iso').".html");
+    my $today = DateTime->now(time_zone => C4::Context->tz );
+    open $html_fh, ">",File::Spec->catdir ($htmlfilename,"notices-".$today->ymd().".html");
   }
   
   print $html_fh "<html>\n";
diff --git a/misc/cronjobs/social_data/get_report_social_data.pl b/misc/cronjobs/social_data/get_report_social_data.pl
new file mode 100644 (file)
index 0000000..7069e24
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/perl
+
+use Modern::Perl;
+use C4::SocialData;
+
+my $results = C4::SocialData::get_report;
+
+say "==== Social Data report ====";
+say "Matched : (" . scalar( @{ $results->{with} } ) . ")";
+say "biblionumber = $_->{biblionumber},\toriginal = $_->{original},\tisbn = $_->{isbn}" for @{ $results->{with} };
+
+say "No Match : (" . scalar( @{ $results->{without} } ) . ")";
+say "biblionumber = $_->{biblionumber},\toriginal = $_->{original},\tisbn = $_->{isbn}" for @{ $results->{without} };
+
+say "Without ISBN : (" . scalar( @{ $results->{no_isbn} } ) . ")";
+say "biblionumber = $_->{biblionumber}" for @{ $results->{no_isbn} };
diff --git a/misc/cronjobs/social_data/update_social_data.pl b/misc/cronjobs/social_data/update_social_data.pl
new file mode 100644 (file)
index 0000000..53058a7
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use Modern::Perl;
+use C4::Context;
+use C4::SocialData;
+
+my $url = C4::Context->preference( "Babeltheque_url_update" );
+my $output_dir = qq{/tmp};
+my $output_filepath = qq{$output_dir/social_data.csv};
+system( qq{/bin/rm -f $output_filepath} );
+system( qq{/bin/rm -f $output_dir/social_data.csv.bz2} );
+system( qq{/usr/bin/wget $url -O $output_dir/social_data.csv.bz2 } ) == 0 or die "Can't get bz2 file from url $url ($?)";
+system( qq{/bin/bunzip2 $output_dir/social_data.csv.bz2 } ) == 0 or die "Can't extract bz2 file ($?)";
+
+
+C4::SocialData::update_data $output_filepath;
index c8a204a..f9abda6 100644 (file)
@@ -39,7 +39,7 @@ sub set_lang {
 
 
 sub new {
-    my ($class, $lang, $pref_only) = @_;
+    my ($class, $lang, $pref_only, $verbose) = @_;
 
     my $self                 = { };
 
@@ -49,8 +49,9 @@ sub new {
                                '/prog/en/modules/admin/preferences';
     set_lang( $self, $lang ) if $lang;
     $self->{pref_only}       = $pref_only;
-    $self->{translator_path} = $Bin;
-    $self->{path_po}         = $self->{translator_path} . "/po";
+    $self->{verbose}         = $verbose;
+    $self->{process}         = "$Bin/tmpl_process3.pl " . ($verbose ? '' : '-q');
+    $self->{path_po}         = "$Bin/po";
     $self->{po}              = {};
 
     # Get all .pref file names
@@ -210,7 +211,7 @@ sub save_po {
     my $self = shift;
     # Write .po entries into a file put in Koha standard po directory
     Locale::PO->save_file_fromhash( $self->po_filename, $self->{po} );
-    print "Saved in file: ", $self->po_filename, "\n";
+    print "Saved in file: ", $self->po_filename, "\n" if $self->{verbose};
 }
 
 
@@ -236,7 +237,7 @@ sub get_po_merged_with_en {
 sub update_prefs {
     my $self = shift;
     print "Update '", $self->{lang},
-          "' preferences .po file from 'en' .pref files\n";
+          "' preferences .po file from 'en' .pref files\n" if $self->{verbose};
     $self->get_po_merged_with_en();
     $self->save_po();
 }
@@ -281,7 +282,7 @@ sub install_prefs {
             $pref->{$tab} = $ntab;
         }
         my $file_trans = $self->{po_path_lang} . "/$file";
-        print "Write $file\n";
+        print "Write $file\n" if $self->{verbose};
         open my $fh, ">", $file_trans;
         print $fh Dump($pref);
     }
@@ -290,19 +291,18 @@ sub install_prefs {
 
 sub install_tmpl {
     my $self = shift;
-
-    print
-        "Install templates\n";
+    print "Install templates\n" if $self->{verbose};
     while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
         print
             "  Install templates '$interface\n",
             "    From: $tmpl->{dir}/en/\n",
             "    To  : $tmpl->{dir}/$self->{lang}\n",
-            "    With: $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
+            "    With: $self->{path_po}/$self->{lang}$tmpl->{suffix}\n"
+                if $self->{verbose};
         my $lang_dir = "$tmpl->{dir}/$self->{lang}";
         mkdir $lang_dir unless -d $lang_dir;
         system
-            "$self->{translator_path}/tmpl_process3.pl install " .
+            "$self->{process} install " .
             "-i $tmpl->{dir}/en/ " .
             "-o $tmpl->{dir}/$self->{lang} ".
             "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
@@ -313,17 +313,17 @@ sub install_tmpl {
 sub update_tmpl {
     my $self = shift;
 
-    print
-        "Update templates\n";
+    print "Update templates\n" if $self->{verbose};
     while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
         print
             "  Update templates '$interface'\n",
             "    From: $tmpl->{dir}/en/\n",
-            "    To  : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
+            "    To  : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n"
+                if $self->{verbose};
         my $lang_dir = "$tmpl->{dir}/$self->{lang}";
         mkdir $lang_dir unless -d $lang_dir;
         system
-            "$self->{translator_path}/tmpl_process3.pl update " .
+            "$self->{process} update " .
             "-i $tmpl->{dir}/en/ " .
             "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
     }
@@ -341,15 +341,15 @@ sub create_prefs {
 sub create_tmpl {
     my $self = shift;
 
-    print
-        "Create templates\n";
+    print "Create templates\n" if $self->{verbose};
     while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
         print
             "  Create templates .po files for '$interface'\n",
             "    From: $tmpl->{dir}/en/\n",
-            "    To  : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
+            "    To  : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n"
+                if $self->{verbose};
         system
-            "$self->{translator_path}/tmpl_process3.pl create " .
+            "$self->{process} create " .
             "-i $tmpl->{dir}/en/ " .
             "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
     }
index cb69117..89c993f 100755 (executable)
@@ -272,7 +272,6 @@ if (defined $href) {
     die "$str_file: PO file is corrupted, or not a PO file\n" unless defined $href->{'""'};
     $charset_out = TmplTokenizer::charset_canon $2 if $href->{'""'}->msgstr =~ /\bcharset=(["']?)([^;\s"'\\]+)\1/;
     $charset_in = $charset_out;
-    warn "Charset in/out: ".$charset_out;
 #     for my $msgid (keys %$href) {
 #   if ($msgid =~ /\bcharset=(["']?)([^;\s"'\\]+)\1/) {
 #       my $candidate = TmplTokenizer::charset_canon $2;
@@ -350,7 +349,7 @@ if ($action eq 'create')  {
         close INPUT;
         close OUTPUT;
     }
-    $st = system('msgmerge', '-U', '-s', $str_file, $tmpfile2);
+    $st = system("msgmerge -U ".($quiet?'-q':'')." -s $str_file $tmpfile2");
     } else {
     error_normal "Text extraction failed: $xgettext: $!\n", undef;
     error_additional "Will not run msgmerge\n", undef;
@@ -376,7 +375,7 @@ if ($action eq 'create')  {
     # Merge the temporary "pot file" with the specified po file ($str_file)
     # FIXME: msgmerge(1) is a Unix dependency
     # FIXME: need to check the return value
-    $st = system('msgmerge', '-U', '-s', $str_file, $tmpfile2);
+    $st = system("msgmerge -U ".($quiet?'-q':'')." -s $str_file $tmpfile2");
     } else {
     error_normal "Text extraction failed: $xgettext: $!\n", undef;
     error_additional "Will not run msgmerge\n", undef;
index 90f2950..f0c12c9 100755 (executable)
@@ -48,7 +48,7 @@ usage() if $#ARGV != 1 && $#ARGV != 0;
 my ($cmd, $lang) = @ARGV;
 $cmd = lc $cmd;
 if ( $cmd =~ /create|install|update/ ) {
-    my $installer = LangInstaller->new( $lang, $pref );
+    my $installer = LangInstaller->new( $lang, $pref, $verbose );
     if ( $cmd !~ /create/ && $lang && not $lang ~~ $installer->{langs} ) {
         print "Unsupported language: $lang\n";
         exit;
index 22d83b8..673b70e 100755 (executable)
@@ -24,7 +24,6 @@ use C4::Members;
 use C4::Circulation;
 use C4::Auth;
 use C4::Output;
-use C4::Dates qw/format_date/;
 use warnings;
 
 my $query = new CGI;
@@ -50,7 +49,6 @@ $template->param( BORROWER_INFO => \@bordat );
 my ( $total , $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber );
 
 for ( my $i = 0 ; $i < $numaccts ; $i++ ) {
-    $accts->[$i]{'date'} = format_date( $accts->[$i]{'date'} );
     $accts->[$i]{'amount'} = sprintf( "%.2f", $accts->[$i]{'amount'} || '0.00');
     if ( $accts->[$i]{'amount'} >= 0 ) {
         $accts->[$i]{'amountcredit'} = 1;
index 610b22e..bea130d 100755 (executable)
 use strict;
 use warnings;
 
-use C4::Biblio;
 use CGI;
-use C4::VirtualShelves qw/:DEFAULT GetAllShelves RefreshShelvesSummary/;
-use C4::Auth;
+use C4::Biblio;
+use C4::VirtualShelves qw/:DEFAULT GetAllShelves/;
 use C4::Output;
-use C4::Auth qw/get_session/;
-use C4::Debug;
-
-#splits incoming biblionumber(s) to array and adds each to shelf.
-sub AddBibliosToShelf {
-    my ($shelfnumber,@biblionumber)=@_;
-
-    # multiple bibs might come in as '/' delimited string (from where, i don't see), or as array.
-    if (scalar(@biblionumber) == 1) {
-        @biblionumber = (split /\//,$biblionumber[0]);
-    }
-    for my $bib (@biblionumber){
-        AddToShelf($bib, $shelfnumber);
-    }
-}
+use C4::Auth;
 
 my $query              = new CGI;
 my @biblionumber       = $query->param('biblionumber');
@@ -53,6 +38,9 @@ my $newshelf          = $query->param('newshelf');
 my $shelfnumber        = $query->param('shelfnumber');
 my $newvirtualshelf    = $query->param('newvirtualshelf');
 my $category           = $query->param('category');
+my $authorized          = 1;
+my $errcode            = 0;
+my @biblios;
 
 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     {
@@ -63,72 +51,120 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     }
 );
 
-if ($newvirtualshelf) {
-       $shelfnumber = AddShelf(  $newvirtualshelf, $loggedinuser, $category );
-       AddBibliosToShelf($shelfnumber, @biblionumber);
-       RefreshShelvesSummary($query->cookie("CGISESSID"),$loggedinuser,($loggedinuser == -1 ? 20 : 10));
-       print $query->header;
-       print "<html><meta http-equiv=\"refresh\" content=\"0;url=opac-shelves.pl?display=privateshelves\" /><body onload=\"window.opener.location.reload(true);self.close();\"></body></html>";
-       exit;
+if( $newvirtualshelf) {
+    HandleNewVirtualShelf();
+    exit if $authorized;
+    ShowTemplate(); #error message
+}
+elsif($shelfnumber) {
+    HandleShelfNumber();
+    exit if $authorized;
+    ShowTemplate(); #error message
+}
+elsif($selectedshelf) {
+    HandleSelectedShelf();
+    LoadBib() if $authorized;
+    ShowTemplate();
 }
+else {
+    HandleSelect();
+    LoadBib() if $authorized;
+    ShowTemplate();
+}
+#end
 
-# verify user is authorized to perform the action on the shelf...
-my $authorized = 1;
-if ($selectedshelf) {
-       $authorized = 0 unless ShelfPossibleAction( $loggedinuser, $selectedshelf );
+sub AddBibliosToShelf {
+    #splits incoming biblionumber(s) to array and adds each to shelf.
+    my ($shelfnumber,@biblionumber)=@_;
+
+    #multiple bibs might come in as '/' delimited string (from where, i don't see), or as array.
+    if (scalar(@biblionumber) == 1) {
+        @biblionumber = (split /\//,$biblionumber[0]);
+    }
+    for my $bib (@biblionumber) {
+        AddToShelf($bib, $shelfnumber, $loggedinuser);
+    }
 }
 
-if ($shelfnumber && ($shelfnumber != -1)) {
-       AddBibliosToShelf($shelfnumber,@biblionumber);
-       RefreshShelvesSummary($query->cookie("CGISESSID"),$loggedinuser,($loggedinuser == -1 ? 20 : 10));
-       print $query->header;
-       print "<html><meta http-equiv=\"refresh\" content=\"0;url=opac-shelves.pl?display=privateshelves\" /><body onload=\"self.close();\"></body></html>";
-       exit;
+sub HandleNewVirtualShelf {
+    if($authorized= ShelfPossibleAction($loggedinuser, undef, $category==1? 'new_private': 'new_public')) {
+    $shelfnumber = AddShelf( {
+            shelfname => $newvirtualshelf,
+            category => $category }, $loggedinuser);
+    if($shelfnumber == -1) {
+        $authorized=0;
+        $errcode=1;
+        return;
+    }
+    AddBibliosToShelf($shelfnumber, @biblionumber);
+    #Reload the page where you came from
+    print $query->header;
+    print "<html><meta http-equiv=\"refresh\" content=\"0\" /><body onload=\"window.opener.location.reload(true);self.close();\"></body></html>";
+    }
+}
+
+sub HandleShelfNumber {
+    if($authorized= ShelfPossibleAction($loggedinuser, $shelfnumber, 'add')) {
+    AddBibliosToShelf($shelfnumber,@biblionumber);
+    #Close this page and return
+    print $query->header;
+    print "<html><meta http-equiv=\"refresh\" content=\"0\" /><body onload=\"self.close();\"></body></html>";
+    }
 }
-else {
-       if($selectedshelf){
-       # adding to specific shelf
-       my ( $singleshelf, $singleshelfname, $singlecategory ) = GetShelf( $query->param('selectedshelf') );
-                               $template->param(
-                               singleshelf             => 1,
-                               shelfnumber         => $singleshelf,
-                               shelfname           => $singleshelfname,
-                               "category$singlecategory" => 1
-                       );
-       } else {
 
-        my $privateshelves = GetAllShelves(1,$loggedinuser);
-        if(@{$privateshelves}){
-                       $template->param (
-                               privatevirtualshelves          => $privateshelves,
-                               existingshelves => 1
-                       );
-               }
-        my $publicshelves = GetAllShelves(2,$loggedinuser);
-        if(@{$publicshelves}){
-                       $template->param (
-                               publicvirtualshelves          => $publicshelves,
-                               existingshelves => 1
-                       );
-        }
+sub HandleSelectedShelf {
+    if($authorized= ShelfPossibleAction( $loggedinuser, $selectedshelf, 'add')){
+        #adding to specific shelf
+        my ($singleshelf, $singleshelfname, $singlecategory)= GetShelf($query->param('selectedshelf'));
+        $template->param(
+        singleshelf               => 1,
+        shelfnumber               => $singleshelf,
+        shelfname                 => $singleshelfname,
+        "category$singlecategory" => 1
+        );
+    }
+}
 
+sub HandleSelect {
+    return unless $authorized= $loggedinuser>0;
+    my $privateshelves = GetAllShelves(1,$loggedinuser,1);
+    if(@{$privateshelves}){
+        $template->param (
+        privatevirtualshelves          => $privateshelves,
+        existingshelves => 1
+    );
+    }
+    my $publicshelves = GetAllShelves(2,$loggedinuser,1);
+    if(@{$publicshelves}){
+        $template->param (
+        publicvirtualshelves          => $publicshelves,
+        existingshelves => 1
+    );
+    }
+}
+
+sub LoadBib {
+    for my $bib (@biblionumber) {
+        my $data = GetBiblioData( $bib );
+    push(@biblios,
+        { biblionumber => $bib,
+          title        => $data->{'title'},
+          author       => $data->{'author'},
+    } );
+    }
+    $template->param(
+        multiple => (scalar(@biblios) > 1),
+    total    => scalar @biblios,
+    biblios  => \@biblios,
+    );
 }
-       my @biblios;
-       for my $bib (@biblionumber) {
-               my $data = GetBiblioData( $bib );
-               push(@biblios, 
-                       { biblionumber => $bib,
-                         title        => $data->{'title'},
-                         author       => $data->{'author'},
-                       } );
-       }
-       $template->param (
-               newshelf => $newshelf,
-               multiple => (scalar(@biblios) > 1),
-               total    => scalar @biblios,
-               biblios  => \@biblios,
-               authorized      => $authorized,
-       );
 
-       output_html_with_http_headers $query, $cookie, $template->output;
+sub ShowTemplate {
+    $template->param (
+    newshelf => $newshelf||0,
+    authorized => $authorized,
+    errcode            => $errcode,
+    OpacAllowPublicListCreation => C4::Context->preference('OpacAllowPublicListCreation'),
+    );
+    output_html_with_http_headers $query, $cookie, $template->output;
 }
index 27684d4..923f3ff 100755 (executable)
@@ -32,7 +32,6 @@ use C4::Biblio;
 use C4::Items;
 use C4::Circulation;
 use C4::Tags qw(get_tags);
-use C4::Dates qw/format_date/;
 use C4::XISBN qw(get_xisbns get_biblionumber_from_isbn);
 use C4::External::Amazon;
 use C4::External::Syndetics qw(get_syndetics_index get_syndetics_summary get_syndetics_toc get_syndetics_excerpt get_syndetics_reviews get_syndetics_anotes );
@@ -47,6 +46,7 @@ use MARC::Record;
 use MARC::Field;
 use List::MoreUtils qw/any none/;
 use C4::Images;
+use Koha::DateUtils;
 
 BEGIN {
        if (C4::Context->preference('BakerTaylorEnabled')) {
@@ -453,8 +453,8 @@ foreach my $subscription (@subscriptions) {
     $cell{subscriptionnotes} = $subscription->{notes};
     $cell{missinglist}       = $subscription->{missinglist};
     $cell{opacnote}          = $subscription->{opacnote};
-    $cell{histstartdate}     = format_date($subscription->{histstartdate});
-    $cell{histenddate}       = format_date($subscription->{histenddate});
+    $cell{histstartdate}     = $subscription->{histstartdate};
+    $cell{histenddate}       = $subscription->{histenddate};
     $cell{branchcode}        = $subscription->{branchcode};
     $cell{branchname}        = GetBranchName($subscription->{branchcode});
     $cell{hasalert}          = $subscription->{hasalert};
@@ -494,8 +494,6 @@ for my $itm (@items) {
         # I can't actually find any case in which this is defined. --amoore 2008-12-09
         $itm->{ $itm->{'publictype'} } = 1;
     }
-    $itm->{datedue}      = format_date($itm->{datedue});
-    $itm->{datelastseen} = format_date($itm->{datelastseen});
 
     # get collection code description, too
     if ( my $ccode = $itm->{'ccode'} ) {
@@ -527,7 +525,7 @@ for my $itm (@items) {
     
      my ( $transfertwhen, $transfertfrom, $transfertto ) = GetTransfers($itm->{itemnumber});
      if ( defined( $transfertwhen ) && $transfertwhen ne '' ) {
-        $itm->{transfertwhen} = format_date($transfertwhen);
+        $itm->{transfertwhen} = $transfertwhen;
         $itm->{transfertfrom} = $branches->{$transfertfrom}{branchname};
         $itm->{transfertto}   = $branches->{$transfertto}{branchname};
      }
@@ -641,7 +639,6 @@ foreach ( @$reviews ) {
     }
     $_->{userid}    = $borrowerData->{'userid'};
     $_->{cardnumber}    = $borrowerData->{'cardnumber'};
-    $_->{datereviewed} = format_date($_->{datereviewed});
     if ($borrowerData->{'borrowernumber'} eq $borrowernumber) {
                $_->{your_comment} = 1;
                $loggedincommenter = 1;
@@ -723,9 +720,6 @@ if ( C4::Context->preference("OPACAmazonEnabled") ) {
     if ( $amazon_reviews ) {
         my $item = $amazon_details->{Items}->{Item}->[0];
         my $customer_reviews = \@{ $item->{CustomerReviews}->{Review} };
-        for my $one_review ( @$customer_reviews ) {
-            $one_review->{Date} = format_date($one_review->{Date});
-        }
         my $editorial_reviews = \@{ $item->{EditorialReviews}->{EditorialReview} };
         my $average_rating = $item->{CustomerReviews}->{AverageRating} || 0;
         $template->param( amazon_average_rating    => $average_rating * 20);
@@ -836,9 +830,16 @@ $template->param(NovelistSelectView => C4::Context->preference('NovelistSelectVi
 if ( C4::Context->preference("Babeltheque") ) {
     $template->param( 
         Babeltheque => 1,
+        Babeltheque_url_js => C4::Context->preference("Babeltheque_url_js"),
     );
 }
 
+# Social Networks
+if ( C4::Context->preference( "SocialNetworks" ) ) {
+    $template->param( current_url => C4::Context->preference('OPACBaseURL') . "/cgi-bin/koha/opac-detail.pl?biblionumber=$biblionumber" );
+    $template->param( SocialNetworks => 1 );
+}
+
 # Shelf Browser Stuff
 if (C4::Context->preference("OPACShelfBrowser")) {
     # pick the first itemnumber unless one was selected by the user
index 337a939..d9d90a6 100755 (executable)
@@ -28,6 +28,8 @@ use Data::ICal::Entry::Event;
 use DateTime;
 use DateTime::Format::ICal;
 use Date::Calc qw (Parse_Date);
+use DateTime;
+use DateTime::Event::ICal;
 
 use C4::Auth;
 use C4::Koha;
@@ -54,7 +56,7 @@ my ( $borr ) =  GetMemberDetails( $borrowernumber );
 my $calendar = Data::ICal->new();
 
 # get issued items ....
-my ($issues) = GetPendingIssues($borrowernumber);
+my $issues = GetPendingIssues($borrowernumber);
 
 foreach my $issue ( @$issues ) {
     my $vevent = Data::ICal::Entry::Event->new();
index 00a91db..04c3293 100755 (executable)
@@ -25,8 +25,8 @@ use C4::Auth;
 use C4::Koha;
 use C4::Biblio;
 use C4::Circulation;
-use C4::Dates qw/format_date/;
 use C4::Members;
+use Koha::DateUtils;
 
 use C4::Output;
 
@@ -89,8 +89,8 @@ foreach my $issue (@{$issues} ) {
     $line{title}           = $issue->{'title'};
     $line{author}          = $issue->{'author'};
     $line{itemcallnumber}  = $issue->{'itemcallnumber'};
-    $line{date_due}        = format_date( $issue->{'date_due'} );
-    $line{returndate}      = format_date( $issue->{'returndate'} );
+    $line{date_due}        = $issue->{'date_due'};
+    $line{returndate}      = $issue->{'returndate'};
     $line{volumeddesc}     = $issue->{'volumeddesc'};
     $issue->{'itemtype'}   = C4::Context->preference('item-level_itypes') ? $issue->{'itype'} : $issue->{'itemtype'};
     if($issue->{'itemtype'}) {
index b2144a9..4e4d440 100755 (executable)
@@ -31,6 +31,7 @@ use C4::Members;
 use C4::Branch; # GetBranches
 use C4::Overdues;
 use C4::Debug;
+use Koha::DateUtils;
 # use Data::Dumper;
 
 my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves");
@@ -198,7 +199,7 @@ if ( $query->param('place_reserve') ) {
         my $itemNum   = shift(@selectedItems);
         my $branch    = shift(@selectedItems); # i.e., branch code, not name
 
-        my $singleBranchMode = $template->param('singleBranchMode');
+        my $singleBranchMode = C4::Context->preference("singleBranchMode");
         if ($singleBranchMode || ! $OPACChooseBranch) { # single branch mode or disabled user choosing
             $branch = $borr->{'branchcode'};
         }
@@ -397,7 +398,7 @@ foreach my $biblioNum (@biblionumbers) {
         # change the background color.
         my $issues= GetItemIssue($itemNum);
         if ( $issues->{'date_due'} ) {
-            $itemLoopIter->{dateDue} = format_date($issues->{'date_due'});
+            $itemLoopIter->{dateDue} = format_sqlduedatetime($issues->{date_due});
             $itemLoopIter->{backgroundcolor} = 'onloan';
         }
 
index eb9ee51..ea0cb98 100755 (executable)
@@ -36,9 +36,11 @@ use C4::Biblio;  # GetBiblioData
 use C4::Koha;
 use C4::Tags qw(get_tags);
 use C4::Branch; # GetBranches
+use C4::SocialData;
 use POSIX qw(ceil floor strftime);
 use URI::Escape;
 use Storable qw(thaw freeze);
+use Business::ISBN;
 
 
 my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
@@ -532,9 +534,23 @@ for (my $i=0;$i<@servers;$i++) {
             foreach (@newresults) {
                 my $record = GetMarcBiblio($_->{'biblionumber'});
                 $_->{coins} = GetCOinSBiblio($record);
+                if ( C4::Context->preference( "Babeltheque" ) and $_->{normalized_isbn} ) {
+                    my $isbn = Business::ISBN->new( $_->{normalized_isbn} );
+                    next if not $isbn;
+                    $isbn = $isbn->as_isbn13->as_string;
+                    $isbn =~ s/-//g;
+                    my $social_datas = C4::SocialData::get_data( $isbn );
+                    next if not $social_datas;
+                    for my $key ( keys %$social_datas ) {
+                        $_->{$key} = $$social_datas{$key};
+                        if ( $key eq 'score_avg' ){
+                            $_->{score_int} = sprintf("%.0f", $$social_datas{score_avg} );
+                        }
+                    }
+                }
             }
         }
-      
+
         if ($results_hashref->{$server}->{"hits"}){
             $total = $total + $results_hashref->{$server}->{"hits"};
         }
@@ -741,24 +757,14 @@ if ($query_desc || $limit_desc) {
 
 # VI. BUILD THE TEMPLATE
 # Build drop-down list for 'Add To:' menu...
-my $session = get_session($cgi->cookie("CGISESSID"));
-my @addpubshelves;
-my $pubshelves = $session->param('pubshelves');
-my $barshelves = $session->param('barshelves');
-foreach my $shelf (@$pubshelves) {
-    next if ( ($shelf->{'owner'} != ($borrowernumber ? $borrowernumber : -1)) && ($shelf->{'category'} < 3) );
-    push (@addpubshelves, $shelf);
-}
-
-if (@addpubshelves) {
-    $template->param( addpubshelves     => scalar (@addpubshelves));
-    $template->param( addpubshelvesloop => \@addpubshelves);
-}
-
-if (defined $barshelves) {
-    $template->param( addbarshelves     => scalar (@$barshelves));
-    $template->param( addbarshelvesloop => $barshelves);
-}
+my ($totalref, $pubshelves, $barshelves)=
+       C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1);
+$template->param(
+       addbarshelves     => $totalref->{bartotal},
+       addbarshelvesloop => $barshelves,
+       addpubshelves     => $totalref->{pubtotal},
+       addpubshelvesloop => $pubshelves,
+       );
 
 my $content_type = ($format eq 'rss' or $format eq 'atom') ? $format : 'html';
 
index f1b7f96..e17e95f 100755 (executable)
@@ -32,9 +32,5 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
         authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ),
     });
 $template->param(listsview => 1);
-# if $loggedinuser is not defined, set it to -1, which should
-# not correspond to any real borrowernumber.  
-# FIXME: this is a hack to temporarily avoid changing several
-#        routines in C4::VirtualShelves and C4::VirtualShelves::page
-#        to deal with lists accessed during an anonymous OPAC session
-shelfpage('opac', $query, $template, (defined($loggedinuser) ? $loggedinuser : -1), $cookie);
+
+shelfpage('opac', $query, $template, $loggedinuser, $cookie);
index 449ffcd..f8fc619 100755 (executable)
@@ -28,7 +28,7 @@ use C4::Output;
 use C4::Circulation;
 use C4::Review;
 use C4::Biblio;
-use C4::Dates qw/format_date/;
+use C4::Dates;
 use C4::Members qw/GetMemberDetails/;
 use POSIX qw(ceil strftime);
 
@@ -117,9 +117,6 @@ for my $result (@$reviews){
         my $rsstimestamp = C4::Dates->new($result->{datereviewed},"iso");
         my $rsstimestamp_output = $rsstimestamp->output("rfc822");
         $result->{timestamp} = $rsstimestamp_output;
-        $result->{datereviewed} = format_date($result->{datereviewed});
-    } else {
-        $result->{datereviewed} = format_date($result->{datereviewed});
     }
 }
 ## Build the page numbers on the bottom of the page
index b5ce340..0953f82 100755 (executable)
@@ -39,7 +39,6 @@ use C4::Auth qw(:DEFAULT check_cookie_auth);
 use C4::Context;
 use C4::Debug;
 use C4::Output 3.02 qw(:html :ajax pagination_bar);
-use C4::Dates qw(format_date);
 use C4::Scrubber;
 use C4::Biblio;
 use C4::Tags qw(add_tag get_approval_rows get_tag_rows remove_tag);
@@ -232,7 +231,6 @@ if ($loggedinuser) {
                my $date = $_->{date_created} || '';
                $date =~ /\s+(\d{2}\:\d{2}\:\d{2})/;
                $_->{time_created_display} = $1;
-               $_->{date_created_display} = format_date($_->{date_created});
        }
 }
 
index 5b18cae..b89e862 100755 (executable)
@@ -33,9 +33,9 @@ use C4::Output;
 use C4::Overdues qw/CheckBorrowerDebarred/;
 use C4::Biblio;
 use C4::Items;
-use C4::Dates qw/format_date/;
 use C4::Letters;
 use C4::Branch; # GetBranches
+use Koha::DateUtils;
 
 use constant ATTRIBUTE_SHOW_BARCODE => 'SHOW_BCODE';
 
@@ -75,9 +75,6 @@ my ( $borr ) = GetMemberDetails( $borrowernumber );
 my (  $today_year,   $today_month,   $today_day) = Today();
 my ($warning_year, $warning_month, $warning_day) = split /-/, $borr->{'dateexpiry'};
 
-for (qw(dateenrolled dateexpiry dateofbirth)) {
-    ($borr->{$_}) and $borr->{$_} = format_date($borr->{$_});
-}
 $borr->{'ethnicity'} = fixEthnicity( $borr->{'ethnicity'} );
 
 my $debar = CheckBorrowerDebarred($borrowernumber);
@@ -87,7 +84,7 @@ if ($debar) {
     $userdebarred = 1;
     $template->param( 'userdebarred' => $userdebarred );
     if ( $debar ne "9999-12-31" ) {
-        $borr->{'userdebarreddate'} = C4::Dates::format_date($debar);
+        $borr->{'userdebarreddate'} = $debar;
     }
 }
 
@@ -151,9 +148,9 @@ my $overdues_count = 0;
 my @overdues;
 my @issuedat;
 my $itemtypes = GetItemTypes();
-my ($issues) = GetPendingIssues($borrowernumber);
+my $issues = GetPendingIssues($borrowernumber);
 if ($issues){
-       foreach my $issue ( sort { $b->{'date_due'} cmp $a->{'date_due'} } @$issues ) {
+       foreach my $issue ( sort { $b->{date_due}->datetime() cmp $a->{date_due}->datetime() } @{$issues} ) {
                # check for reserves
                my ( $restype, $res, undef ) = CheckReserves( $issue->{'itemnumber'} );
                if ( $restype ) {
@@ -200,7 +197,6 @@ if ($issues){
                        $issue->{'imageurl'}    = getitemtypeimagelocation( 'opac', $itemtypes->{$itemtype}->{'imageurl'} );
                        $issue->{'description'} = $itemtypes->{$itemtype}->{'description'};
                }
-               $issue->{date_due} = format_date($issue->{date_due});
                push @issuedat, $issue;
                $count++;
                
@@ -253,18 +249,14 @@ $template->param( branchloop => \@branch_loop );
 # now the reserved items....
 my @reserves  = GetReservesFromBorrowernumber( $borrowernumber );
 foreach my $res (@reserves) {
-    $res->{'reservedate'} = format_date( $res->{'reservedate'} );
 
-    if ( $res->{'expirationdate'} ne '0000-00-00' ) {
-      $res->{'expirationdate'} = format_date( $res->{'expirationdate'} ) 
-    } else {
+    if ( $res->{'expirationdate'} eq '0000-00-00' ) {
       $res->{'expirationdate'} = '';
     }
     
     my $publictype = $res->{'publictype'};
     $res->{$publictype} = 1;
     $res->{'waiting'} = 1 if $res->{'found'} eq 'W';
-    $res->{'formattedwaitingdate'} = format_date($res->{'waitingdate'});
     $res->{'branch'} = $branches->{ $res->{'branchcode'} }->{'branchname'};
     my $biblioData = GetBiblioData($res->{'biblionumber'});
     $res->{'reserves_title'} = $biblioData->{'title'};
@@ -310,7 +302,7 @@ foreach my $res (@reserves) {
             my ($transfertwhen, $transfertfrom, $transfertto) = GetTransfers( $res->{'itemnumber'} );
             if ($transfertwhen) {
                 $res->{intransit} = 1;
-                $res->{datesent}   = format_date($transfertwhen);
+                $res->{datesent}   = $transfertwhen;
                 $res->{frombranch} = GetBranchName($transfertfrom);
             }
         }
index 7402b45..b37d88c 100755 (executable)
@@ -141,9 +141,6 @@ EOF
     }
 }
 
-$borr->{'dateenrolled'} = format_date( $borr->{'dateenrolled'} );
-$borr->{'dateexpiry'}   = format_date( $borr->{'dateexpiry'} );
-$borr->{'dateofbirth'}  = format_date( $borr->{'dateofbirth'} );
 $borr->{'ethnicity'}    = fixEthnicity( $borr->{'ethnicity'} );
 $borr->{'branchname'}   = GetBranchName($borr->{'branchcode'});
 
index f0ca37e..243dddd 100755 (executable)
@@ -39,12 +39,10 @@ use Digest::MD5 qw(md5_base64);
 
 use C4::Auth qw(get_template_and_user checkpw);
 use C4::Koha;
-use C4::Dates qw/format_date/;
 use C4::Circulation;
 use C4::Reserves;
 use C4::Output;
 use C4::Members;
-use C4::Dates;
 use C4::Biblio;
 use C4::Items;
 
@@ -218,7 +216,6 @@ if ($borrower->{cardnumber}) {
     my @issues;
     my ($issueslist) = GetPendingIssues( $borrower->{'borrowernumber'} );
     foreach my $it (@$issueslist) {
-        $it->{date_due_display} = format_date($it->{date_due});
         my ($renewokay, $renewerror) = CanBookBeIssued(
             $borrower,
             $it->{'barcode'},
index ad0ac3f..7207e64 100755 (executable)
@@ -108,7 +108,7 @@ if ($do_it) {
         }
         print $sep. @$results[0]->{total};
     }
-    exit(1);
+    exit;
 }
 else {
     my $dbh = C4::Context->dbh;
index 95fc287..6ad3495 100755 (executable)
@@ -102,7 +102,7 @@ if ($do_it) {
                print join($sep, map {$_->{totalcol}} @$cols);
         print $sep.@$results[0]->{total};
     }
-    exit(1);
+    exit;
 }
 
 my $dbh = C4::Context->dbh;
index 278e412..722faba 100755 (executable)
@@ -69,7 +69,7 @@ if ($do_it) {
 # Printing results to screen
         $template->param(mainloop => $results);
         output_html_with_http_headers $input, $cookie, $template->output;
-        exit(1);
+        exit;
     } else {
 # Printing to a csv file
         print $input->header(-type => 'application/vnd.sun.xml.calc',
@@ -103,7 +103,7 @@ if ($do_it) {
             print $sep.$col->{totalcol};
         }
         print $sep.@$results[0]->{total};
-        exit(1);
+        exit;
     }
 # Displaying choices
 } else {
index c17a326..9e00ea3 100755 (executable)
@@ -107,7 +107,7 @@ if ($do_it) {
                }
                print $sep.@$results[0]->{total};
        }
-       exit(1);        # exit after do_it, regardless
+       exit;   # exit after do_it, regardless
 } else {
        my $dbh = C4::Context->dbh;
        my $req;
index 606106d..2a6409d 100755 (executable)
@@ -75,7 +75,7 @@ if ($do_it) {
         $template->param(mainloop => $results,
                         limit => $limit);
         output_html_with_http_headers $input, $cookie, $template->output;
-        exit(1);
+        exit;
     } else {
 # Printing to a csv file
         print $input->header(-type => 'application/vnd.sun.xml.calc',
@@ -108,7 +108,7 @@ if ($do_it) {
             print $sep.$col->{totalcol};
         }
         print $sep.@$results[0]->{total};
-        exit(1);
+        exit;
     }
 # Displaying choices
 } else {
index 87990c1..8a22a18 100755 (executable)
@@ -96,7 +96,7 @@ if ($do_it) {
         }
         print $sep.@$results[0]->{total};
     }
-       exit(1); # in either case, exit after do_it
+    exit; # in either case, exit after do_it
 }
 
 # Displaying choices (i.e., not do_it)
index 11dff4d..c8e2194 100755 (executable)
@@ -74,7 +74,7 @@ if ($do_it) {
        if ($output eq "screen"){
                $template->param(mainloop => $results);
                output_html_with_http_headers $input, $cookie, $template->output;
-               exit(1);
+               exit;
        } else {
                print $input->header(-type => 'application/vnd.sun.xml.calc',
                                      -encoding    => 'utf-8',
@@ -102,7 +102,7 @@ if ($do_it) {
                        print $sep.$col->{totalcol};
                }
                print $sep.@$results[0]->{total};
-               exit(1);
+               exit;
        }
 } else {
        my $dbh = C4::Context->dbh;
index c6a3859..372f3c0 100755 (executable)
@@ -77,7 +77,7 @@ if ($do_it) {
 # Printing results to screen
         $template->param(mainloop => $results);
         output_html_with_http_headers $input, $cookie, $template->output;
-        exit(1);
+        exit;
     } else {
 # Printing to a csv file
         print $input->header(-type => 'application/vnd.sun.xml.calc',
@@ -110,7 +110,7 @@ if ($do_it) {
             print $sep.$col->{totalcol};
         }
         print $sep.@$results[0]->{total};
-        exit(1);
+        exit;
     }
 # Displaying choices
 } else {
index 2f8a7e3..4b6aa42 100755 (executable)
@@ -123,7 +123,7 @@ if ($do_it) {
                print map {$sep.$_->{totalcol}} @$cols;
         print $sep.@$results[0]->{total};
        }
-       exit(1); # exit either way after $do_it
+       exit; # exit either way after $do_it
 }
 
 my $dbh = C4::Context->dbh;
index a2b3737..c20a676 100755 (executable)
@@ -130,7 +130,7 @@ if ($do_it) {
                print map {$sep.$_->{totalcol}} @$cols;
         print $sep.@$results[0]->{total};
        }
-       exit(1); # exit either way after $do_it
+       exit; # exit either way after $do_it
 }
 
 my $dbh = C4::Context->dbh;
index 88918cc..ff80b2f 100755 (executable)
@@ -125,7 +125,7 @@ if($do_it){
             print $item->{startdate}.$sep;
             print $item->{enddate}."\n";
         }
-        exit(1);
+        exit;
     }
 }else{
     ## We generate booksellers list
index f4c7fb4..ad03d88 100755 (executable)
@@ -27,7 +27,7 @@ use CGI;
 use C4::Circulation;
 use C4::Auth;
 use URI::Escape;
-use C4::Dates qw/format_date_in_iso/;
+use Koha::DateUtils;
 my $input = new CGI;
 
 #Set Up User_env
@@ -66,7 +66,7 @@ if ($input->param('return_all')) {
 my $branch=$input->param('branch');
 my $datedue;
 if ($input->param('newduedate')){
-    $datedue=C4::Dates->new($input->param('newduedate'));
+    $datedue = dt_from_string($input->param('newduedate'));
 }
 
 # warn "barcodes : @barcodes";
index 24557f4..b96447f 100755 (executable)
@@ -42,6 +42,7 @@ use C4::Circulation;
 use C4::Dates qw/format_date/;
 use C4::Members;
 use C4::Search;                # enabled_staff_search_views
+use Koha::DateUtils;
 
 my $dbh = C4::Context->dbh;
 my $sth;
@@ -367,7 +368,7 @@ foreach my $biblionumber (@biblionumbers) {
             # change the background color
             my $issues= GetItemIssue($itemnumber);
             if ( $issues->{'date_due'} ) {
-                $item->{date_due} = format_date($issues->{'date_due'});
+                $item->{date_due} = format_sqldatetime($issues->{date_due});
                 $item->{backgroundcolor} = 'onloan';
             }
 
index 8a82df7..031e361 100755 (executable)
@@ -47,6 +47,7 @@ use C4::Auth;
 use C4::Serials;
 use C4::Output;
 use C4::Context;
+use C4::Branch;
 
 my $query         = new CGI;
 my $title         = $query->param('title_filter');
@@ -99,6 +100,7 @@ if ($searched){
 if ($routing) {
     for my $subscription ( @subscriptions) {
         $subscription->{routingedit} = check_routing( $subscription->{subscriptionid} );
+        $subscription->{branchname} = GetBranchName ( $subscription->{branchcode} );
     }
 }
 
index 9acee7b..0a33875 100755 (executable)
@@ -34,7 +34,7 @@ use Carp;
 
 #use Smart::Comments;
 
-my $query = CGI->new;
+our $query = CGI->new;
 my $op = $query->param('op') || '';
 my $dbh = C4::Context->dbh;
 my $sub_length;
@@ -64,7 +64,6 @@ my @sub_type_data;
 
 my $subs;
 my $firstissuedate;
-my $nextexpected;
 
 if ($op eq 'modify' || $op eq 'dup' || $op eq 'modsubscription') {
 
@@ -89,7 +88,7 @@ if ($op eq 'modify' || $op eq 'dup' || $op eq 'modsubscription') {
           $subs->{letter}= q{};
       }
     letter_loop($subs->{'letter'}, $template);
-    $nextexpected = GetNextExpected($subscriptionid);
+    my $nextexpected = GetNextExpected($subscriptionid);
     $nextexpected->{'isfirstissue'} = $nextexpected->{planneddate}->output('iso') eq $firstissuedate ;
     $subs->{nextacquidate} = $nextexpected->{planneddate}->output()  if($op eq 'modify');
     unless($op eq 'modsubscription') {
@@ -113,6 +112,12 @@ if ($op eq 'modify' || $op eq 'dup' || $op eq 'modsubscription') {
                     firstacquiyear => substr($firstissuedate,0,4),
                     );
     }
+
+    if ( $op eq 'dup' ) {
+        my $dont_copy_fields = C4::Context->preference('SubscriptionDuplicateDroppedInput');
+        my @fields_id = map { fieldid => $_ }, split '\|', $dont_copy_fields;
+        $template->param( dont_export_field_loop => \@fields_id );
+    }
 }
 
 my $onlymine=C4::Context->preference('IndependantBranches') &&
@@ -326,6 +331,7 @@ sub redirect_mod_subscription {
        my $opacdisplaycount = $query->param('opacdisplaycount');
     my $graceperiod     = $query->param('graceperiod') || 0;
     my $location = $query->param('location');
+    my $nextexpected = GetNextExpected($subscriptionid);
        #  If it's  a mod, we need to check the current 'expected' issue, and mod it in the serials table if necessary.
     if ( $nextacquidate ne $nextexpected->{planneddate}->output('iso') ) {
         ModNextExpected($subscriptionid,C4::Dates->new($nextacquidate,'iso'));
diff --git a/services/itemrecorddisplay.pl b/services/itemrecorddisplay.pl
new file mode 100755 (executable)
index 0000000..cd5fb32
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+
+# Copyright 2011 BibLibre SARL
+# 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.
+#
+# 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.
+
+=head1 NAME
+
+itemrecorddisplay.pl
+
+=head1 DESCRIPTION
+
+Return a HTML form for Item record modification or creation.
+It uses PrepareItemrecordDisplay
+
+=cut
+
+use strict;
+use warnings;
+
+use CGI;
+use C4::Auth;
+use C4::Output;
+use C4::Items;
+
+my $input = new CGI;
+my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( {
+    template_name   => 'services/itemrecorddisplay.tmpl',
+    query           => $input,
+    type            => 'intranet',
+    authnotrequired => 1,
+} );
+
+my $biblionumber = $input->param('biblionumber') || '';
+my $itemnumber = $input->param('itemnumber') || '';
+my $frameworkcode = $input->param('frameworkcode') || '';
+
+my $result = PrepareItemrecordDisplay($biblionumber, $itemnumber, undef, $frameworkcode);
+unless($result) {
+    $result = PrepareItemrecordDisplay($biblionumber, $itemnumber, undef, '');
+}
+
+$template->param(%$result);
+
+output_html_with_http_headers $input, $cookie, $template->output;
index 195011e..7f197d8 100755 (executable)
@@ -77,13 +77,13 @@ my $input           = CGI->new;
 my $suggestedbyme   = (defined $input->param('suggestedbyme')? $input->param('suggestedbyme'):1);
 my $op              = $input->param('op')||'else';
 my @editsuggestions = $input->param('edit_field');
-my $branchfilter   = $input->param('branchcode');
-my $suggestedby    = $input->param('suggestedby');
-my $returnsuggested = $input->param('returnsuggested');
+my $suggestedby     = $input->param('suggestedby');
 my $returnsuggestedby = $input->param('returnsuggestedby');
-my $managedby    = $input->param('managedby');
-my $displayby    = $input->param('displayby');
-my $tabcode    = $input->param('tabcode');
+my $returnsuggested = $input->param('returnsuggested');
+my $managedby       = $input->param('managedby');
+my $displayby       = $input->param('displayby') || '';
+my $branchfilter    = ($displayby ne "branchcode") ? $input->param('branchcode') : '';
+my $tabcode         = $input->param('tabcode');
 
 # filter informations which are not suggestion related.
 my $suggestion_ref  = $input->Vars;
@@ -189,21 +189,29 @@ if ($op=~/else/) {
     $op='else';
     
     $displayby||="STATUS";
+    delete $$suggestion_ref{'branchcode'} if($displayby eq "branchcode");
     my $criteria_list=GetDistinctValues("suggestions.".$displayby);
     my @allsuggestions;
     my $reasonsloop = GetAuthorisedValues("SUGGEST");
-    foreach my $criteriumvalue (map{$$_{'value'}} @$criteria_list){
+    foreach my $criteriumvalue ( map { $$_{'value'} } @$criteria_list ) {
+        # By default, display suggestions from current working branch
+        if(not defined $branchfilter) {
+            $$suggestion_ref{'branchcode'} = C4::Context->userenv->{'branch'};
+        }
         my $definedvalue = defined $$suggestion_ref{$displayby} && $$suggestion_ref{$displayby} ne "";
-        
-        next if ($definedvalue && $$suggestion_ref{$displayby} ne $criteriumvalue);
-        $$suggestion_ref{$displayby}=$criteriumvalue;
-#        warn $$suggestion_ref{$displayby}."=$criteriumvalue; $displayby";
-    
+
+        next if ( $definedvalue && $$suggestion_ref{$displayby} ne $criteriumvalue );
+        $$suggestion_ref{$displayby} = $criteriumvalue;
+
         my $suggestions = &SearchSuggestion($suggestion_ref);
-        foreach my $suggestion (@$suggestions){
-            if($suggestion->{budgetid}) {
-                my $budget = GetBudget($suggestion->{budgetid});
-                $suggestion->{budget_name}=$budget->{budget_name} if $budget;
+        foreach my $suggestion (@$suggestions) {
+            $suggestion->{budget_name} = GetBudget( $suggestion->{budgetid} )->{budget_name} if $suggestion->{budgetid};
+            foreach my $date qw(suggesteddate manageddate accepteddate) {
+                if ($suggestion->{$date} and $suggestion->{$date} ne "0000-00-00" && $suggestion->{$date} ne "" ) {
+                    $suggestion->{$date} = format_date( $suggestion->{$date} );
+                } else {
+                    $suggestion->{$date} = "";
+                }
             }
             foreach my $date ( qw(suggesteddate manageddate accepteddate) ){
                 if ($suggestion->{$date} ne "0000-00-00" && $suggestion->{$date} ne "" ){
@@ -272,8 +280,7 @@ foreach my $thisbranch ( sort {$branches->{$a}->{'branchname'} cmp $branches->{$
     my %row = (
         value      => $thisbranch,
         branchname => $branches->{$thisbranch}->{'branchname'},
-        selected   => ($branches->{$thisbranch}->{'branchcode'} eq $branchfilter)
-                    ||($branches->{$thisbranch}->{'branchcode'} eq $$suggestion_ref{'branchcode'})    
+        selected   => ($branchfilter and $branches->{$thisbranch}->{'branchcode'} eq $branchfilter ) || ( $$suggestion_ref{'branchcode'} and $branches->{$thisbranch}->{'branchcode'} eq $$suggestion_ref{'branchcode'} )
     );
     push @branchloop, \%row;
 }
@@ -283,14 +290,16 @@ $template->param( branchloop => \@branchloop,
                 branchfilter => $branchfilter);
 
 # the index parameter is different for item-level itemtypes
-my $supportlist=GetSupportList();                              
-foreach my $support(@$supportlist){
-    $$support{'selected'}= $$support{'itemtype'} eq $$suggestion_ref{'itemtype'};
-    if ($$support{'imageurl'}){
-        $$support{'imageurl'}= getitemtypeimagelocation( 'intranet', $$support{'imageurl'} );
-    }
-    else {
-    delete $$support{'imageurl'}
+my $supportlist = GetSupportList();
+
+foreach my $support (@$supportlist) {
+    $$support{'selected'} = (defined $$suggestion_ref{'itemtype'})
+        ? $$support{'itemtype'} eq $$suggestion_ref{'itemtype'}
+        : 0;
+    if ( $$support{'imageurl'} ) {
+        $$support{'imageurl'} = getitemtypeimagelocation( 'intranet', $$support{'imageurl'} );
+    } else {
+        delete $$support{'imageurl'};
     }
 }
 $template->param(itemtypeloop=>$supportlist);
@@ -314,7 +323,7 @@ foreach my $budget ( @{$budgets} ) {
 };
 
 $template->param( budgetsloop => $budgets);
-$template->param( "statusselected_$$suggestion_ref{'STATUS'}" =>1);
+$template->param( "statusselected_$$suggestion_ref{'STATUS'}" =>1) if ($$suggestion_ref{'STATUS'});
 
 # get currencies and rates
 my @rates = GetCurrencies();
@@ -347,14 +356,14 @@ $template->param(
 my %hashlists;
 foreach my $field ( qw(managedby acceptedby suggestedby budgetid) ) {
     my $values_list;
-    $values_list=GetDistinctValues("suggestions.".$field) ;
-    my @codes_list = map{
-                        { 'code'=>$$_{'value'},
-                        'desc'=>GetCriteriumDesc($$_{'value'},$field),
-                        'selected'=> $$_{'value'} eq $$suggestion_ref{$field}
-                        }
-                    } @$values_list;
-    $hashlists{lc($field)."_loop"}=\@codes_list;
+    $values_list = GetDistinctValues( "suggestions." . $field );
+    my @codes_list = map {
+        {   'code' => $$_{'value'},
+            'desc' => GetCriteriumDesc( $$_{'value'}, $field ),
+            'selected' => ($$suggestion_ref{$field}) ? $$_{'value'} eq $$suggestion_ref{$field} : 0,
+        }
+    } @$values_list;
+    $hashlists{ lc($field) . "_loop" } = \@codes_list;
 }
 $template->param(%hashlists);
 $template->param(DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),);
index 6018502..c28a2dc 100755 (executable)
@@ -14,10 +14,10 @@ use English qw(-no_match_vars);
 
 my @all_koha_dirs = qw( acqui admin authorities basket C4 catalogue cataloguing circ debian errors
 labels members misc offline_circ opac patroncards reports reserve reviews rotating_collections
-serials sms suggestion t tags test tools virtualshelves);
+serials sms suggestion t tags test tools virtualshelves Koha);
 
 my @dirs = qw( acqui admin authorities basket catalogue cataloguing circ debian errors labels
-    offline_circ reserve reviews rotating_collections serials sms virtualshelves );
+    offline_circ reserve reviews rotating_collections serials sms virtualshelves Koha);
 
 if ( not $ENV{TEST_QA} ) {
     my $msg = 'Author test. Set $ENV{TEST_QA} to a true value to run';
diff --git a/t/DateUtils.t b/t/DateUtils.t
new file mode 100755 (executable)
index 0000000..dbf38a6
--- /dev/null
@@ -0,0 +1,97 @@
+use strict;
+use warnings;
+use 5.010;
+use DateTime;
+use DateTime::TimeZone;
+
+use C4::Context;
+use Test::More tests => 25;
+
+BEGIN { use_ok('Koha::DateUtils'); }
+
+my $tz = C4::Context->tz;
+
+isa_ok( $tz, 'DateTime::TimeZone', 'Context returns timezone object' );
+
+my $testdate_iso = '2011-06-16';                   # Bloomsday 2011
+my $dt = dt_from_string( $testdate_iso, 'iso' );
+
+isa_ok( $dt, 'DateTime', 'dt_from_string returns a DateTime object' );
+
+cmp_ok( $dt->ymd(), 'eq', $testdate_iso, 'Returned object matches input' );
+
+$dt->set_hour(12);
+$dt->set_minute(0);
+
+my $date_string = output_pref( $dt, 'iso' );
+cmp_ok $date_string, 'eq', '2011-06-16 12:00', 'iso output';
+
+$date_string = output_pref( $dt, 'us' );
+cmp_ok $date_string, 'eq', '06/16/2011 12:00', 'us output';
+
+# metric should return the French Revolutionary Calendar Really
+$date_string = output_pref( $dt, 'metric' );
+cmp_ok $date_string, 'eq', '16/06/2011 12:00', 'metric output';
+
+$date_string = output_pref_due( $dt, 'metric' );
+cmp_ok $date_string, 'eq', '16/06/2011 12:00',
+  'output_pref_due preserves non midnight HH:SS';
+
+$dt->set_hour(23);
+$dt->set_minute(59);
+$date_string = output_pref_due( $dt, 'metric' );
+cmp_ok $date_string, 'eq', '16/06/2011',
+  'output_pref_due truncates HH:SS at midnight';
+
+my $dear_dirty_dublin = DateTime::TimeZone->new( name => 'Europe/Dublin' );
+my $new_dt = dt_from_string( '16/06/2011', 'metric', $dear_dirty_dublin );
+isa_ok( $new_dt, 'DateTime', 'Create DateTime with different timezone' );
+cmp_ok( $new_dt->ymd(), 'eq', $testdate_iso,
+    'Returned Dublin object matches input' );
+
+$new_dt = dt_from_string( '2011-06-16 12:00', 'sql' );
+isa_ok( $new_dt, 'DateTime', 'Create DateTime from (mysql) sql' );
+cmp_ok( $new_dt->ymd(), 'eq', $testdate_iso, 'sql returns correct date' );
+
+$new_dt = dt_from_string( $dt, 'iso' );
+isa_ok( $new_dt, 'DateTime', 'Passed a DateTime dt_from_string returns it' );
+
+# C4::Dates allowed 00th of the month
+
+my $ymd = '2012-01-01';
+my $dt0 = dt_from_string( '00/01/2012', 'metric' );
+isa_ok( $dt0, 'DateTime',
+    'dt_from_string returns a DateTime object passed a zero metric day' );
+cmp_ok( $dt0->ymd(), 'eq', $ymd, 'Returned object corrects metric day 0' );
+
+$dt0 = dt_from_string( '01/00/2012', 'us' );
+isa_ok( $dt0, 'DateTime',
+    'dt_from_string returns a DateTime object passed a zero us day' );
+cmp_ok( $dt0->ymd(), 'eq', $ymd, 'Returned object corrects us day 0' );
+
+$dt0 = dt_from_string( '2012-01-00', 'iso' );
+isa_ok( $dt0, 'DateTime',
+    'dt_from_string returns a DateTime object passed a zero iso day' );
+cmp_ok( $dt0->ymd(), 'eq', $ymd, 'Returned object corrects iso day 0' );
+
+# Return undef if passed mysql 0 dates
+$dt0 = dt_from_string( '0000-00-00', 'iso' );
+is( $dt0, undef, "undefined returned for 0 iso date" );
+
+my $formatted = format_sqldatetime( '2011-06-16 12:00:07', 'metric' );
+cmp_ok( $formatted, 'eq', '16/06/2011 12:00', 'format_sqldatetime conversion' );
+
+$formatted = format_sqldatetime( undef, 'metric' );
+cmp_ok( $formatted, 'eq', q{},
+    'format_sqldatetime formats undef as empty string' );
+
+$formatted = format_sqlduedatetime( '2011-06-16 12:00:07', 'metric' );
+cmp_ok(
+    $formatted, 'eq',
+    '16/06/2011 12:00',
+    'format_sqlduedatetime conversion for hourly loans'
+);
+
+$formatted = format_sqlduedatetime( '2011-06-16 23:59:07', 'metric' );
+cmp_ok( $formatted, 'eq', '16/06/2011',
+    'format_sqlduedatetime conversion for daily loans' );
index 198eaea..0e1f1c9 100755 (executable)
@@ -7,12 +7,16 @@ use strict;
 use warnings;
 
 use Test::More tests => 3;
+use C4::Context;
 
 BEGIN {
         use_ok('C4::Heading');
 }
 
-my $field = MARC::Field->new( '650', ' ', '0', a => 'Uncles', x => 'Fiction' );
-my $heading = C4::Heading->new_from_bib_field($field);
-is($heading->display_form(), 'Uncles--Fiction', 'Display form generation');
-is($heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation');
+SKIP: {
+    skip "MARC21 heading tests not applicable to UNIMARC", 2 if C4::Context->preference('marcflavour') eq 'UNIMARC';
+    my $field = MARC::Field->new( '650', ' ', '0', a => 'Uncles', x => 'Fiction' );
+    my $heading = C4::Heading->new_from_bib_field($field);
+    is($heading->display_form(), 'Uncles--Fiction', 'Display form generation');
+    is($heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation');
+}
diff --git a/t/Kalendar.t b/t/Kalendar.t
new file mode 100755 (executable)
index 0000000..f955231
--- /dev/null
@@ -0,0 +1,62 @@
+use strict;
+use warnings;
+use 5.010;
+use DateTime;
+use DateTime::TimeZone;
+
+use C4::Context;
+use Test::More tests => 9;
+
+BEGIN { use_ok('Koha::Calendar'); }
+
+my $cal = Koha::Calendar->new( TEST_MODE => 1 );
+
+isa_ok( $cal, 'Koha::Calendar', 'Calendar class returned' );
+
+my $saturday = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 25,
+    time_zone => 'Europe/London',
+);
+my $sunday = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 26,
+    time_zone => 'Europe/London',
+);
+my $monday = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 27,
+    time_zone => 'Europe/London',
+);
+my $bloomsday = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 16,
+    time_zone => 'Europe/London',
+);    # should be a holiday
+my $special = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 1,
+    time_zone => 'Europe/London',
+);    # should be a holiday
+my $notspecial = DateTime->new(
+    year      => 2011,
+    month     => 6,
+    day       => 2,
+    time_zone => 'Europe/London',
+);    # should NOT be a holiday
+is( $cal->is_holiday($sunday), 1, 'Sunday is a closed day' );   # wee free test;
+is( $cal->is_holiday($monday),     0, 'Monday is not a closed day' );    # alas
+is( $cal->is_holiday($bloomsday),  1, 'month/day closed day test' );
+is( $cal->is_holiday($special),    1, 'special closed day test' );
+is( $cal->is_holiday($notspecial), 0, 'open day test' );
+
+my $dt = $cal->addDate( $saturday, 1, 'days' );
+is( $dt->day_of_week, 1, 'addDate skips closed Sunday' );
+
+$dt = $cal->addDate( $bloomsday, -1 );
+cmp_ok( $dt->ymd(), 'cmp', '2011-06-15', 'Negative call to addDate' );
index a50f81e..a0ac90e 100755 (executable)
@@ -9,7 +9,7 @@ use strict;
 use warnings;
 use C4::Context;
 
-use Test::More tests => 92;
+use Test::More tests => 82;
 
 # Getting some borrowers from database.
 my $dbh = C4::Context->dbh;
@@ -66,7 +66,8 @@ use_ok('C4::VirtualShelves');
 # creating 10 good shelves.
 my @shelves;
 for(my $i=0; $i<10;$i++){
-     my $ShelfNumber = AddShelf("Shelf_".$i,$borrowers[$i] || '',int(rand(3))+1);
+     my $ShelfNumber = AddShelf(
+       {shelfname=>"Shelf_".$i, category=>int(rand(2))+1 }, $borrowers[$i] );
      die "test Not ok, remove some shelves before" if ($ShelfNumber == -1);
      ok($ShelfNumber > -1, "created shelf");   # Shelf creation successful;
      push @shelves, $ShelfNumber if $ShelfNumber > -1;
@@ -76,7 +77,9 @@ ok(10 == scalar @shelves, 'created 10 lists'); # 10 shelves in @shelves;
 
 # try to create some shelf which already exists.
 for(my $i=0;$i<10;$i++){
-    my $badNumShelf = AddShelf("Shelf_".$i,$borrowers[$i] || '','');
+    my @shlf=GetShelf($shelves[$i]);
+    my $badNumShelf = AddShelf(
+       {shelfname=>"Shelf_".$i, category=>$shlf[3] }, $borrowers[$i]);
     ok(-1 == $badNumShelf, 'do not create lists with duplicate names');   # AddShelf returns -1 if name already exist.
 }
 
@@ -94,7 +97,7 @@ for(my $i=0; $i<10;$i++){
     my $should_fail = exists($used{$key}) ? 1 : 0;
  
     my ($biblistBefore,$countbefore) = GetShelfContents($shelfnumber);
-    my $status = AddToShelf($bib,$shelfnumber);
+    my $status = AddToShelf($bib,$shelfnumber,$borrowers[$i]);
     my ($biblistAfter,$countafter) = GetShelfContents($shelfnumber);
 
     if ($should_fail) {
@@ -121,15 +124,13 @@ for(my $i=0; $i<10;$i++){
     my $rand = int(rand(9));
     my $numA = $shelves[$rand];
     my $shelf = { shelfname => "NewName_".$rand,
-       owner => $borrowers[$rand],
-       category =>  int(rand(3))+1 };
+       category =>  int(rand(2))+1 };
     
     ModShelf($numA,$shelf);
     my ($numB,$nameB,$ownerB,$categoryB) = GetShelf($numA);
     
     ok($numA == $numB, 'modified shelf');
     ok($shelf->{shelfname} eq $nameB,     '... and name change took');
-    ok($shelf->{owner}     eq $ownerB,    '... and owner change took');
     ok($shelf->{category}  eq $categoryB, '... and category change took');
 }
 
diff --git a/t/db_dependent/rollingloans.t b/t/db_dependent/rollingloans.t
new file mode 100644 (file)
index 0000000..55fa58b
--- /dev/null
@@ -0,0 +1,53 @@
+
+use strict;
+use warnings;
+use 5.010;
+use C4::Context;
+use C4::Circulation;
+use C4::Members;
+use C4::Items;
+
+use Test::More tests => 8;
+C4::Context->_new_userenv(1234567);
+C4::Context->set_userenv(91, 'CLIstaff', '23529001223661', 'CPL',
+                         'CPL', 'CPL', '', 'cc@cscnet.co.uk');
+
+
+my $test_patron = '23529001223651';
+my $test_item_fic = '502326000402';
+my $test_item_24 = '502326000404';
+my $test_item_48 = '502326000403';
+
+my $borrower1 =  GetMember(cardnumber => $test_patron);
+my $item1 = GetItem (undef,$test_item_fic);
+
+SKIP: {
+    skip 'Missing test borrower or item, skipping tests', 8
+      unless ( defined $borrower1 && defined $item1 );
+
+    for my $item_barcode ( $test_item_fic, $test_item_24, $test_item_48 ) {
+        my $duedate = try_issue( $test_patron, $item_barcode );
+        isa_ok( $duedate, 'DateTime' );
+        if ( $item_barcode eq $test_item_fic ) {
+            is( $duedate->hour(),   23, "daily loan hours = 23" );
+            is( $duedate->minute(), 59, "daily loan mins = 59" );
+        }
+        my $ret_ok = try_return($item_barcode);
+        is( $ret_ok, 1, 'Return succeeded' );
+    }
+}
+
+sub try_issue {
+    my ($cardnumber, $item ) = @_;
+    my $issuedate = '2011-05-16';
+    my $borrower = GetMemberDetails(0, $cardnumber);
+    my ($issuingimpossible,$needsconfirmation) = CanBookBeIssued( $borrower, $item );
+       my $due_date = AddIssue($borrower, $item, undef, 0, $issuedate);
+    return $due_date;
+}
+
+sub try_return {
+    my $barcode = shift;
+    my ($ret, $messages, $iteminformation, $borrower) = AddReturn($barcode);
+    return $ret;
+}
index 4fde0f2..0b37c20 100755 (executable)
@@ -40,6 +40,7 @@ use C4::Output;
 use C4::Dates qw/format_date format_date_in_iso/;
 use C4::Members;        # GetBorrowersWhoHavexxxBorrowed.
 use C4::Circulation;    # AnonymiseIssueHistory.
+use C4::VirtualShelves (); #no import
 use Date::Calc qw/Today Add_Delta_YM/;
 
 my $cgi = new CGI;
@@ -117,13 +118,15 @@ if ( $params->{'step3'} ) {
             my $i;
             for ( $i = 0 ; $i < $totalDel ; $i++ ) {
                 MoveMemberToDeleted( $membersToDelete->[$i]->{'borrowernumber'} );
+                C4::VirtualShelves::HandleDelBorrower($membersToDelete->[$i]->{'borrowernumber'});
                 DelMember( $membersToDelete->[$i]->{'borrowernumber'} );
             }
         }
         else {    # delete completly.
             my $i;
             for ( $i = 0 ; $i < $totalDel ; $i++ ) {
-               DelMember($membersToDelete->[$i]->{'borrowernumber'});
+                C4::VirtualShelves::HandleDelBorrower($membersToDelete->[$i]->{'borrowernumber'});
+                DelMember($membersToDelete->[$i]->{'borrowernumber'});
             }
         }
         $template->param(
index eb9d6a6..44f21ab 100755 (executable)
@@ -85,17 +85,17 @@ sub protected_letters {
     return { map { $_->[0] => 1 } @{$codes} };
 }
 
-my $input       = new CGI;
+our $input       = new CGI;
 my $searchfield = $input->param('searchfield');
 my $script_name = '/cgi-bin/koha/tools/letter.pl';
-my $branchcode  = $input->param('branchcode');
+our $branchcode  = $input->param('branchcode');
 my $code        = $input->param('code');
 my $module      = $input->param('module');
 my $content     = $input->param('content');
 my $op          = $input->param('op') || '';
 my $dbh = C4::Context->dbh;
 
-my ( $template, $borrowernumber, $cookie, $staffflags ) = get_template_and_user(
+our ( $template, $borrowernumber, $cookie, $staffflags ) = get_template_and_user(
     {
         template_name   => 'tools/letter.tmpl',
         query           => $input,
@@ -106,7 +106,7 @@ my ( $template, $borrowernumber, $cookie, $staffflags ) = get_template_and_user(
     }
 );
 
-my $my_branch = C4::Context->preference("IndependantBranches") && !$staffflags->{'superlibrarian'}
+our $my_branch = C4::Context->preference("IndependantBranches") && !$staffflags->{'superlibrarian'}
   ?  C4::Context->userenv()->{'branch'}
   : undef;
 # we show only the TMPL_VAR names $op
index 34d2639..cc22aeb 100755 (executable)
@@ -42,7 +42,7 @@ my $script_name = "/cgi-bin/koha/tools/manage-marc-import.pl";
 my $input = new CGI;
 my $op = $input->param('op') || '';
 my $completedJobID = $input->param('completedJobID');
-my $runinbackground = $input->param('runinbackground');
+our $runinbackground = $input->param('runinbackground');
 my $import_batch_id = $input->param('import_batch_id') || '';
 
 # record list displays
@@ -60,7 +60,7 @@ my ($template, $loggedinuser, $cookie)
 
 my %cookies = parse CGI::Cookie($cookie);
 my $sessionID = $cookies{'CGISESSID'}->value;
-my $dbh = C4::Context->dbh;
+our $dbh = C4::Context->dbh;
 
 # Frameworks selection loop
 {
@@ -433,11 +433,11 @@ sub batch_info {
             $template->param('current_matcher_description' => $matcher->description());
         }
     }
-    add_matcher_list($batch->{'matcher_id'});
+    add_matcher_list($template,$batch->{'matcher_id'});
 }
 
 sub add_matcher_list {
-    my $current_matcher_id = shift;
+    my ($template,$current_matcher_id) = @_;
     my @matchers = C4::Matcher::GetMatcherList();
     if (defined $current_matcher_id) {
         for (my $i = 0; $i <= $#matchers; $i++) {
index d520b4d..b705f5c 100755 (executable)
@@ -46,7 +46,7 @@ if ($auth_status ne "ok") {
     exit 0;
 }
 
-my $uploaded_file = C4::UploadedFile->new($sessionID);
+our $uploaded_file = C4::UploadedFile->new($sessionID);
 unless (defined $uploaded_file) {
     # FIXME - failed to create file for some reason
     send_reply('failed', '');
@@ -54,8 +54,6 @@ unless (defined $uploaded_file) {
 }
 $uploaded_file->max_size($ENV{'CONTENT_LENGTH'}); # may not be the file size, exactly
 
-my $first_chunk = 1;
-
 my $query;
 $query = new CGI \&upload_hook;
 $uploaded_file->done();
@@ -68,9 +66,8 @@ exit 0;
 sub upload_hook {
     my ($file_name, $buffer, $bytes_read, $session) = @_;
     $uploaded_file->stash(\$buffer, $bytes_read);
-    if ($first_chunk) {
+    if ( ! $uploaded_file->name && $file_name ) { # save name on first chunk
         $uploaded_file->name($file_name);
-        $first_chunk = 0;
     }
 }
 
index 1dbffbb..0927622 100755 (executable)
 =cut
 
 use strict;
-#use warnings; FIXME - Bug 2505
-use C4::Biblio;
+use warnings;
+
 use CGI;
+use C4::Biblio;
 use C4::Output;
-use C4::VirtualShelves qw/:DEFAULT GetRecentShelves/;
-use C4::Circulation;
+use C4::VirtualShelves qw/:DEFAULT GetAllShelves/;
 use C4::Auth;
 
-# splits incoming biblionumber(s) to array and adds each to shelf.
-sub AddBibliosToShelf {
-    my ($shelfnumber,@biblionumber)=@_;
-
-    # multiple bibs might come in as '/' delimited string (from where, i don't see), or as array.
-    # (Note : they come in as '/' when added from the cart)
-    if (scalar(@biblionumber) == 1) {
-        @biblionumber = (split /\//,$biblionumber[0]);
-    }
-    for my $bib (@biblionumber){
-        AddToShelf($bib, $shelfnumber);
-    }
-}
 
 my $query           = new CGI;
-
-# If set, then single item case.
-my $biblionumber    = $query->param('biblionumber');
-
-# If set, then multiple item case.
-my @biblionumber   = $query->param('biblionumber');
-my $biblionumbers   = $query->param('biblionumbers');
-
+my @biblionumber    = HandleBiblioPars();
 my $shelfnumber     = $query->param('shelfnumber');
 my $newvirtualshelf = $query->param('newvirtualshelf');
 my $newshelf        = $query->param('newshelf');
 my $category        = $query->param('category');
 my $sortfield      = $query->param('sortfield');
 my $confirmed       = $query->param('confirmed') || 0;
-
+my $authorized      = 1;
+my $errcode        = 0;
 
 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     {
@@ -108,120 +89,122 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     }
 );
 
-my @biblionumbers;
-if ($biblionumbers) {
-    @biblionumbers = split '/', $biblionumbers;
-} else {
-    @biblionumbers = (@biblionumber);
+if( $newvirtualshelf) {
+    HandleNewVirtualShelf();
+    exit if $authorized;
+    ShowTemplate(); #error message
+}
+elsif($shelfnumber && $confirmed) {
+    HandleShelfNumber();
+    exit if $authorized;
+    ShowTemplate(); #error message
+}
+elsif($shelfnumber) { #still needs confirmation
+    HandleSelectedShelf();
+    LoadBib() if $authorized;
+    ShowTemplate();
 }
-if (scalar(@biblionumber) == 1) {
-        @biblionumber = (split /\//,$biblionumber[0]);
+else {
+    HandleSelect();
+    LoadBib();
+    ShowTemplate();
 }
+#end
 
-$shelfnumber = AddShelf( $newvirtualshelf, $loggedinuser, $category, $sortfield ) if $newvirtualshelf;
-if ( $shelfnumber || ( $shelfnumber == -1 ) ) {    # the shelf already exist.
-
-    if ($confirmed == 1) {
-       AddBibliosToShelf($shelfnumber,@biblionumber);
-       print
-    "Content-Type: text/html\n\n<html><body onload=\"window.opener.location.reload(true);window.close()\"></body></html>";
-       exit;
-    } else {
-       my ( $singleshelf, $singleshelfname, $singlecategory ) = GetShelf( $query->param('shelfnumber') );
-       my @biblios;
-        for my $bib (@biblionumber) {
-           my $data = GetBiblioData( $bib );
-            push(@biblios,
-                        { biblionumber => $bib,
-                          title        => $data->{'title'},
-                          author       => $data->{'author'},
-                        } );
-        }
-
-               $template->param
-        (
-         biblionumber => \@biblionumber,
-         biblios      => \@biblios,
-         multiple     => (scalar(@biblionumber) > 1),
-         singleshelf  => 1,
-         shelfname    => $singleshelfname,
-         shelfnumber  => $singleshelf,
-         total        => scalar(@biblionumber),
-         confirm      => 1,
-        );
+sub HandleBiblioPars {
+    my @bib= $query->param('biblionumber');
+    if(@bib==0 && $query->param('biblionumbers')) {
+        my $str= $query->param('biblionumbers');
+        @bib= split '/', $str;
+    }
+    elsif(@bib==1 && $bib[0]=~/\//) {
+        @bib= split '/', $bib[0];
+    }
+    return @bib;
+}
+
+sub AddBibliosToShelf {
+    my ($shelfnumber, @biblionumber)=@_;
+    for my $bib (@biblionumber){
+        AddToShelf($bib, $shelfnumber, $loggedinuser);
+    }
+}
+
+sub HandleNewVirtualShelf {
+    $shelfnumber = AddShelf( {
+        shelfname => $newvirtualshelf,
+        sortfield => $sortfield,
+        category => $category }, $loggedinuser);
+    if($shelfnumber == -1) {
+        $authorized=0;
+        $errcode=1; #add failed
+        return;
     }
+    AddBibliosToShelf($shelfnumber, @biblionumber);
+    #Reload the page where you came from
+    print $query->header;
+    print "<html><meta http-equiv=\"refresh\" content=\"0\" /><body onload=\"window.opener.location.reload(true);self.close();\"></body></html>";
 }
-else {    # this shelf doesn't already exist.
-#    my $limit = 10;
-    my ($shelflist);
-    my @shelvesloop;
-    my %shelvesloop;
-
-    #grab each type of shelf, open (type 3) should not be limited by user.
-    foreach my $shelftype (1,2,3) {
-           my ($shelflist) = GetRecentShelves($shelftype, undef, $shelftype == 3 ? undef : $loggedinuser);
-           for my $shelf (@{ $shelflist }) {
-                   push(@shelvesloop, $shelf->{shelfnumber});
-                   $shelvesloop{$shelf->{shelfnumber}} = $shelf->{shelfname};
-           }
+
+sub HandleShelfNumber {
+    if($authorized= ShelfPossibleAction($loggedinuser, $shelfnumber, 'add')) {
+    AddBibliosToShelf($shelfnumber, @biblionumber);
+    #Close this page and return
+    print $query->header;
+    print "<html><meta http-equiv=\"refresh\" content=\"0\" /><body onload=\"self.close();\"></body></html>";
+    }
+    else {
+    $errcode=2; #no perm
     }
+}
 
-    if( @shelvesloop ){
-        my $CGIvirtualshelves = CGI::scrolling_list
-          (
-           -name     => 'shelfnumber',
-           -values   => \@shelvesloop,
-           -labels   => \%shelvesloop,
-           -size     => 1,
-           -tabindex => '',
-           -multiple => 0
-          );
-        $template->param
-          (
-           CGIvirtualshelves => $CGIvirtualshelves,
-          );
+sub HandleSelectedShelf {
+    if($authorized= ShelfPossibleAction( $loggedinuser, $shelfnumber, 'add')){
+        #confirm adding to specific shelf
+        my ($singleshelf, $singleshelfname, $singlecategory)= GetShelf($shelfnumber);
+        $template->param(
+        singleshelf               => 1,
+        shelfnumber               => $singleshelf,
+        shelfname                 => $singleshelfname,
+        "category$singlecategory" => 1
+        );
     }
-       my @biblios;
-        for my $bib (@biblionumber) {
-           my $data = GetBiblioData( $bib );
-            push(@biblios,
-                        { biblionumber => $bib,
-                          title        => $data->{'title'},
-                          author       => $data->{'author'},
-                        } );
-        }
+    else {
+    $errcode=2; #no perm
+    }
+}
+
+sub HandleSelect {
+    my $privateshelves = GetAllShelves(1,$loggedinuser,1);
+    my $publicshelves = GetAllShelves(2,$loggedinuser,1);
     $template->param(
-           newshelf     => $newshelf,
-          biblios=>\@biblios,
-           multiple     => (scalar(@biblionumber) > 1),
-           total        => scalar(@biblionumber),
+    privatevirtualshelves => $privateshelves,
+    publicvirtualshelves  => $publicshelves,
     );
+}
 
-    unless (@biblionumbers) {
-        my ( $bibliocount, @biblios ) = GetBiblio($biblionumber);
-    
-        $template->param
-          (
-           biblionumber      => $biblionumber,
-           title             => $biblios[0]->{'title'},
-           author            => $biblios[0]->{'author'},
-          );
-    } else {
-        my @biblioloop = ();
-        foreach my $biblionumber (@biblionumbers) {
-            my ( $bibliocount, @biblios ) = GetBiblio($biblionumber);
-            my %biblioiter = (
-                              title=>$biblios[0]->{'title'},
-                              author=>$biblios[0]->{'author'}
-                             );
-            push @biblioloop, \%biblioiter;
-        }
-        $template->param
-          (
-           biblioloop => \@biblioloop,
-           biblionumbers => $biblionumbers
-          );
+sub LoadBib {
+    my @biblios;
+    for my $bib (@biblionumber) {
+        my $data = GetBiblioData($bib);
+    push(@biblios,
+        { biblionumber => $bib,
+          title        => $data->{'title'},
+          author       => $data->{'author'},
+    } );
     }
-    
+    $template->param(
+        multiple => (scalar(@biblios) > 1),
+    total    => scalar @biblios,
+    biblios  => \@biblios,
+    );
+}
+
+sub ShowTemplate {
+    $template->param (
+    newshelf => $newshelf||0,
+    authorized => $authorized,
+    errcode            => $errcode,
+    );
+    output_html_with_http_headers $query, $cookie, $template->output;
 }
-output_html_with_http_headers $query, $cookie, $template->output;