Adding the Batch Create Tickets feature wiki macro to BH by merging the finalized changes on bep_0011_batch_create_tickets feature branch [1598681]:[1786358] into trunk

git-svn-id: https://svn.apache.org/repos/asf/bloodhound/trunk@1786396 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bloodhound_theme/bhtheme/tests/theme.py b/bloodhound_theme/bhtheme/tests/theme.py
index 2ec72fa..ebfca86 100644
--- a/bloodhound_theme/bhtheme/tests/theme.py
+++ b/bloodhound_theme/bhtheme/tests/theme.py
@@ -17,24 +17,14 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-from trac.test import EnvironmentStub, Mock, MockPerm
-from trac.util.datefmt import utc
+from trac.test import EnvironmentStub
 from trac.web.chrome import Chrome
-from trac.wiki.model import WikiPage
 
 from bhdashboard.web_ui import DashboardModule
-from bhtheme.theme import BloodhoundTheme, BatchCreateTicketsMacro, CreatedTicketsMacro
+from bhtheme.theme import BloodhoundTheme
 from bhtheme.tests import unittest
 
 
-try:
-    from babel import Locale
-
-    locale_en = Locale.parse('en_US')
-except ImportError:
-    locale_en = None
-
-
 class ThemeTestCase(unittest.TestCase):
 
     def setUp(self):
@@ -42,16 +32,6 @@
                                    default_data=True)
         self.bhtheme = BloodhoundTheme(self.env)
 
-        self.BatchCreateTicketsMacro = BatchCreateTicketsMacro(self.env)
-        self.CreatedTicketsMacro = CreatedTicketsMacro(self.env)
-
-        self.req = Mock(href=self.env.href, authname='anonymous', tz=utc,
-                        method='POST',
-                        args=dict(action='dummy'),
-                        locale=locale_en, lc_time=locale_en,
-                        chrome={'warnings': []})
-        self.req.perm = MockPerm()
-
     def tearDown(self):
         self.env.reset_db()
 
@@ -61,49 +41,6 @@
         for dir in self.bhtheme.get_templates_dirs():
             self.assertIn(dir, chrome.get_all_templates_dirs())
 
-    def test_batch_create(self):
-        with self.env.db_transaction as db:
-            db("CREATE TABLE bloodhound_product (prefix text,name text,description text,owner text,UNIQUE (prefix,name))")
-            db("INSERT INTO bloodhound_product VALUES ('my','product001','test product 001','anonymous')")
-        attr = {
-            'summary0': u's1',
-            'summary1': u's2',
-            'summary2': u's3',
-            'summary3': u's4',
-            'summary4': u's5',
-            'priority1': u'critical',
-            'priority0': u'blocker',
-            'priority3': u'minor',
-            'priority2': u'major',
-            'priority4': u'trivial',
-            'milestone0': u'milestone1',
-            'milestone1': u'milestone2',
-            'milestone2': u'milestone3',
-            'milestone3': u'milestone4',
-            'milestone4': u'milestone1',
-            'component4': u'component1',
-            'product4': u'my',
-            'product3': u'my',
-            'product2': u'my',
-            'product1': u'my',
-            'product0': u'my',
-            'component1': u'component2',
-            'component0': u'component1',
-            'component3': u'component2',
-            'component2': u'component1',
-            'description4': u'd5',
-            'description2': u'd3',
-            'description3': u'd4',
-            'description0': u'd1',
-            'description1': u'd2'}
-
-    def test_update_wiki_content(self):
-
-        w = WikiPage(self.env)
-        w.name = 'temp_page'
-        w.text = 'test the wiki replace function. ie: [[BatchCreateTickets(5)]] replaces with Created Tickets macro.'
-        WikiPage.save(w, 'anonymous', 'comment 01', '127.0.0.1')
-
 
 def suite():
     suite = unittest.TestSuite()
