Example #1
0
 def __call__(self):
     registry = IOrderRegistry(self.context)
     order = registry.getOrder(
         self.request.SESSION.get(ORDER_SESSION_KEY, 0))
     return self.request.RESPONSE.redirect(
         '%s/@@checkout?checkout.stepid=%s' %
         (self.context.absolute_url(), max(order.processed_steps) + 1))
Example #2
0
def notifyDel(self, item):
    if item.has_key(ORDER_SESSION_KEY):
        try:
            site = getSite()
            app = self
            while not isinstance(app, Application):
                app = aq_parent(app)
            instances = _findInstances(app)
            for instance in instances:
                try:
                    _setSite(instance)
                    registry = IOrderRegistry(instance)
                    registry.cancel(item.get(ORDER_SESSION_KEY))
                except:
                    pass
        except:
            pass
        finally:
            try:
                if not site.REQUEST._lazies.has_key("SESSION"):
                    # add a lazy callable to the request to prevent KeyError
                    # as we might have a recursive call to HTTPRequest.get
                    # which will remove the before available lazy SESSION
                    # ZPublisher.HTTPRequest[1333:1339]
                    site.REQUEST.set_lazy("SESSION", lambda: 1)
                _setSite(site)
            except:
                pass
    TransientObjectContainer.__old__notifyDel(self, item)
Example #3
0
 def __call__(self):
     registry = IOrderRegistry(self.context)
     registry.fail(self.request.SESSION.get(ORDER_SESSION_KEY, 0))
     statusmessage = IStatusMessage(self.request)
     statusmessage.addStatusMessage(
         _('message_checkout_failed', default=u'Check out failed'), 'error')
     return self.request.RESPONSE.redirect('%s/@@cart' %
                                           self.context.absolute_url())
Example #4
0
 def __call__(self, orderid, failed=False):
     orderid = int(orderid)
     registry = IOrderRegistry(self.context)
     order = registry.getOrder(orderid)
     if order is not None and order.paymentid == "pcommerce.payment.invoice":
         order.paymentdata.state = failed and FAILED or SUCCESS
     processor = IPaymentProcessor(self.context)
     return processor.processOrder(orderid, "pcommerce.payment.invoice")
Example #5
0
 def __call__(self):
     registry = IOrderRegistry(self.context)
     order = registry.getOrder(
             self.request.SESSION.get(ORDER_SESSION_KEY, 0))
     return self.request.RESPONSE.redirect(
             '%s/@@checkout?checkout.stepid=%s' % (
                 self.context.absolute_url(),
                 max(order.processed_steps) + 1))
Example #6
0
 def __call__(self):
     registry = IOrderRegistry(self.context)
     registry.fail(self.request.SESSION.get(ORDER_SESSION_KEY, 0))
     statusmessage = IStatusMessage(self.request)
     statusmessage.addStatusMessage(_('message_checkout_failed',
         default=u'Check out failed'), 'error')
     return self.request.RESPONSE.redirect(
             '%s/@@cart' % self.context.absolute_url())
 def status_description(self):
     """ return the docdata status """
     orderId = self.form.get('form_id', '')
     orderId = int(orderId)
     registry = IOrderRegistry(self.context)
     order = registry.getOrder(orderId)
     status = order.paymentdata._payment_status
     status_description = _(status)
     return status_description
