1
This commit is contained in:
+44
-17
@@ -183,7 +183,37 @@ def export_travel(state, destination):
|
||||
workbook.save(destination)
|
||||
|
||||
|
||||
def export_expense(state, destination, template, purposes, signatures):
|
||||
def expense_rows(matches, purposes, category_purposes=None):
|
||||
grouped = {}
|
||||
for match in matches:
|
||||
category = match.get('category') or '其他'
|
||||
row = grouped.setdefault(category, dict(category=category, count=0, amount=Decimal(0), types=[], purposes=[]))
|
||||
row['count'] += len(match['invoices'])
|
||||
purpose = purposes.get(match['id'], '').strip()
|
||||
if purpose and purpose not in row['purposes']:
|
||||
row['purposes'].append(purpose)
|
||||
for invoice in match['invoices']:
|
||||
content = text(invoice)
|
||||
if '专用发票' in content:
|
||||
invoice_type = '专票'
|
||||
elif 'invoice' in content.lower():
|
||||
invoice_type = 'Invoice'
|
||||
elif '押金' in content and '收据' in content:
|
||||
invoice_type = '押金收据'
|
||||
else:
|
||||
invoice_type = '普票'
|
||||
if invoice_type not in row['types']:
|
||||
row['types'].append(invoice_type)
|
||||
row['amount'] += max((abs(Decimal(value.replace(',', ''))) for value in invoice['ocr']['amounts']), default=Decimal(0))
|
||||
for row in grouped.values():
|
||||
if category_purposes is not None:
|
||||
row['purpose'] = category_purposes.get(row['category'], '').strip() or row['category']
|
||||
else:
|
||||
row['purpose'] = ';'.join(row['purposes']) or row['category']
|
||||
return list(grouped.values())
|
||||
|
||||
|
||||
def export_expense(state, destination, template, purposes, signatures, payee=None, category_purposes=None):
|
||||
from lxml import etree as ET
|
||||
namespace = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
|
||||
relationships = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
|
||||
@@ -207,7 +237,10 @@ def export_expense(state, destination, template, purposes, signatures):
|
||||
names.clear()
|
||||
sheets.clear()
|
||||
signatures = signatures or DEFAULT_SIGNATURES
|
||||
page_count = math.ceil(len(state['matches']) / 13)
|
||||
rows = expense_rows(state['matches'], purposes, category_purposes)
|
||||
if not rows:
|
||||
raise ValueError('请先勾选要导出的已核对材料')
|
||||
page_count = math.ceil(len(rows) / 13)
|
||||
|
||||
def set_cell(document, reference, value):
|
||||
cell = document.find('.//' + tag('c') + '[@r="' + reference + '"]')
|
||||
@@ -229,25 +262,18 @@ def export_expense(state, destination, template, purposes, signatures):
|
||||
|
||||
for page in range(page_count):
|
||||
document = ET.fromstring(sheet_bytes)
|
||||
profile = payee or {}
|
||||
for reference, field in [('C23', 'recipient'), ('C24', 'bankName'), ('C25', 'accountNumber'), ('H6', 'preparer')]:
|
||||
value = str(profile.get(field, '') or '').strip()
|
||||
if field == 'preparer' and not value:
|
||||
value = str(profile.get('recipient', '') or '').strip()
|
||||
set_cell(document, reference, value)
|
||||
for row_number in range(9, 22):
|
||||
for column in ['B', 'C', 'G', 'H', 'I']:
|
||||
set_cell(document, column + str(row_number), '')
|
||||
set_cell(document, 'A' + str(row_number), row_number - 8)
|
||||
for index, match in enumerate(state['matches'][page * 13:(page + 1) * 13]):
|
||||
invoice_type = '普票'
|
||||
for invoice in match['invoices']:
|
||||
content = text(invoice)
|
||||
if '专用发票' in content:
|
||||
invoice_type = '专票'
|
||||
break
|
||||
if 'invoice' in content.lower():
|
||||
invoice_type = 'Invoice'
|
||||
break
|
||||
if '押金' in content and '收据' in content:
|
||||
invoice_type = '押金收据'
|
||||
break
|
||||
total = sum(max((abs(Decimal(value.replace(',', ''))) for value in item['ocr']['amounts']), default=Decimal(0)) for item in match['invoices'])
|
||||
for column, value in [('B', invoice_type), ('C', purposes.get(match['id'], '').strip()), ('G', len(match['invoices'])), ('H', total)]:
|
||||
for index, row in enumerate(rows[page * 13:(page + 1) * 13]):
|
||||
for column, value in [('B', '/'.join(row['types'])), ('C', row['purpose']), ('G', row['count']), ('H', row['amount'])]:
|
||||
set_cell(document, column + str(index + 9), value)
|
||||
for index, cell in enumerate(['A30', 'D30', 'A31', 'D31', 'A32', 'D32']):
|
||||
value = signatures[index].strip() if index < len(signatures) else ''
|
||||
@@ -277,3 +303,4 @@ def export_expense(state, destination, template, purposes, signatures):
|
||||
with zipfile.ZipFile(destination, 'w', zipfile.ZIP_DEFLATED) as output:
|
||||
for name, content in parts.items():
|
||||
output.writestr(name, content)
|
||||
return dict(expenseGrouping='category-v1', expenseRowCount=len(rows))
|
||||
|
||||
Reference in New Issue
Block a user