mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 05:30:55 +00:00
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:
@@ -65,6 +65,7 @@ import {
|
|||||||
} from "@/services/files.service";
|
} from "@/services/files.service";
|
||||||
import { api } from "@/services/api";
|
import { api } from "@/services/api";
|
||||||
import type {
|
import type {
|
||||||
|
Company,
|
||||||
CompanyProfile,
|
CompanyProfile,
|
||||||
CustomerBooking,
|
CustomerBooking,
|
||||||
CustomerDocument,
|
CustomerDocument,
|
||||||
@@ -79,6 +80,32 @@ import {
|
|||||||
type ColumnDef,
|
type ColumnDef,
|
||||||
} from "@edr/ui-common";
|
} 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 }) {
|
function InfoField({ label, value }: { label: string; value?: string | null }) {
|
||||||
return (
|
return (
|
||||||
<Stack gap={2}>
|
<Stack gap={2}>
|
||||||
@@ -814,18 +841,29 @@ export default function CustomerDetailPage() {
|
|||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<Stack gap="lg">
|
<Stack gap="lg">
|
||||||
<Group gap="xs" wrap="nowrap">
|
<Group gap="xs" wrap="nowrap" justify="space-between">
|
||||||
<Text fw={600} c="edr-text">
|
<Group gap="xs" wrap="nowrap">
|
||||||
eTrade registration
|
<Text fw={600} c="edr-text">
|
||||||
</Text>
|
eTrade registration
|
||||||
{hasEtradeRecord ? (
|
</Text>
|
||||||
<Badge size="sm" color="edr-green" variant="light">
|
{hasEtradeRecord ? (
|
||||||
Verified with eTrade
|
<Badge size="sm" color="edr-green" variant="light">
|
||||||
</Badge>
|
Verified with eTrade
|
||||||
) : (
|
</Badge>
|
||||||
<Badge size="sm" color="gray" variant="light">
|
) : (
|
||||||
No eTrade record
|
<Badge size="sm" color="gray" variant="light">
|
||||||
</Badge>
|
No eTrade record
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</Group>
|
||||||
|
{hasEtradeRecord && (
|
||||||
|
<ActionIcon
|
||||||
|
variant="default"
|
||||||
|
aria-label="Download TIN record"
|
||||||
|
onClick={() => downloadTinRecord(company)}
|
||||||
|
>
|
||||||
|
<Download size={16} />
|
||||||
|
</ActionIcon>
|
||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
{hasEtradeRecord ? (
|
{hasEtradeRecord ? (
|
||||||
|
|||||||
@@ -28,6 +28,31 @@ interface ETradeInfoProps {
|
|||||||
|
|
||||||
const isValidTin = (tin: string) => tin.length === 10;
|
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({
|
export default function ETradeInfo({
|
||||||
tin,
|
tin,
|
||||||
register,
|
register,
|
||||||
@@ -123,6 +148,17 @@ export default function ETradeInfo({
|
|||||||
{isLoading ? "Getting..." : "Get Data"}
|
{isLoading ? "Getting..." : "Get Data"}
|
||||||
</Button>
|
</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>
|
</Group>
|
||||||
|
|
||||||
{notFound && (
|
{notFound && (
|
||||||
|
|||||||
Reference in New Issue
Block a user