Example #8
0
    def __call__(self):
        self.request.set('disable_border', 1)
        self.errors = {}

        self.cart = IShoppingCart(self.context)

        if not len(self.cart):
            statusmessage = IStatusMessage(self.request)
            statusmessage.addStatusMessage(_(u'You have not yet added any '
                'products to your cart'), 'error')
            return self.request.RESPONSE.redirect('%s/@@cart' %
                    self.context.absolute_url())

        if self.request.form.get('checkout.cancel', None):
            return getMultiAdapter((self.context, self.request),
                    name=u'checkout.cancel')()

        self.stepid = int(self.request.form.get('checkout.stepid', 0))

        temp_state = None
        registry = IOrderRegistry(self.context)
        self.order = registry.getOrder(self.request.SESSION.get(
            ORDER_SESSION_KEY, 0))
        if self.order is not None and self.order.state != INITIALIZED:
            temp_state = self.order.state
            self.order.state = INITIALIZED

        self.order = IOrder(self.context)

        self._stepid_validator()

        if self.request.form.get('checkout.next') and \
            self.stepid < len(self.steps) - 1:
            self.next()
        elif self.request.form.get('checkout.previous') and self.stepid > 0:
            self.previous()
        elif self.request.get('stepid'):
            self.gotostep(int(self.request.get('stepid', 0)))

        if self.redirect is not None:
            return self.request.RESPONSE.redirect(self.redirect)

        html = self.template()

        if temp_state is not None:
            self.order.state = temp_state

        if self.laststep:
            registry = IOrderRegistry(self.context)
            registry.send(self.order.orderid)
            self.cart.clear()
        return html
Example #9
0
def migrate05a105a2(context):

    if context.readDataFile('pcommerce.core_migrate05a105a2.txt') is None:
        return
    
    portal = context.getSite()
    
    registry = IOrderRegistry(portal)
    for order in registry.getOrders().itervalues():
        if hasattr(order.paymentdata, 'shipmentid'):
            order.paymentdata.id = order.paymentdata.shipmentid
            delattr(order.paymentdata, 'shipmentid')
        for data in order.shipmentdata.values():
            if hasattr(data, 'shipmentid'):
                data.id = data.shipmentid
                delattr(data, 'shipmentid')
 def __call__(self, orderid, failed=False):
     orderid = int(orderid)
     registry = IOrderRegistry(self.context)
     order = registry.getOrder(orderid)
     if order is not None and order.paymentid == 'pcommerce.payment.invoice':
         pre_state = order.state
         order.paymentdata.state = FAILED if failed or pre_state is FAILED else SUCCESS
         processor = IPaymentProcessor(self.context)
         result = processor.processOrder(orderid, 'pcommerce.payment.invoice')
         msg = (_('Processing the order failed'), 'error')
         if pre_state is config.PROCESSED or pre_state is config.FAILED:
             msg = (_('Order already processed'), 'error')
         elif failed and order.state is config.FAILED:
             msg = (_('Order successfully canceled'), 'info')
         elif not failed and order.state is config.PROCESSED:
             msg = (_('Order successfully processed'), 'info')
         self.request.response.redirect('%s/order-details?order_id=%s' % (self.context.absolute_url(), orderid))
     else:
         msg = (_('Order not found'), 'error')
         self.request.response.redirect('%s/manage-orders' % self.context.absolute_url())
     IStatusMessage(self.request).add(*msg)
Example #11
0
 def products(self):
     if not hasattr(self, 'cart'):
         self.cart = IShoppingCart(self.context)
     order = None
     if self.request.SESSION.get(ORDER_SESSION_KEY, None) is not None:
         registry = IOrderRegistry(self.context)
         order = registry.getOrder(self.request.SESSION.get(ORDER_SESSION_KEY, 0))
         if order is not None:
             increaseStockFromOrder(registry, order)
     products = self.cart.getProducts()
     uid_catalog = getToolByName(self.context, 'uid_catalog')
     for product in products:
         provider = IStock(uid_catalog(UID=product['uid'])[0].getObject())
         if not len(product['variations']):
             product['stock'] = provider.stock()
         else:
             product['stock'] = provider.variationStock([uid_catalog(UID=v['uid'])[0].getObject() for v in product['variations']])
         product['outofstock'] = product['amount'] > product['stock']
         product['checkout_allowed'] = not product['outofstock'] or provider.outOfStockCheckoutAllowed()
     if order is not None:
         decreaseStockFromOrder(registry, order)
     return products
