diff --git a/CHANGES.rst b/CHANGES.rst index 971383301d..f48bcdce7c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Changelog ------------------ **Added** +- BC-99: Added Print Stickers button to AR listings - Issue-288: Worksheet: "Print" does not display/print partial results https://github.com/senaite/bika.lims/issues/288 diff --git a/bika/lims/browser/analysisrequest/analysisrequests.py b/bika/lims/browser/analysisrequest/analysisrequests.py index 4202b62e5f..21796afa2d 100644 --- a/bika/lims/browser/analysisrequest/analysisrequests.py +++ b/bika/lims/browser/analysisrequest/analysisrequests.py @@ -5,20 +5,13 @@ import json import traceback +from plone.api import user from DateTime import DateTime from Products.Archetypes import PloneMessageFactory as PMF from Products.CMFCore.permissions import ModifyPortalContent from Products.CMFCore.utils import getToolByName from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile -from collective.taskqueue.interfaces import ITaskQueue -from plone import api -from plone.app.layout.globals.interfaces import IViewView -from plone.protect import CheckAuthenticator -from plone.protect import PostOnly -from zope.component import queryUtility -from zope.interface import implements - from bika.lims import bikaMessageFactory as _ from bika.lims import logger from bika.lims.browser.analysisrequest.analysisrequests_filter_bar \ @@ -30,6 +23,12 @@ from bika.lims.permissions import Verify as VerifyPermission from bika.lims.utils import getUsers from bika.lims.utils import t +from collective.taskqueue.interfaces import ITaskQueue +from plone.app.layout.globals.interfaces import IViewView +from plone.protect import CheckAuthenticator +from plone.protect import PostOnly +from zope.component import queryUtility +from zope.interface import implements class AnalysisRequestsView(BikaListingView): @@ -228,7 +227,10 @@ def __init__(self, context, request): {'id': 'republish'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'Progress', 'getRequestID', @@ -269,7 +271,10 @@ def __init__(self, context, request): {'id': 'submit'}, {'id': 'cancel'}, ], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -306,7 +311,10 @@ def __init__(self, context, request): 'transitions': [{'id': 'preserve'}, {'id': 'cancel'}, ], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -341,7 +349,10 @@ def __init__(self, context, request): 'transitions': [{'id': 'sample'}, {'id': 'cancel'}, ], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -382,7 +393,10 @@ def __init__(self, context, request): {'id': 'receive'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -419,7 +433,10 @@ def __init__(self, context, request): 'transitions': [{'id': 'prepublish'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -458,7 +475,10 @@ def __init__(self, context, request): {'id': 'prepublish'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -495,7 +515,10 @@ def __init__(self, context, request): 'transitions': [{'id': 'publish'}, {'id': 'cancel'}, ], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -613,7 +636,10 @@ def __init__(self, context, request): 'sort_on': 'Created', 'sort_order': 'reverse'}, 'transitions': [], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns':['getRequestID', 'getSample', 'BatchID', @@ -659,7 +685,10 @@ def __init__(self, context, request): {'id': 'republish'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -707,7 +736,10 @@ def __init__(self, context, request): {'id': 'republish'}, {'id': 'cancel'}, {'id': 'reinstate'}], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['Priority', 'getRequestID', 'getSample', @@ -744,7 +776,10 @@ def __init__(self, context, request): 'sort_on': 'Created', 'sort_order': 'reverse'}, 'transitions': [], - 'custom_actions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['getRequestID', 'getSample', 'BatchID', @@ -1018,7 +1053,7 @@ def folderitem(self, obj, item, index): # Thee conditions to improve performance, some functions to check # the condition need to get the full analysis request. if states_dict.get('review_state', '') == 'to_be_verified': - allowed = api.user.has_permission( + allowed = user.has_permission( VerifyPermission, username=self.member.getUserName()) # TODO-performance: isUserAllowedToVerify getts all analysis diff --git a/bika/lims/browser/bika_listing.py b/bika/lims/browser/bika_listing.py index 18606ebf6b..7d71a9b2d3 100644 --- a/bika/lims/browser/bika_listing.py +++ b/bika/lims/browser/bika_listing.py @@ -150,6 +150,28 @@ def workflow_action_copy_to_new(self): self.request.response.redirect(url) return + def workflow_action_print_stickers(self): + """Invoked from AR or Sample listings in the current context, passing + the uids of the selected items and default sticker template as + request parameters to the stickers rendering machinery, that + generates the PDF + """ + uids = self.request.form.get("uids", []) + if not uids: + message = self.context.translate( + _("No ARs have been selected")) + self.context.plone_utils.addPortalMessage(message, 'info') + self.destination_url = self.context.absolute_url() + self.request.response.redirect(self.destination_url) + return + + url = '{0}/sticker?autoprint=1&template={1}&items={2}'.format( + self.context.absolute_url(), + self.portal.bika_setup.getAutoStickerTemplate(), + ','.join(uids) + ) + self.request.response.redirect(url) + def __call__(self): form = self.request.form plone.protect.CheckAuthenticator(form) diff --git a/bika/lims/browser/sample/view.py b/bika/lims/browser/sample/view.py index ef6c76b791..e1b2f44f51 100644 --- a/bika/lims/browser/sample/view.py +++ b/bika/lims/browser/sample/view.py @@ -190,7 +190,11 @@ def __init__(self, context, request): 'getDatePreserved', 'getPreserver', 'DateReceived', - 'state_title']}, + 'state_title'], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}],}, {'id': 'to_be_sampled', 'title': _('To be sampled'), 'contentFilter': {'review_state': ('to_be_sampled', @@ -213,6 +217,10 @@ def __init__(self, context, request): 'state_title'], 'transitions': [ {'id': 'schedule_sampling'}, {'id': 'sample'}], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], }, {'id': 'sample_due', 'title': _('Due'), @@ -263,7 +271,11 @@ def __init__(self, context, request): 'getSampler', 'getDatePreserved', 'getPreserver', - 'DateReceived']}, + 'DateReceived'], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}],}, {'id':'expired', 'title': _('Expired'), 'contentFilter':{'review_state':'expired', @@ -287,7 +299,11 @@ def __init__(self, context, request): 'getSampler', 'getDatePreserved', 'getPreserver', - 'DateReceived']}, + 'DateReceived'], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}],}, {'id':'disposed', 'title': _('Disposed'), 'contentFilter':{'review_state':'disposed', @@ -311,7 +327,11 @@ def __init__(self, context, request): 'getSampler', 'getDatePreserved', 'getPreserver', - 'DateReceived']}, + 'DateReceived'], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}],}, {'id':'cancelled', 'title': _('Cancelled'), 'contentFilter': {'cancellation_state': 'cancelled', @@ -344,6 +364,10 @@ def __init__(self, context, request): 'sort_order': 'reverse', 'sort_on': 'created'}, 'transitions': [], + 'custom_actions': [{ + 'id': 'print_stickers', + 'title': _('Print stickers'), + 'url': 'workflow_action?action=print_stickers'}], 'columns': ['getSampleID', 'Client', 'Creator', diff --git a/bika/lims/browser/templates/stickers_preview.pt b/bika/lims/browser/templates/stickers_preview.pt index 0f80e7f2c5..53eafd103d 100644 --- a/bika/lims/browser/templates/stickers_preview.pt +++ b/bika/lims/browser/templates/stickers_preview.pt @@ -135,6 +135,7 @@ $('#print-button').click(function(e) { e.preventDefault(); printPdf(); + window.location = $('#cancel-button').attr('data-url'); }); $('#cancel-button').click(function(e) { e.preventDefault(); @@ -188,14 +189,21 @@ '' + '' + ''; - $('body').html(form); - document.forms.topdf.submit(); + var pdfwindow = window.open(); + $(pdfwindow.document.body).html(form); + pdfwindow.document.forms.topdf.submit(); + } + + // If autoprint=1, render the pdf automatically + var autoprint = $.query.get('autoprint'); + if (autoprint == '1') { + printPdf(); + window.location = $('#cancel-button').attr('data-url'); } }); -
+