feat(expense): 전부 다운로드 zip에 승인 목록 엑셀 동봉
- _build_approved_xlsx 헬퍼로 엑셀 생성 로직 추출(export/zip 공용)
- zip 최상단에 승인목록_{month}.xlsx 포함 + 첨부 파일들
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -402,19 +402,12 @@ async def approved_page(request: Request) -> HTMLResponse:
|
||||
)
|
||||
|
||||
|
||||
@router.get("/api/approved/export.xlsx")
|
||||
async def approved_export(
|
||||
request: Request,
|
||||
user: dict[str, Any] = Depends(_require_approver),
|
||||
) -> StreamingResponse:
|
||||
def _build_approved_xlsx(
|
||||
items: list[dict[str, Any]], names: dict[str, str]
|
||||
) -> io.BytesIO:
|
||||
"""승인완료 목록 + 직원별합계 시트 xlsx 바이트 생성."""
|
||||
from openpyxl import Workbook # 지연 import
|
||||
|
||||
store = _store(request)
|
||||
_require_db_store(store)
|
||||
year, mon, raw = _parse_month(request)
|
||||
items = store.list_approved(year=year, month=mon)
|
||||
names = _name_map(request)
|
||||
|
||||
wb = Workbook()
|
||||
ws = wb.active
|
||||
ws.title = "승인완료"
|
||||
@@ -453,6 +446,20 @@ async def approved_export(
|
||||
buf = io.BytesIO()
|
||||
wb.save(buf)
|
||||
buf.seek(0)
|
||||
return buf
|
||||
|
||||
|
||||
@router.get("/api/approved/export.xlsx")
|
||||
async def approved_export(
|
||||
request: Request,
|
||||
user: dict[str, Any] = Depends(_require_approver),
|
||||
) -> StreamingResponse:
|
||||
store = _store(request)
|
||||
_require_db_store(store)
|
||||
year, mon, raw = _parse_month(request)
|
||||
items = store.list_approved(year=year, month=mon)
|
||||
names = _name_map(request)
|
||||
buf = _build_approved_xlsx(items, names)
|
||||
fname = f"expense_approved_{raw}.xlsx"
|
||||
return StreamingResponse(
|
||||
buf,
|
||||
@@ -470,6 +477,7 @@ async def approved_attachments_zip(
|
||||
store = _store(request)
|
||||
_require_db_store(store)
|
||||
year, mon, raw = _parse_month(request)
|
||||
items = store.list_approved(year=year, month=mon)
|
||||
atts = store.approved_attachments(year=year, month=mon)
|
||||
names = _name_map(request)
|
||||
upload_root = _upload_dir(request)
|
||||
@@ -495,6 +503,10 @@ async def approved_attachments_zip(
|
||||
buf = io.BytesIO()
|
||||
used: dict[str, int] = {}
|
||||
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
# 1) 승인 목록 엑셀 동봉
|
||||
xlsx_buf = _build_approved_xlsx(items, names)
|
||||
zf.writestr(f"승인목록_{raw}.xlsx", xlsx_buf.getvalue())
|
||||
# 2) 첨부 파일들
|
||||
for a in atts:
|
||||
path = _resolve(a)
|
||||
if path is None:
|
||||
|
||||
Reference in New Issue
Block a user