feat(freight): add download for the TIN business registration record

Ticket #181 — eTrade auto-fetch already existed; adds a client-side
download of the fetched record (eTrade returns data, not a document)
on the portal onboarding step and the backoffice customer detail page.
This commit is contained in:
Nathnael
2026-07-31 11:45:24 +00:00
parent 7c5d96795c
commit 3952e8bbdf
2 changed files with 86 additions and 12 deletions

View File

@@ -65,6 +65,7 @@ import {
} from "@/services/files.service";
import { api } from "@/services/api";
import type {
Company,
CompanyProfile,
CustomerBooking,
CustomerDocument,
@@ -79,6 +80,32 @@ import {
type ColumnDef,
} from "@edr/ui-common";
/** Plain-text summary of the company's eTrade-sourced record, downloaded client-side (eTrade returns data, not a document). */
function downloadTinRecord(company: Company) {
const lines = [
`TIN: ${company.tin}`,
`Company name: ${company.name}`,
`Licence number: ${company.licenceNumber ?? ""}`,
`Status: ${company.statusDescription ?? ""}`,
`Date registered: ${company.dateRegistered ?? ""}`,
`Renewed from: ${company.renewedFrom ?? ""}`,
`Renewal date: ${company.renewalDate ?? ""}`,
`Renewed to: ${company.renewedTo ?? ""}`,
`Address: ${[company.region, company.zone, company.woreda, company.kebele, company.houseNo].filter(Boolean).join(", ")}`,
];
const blob = new Blob([lines.join("\n")], {
type: "text/plain;charset=utf-8",
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `tin-${company.tin}.txt`;
document.body.appendChild(a);
a.click();
a.remove();
setTimeout(() => URL.revokeObjectURL(url), 60_000);
}
function InfoField({ label, value }: { label: string; value?: string | null }) {
return (
<Stack gap={2}>
@@ -814,18 +841,29 @@ export default function CustomerDetailPage() {
<Card>
<Stack gap="lg">
<Group gap="xs" wrap="nowrap">
<Text fw={600} c="edr-text">
eTrade registration
</Text>
{hasEtradeRecord ? (
<Badge size="sm" color="edr-green" variant="light">
Verified with eTrade
</Badge>
) : (
<Badge size="sm" color="gray" variant="light">
No eTrade record
</Badge>
<Group gap="xs" wrap="nowrap" justify="space-between">
<Group gap="xs" wrap="nowrap">
<Text fw={600} c="edr-text">
eTrade registration
</Text>
{hasEtradeRecord ? (
<Badge size="sm" color="edr-green" variant="light">
Verified with eTrade
</Badge>
) : (
<Badge size="sm" color="gray" variant="light">
No eTrade record
</Badge>
)}
</Group>
{hasEtradeRecord && (
<ActionIcon
variant="default"
aria-label="Download TIN record"
onClick={() => downloadTinRecord(company)}
>
<Download size={16} />
</ActionIcon>
)}
</Group>
{hasEtradeRecord ? (

View File

@@ -28,6 +28,31 @@ interface ETradeInfoProps {
const isValidTin = (tin: string) => tin.length === 10;
/** Plain-text summary of the fetched eTrade record, downloaded client-side (eTrade returns data, not a document). */
function downloadTinRecord(tin: string, data: CompanyRegistrationData) {
const lines = [
`TIN: ${tin}`,
`Company name: ${data.companyName}`,
`Licence number: ${data.licenceNumber}`,
`Status: ${data.statusDescription}`,
`Date registered: ${data.dateRegistered}`,
`Renewed from: ${data.renewedFrom}`,
`Renewal date: ${data.renewalDate}`,
`Renewed to: ${data.renewedTo}`,
`Address: ${[data.region, data.zone, data.woreda, data.kebele, data.houseNo].filter(Boolean).join(", ")}`,
`Manager: ${data.managerName}`,
];
const blob = new Blob([lines.join("\n")], { type: "text/plain;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `tin-${tin}.txt`;
document.body.appendChild(a);
a.click();
a.remove();
setTimeout(() => URL.revokeObjectURL(url), 60_000);
}
export default function ETradeInfo({
tin,
register,
@@ -123,6 +148,17 @@ export default function ETradeInfo({
{isLoading ? "Getting..." : "Get Data"}
</Button>
)}
{status === "verified" && mutation.data && !mutation.data.tinTaken && (
<Button
variant="light"
color="edr-green"
onClick={() => downloadTinRecord(tin, mutation.data!)}
leftSection={<Download size={16} />}
mt="24px"
>
Download
</Button>
)}
</Group>
{notFound && (