diff --git a/bloodhound_theme/bhtheme/theme.py b/bloodhound_theme/bhtheme/theme.py
index 5ef5135..9a12e59 100644
--- a/bloodhound_theme/bhtheme/theme.py
+++ b/bloodhound_theme/bhtheme/theme.py
@@ -17,27 +17,16 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-import random
-import re
-import string
 import sys
 
-from bhdashboard import wiki
-from bhdashboard.util import dummy_request
-from bhdashboard.web_ui import DashboardModule
-from bhtheme.translation import _, add_domain
 from genshi.builder import tag
 from genshi.core import TEXT
 from genshi.filters.transform import Transformer
 from genshi.output import DocType
-from multiproduct.env import ProductEnvironment
-from multiproduct.web_ui import PRODUCT_RE, ProductModule
-from pkg_resources import get_distribution
-from themeengine.api import ThemeBase, ThemeEngineSystem
+
 from trac.config import ListOption, Option
 from trac.core import Component, TracError, implements
 from trac.mimeview.api import get_mimetype
-from trac.perm import IPermissionRequestor
 from trac.resource import get_resource_url, Neighborhood, Resource
 from trac.ticket.api import TicketSystem
 from trac.ticket.model import Ticket, Milestone
@@ -45,15 +34,22 @@
 from trac.ticket.web_ui import TicketModule
 from trac.util.compat import set
 from trac.util.presentation import to_json
-from trac.util.translation import cleandoc_
 from trac.versioncontrol.web_ui.browser import BrowserModule
-from trac.web.api import IRequestFilter, ITemplateStreamFilter
+from trac.web.api import IRequestFilter, IRequestHandler, ITemplateStreamFilter
 from trac.web.chrome import (add_stylesheet, add_warning, INavigationContributor,
                              ITemplateProvider, prevnext_nav, Chrome, add_script)
-from trac.web.main import IRequestHandler
 from trac.wiki.admin import WikiAdmin
 from trac.wiki.formatter import format_to_html
-from trac.wiki.macros import WikiMacroBase
+
+from themeengine.api import ThemeBase, ThemeEngineSystem
+
+from bhdashboard.util import dummy_request
+from bhdashboard.web_ui import DashboardModule
+from bhdashboard import wiki
+
+from multiproduct.env import ProductEnvironment
+from multiproduct.web_ui import PRODUCT_RE, ProductModule
+from bhtheme.translation import _, add_domain
 
 try:
     from multiproduct.ticket.web_ui import ProductTicketModule
@@ -384,7 +380,7 @@
         self._modify_resource_breadcrumb(req, template, data, content_type,
                                          is_active)
 
-        # add a creation event to the changelog if the ticket exists
+        #add a creation event to the changelog if the ticket exists
         ticket = data['ticket']
         if ticket.exists:
             data['changes'] = [{'comment': '',
@@ -396,7 +392,7 @@
                                 'date': ticket['time'],
                                 },
                                ] + data['changes']
-        # and set default order
+        #and set default order
         if not req.session.get('ticket_comments_order'):
             req.session['ticket_comments_order'] = 'newest'
 
