diff --git a/APP/src/app/core/models/permission.model.ts b/APP/src/app/core/models/permission.model.ts index 2f9ac40..d8e22d5 100644 --- a/APP/src/app/core/models/permission.model.ts +++ b/APP/src/app/core/models/permission.model.ts @@ -33,6 +33,7 @@ export const PermissionModules = { SystemLogs: 'SystemLogs', AuditLogs: 'AuditLogs', Settings: 'Settings', + Form1099: 'Form1099', } as const; /** A required permission, used in route data and the *appHasPermission directive. */ diff --git a/APP/src/app/features/payee1099/models/payee1099.model.ts b/APP/src/app/features/payee1099/models/payee1099.model.ts new file mode 100644 index 0000000..0a61ca2 --- /dev/null +++ b/APP/src/app/features/payee1099/models/payee1099.model.ts @@ -0,0 +1,43 @@ +export interface Payee1099ListItem { + id: number; legalName: string; displayName?: string; + memberId?: number; memberName?: string; taxClassification: string; + is1099Tracked: boolean; tinType?: string; tinLast4?: string; + w9Status: string; isActive: boolean; +} + +export interface Payee1099 extends Payee1099ListItem { + addressLine1?: string; addressLine2?: string; city?: string; state?: string; zip?: string; + email?: string; phone?: string; w9ReceivedDate?: string; hasW9Document: boolean; notes?: string; +} + +export interface SavePayee1099Request { + legalName: string; displayName?: string; memberId?: number | null; + taxClassification: string; is1099Tracked: boolean; + tinType?: string; tin?: string | null; + addressLine1?: string; addressLine2?: string; city?: string; state?: string; zip?: string; + email?: string; phone?: string; w9Status: string; w9ReceivedDate?: string | null; + isActive: boolean; notes?: string; +} + +export interface Form1099Box { + id: number; boxCode: string; name_en: string; name_zh?: string; formType: string; sortOrder: number; +} + +export interface Form1099RecipientRow { + payeeId: number; legalName: string; tinLast4?: string; w9Status: string; + necTotal: number; rentsTotal: number; grandTotal: number; meetsThreshold: boolean; w9Missing: boolean; +} + +export interface Form1099Summary { + taxYear: number; rows: Form1099RecipientRow[]; + totalReportable: number; recipientsAtThreshold: number; recipientsMissingW9: number; +} + +export interface Form1099Payment { + paidDate: string; description: string; categoryName: string; boxCode: string; amount: number; +} + +export interface Form1099RecipientDetail { + payeeId: number; legalName: string; tinLast4?: string; w9Status: string; + taxYear: number; payments: Form1099Payment[]; +} diff --git a/APP/src/app/features/payee1099/services/form1099-report-api.service.ts b/APP/src/app/features/payee1099/services/form1099-report-api.service.ts new file mode 100644 index 0000000..d7e692c --- /dev/null +++ b/APP/src/app/features/payee1099/services/form1099-report-api.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { ApiConfigService } from '../../../core/services/api-config.service'; +import { + Form1099Box, Form1099Summary, Form1099RecipientDetail, +} from '../models/payee1099.model'; + +@Injectable({ providedIn: 'root' }) +export class Form1099ReportApiService { + private readonly endpoint: string; + + constructor(private http: HttpClient, apiConfig: ApiConfigService) { + this.endpoint = apiConfig.getApiUrl('form1099-report'); + } + + getBoxes(): Observable { + return this.http.get(`${this.endpoint}/boxes`); + } + + getSummary(taxYear: number): Observable { + return this.http.get(`${this.endpoint}/summary`, { + params: { taxYear: String(taxYear) }, + }); + } + + getRecipient(payeeId: number, taxYear: number): Observable { + return this.http.get(`${this.endpoint}/recipient/${payeeId}`, { + params: { taxYear: String(taxYear) }, + }); + } + + copyBUrl(payeeId: number, taxYear: number): string { + return `${this.endpoint}/recipient/${payeeId}/copy-b?taxYear=${taxYear}`; + } + + exportCsvUrl(taxYear: number): string { + return `${this.endpoint}/export-csv?taxYear=${taxYear}`; + } +} diff --git a/APP/src/app/features/payee1099/services/payee1099-api.service.ts b/APP/src/app/features/payee1099/services/payee1099-api.service.ts new file mode 100644 index 0000000..6b0468e --- /dev/null +++ b/APP/src/app/features/payee1099/services/payee1099-api.service.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { ApiConfigService } from '../../../core/services/api-config.service'; +import { + Payee1099ListItem, Payee1099, SavePayee1099Request, +} from '../models/payee1099.model'; + +@Injectable({ providedIn: 'root' }) +export class Payee1099ApiService { + private readonly endpoint: string; + + constructor(private http: HttpClient, apiConfig: ApiConfigService) { + this.endpoint = apiConfig.getApiUrl('payee-1099'); + } + + getAll(includeInactive = false): Observable { + return this.http.get(this.endpoint, { + params: { includeInactive: String(includeInactive) }, + }); + } + + getById(id: number): Observable { + return this.http.get(`${this.endpoint}/${id}`); + } + + create(req: SavePayee1099Request): Observable<{ id: number }> { + return this.http.post<{ id: number }>(this.endpoint, req); + } + + update(id: number, req: SavePayee1099Request): Observable { + return this.http.put(`${this.endpoint}/${id}`, req); + } + + delete(id: number): Observable { + return this.http.delete(`${this.endpoint}/${id}`); + } + + revealTin(id: number): Observable<{ tin: string | null }> { + return this.http.get<{ tin: string | null }>(`${this.endpoint}/${id}/tin`); + } +}