Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/helpers/__tests__/format-line-item.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { LineItem } from "xero-node";
import { formatLineItem } from "../format-line-item.js";

describe("formatLineItem", () => {
it("formats tracking categories without object stringification", () => {
const lineItem = {
itemCode: "CONSULT",
description: "Consulting services",
tracking: [
{
name: "Project",
option: "Website Redesign",
trackingCategoryID: "category-1",
trackingOptionID: "option-1",
},
{
name: "Cost Centre",
option: "Marketing",
trackingCategoryID: "category-2",
trackingOptionID: "option-2",
},
],
lineAmount: 120,
} as LineItem;

const result = formatLineItem(lineItem);

expect(result).toContain(
"Tracking: Category: Project, Category ID: category-1, Option: Website Redesign, Option ID: option-1; Category: Cost Centre, Category ID: category-2, Option: Marketing, Option ID: option-2",
);
expect(result).not.toContain("[object Object]");
});

it("omits tracking when there are no tracking categories", () => {
expect(
formatLineItem({ description: "No tracking" } as LineItem),
).not.toContain("Tracking:");
});
});
32 changes: 30 additions & 2 deletions src/helpers/format-line-item.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
import { LineItem } from "xero-node";

const formatTracking = (tracking: LineItem["tracking"]): string | undefined => {
if (!tracking?.length) {
return undefined;
}

return tracking
.map((trackingItem) =>
[
trackingItem.name ? `Category: ${trackingItem.name}` : undefined,
trackingItem.trackingCategoryID
? `Category ID: ${trackingItem.trackingCategoryID}`
: undefined,
trackingItem.option ? `Option: ${trackingItem.option}` : undefined,
trackingItem.trackingOptionID
? `Option ID: ${trackingItem.trackingOptionID}`
: undefined,
]
.filter(Boolean)
.join(", "),
)
.filter(Boolean)
.join("; ");
};

export const formatLineItem = (lineItem: LineItem): string => {
const tracking = formatTracking(lineItem.tracking);

return [
`Item ID: ${lineItem.item}`,
`Item Code: ${lineItem.itemCode}`,
Expand All @@ -9,7 +35,9 @@ export const formatLineItem = (lineItem: LineItem): string => {
`Unit Amount: ${lineItem.unitAmount}`,
`Account Code: ${lineItem.accountCode}`,
`Tax Type: ${lineItem.taxType}`,
`Tracking: ${lineItem.tracking}`,
tracking ? `Tracking: ${tracking}` : undefined,
`Line Amount: ${lineItem.lineAmount}`,
].join("\n");
]
.filter(Boolean)
.join("\n");
};