Gopakumar N G
Gopakumar N G

Reputation: 1843

How to add (sum) the two values in a python dictionary based on another value?

I am creating 2 reports in openerp using jasper. But I am using same parser for the 2 reports, first report is 'detailed report' and second one is 'summary'. In the dictionary (named data) that is appended to the result list there are keys date, invoice, debit and credit. For the detailed report i only need to get these values from account.move.line. But for the summary report there should be only one line for the account move lines containing same invoice number. That is I need to add the debits and credits of account move lines with same invoice number and display it as one line, how can I do it in Python. For example the result list is

[{'invoice':1,'debit':10,'credit':10},
 {'name':'b','invoice':2,'debit':10,'credit':18},
 {'invoice':1,'debit':10,'credit':10}]

and what I need is

[{'invoice':1,'debit':20,'credit':20},
 {'invoice':2,'debit':10,'credit':18}]

EDIT: The code is

move_line_ids = move_line_pool.search(cr, uid, domain, context=context)
        print 'move_line_ids', len(move_line_ids)

        for move_line in move_line_pool.browse(cr, uid, move_line_ids, context=context):
            group_by = grp = grp_acc = ''
            debit = credit = bal = 0.0
            if move_line.debit > 0.0:
                debit = move_line.amount_residual
            elif move_line.credit > 0.0:
                credit = move_line.amount_residual
            bal = debit - credit    
            if form_group_by == 'group_account_code':
                group_by = 'ACCOUNT CODE : '
                grp = move_line.account_id.code or ''
                grp_acc = move_line.account_id.name or ''
            elif form_group_by == 'group_order_no':
                group_by = 'ORDER : '
                grp = move_line.sale_id.name or ''
            else:
                group_by = 'INVOICE : '
                grp = move_line.invoice.number or ''
            date = dt.strptime(str(move_line.date), '%Y-%m-%d').strftime('%d-%m-%Y')

            data = {
                        'period': period,
                        'date': date,
                        'company': company or '',
                        'so': move_line.sale_id.name or '',
                        'invoice': move_line.invoice.number or '',
                        'po': '',
                        'status': '',
                        'ref': move_line.move_id.name or '',
                        'debit': debit,
                        'credit': credit,
                        'bal': bal,
                        'fc': '',
                        'f_amt': '',
                        'trx': move_line.journal_id.code or '',
                        'account': move_line.account_id.name or '',
                        'account_code': move_line.account_id.code or '',
                        'acc_range': acc_range,
                        'group_by': group_by,
                        'grp': grp,
                        'grp_acc': grp_acc,
            }

            result.append(data)

        if form_group_by == 'group_account_code':
            result = sorted(result, key=lambda k: k['account_code'])
        elif form_group_by == 'group_order_no':
            result = sorted(result, key=lambda k: k['so'])
        else:
            result = sorted(result, key=lambda k: k['invoice'])
        return result

Only consider the keys invoice,debit and credit in the dictionary, others are not needed to updated if invoice is same.

Upvotes: 0

Views: 307

Answers (2)

selllikesybok
selllikesybok

Reputation: 1225

Assuming I understand your question, something like this would do the trick:

sum_dict = {}

for e in source_list:
    if e["invoice"] in sum_dict.keys():
        sum_dict[e["invoice"]]["debit"]+=e["debit"]
        sum_dict[e["invoice"]]["credit"]+=e["credit"]
    else:
        sum_dict[e["invoice"] = e

result_list = [sum_dict[k] for k in sum_dict.keys()]

ETA:

I answered on the base question, prior to code being added. Will update.

ETA 2:

Okay, I stand by this as an easy fix to run in between the for loop and the if/else block.

However, as a commenter noted, the best fix is probably to make some changes in the logic for your db calls. I do not know enough to suggest good changes there, though.

Upvotes: 2

Vb407
Vb407

Reputation: 1707

Might not be the optimized answer...

li_dict =[{'invoice':1,'debit':10,'credit':10},{'name':'b','invoice':2,'debit':10,'credit':18},
{'invoice':1,'debit':10,'credit':10}, {'name':'b','invoice':2,'debit':10,'credit':18}]


final_result = []
for dic in li_dict :
    temp_dict = {}
    flag = False

    for dic_f in final_result:
        if 'invoice' in dic and 'invoice' in dic_f:
            if dic['invoice'] == dic_f['invoice']:
                dic_f['debit'] = dic['debit'] + dic_f['debit']
                dic_f['credit'] = dic['credit'] + dic_f['credit']
                flag = True
                break

    if not flag:
        temp_dict['invoice'] = dic.get('invoice', 0)
        temp_dict['debit'] = dic.get('debit', 0)
        temp_dict['credit'] = dic.get('credit', 0)
        final_result.append(temp_dict)

print final_result

Result:

[{'credit': 20, 'invoice': 1, 'debit': 20}, {'credit': 18, 'invoice': 2, 'debit': 10}]

Upvotes: 1

Related Questions