Example #12
0
    def verify_ipn(self, data):
        # prepares provided data set to inform PayPal we wish to validate the response
        data["cmd"] = "_notify-validate"
        params = urlencode(data)

        props = getToolByName(self.context,
                              'portal_properties').paypal_properties
        # sends the data and request to the PayPal Sandbox
        paypalurl = self.getPayPalURL()
        req = Request(paypalurl, params)
        req.add_header("Content-type", "application/x-www-form-urlencoded")
        # reads the response back from PayPal
        response = urlopen(req)
        status = response.read()
        # If not verified
        if not status == "VERIFIED":
            return False

        # if not the correct receiver ID
        if not data["receiver_id"] == props.receiver_id:
            return False

        # if not the correct currency
        if not data["mc_currency"] == "EUR":
            return False
        # already processed?
        order_registry = IOrderRegistry(self.context)
        order = order_registry.getOrder(int(data['item_number1']))
        try:
            if order.txn_id == data['txn_id']:
                logger.info(
                    "pcommerce.payment.paypal: Transaction already processed")
                return False
        except:
            order.txn_id = data['txn_id']
            transaction.commit()
        # otherwise...
        return True
Example #13
0
    def __call__(self):
        self.request.set('disable_border', 1)
        self.errors = {}

        self.cart = IShoppingCart(self.context)

        if not len(self.cart):
            statusmessage = IStatusMessage(self.request)
            statusmessage.addStatusMessage(
                _(u'You have not yet added any '
                  'products to your cart'), 'error')
            return self.request.RESPONSE.redirect('%s/@@cart' %
                                                  self.context.absolute_url())

        if self.request.form.get('checkout.cancel', None):
            return getMultiAdapter((self.context, self.request),
                                   name=u'checkout.cancel')()

        self.stepid = int(self.request.form.get('checkout.stepid', 0))

        temp_state = None
        registry = IOrderRegistry(self.context)
        self.order = registry.getOrder(
            self.request.SESSION.get(ORDER_SESSION_KEY, 0))
        if self.order is not None and self.order.state != INITIALIZED:
            temp_state = self.order.state
            self.order.state = INITIALIZED

        self.order = IOrder(self.context)

        self._stepid_validator()

        if self.request.form.get('checkout.next') and \
            self.stepid < len(self.steps) - 1:
            self.next()
        elif self.request.form.get('checkout.previous') and self.stepid > 0:
            self.previous()
        elif self.request.get('stepid'):
            self.gotostep(int(self.request.get('stepid', 0)))

        if self.redirect is not None:
            return self.request.RESPONSE.redirect(self.redirect)

        html = self.template()

        if temp_state is not None:
            self.order.state = temp_state

        if self.laststep:
            registry = IOrderRegistry(self.context)
            registry.send(self.order.orderid)
            self.cart.clear()
        return html
Example #14
0
 def __init__(self, *args, **kwargs):
     super(ManageOrders, self).__init__(*args, **kwargs)
     self.translation_service = getToolByName(self.context,
         'translation_service')
     self.registry = IOrderRegistry(self.context)
     self.pagesize = 20
     session = self.request.SESSION
     self.pagenumber = session.get(SESSION_KEY + 'pagenumber', 1)
     if self.request.get('pagenumber', None) is not None:
         self.pagenumber = int(self.request.get('pagenumber'))
         session.set(SESSION_KEY + 'pagenumber', self.pagenumber)
     self.sort_on = session.get(SESSION_KEY + 'sort_on', 1)
     self.reverse = session.get(SESSION_KEY + 'reverse', False)
     if not self.request.get('sort_on', None) in ('getObjPositionInParent', '', None):
         if self.request.get('sort_on', None) == self.sort_on:
             self.reverse = not self.reverse
         else:
             self.reverse = False
         self.sort_on = self.request.get('sort_on')
         session.set(SESSION_KEY + 'reverse', self.reverse)
         session.set(SESSION_KEY + 'sort_on', self.sort_on)
         self.request.set('sort_on', '')
     self.url = '%s/@@manage-orders' % self.context.absolute_url()
