feat(1099): wire W-9 document upload/view for recipients

Adds POST/GET payee-1099/{id}/w9, mirroring the expense-receipt upload:
IFileStorage saves to finance/w9/{id}{ext}, content-type derived from the
blob extension. Frontend dialog (edit mode) gains a W-9 file input and an
auth-correct blob "View W-9" link. Payee1099Service ctor now takes
IFileStorage; tests updated with an in-memory FakeStorage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Chris Chen
2026-06-25 18:11:11 -07:00
parent ad276c01f3
commit d29de83116
7 changed files with 182 additions and 4 deletions
@@ -146,6 +146,17 @@
<kendo-datepicker [(value)]="form.w9ReceivedDate"></kendo-datepicker>
</label>
<!-- W-9 document upload/view: edit mode only (a new record is saved first, then re-opened to attach). -->
<div *ngIf="editingId != null" class="flex flex-col gap-1 md:col-span-2">
<span>W-9 Document / W-9 文件</span>
<input type="file" accept="image/jpeg,image/png,image/webp,application/pdf"
*appHasPermission="{ module: 'Form1099', action: 'write' }"
(change)="onW9FileSelected($event)" />
<span class="hint-text-sm">Upload W-9 / 上傳 W-9</span>
<button *ngIf="editingHasW9" kendoButton type="button" fillMode="link" class="self-start"
(click)="viewW9()">View W-9 / 檢視 W-9</button>
</div>
<label class="flex flex-col gap-1 md:col-span-2">
Notes / 備註
<kendo-textarea [(ngModel)]="form.notes" [rows]="3"></kendo-textarea>