feat: implement SalesInvoiceTspSwitchService and SalesInvoiceTspService for handling TSP provider interactions

- Add SalesInvoiceTspSwitchService to manage TSP provider selection and sending invoices.
- Introduce SalesInvoiceTspService for creating, sending, and retrieving sales invoices.
- Implement NamaProviderSwitchAdapter for communication with the NAMA TSP provider API.
- Define DTOs for request and response structures specific to the NAMA provider.
- Enhance error handling and logging for TSP provider interactions.
This commit is contained in:
2026-05-03 16:23:17 +03:30
parent ad470d2166
commit a486127ade
62 changed files with 4136 additions and 5015 deletions
@@ -0,0 +1,59 @@
import { Injectable } from '@nestjs/common'
import {
TspProviderBulkSendResultDto,
TspProviderGetResultDto,
TspProviderSendItemResultDto,
TspProviderSendPayloadDto,
} from './dto/provider-switch.dto'
import { NamaProviderSwitchAdapter } from './switch/nama/nama-provider.adapter'
@Injectable()
export class SalesInvoiceTspSwitchService {
constructor(private readonly namaAdapter: NamaProviderSwitchAdapter) {}
private resolveSwitch(providerCode: string) {
const normalizedCode = providerCode.trim().toUpperCase() || ''
switch (normalizedCode) {
case 'NAMA':
default:
return this.namaAdapter
}
}
async send(payload: TspProviderSendPayloadDto): Promise<TspProviderSendItemResultDto> {
const adapter = this.resolveSwitch(payload.tsp_provider)
return adapter.send(payload)
}
async sendBulk(
payloads: TspProviderSendPayloadDto[],
): Promise<TspProviderBulkSendResultDto[]> {
const groupedByProvider = new Map<string, TspProviderSendPayloadDto[]>()
for (const payload of payloads) {
const key = payload.tsp_provider?.trim().toUpperCase() || 'NAMA'
const currentGroup = groupedByProvider.get(key) || []
currentGroup.push(payload)
groupedByProvider.set(key, currentGroup)
}
const result: TspProviderBulkSendResultDto[] = []
for (const [providerCode, groupedPayloads] of groupedByProvider.entries()) {
const adapter = this.resolveSwitch(providerCode)
const providerResult = await adapter.sendBulk(groupedPayloads)
result.push(...providerResult)
}
return result
}
async get(
providerCode: string,
invoiceId: string,
tspToken: string,
): Promise<TspProviderGetResultDto> {
const adapter = this.resolveSwitch(providerCode)
return await adapter.get(invoiceId, tspToken)
}
}