Example #15
0
    def verify_ipn(self,data):
        # prepares provided data set to inform PayPal we wish to validate the response
        data["cmd"] = "_notify-validate"
        params = urlencode(data)

        props = getToolByName(self.context, 'portal_properties').paypal_properties
        # sends the data and request to the PayPal Sandbox
        paypalurl = self.getPayPalURL()
        req = Request(paypalurl, params)
        req.add_header("Content-type", "application/x-www-form-urlencoded")
        # reads the response back from PayPal
        response = urlopen(req)
        status = response.read()
        # If not verified
        if not status == "VERIFIED":
            return False
 
        # if not the correct receiver ID
        if not data["receiver_id"] == props.receiver_id:
            return False
 
        # if not the correct currency
        if not data["mc_currency"] == "EUR":
            return False
        # already processed?
        order_registry = IOrderRegistry(self.context)
        order = order_registry.getOrder(int(data['item_number1']))
        try:
            if order.txn_id == data['txn_id']:
                logger.info("pcommerce.payment.paypal: Transaction already processed")
                return False
        except:
            order.txn_id = data['txn_id'] 
            transaction.commit() 
        # otherwise...
        return True
Example #16
0
 def __init__(self, *args, **kwargs):
     super(ManageOrders, self).__init__(*args, **kwargs)
     self.translation_service = getToolByName(self.context, 
         'translation_service')
     self.registry = IOrderRegistry(self.context)
     self.pagesize = 20
     session = self.request.SESSION
     self.pagenumber = session.get(SESSION_KEY + 'pagenumber', 1)
     if self.request.get('pagenumber', None) is not None:
         self.pagenumber = int(self.request.get('pagenumber'))
         session.set(SESSION_KEY + 'pagenumber', self.pagenumber)
     self.sort_on = session.get(SESSION_KEY + 'sort_on', 1)
     self.reverse = session.get(SESSION_KEY + 'reverse', False)
     if not self.request.get('sort_on', None) in ('getObjPositionInParent', '', None):
         if self.request.get('sort_on', None) == self.sort_on:
             self.reverse = not self.reverse
         else:
             self.reverse = False
         self.sort_on = self.request.get('sort_on')
         session.set(SESSION_KEY + 'reverse', self.reverse)
         session.set(SESSION_KEY + 'sort_on', self.sort_on)
         self.request.set('sort_on', '')
     self.url = '%s/@@manage-orders' % self.context.absolute_url()
