docs: def get_payroll_totals(month_work_entries, month_leave_entries):
      """Summarizes monthly work and leave totals, grouped by user.
  
      Returns (labels, rows).
          labels -> {'billable': [proj_labels], 'nonbillable': [proj_labels]}
          rows -> [{
              name: name of user,
              billable, nonbillable, leave: [
                  {'hours': hours for label, 'percent': % of work or leave total}
              ],
              work_total: sum of billable and nonbillable hours,
              leave_total: sum of leave hours
              grand_total: sum of work_total and leave_total
          }]
  
      The last entry in each of the billable/nonbillable/leave lists contains a
      summary of the status. The last row contains sum totals for all other rows.
      """
      def _get_user_info(entries):
          """Helper for getting the associated user's first and last name."""
          fname = entries[0].get('user__first_name', '') if entries else ''
          lname = entries[0].get('user__last_name', '') if entries else ''
          name = '{0} {1}'.format(fname, lname).strip()
          user_id = entries[0].get('user', None) if entries else None
          return {'name': name, 'user_id': user_id}
  
      def _get_index(status, label):
          """
          Returns the index in row[status] (where row is the row corresponding
          to the current user) where hours for the project label should be
          recorded.
  
          If the label does not exist, then it is added to the labels list.
          Each row and the totals row is updated accordingly.
  
          Requires that labels, rows, and totals are in scope.
          """
          if label in labels[status]:
              return labels[status].index(label)
          # Otherwise: update labels, rows, and totals to reflect the addition.
          labels[status].append(label)
          for row in rows:
              row[status].insert(-1, {'hours': Decimal(), 'percent': Decimal()})
          totals[status].insert(-1, {'hours': Decimal(), 'percent': Decimal()})
          return len(labels[status]) - 1
  
      def _construct_row(name, user_id=None):
          """Constructs an empty row for the given name."""
          row = {'name': name, 'user_id': user_id}
          for status in labels.keys():
              # Include an extra entry for summary.
              row[status] = [{'hours': Decimal(), 'percent': Decimal()}
                             for i in range(len(labels[status]) + 1)]
          row['work_total'] = Decimal()
          row['grand_total'] = Decimal()
          return row
  
      def _add_percentages(row, statuses, total):
          """For each entry in each status, percent = hours / total"""
          if total:
              for status in statuses:
                  for i in range(len(row[status])):
                      p = row[status][i]['hours'] / total * 100
                      row[status][i]['percent'] = p
  
      def _get_sum(row, statuses):
          """Sum the number of hours worked in given statuses."""
          return sum([row[status][-1]['hours'] for status in statuses])
  
      work_statuses = ('billable', 'nonbillable')
      leave_statuses = ('leave', )
      labels = dict([(status, []) for status in work_statuses + leave_statuses])
      rows = []
      totals = _construct_row('Totals')
      for user, work_entries in groupby(month_work_entries, lambda e: e['user']):
  
          work_entries = list(work_entries)
          row = _construct_row(**_get_user_info(work_entries))
          rows.append(row)
          for entry in work_entries:
              status = 'billable' if entry['billable'] else 'nonbillable'
              label = entry['project__type__label']
              index = _get_index(status, label)
              hours = entry['hours']
              row[status][index]['hours'] += hours
              row[status][-1]['hours'] += hours
              totals[status][index]['hours'] += hours
              totals[status][-1]['hours'] += hours
  
          leave_entries = month_leave_entries.filter(user=user)
          status = 'leave'
          for entry in leave_entries:
              label = entry.get('project__name')
              index = _get_index(status, label)
              hours = entry.get('hours')
              row[status][index]['hours'] += hours
              row[status][-1]['hours'] += hours
              totals[status][index]['hours'] += hours
              totals[status][-1]['hours'] += hours
  
          row['work_total'] = _get_sum(row, work_statuses)
          _add_percentages(row, work_statuses, row['work_total'])
          row['leave_total'] = _get_sum(row, leave_statuses)
          _add_percentages(row, leave_statuses, row['leave_total'])
          row['grand_total'] = row['work_total'] + row['leave_total']
  
      totals['work_total'] = _get_sum(totals, work_statuses)
      _add_percentages(totals, work_statuses, totals['work_total'])
      totals['leave_total'] = _get_sum(totals, leave_statuses)
      _add_percentages(totals, leave_statuses, totals['leave_total'])
      totals['grand_total'] = totals['work_total'] + totals['leave_total']
  
      if rows:
          rows.append(totals)
      return labels, rows