Пример #1
0
 def _determineCreditCoupon(self, session, order):
     # get coupon/credit history of order
     # XXX How is the refund amount distributed across the
     # various items in an order?
     refunds = []
     creds = session.query(Refund)\
             .filter_by(order_id = order.order_id)\
             .options(eagerload("reason_category"),
                      eagerload("reason_subcategory")).all()
     coups = session.query(Coupon)\
             .filter_by(orig_order_id = order.order_id)\
            .options(eagerload("reason_category"),
                     eagerload("reason_subcategory")).all()
     for refs, kind in((creds, "credit"), (coups, "coupon")):
         for ref in refs:
             date = str(Date(ref.created))
             total = formatDollars(ref.amount, self._determineCurrency(ref))
             refunds.append("%s %s issued a %s %s (%s)" % 
                            (date, ref.user.username, total, kind,
                             ref.comments or
                             ref.reason_subcategory or
                             ref.reason_category))
     return refunds
Пример #2
0
    def getData(self, session, params):
        '''Get the order summary data based on the given parameters.'''

        from web.htmlutil import Encryption
        encrypt = Encryption().simple_encrypt
        cube = DataCube()
        data_tables = []
        filters = params.filters
        facts = params.get('facts', ['orders'] * len(params.dims))
        # extras are additional facts that will display in columns to
        # the right of the group by columns
        extra = params.get('extra_cols', [])
        # ratio data <A>_per_<B> computed from A and B, such that
        # division of B occurs only after all A's are summed up
        extra_facts = [e for e in extra if '_per_' not in e]
        for i, dims in enumerate(params.dims):
            fact = facts[i]
            percent_dims = [d.endswith('_percent') for d in dims[1:]]
            percent_cols = []
            dims = [d.replace('_percent', '') for d in dims]
            # main dimension used to title the table
            row_dim = dims[0]
            dim_name = ' '.join(s.title() for s in row_dim.split('_'))
            data = odict({'title': fact.title(), 'row_name': dim_name,
                          'cols': [], 'rows': [], 'body': [], 'dims': dims})
            if any(percent_dims):
                data.title = '%s Percentages' % data.title.rstrip('s')
            filter_str = ''
            if filters:
                filter_str = ';'.join(filters) + ';'
            for d in sorted(cube.getData(session, [fact] + extra_facts, 
                                         dims, filters[:])):
                #print d, '<br/>'
                row_val = getattr(d, row_dim)
                if row_val not in data.rows:
                    if not row_val: continue
                    data.rows.append(row_val)
                    data.body.append({row_dim: row_val, 'Total': 0, 
                                      'detail_params': {}})
                row_filter_str = filter_str + "dc.%s == '%s'" % \
                                 (dims[0], row_val)
                for g, col_dim in enumerate(dims[1:]):
                    key = getattr(d, col_dim)
                    # grouping is to ensure proper column ordering
                    if len(data.cols) < g + 1:
                        data.cols.append([])
                        percent_cols.append([])
                    if key not in data.cols[g]:
                        data.cols[g].append(key)
                        percent_cols[g].append(percent_dims[g])
                    if key not in data.body[-1]:
                        data.body[-1][key] = 0
                    val = getattr(d, fact)
                    data.body[-1][key] += val
                    data.body[-1]['Total'] += val
                    p = row_filter_str + ";dc.%s == '%s'" % (dims[1], key)
                    data.body[-1]['detail_params'][key] = encrypt(p)
                for e in extra:
                    if e not in data.body[-1]:
                        data.body[-1][e] = 0
                    if '_per_' in e:
                        # just numerator part of ratio data
                        num = e.split('_per_')[0]
                        data.body[-1][e] += getattr(d, num)
                    else:
                        data.body[-1][e] += getattr(d, e)
                data.body[-1]['detail_params']['Total'] = \
                    encrypt(row_filter_str)
            data.cols = [c for g in data.cols for c in g]       # flatten cols
            percent_cols = [c for g in percent_cols for c in g] # flatten cols
            # only show total column if there are more than 1 col to sum
            if len(data.cols) > 1:
                data.cols.append('Total')
                percent_cols.append(percent_cols[-1])
            data.cols += extra
            percent_cols += [False] * len(extra)
            data.total_row = {'detail_params': {}}
            # add 0 for missing values, populate total row and detail filters
            for col in data.cols:
                for row in data.body:
                    if col not in row:
                        row[col] = 0
                data.total_row[col] = sum(row[col] for row in data.body)
                if col not in extra:
                    p = filter_str + "dc.%s == '%s'" % (dims[1], col)
                    data.total_row['detail_params'][col] = encrypt(p)
            # apply special formatting, 
            # divide denominator part of ratio data and percents
            data.col_names = []
            for i, col in enumerate(data.cols):
                for row in data.body + [data.total_row]:
                    if '_per_' in col:
                        div = col.split('_per_')[1] + 's'
                        if div == fact:
                            row[col] /= Decimal(row.get('Total', 1) or 1)
                        else:
                            row[col] /= Decimal(row[div] or 1)
                    elif percent_cols[i]:
                        if col == 'Total':
                            div = Decimal(data.total_row['Total'])
                        else:
                            div = Decimal(row['Total'])
                        row[col] *= 100 / (div or 1)
                    if col.split('_per_')[0] in MONEY_FIELDS:
                        row[col] = formatDollars(row[col])
                    elif percent_cols[i] and row[col]:
                        row[col] = '%0.1f%%' % row[col]
                    elif isinstance(row[col], (float, Decimal)) and \
                         row[col] <> int(row[col]):
                        row[col] = '%0.4f' % row[col]
                data.col_names.append(' '.join(s.replace('usd', '$').title() 
                                               for s in col.split('_')))
            data_tables.append(data)
        #for b in data_tables[0].body:
        #    print [(k, v) for k,v in b.items() if k <> 'detail_params'], '<br/>'
        return data_tables