Example #17
0
class ManageOrders(BrowserView):
    """Overview of all orders.
    """

    template = ViewPageTemplateFile('manage_orders.pt')
    batching = ViewPageTemplateFile(batchingfile)

    def __init__(self, *args, **kwargs):
        super(ManageOrders, self).__init__(*args, **kwargs)
        self.translation_service = getToolByName(self.context,
            'translation_service')
        self.registry = IOrderRegistry(self.context)
        self.pagesize = 20
        session = self.request.SESSION
        self.pagenumber = session.get(SESSION_KEY + 'pagenumber', 1)
        if self.request.get('pagenumber', None) is not None:
            self.pagenumber = int(self.request.get('pagenumber'))
            session.set(SESSION_KEY + 'pagenumber', self.pagenumber)
        self.sort_on = session.get(SESSION_KEY + 'sort_on', 1)
        self.reverse = session.get(SESSION_KEY + 'reverse', False)
        if not self.request.get('sort_on', None) in ('getObjPositionInParent', '', None):
            if self.request.get('sort_on', None) == self.sort_on:
                self.reverse = not self.reverse
            else:
                self.reverse = False
            self.sort_on = self.request.get('sort_on')
            session.set(SESSION_KEY + 'reverse', self.reverse)
            session.set(SESSION_KEY + 'sort_on', self.sort_on)
            self.request.set('sort_on', '')
        self.url = '%s/@@manage-orders' % self.context.absolute_url()

    def __call__(self):
        self.request.set('disable_border', 1)
        return self.template()

    def _translate_order_status_id(self, status_id):
        """
        """
        order_status_string = {
            1: _('label_initialized', default="Initialized"),
            2: _('label_sent', default="Sent"),
            3: _('label_processed', default="Processed"),
            4: _('label_failed', default="Failed"),
            5: _('label_cancelled', default="Cancelled"),
        }
        return order_status_string[status_id]

    def order_fields(self):
        """Fields and fieldnames to show in tables (order overviews / details).

            {   'field_id': '',
                'field_name': _("label_", default=""),
                'sortable': True
                },
        """
        fields = [
            {   'field_id': 'orderid',
                'field_name': _("label_order_id", default="Order id"),
                'sortable': True
                },
            {   'field_id': 'userid',
                'field_name': _("label_user_id", default="User id"),
                'sortable': True
                },
            {   'field_id': 'date',
                'field_name': _("label_date", default="Date"),
                'sortable': True
                },
            {   'field_id': 'currency',
                'field_name': _("label_currency", default="Currency"),
                'sortable': True
                },
            {   'field_id': 'totalincl',
                'field_name': _("label_price_total", default="Price total"),
                'field_converter': self._totalincl_converter,
                'sortable': True
                },
            {   'field_id': 'state',
                'field_name': _("label_order_state", default="Order status"),
                'sortable': True
                },
            {   'field_id': 'zone',
                'field_name': _("label_zone", default="Zone"),
                'field_converter': self._zone_converter,
                'sortable': True
                },
            {   'field_id': 'address',
                'field_name': _("label_address", default="Address"),
                'field_converter': self._address_converter,
                'sortable': True
                },
            {   'field_id': 'products',
                'field_name': _("label_products", default="Products"),
                'field_converter': self._products_converter,
                'sortable': False
                },
            {   'field_id': 'shipmentids',
                'field_name': _("label_shipmentids", default="Shipment id's"),
                'field_converter': self._shipmentids_converter,
                'sortable': False
                },
            ]
        return fields

    def _zone_converter(self, value, order):
        return '<strong>%s</strong> (%s%% %s)' % (value[0], value[1][0], value[1][1])

    def _totalincl_converter(self, value, order):
        return CurrencyAware(value).valueToString()

    def _address_converter(self, value, order):
        return '<pre>%s</pre>' % value.mailInfo(self.request)

    def _products_converter(self, value, order):
        rows = []
        for product in value:
            cells = [str(i) for i in product[1:5]]
            cells.append(str(product[3]*product[4]))
            rows.append('</td><td>'.join(cells))
        return '''
<table class="listing">
    <thead>
        <tr><th>%s</th></tr>
    </thead>
    <tbody>
        <tr><td>%s</td></tr>
    </tbody>
</table>''' % ('</th><th>'.join((translate(_(u'No'), context=self.request),
                                 translate(_(u'Product'), context=self.request),
                                 translate(_(u'Amount'), context=self.request),
                                 translate(_(u'Price'), context=self.request),
                                 translate(_(u'Price total'), context=self.request))), '</td></tr><tr><td>'.join(rows))

    def _shipmentids_converter(self, value, order):
        return '<ul><li>%s</li></ul>' % '</li><li>'.join(value.keys())

    def order_management_columns(self):
        """Fields for order management table. """
        field_ids = [
            'orderid',
            'userid',
            'date',
            'currency',
            'totalincl',
            'state',
            ]
        columns = [ column for column in self.order_fields() if \
            column['field_id'] in field_ids]
        return columns

    def _massageData(self, field_id, value):
        """Modify the field values (if needed) for displaying to humans. """
        # Convert the date (float) to a DateTime format.
        if field_id == 'date':
            value = DateTime(value)
            value = self.translation_service.ulocalized_time(
                value, long_format=True, time_only=None,
                context=self.context, domain='plonelocales',
                request=self.request)
        # Convert order status to a translated string
        if field_id == 'state':
            value = self._translate_order_status_id(value)
        return value

    def _get_order_data(self, order_nr, fields):
        """Returns data of a single order as as a list of dictionaries,
        suitable for displaying in a page template.

        Copies only the specified fields (which are defined like the
        _order_fields list of dicts above.

        [   {   'id':   ..., # field id
                'value: ..., # field value
                'name': ..., # field name (optional)
            },
        ]
        """
        r_order = self.registry.getOrder(order_nr)
        order_data = []
        sort = 0
        for field in fields:
            field_data = {}
            field_id = field['field_id']
            field_data['id'] = field_id
            value = getattr(r_order, field_id)
            if field_id == self.sort_on:
                sort = value
            if field.has_key('field_converter'):
                try:
                    value = field['field_converter'](value, r_order)
                except:
                    pass
            field_data['value'] = self._massageData(field_id, value)
            field_data['name'] = field['field_name']
            order_data.append(field_data)
        return order_data, sort

    @property
    def batch(self):
        """Returns data rows for order management table. """
        orders = []
        sorting = []
        # use only selected fields in the table
        columns = self.order_management_columns()
        for order_nr in self.registry.getOrders():
            data, sort = self._get_order_data(order_nr, columns)
            index = len(orders) - 1
            while index >= 0 and sort < sorting[index]:
                index -= 1
            sorting.insert(index + 1, sort)
            orders.insert(index + 1, data)
        if self.reverse:
            orders.reverse()
        pagesize = self.pagesize
        if NEW_BATCHING:
            b = Batch(orders,
                    size=pagesize,
                    start=self.pagenumber * pagesize)
        else:
            b = Batch(orders,
                    pagesize=pagesize,
                    pagenumber=self.pagenumber)
        return b