@@ -468,7 +464,7 @@
                 SELECT product, value FROM bloodhound_productconfig
                 WHERE product IN (%s) AND section='project' AND
                 option='icon'""" % ', '.join(["%s"] * len(products)),
-                               tuple(p.prefix for p in products))
+                tuple(p.prefix for p in products))
         icons = dict(icons)
         data['thumbsize'] = 64
         # FIXME: Gray icon for missing products
@@ -483,11 +479,11 @@
                                                    product_ctx(product),
                                                    product.description),
                         links={'extras': (([{'href': req.href.products(
-                            product.prefix, action='edit'),
-                            'title': _('Edit product %(prefix)s',
-                                       prefix=product.prefix),
-                            'icon': tag.i(class_='icon-edit'),
-                            'label': _('Edit')}, ]
+                                                product.prefix, action='edit'),
+                                             'title': _('Edit product %(prefix)s',
+                                                        prefix=product.prefix),
+                                             'icon': tag.i(class_='icon-edit'),
+                                             'label': _('Edit')},]
                                            if 'PRODUCT_MODIFY' in req.perm
                                            else []) +
                                           [{'href': product.href(),
@@ -523,7 +519,6 @@
                        tag.a(_('Source'),
                              href=req.href.wiki('TracRepositoryAdmin')))
 
-
 class QCTSelectFieldUpdate(Component):
     implements(IRequestHandler)
 
@@ -535,8 +530,8 @@
         fields_to_update = req.args.get('fields_to_update[]');
         env = ProductEnvironment(self.env.parent, req.args.get('product'))
         ticket_fields = TicketSystem(env).get_ticket_fields()
-        data = dict([f['name'], f['options']] for f in ticket_fields
-                    if f['type'] == 'select' and f['name'] in fields_to_update)
+        data = dict([f['name'], f['options']]  for f in ticket_fields
+            if f['type'] == 'select' and f['name'] in fields_to_update)
         req.send(to_json(data), 'application/json')
 
 
@@ -545,7 +540,7 @@
 
     qct_fields = ListOption('ticket', 'quick_create_fields',
                             'product, version, type',
-                            doc="""Multiple selection fields displayed in create ticket menu""",
+        doc="""Multiple selection fields displayed in create ticket menu""",
                             doc_domain='bhtheme')
 
     def __init__(self, *args, **kwargs):
@@ -596,7 +591,8 @@
                     dict(value=p,
                          new_ticket_url=dum_req.href.products(p, 'newticket'),
                          description=ProductEnvironment.lookup_env(self.env, p)
-                                                       .product.name)
+                                                       .product.name
+                    )
                 for p in product_field['options']
                     if req.perm.has_permission('TICKET_CREATE',
                                                Neighborhood('product', p)
@@ -614,7 +610,7 @@
                 'fields': [all_fields[k] for k in self.qct_fields
                            if k in all_fields],
                 'hidden_fields': [all_fields[k] for k in all_fields.keys()
-                                  if k not in self.qct_fields]}
+                                  if k not in self.qct_fields] }
         return template, data, content_type
 
     # IRequestHandler methods
@@ -691,457 +687,5 @@
                                    "of ticket #%s: %s" % (t.id, e))
         return t['product'], t.id
 
+from pkg_resources import get_distribution
 application_version = get_distribution('BloodhoundTheme').version
-
-
-class BatchCreateTicketsMacro(WikiMacroBase):
-    def parse_macro(self, parser, name, content):
-        pass
-
-    implements(
-        IRequestFilter,
-        IRequestHandler,
-        ITemplateStreamFilter,
-        IPermissionRequestor)
-    _description = cleandoc_(
-        """
-	Helps to create batch of tickets at once.
-
-	This macro accepts only one argument, which should be an integer value equal to the number of tickets that is going to 		create as a batch.
-
-	Example:
-	{{{
-    		[[BatchCreateTickets(5)]]    # This will create an empty table with 5 rows.
-	}}}
-
-	The empty table which will be created will contain the following tickets fields.
-	* `Summary` //(This field is mandatory.)//
-	* `Description`
-	* `Product`
-	* `Priority`
-	* `Milestone`
-	* `Component`
-
-	`BatchCreateTickets` has also make it possible to increase or decrease the size of the empty table created. After
-	filling 	the appropriate ticket fields you can create that batch of tickets and will be able to view the
-	details of the created 	tickets as a ticket table.
-    """)
-
-    bct_fields = ListOption(
-        'ticket',
-        'batch_create_fields',
-        'product, version, type',
-        doc="""Multiple selection fields displayed in create ticket menu""",
-        doc_domain='bhtheme')
-
-    def __init__(self, *args, **kwargs):
-        import pkg_resources
-        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
-        add_domain(self.env.path, locale_dir)
-        self.rows = 0
-        self.rqst = None
-        self.file = None
-        super(BatchCreateTicketsMacro, self).__init__(*args, **kwargs)
-
-    # IPermissionRequestor methods
-    def get_permission_actions(self):
-        return ['TICKET_BATCH_CREATE']
-
-    def expand_macro(self, formatter, name, args):
-        """Set the number of rows for empty ticket table to be generated.
-        Return none as the template will not changed at this point.
-
-        `name` is the actual name of the macro. (here it'll be
-        `'BatchCreateTickets'`),
-        `args` is the text enclosed in parenthesis at the call of the macro.
-          Note that if there are ''no'' parenthesis (like in, e.g.
-          [[BatchCreateTickets]]), then `args` is `None` and its not a valid argument.
-          Or if the argument is not a valid type(like in, e.g.
-          [[BatchCreateTickets("Hello")]] "Hello" is a string which can't be parsed to an integer)
-          then the bh will raise an error.
-        """
-        self.rows = args
-        # check the permission conditions and allow the feature only on wiki formatted pages.
-        if (
-                    self.env.product is not None) and (
-                            self.file == 'bh_wiki_view.html' or self.file == 'bh_wiki_edit.html' or self.file is None) and (
-                    self.rqst.perm.has_permission('TRAC_ADMIN') or self.rqst.perm.has_permission(
-                    'TICKET_BATCH_CREATE')):
-            # todo let the user select the product when creating tickets
-            # generate the required data to be parsed to the js functions too create the empty ticket table.
-
-            product_id = str(self.env.product.resource.id)
-            milestones = self.env.db_query(
-                "SELECT * FROM milestone WHERE product=%s", (product_id,))
-            components = self.env.db_query(
-                "SELECT * FROM component WHERE product=%s", (product_id,))
-
-            random_string = '%s%s' % ('-', ''.join(random.choice(string.lowercase) for i in range(10)))
-            form = tag.form(
-                tag.div(
-                    tag.span(
-                        tag.script(
-                            type="text/javascript",
-                            charset="utf-8",
-                            src=str(self.rqst.href.chrome('theme/js/batchcreate.js'))),
-                        tag.script(
-                            # pass the relevant arguments to the js function as JSON parameters.
-                            "emptyTable(" + to_json(str(self.rows)) + "," + to_json(self.env.product._data['name']) + "," +
-                            to_json(milestones) + "," + to_json(components) + "," +
-                            to_json(self.rqst.href() + "/bct") + "," +
-                            to_json(str(self.rqst.environ["HTTP_COOKIE"])) + "," +
-                            to_json(random_string) + ")",
-                            id="js-caller" + random_string,
-                            type="text/javascript"),
-                        class_="input-group-btn"),
-                    class_='report',
-                    id="div-empty-table" + random_string),
-                method="get",
-                style="display:inline",
-                id="batchcreate" + random_string)
-            try:
-                int(self.rows)
-            except TracError:
-                print "Enter  a valid argument (integer) to the BatchCreateTickets macro."
-
-            return form
-        else:
-            return None
-
-    # IRequestFilter(Interface):
-    def pre_process_request(self, req, handler):
-        """Nothing to do.
-        """
-        self.rqst = req
-        return handler
-
-    def post_process_request(self, req, template, data, content_type):
-        """Append necessary ticket data
-        """
-        try:
-            tm = self._get_ticket_module()
-        except TracError:
-            # no ticket module so no create ticket button
-            return template, data, content_type
-
-        if (template, data, content_type) != (None,) * 3:  # TODO: Check !
-            if data is None:
-                data = {}
-            dum_req = dummy_request(self.env)
-            dum_req.perm = req.perm
-            ticket = Ticket(self.env)
-            tm._populate(dum_req, ticket, False)
-            all_fields = dict([f['name'], f]
-                              for f in tm._prepare_fields(dum_req, ticket)
-                              if f['type'] == 'select')
-
-            product_field = all_fields.get('product')
-            if product_field:
-                # When at product scope, set the default selection to the
-                # product at current scope. When at global scope the default
-                # selection is determined by [ticket] default_product
-                if self.env.product and \
-                                self.env.product.prefix in product_field['options']:
-                    product_field['value'] = self.env.product.prefix
-                # Transform the options field to dictionary of product
-                # attributes and filter out products for which user doesn't
-                #  have TICKET_CREATE permission
-                product_field['options'] = [
-                    dict(value=p,
-                         new_ticket_url=dum_req.href.products(p, 'newticket'),
-                         description=ProductEnvironment.lookup_env(self.env, p)
-                         .product.name
-                         )
-                    for p in product_field['options']
-                    if req.perm.has_permission('TICKET_CREATE',
-                                               Neighborhood('product', p)
-                                               .child(None, None))]
-            else:
-                msg = _("Missing ticket field '%(field)s'.", field='product')
-                if ProductTicketModule is not None and \
-                                self.env[ProductTicketModule] is not None:
-                    # Display warning alert to users
-                    add_warning(req, msg)
-                else:
-                    # Include message in logs since this might be a failure
-                    self.log.warning(msg)
-            data['bct'] = {
-                'fields': [all_fields[k] for k in self.bct_fields
-                           if k in all_fields],
-                'hidden_fields': [all_fields[k] for k in all_fields.keys()
-                                  if k not in self.bct_fields]}
-        return template, data, content_type
-
-    # IRequestHandler methods
-
-    def match_request(self, req):
-        """Handle requests sent to /bct
-        """
-        m = PRODUCT_RE.match(req.path_info)
-        return req.path_info == '/bct' or \
-               (m and m.group('pathinfo').strip('/') == 'bct')
-
-    def process_request(self, req):
-
-        self.log.debug("BatchCreateTicketsModule: process_request entered")
-        """Forward new ticket request to `trac.ticket.web_ui.TicketModule`
-        but return plain text suitable for AJAX requests.
-        """
-        try:
-            tm = self._get_ticket_module()
-            req.perm.require('TICKET_BATCH_CREATE')
-
-            attrs = dict([k[6:], v] for k, v in req.args.iteritems()
-                         if k.startswith('field_'))
-            # new_tkts variable will contain the tickets that have been created as a batch
-            # that information will be used to load the resultant query table
-            product, tid, new_tkts = self.batch_create(
-                req, attrs, True)
-        except Exception as exc:
-            self.log.exception("BH: Batch create tickets failed %s" % (exc,))
-            req.send(str(exc), 'plain/text', 500)
-        else:
-            tkt_list = []
-            tkt_dict = {}
-            num_of_tkts = len(new_tkts)
-            for i in range(0, num_of_tkts):
-                tres = Neighborhood(
-                    'product',
-                    new_tkts[i].values['product'])(
-                    'ticket',
-                    tid -
-                    num_of_tkts +
-                    i +
-                    1)
-                href = req.href
-                tkt_list.append(
-                    to_json(
-                        {
-                            'product': new_tkts[i].values['product'],
-                            'id': tid - num_of_tkts + i + 1,
-                            'url': get_resource_url(
-                                self.env,
-                                tres,
-                                href),
-                            'summary': new_tkts[i].values['summary'],
-                            'status': new_tkts[i].values['status'],
-                            'milestone': new_tkts[i].values['milestone'],
-                            'component': new_tkts[i].values['component'],
-                            'priority': new_tkts[i].values['priority'],
-                            'description': new_tkts[i].values['description']}))
-
-            tkt_dict["tickets"] = tkt_list
-
-            self._update_wiki_content(num_of_tkts)
-
-            # send the HTTP POST request
-            req.send(to_json(tkt_dict), 'application/json')
-
-    # Public API
-    def _update_wiki_content(self, num_of_tkts):
-        """Editing the wiki content
-            After creating the tickets successfully the feature requires to display the details of the created tickets
-            within the wiki.
-            To do that at this point the wiki content will be updated.
-            ie. [[BatchCreateTickets(x)]] to [[CreatedTickets(start id,end id)]]
-            """
-        max_uid = self.env.db_query("SELECT MAX(uid) FROM ticket")
-        max_time = self.env.db_query("SELECT MAX(time) FROM wiki")
-        wiki_content = self.env.db_query(
-            "SELECT * FROM wiki WHERE time==%s", (max_time[0][0],))
-        wiki_string = wiki_content[0][5]
-        # regex pattern of the macro declaration.
-        pattern = '\[\[BatchCreateTickets\([0-9]+\)\]\]'
-        l = re.search(pattern, wiki_string)
-        l1 = str(wiki_string[l.regs[0][0]:l.regs[0][1]])
-        updated_wiki_content = wiki_string.replace(
-            l1, "[[CreatedTickets(" + str(max_uid[0][0] - num_of_tkts) + "," + str(max_uid[0][0]) + ")]]")
-        with self.env.db_transaction as db:
-            db("UPDATE wiki SET text=%s WHERE time=%s",
-               (updated_wiki_content, max_time[0][0]))
-        return None
-
-    def _get_ticket_module(self):
-        ptm = None
-        if ProductTicketModule is not None:
-            ptm = self.env[ProductTicketModule]
-        tm = self.env[TicketModule]
-        if not (tm is None) ^ (ptm is None):
-            raise TracError('Unable to load TicketModule (disabled)?')
-        if tm is None:
-            tm = ptm
-        return tm
-
-    # ITemplateStreamFilter methods
-    def filter_stream(self, req, method, filename, stream, data):
-        self.file = filename
-        return stream
-
-    # Public API
-    def batch_create(self, req, attributes={}, notify=False):
-        """ Create batch of tickets, returning created tickets.
-        """
-        num_of_tkts = attributes.__len__() / 5
-        created_tickets = []
-        loop_condition = True
-        i = -1
-        # iterate data row by row and create tickets using those user filled data fields.
-        while loop_condition:
-            if num_of_tkts <= 0:
-                loop_condition = False
-                break
-            i += 1
-
-            if 'summary' + str(i) not in attributes:
-                continue
-
-            if 'product' + str(i) in attributes:
-                env = self.env.parent or self.env
-                if attributes['product' + str(i)]:
-                    env = ProductEnvironment(
-                        env,
-                        attributes[
-                            'product' +
-                            str(i)])
-            else:
-                env = self.env
-            # If the summary field of a particular data row is empty skip creating that ticket.
-            if attributes.get('summary' + str(i)) == "":
-                num_of_tkts -= 1
-                continue
-
-            description = attributes.pop('description' + str(i))
-            status = 'new'
-            summary = attributes.pop('summary' + str(i))
-            priority = attributes.pop('priority' + str(i))
-            milestone = attributes.pop('milestone' + str(i))
-            component = attributes.pop('component' + str(i))
-
-            # Create the tickets using extracted data.
-            t = Ticket(env)
-            t['summary'] = summary
-            t['description'] = description
-            t['reporter'] = req.authname
-            t['status'] = status
-            t['resolution'] = ''
-            t['product'] = self.env.product._data['prefix']
-            t['priority'] = priority
-            t['milestone'] = milestone
-            t['component'] = component
-            # Insert the data into the DB.
-            t.insert()
-            created_tickets.append(t)
-
-            if notify:
-                try:
-                    tn = TicketNotifyEmail(env)
-                    tn.notify(t, newticket=True)
-                except Exception as e:
-                    self.log.exception(
-                        "Failure sending notification on creation "
-                        "of ticket #%s: %s" %
-                        (t.id, e))
-            num_of_tkts -= 1
-        return t['product'], t.id, created_tickets
-
-
-class CreatedTicketsMacro(WikiMacroBase):
-    implements(ITemplateStreamFilter)
-    _description = cleandoc_(
-        """
-	Helps to generate a ticket table within the wiki.
-
-	You can use this macro in order to display the details of a batch of tickets. `CreatedTickets` macro takes exactly
-	two integer arguments. The arguments defines the range of the tickets that will be displayed in the ticket table.
-
-	Example:
-	{{{
-	    [[CreatedTickets(10,15)]]    # This will create a ticket table with tickets which has id's between 10 and 15.
-	}}}
-    """)
-
-    def __init__(self, *args, **kwargs):
-        import pkg_resources
-        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
-        add_domain(self.env.path, locale_dir)
-        self.rqst = None
-        self.file = None
-        super(CreatedTicketsMacro, self).__init__(*args, **kwargs)
-
-    # Template Stream Filter methods
-    def filter_stream(self, req, method, filename, stream, data):
-        self.rqst = req
-        self.file = filename
-        return stream
-
-    def expand_macro(self, formatter, name, args):
-        """Set the number of rows for empty ticket table to be generated.
-        Return none as the template will not changed at this point.
-
-        `name` is the actual name of the macro. (here it'll be
-        `'BatchCreateTickets'`),
-        `args` is the text enclosed in parenthesis at the call of the macro.
-          Note that if there are ''no'' parenthesis (like in, e.g.
-          [[BatchCreateTickets]]), then `args` is `None` and its not a valid argument.
-          Or if the argument is not a valid type(like in, e.g.
-          [[BatchCreateTickets("Hello")]] "Hello" is a string which can't be parsed to an integer)
-          then the bh will raise an error.
-        """
-        if self.file == 'bh_wiki_view.html' or self.file == 'bh_wiki_edit.html' or self.file is None:
-            # Extract the macro arguments.
-            id_range = args.split(',')
-            start_id = int(id_range[0])
-            end_id = int(id_range[1])
-
-            display_tickets = self.env.db_query(
-                "SELECT id,summary,product,status,milestone,component FROM ticket WHERE uid>=%s and uid<=%s",
-                (start_id +
-                 1,
-                 end_id),
-            )
-            display_tickets_list = []
-            for i in range(0, end_id - start_id):
-                tres = Neighborhood(
-                    'product',
-                    display_tickets[i][2])(
-                    'ticket',
-                    display_tickets[i][0])
-                href = self.rqst.href
-                display_tickets_list.append(
-                    to_json(
-                        {
-                            'product': display_tickets[i][2],
-                            'id': display_tickets[i][0],
-                            'url': get_resource_url(
-                                self.env,
-                                tres,
-                                href),
-                            'summary': display_tickets[i][1],
-                            'status': display_tickets[i][3],
-                            'milestone': display_tickets[i][4],
-                            'component': display_tickets[i][5]
-                        }))
-
-            random_string = '%s%s' % ('-', ''.join(random.choice(string.lowercase) for i in range(10)))
-            # Send the ticket data to be displayed on the ticket table as JSON parameters.
-            form = tag.form(
-                tag.div(
-                    tag.span(
-                        tag.script(
-                            type='text/javascript',
-                            charset='utf-8',
-                            src=str(self.rqst.href.chrome('theme/js/batchcreate.js'))),
-                        tag.script(
-                            'display_created_tickets(' + to_json(display_tickets_list) + ',' +
-                            to_json(random_string) + ',' + to_json(self.env.product._data['name']) + ')',
-                            id='js-caller' + random_string,
-                            type='text/javascript'),
-                        class_='input-group-btn'),
-                    class_='report',
-                    id='div-created-ticket-table' + random_string),
-                method='get',
-                style='display:inline',
-                id='batchcreate' + random_string)
-            return form
-        else:
-            return None