Example #18
0
 def __init__(self, *args, **kwargs):
     super(ManageOrders, self).__init__(*args, **kwargs)
     self.translation_service = getToolByName(self.context, 
         'translation_service')
     self.registry = IOrderRegistry(self.context)
Example #19
0
class ManageOrders(BrowserView):
    """Overview of all orders.
    """

    template = ViewPageTemplateFile('manage_orders.pt')
    batching = ViewPageTemplateFile(os.path.join(os.path.dirname(tableview.__file__), 'batching.pt'))

    def __init__(self, *args, **kwargs):
        super(ManageOrders, self).__init__(*args, **kwargs)
        self.translation_service = getToolByName(self.context, 
            'translation_service')
        self.registry = IOrderRegistry(self.context)
        self.pagesize = 20
        session = self.request.SESSION
        self.pagenumber = session.get(SESSION_KEY + 'pagenumber', 1)
        if self.request.get('pagenumber', None) is not None:
            self.pagenumber = int(self.request.get('pagenumber'))
            session.set(SESSION_KEY + 'pagenumber', self.pagenumber)
        self.sort_on = session.get(SESSION_KEY + 'sort_on', 1)
        self.reverse = session.get(SESSION_KEY + 'reverse', False)
        if not self.request.get('sort_on', None) in ('getObjPositionInParent', '', None):
            if self.request.get('sort_on', None) == self.sort_on:
                self.reverse = not self.reverse
            else:
                self.reverse = False
            self.sort_on = self.request.get('sort_on')
            session.set(SESSION_KEY + 'reverse', self.reverse)
            session.set(SESSION_KEY + 'sort_on', self.sort_on)
            self.request.set('sort_on', '')
        self.url = '%s/@@manage-orders' % self.context.absolute_url()

    def __call__(self):
        self.request.set('disable_border', 1)
        return self.template()

    def _translate_order_status_id(self, status_id):
        """
        """
        order_status_string = {
            1: _('label_initialized', default="Initialized"),
            2: _('label_sent', default="Sent"),
            3: _('label_processed', default="Processed"),
            4: _('label_failed', default="Failed"),
            5: _('label_cancelled', default="Cancelled"),
        }
        return order_status_string[status_id]

    def order_fields(self):
        """Fields and fieldnames to show in tables (order overviews / details).

            {   'field_id': '',
                'field_name': _("label_", default=""),
                'sortable': True
                },
        """
        fields = [
            {   'field_id': 'orderid',
                'field_name': _("label_order_id", default="Order id"),
                'sortable': True
                },
            {   'field_id': 'userid',
                'field_name': _("label_user_id", default="User id"),
                'sortable': True
                },
            {   'field_id': 'date',
                'field_name': _("label_date", default="Date"),
                'sortable': True
                },
            {   'field_id': 'currency',
                'field_name': _("label_currency", default="Currency"),
                'sortable': True
                },
            {   'field_id': 'totalincl',
                'field_name': _("label_price_total", default="Price total"),
                'field_converter': self._totalincl_converter,
                'sortable': True
                },
            {   'field_id': 'state',
                'field_name': _("label_order_state", default="Order status"),
                'sortable': True
                },
            {   'field_id': 'zone',
                'field_name': _("label_zone", default="Zone"),
                'field_converter': self._zone_converter,
                'sortable': True
                },
            {   'field_id': 'address',
                'field_name': _("label_address", default="Address"),
                'field_converter': self._address_converter,
                'sortable': True
                },
            {   'field_id': 'products',
                'field_name': _("label_products", default="Products"),
                'field_converter': self._products_converter,
                'sortable': False
                },
            {   'field_id': 'shipmentids',
                'field_name': _("label_shipmentids", default="Shipment id's"),
                'field_converter': self._shipmentids_converter,
                'sortable': False
                },
            ]
        return fields

    def _zone_converter(self, value, order):
        return '<strong>%s</strong> (%s%% %s)' % (value[0], value[1][0], value[1][1])

    def _totalincl_converter(self, value, order):
        return CurrencyAware(value).valueToString()

    def _address_converter(self, value, order):
        return '<pre>%s</pre>' % value.mailInfo(self.request)

    def _products_converter(self, value, order):
        rows = []
        for product in value:
            cells = [str(i) for i in product[1:5]]
            cells.append(str(product[3]*product[4]))
            rows.append('</td><td>'.join(cells))
        return '''
<table class="listing">
    <thead>
        <tr><th>%s</th></tr>
    </thead>
    <tbody>
        <tr><td>%s</td></tr>
    </tbody>
</table>''' % ('</th><th>'.join((translate(_(u'No'), context=self.request),
                                 translate(_(u'Product'), context=self.request),
                                 translate(_(u'Amount'), context=self.request),
                                 translate(_(u'Price'), context=self.request),
                                 translate(_(u'Price total'), context=self.request))), '</td></tr><tr><td>'.join(rows))

    def _shipmentids_converter(self, value, order):
        return '<ul><li>%s</li></ul>' % '</li><li>'.join(value.keys())

    def order_management_columns(self):
        """Fields for order management table. """
        field_ids = [
            'orderid',
            'userid',
            'date',
            'currency',
            'totalincl',
            'state',
            ]
        columns = [ column for column in self.order_fields() if \
            column['field_id'] in field_ids]
        return columns

    def _massageData(self, field_id, value):
        """Modify the field values (if needed) for displaying to humans. """
        # Convert the date (float) to a DateTime format.
        if field_id == 'date':
            value = DateTime(value)
            value = self.translation_service.ulocalized_time(
                value, long_format=True, time_only=None, 
                context=self.context, domain='plonelocales', 
                request=self.request)
        # Convert order status to a translated string
        if field_id == 'state':
            value = self._translate_order_status_id(value)
        return value

    def _get_order_data(self, order_nr, fields):
        """Returns data of a single order as as a list of dictionaries, 
        suitable for displaying in a page template.

        Copies only the specified fields (which are defined like the 
        _order_fields list of dicts above.

        [   {   'id':   ..., # field id
                'value: ..., # field value
                'name': ..., # field name (optional)
            },
        ]
        """
        r_order = self.registry.getOrder(order_nr)
        order_data = []
        sort = 0
        for field in fields:
            field_data = {}
            field_id = field['field_id']
            field_data['id'] = field_id
            value = getattr(r_order, field_id)
            if field_id == self.sort_on:
                sort = value
            if field.has_key('field_converter'):
                try:
                    value = field['field_converter'](value, r_order)
                except:
                    pass
            field_data['value'] = self._massageData(field_id, value)
            field_data['name'] = field['field_name']
            order_data.append(field_data)
        return order_data, sort

    @property
    def batch(self):
        """Returns data rows for order management table. """
        orders = []
        sorting = []
        # use only selected fields in the table
        columns = self.order_management_columns()
        for order_nr in self.registry.getOrders():
            data, sort = self._get_order_data(order_nr, columns)
            index = len(orders) - 1
            while index >= 0 and sort < sorting[index]:
                index -= 1
            sorting.insert(index + 1, sort)
            orders.insert(index + 1, data)
        if self.reverse:
            orders.reverse()
        pagesize = self.pagesize
        b = Batch(orders,
                  pagesize=pagesize,
                  pagenumber=self.pagenumber)
        return b