first version
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
import type { AdminApiContext } from "@shopify/shopify-app-react-router/server";
|
||||
|
||||
/**
|
||||
* Raw shape of the data we need from the Shopify Admin GraphQL API to
|
||||
* compose an invoice. Kept narrow so the composer is testable with fixtures.
|
||||
*/
|
||||
export interface RawOrderForInvoice {
|
||||
id: string;
|
||||
name: string;
|
||||
orderNumber: number;
|
||||
createdAt: string;
|
||||
processedAt: string | null;
|
||||
currencyCode: string;
|
||||
displayFinancialStatus: string | null;
|
||||
customer: {
|
||||
firstName: string | null;
|
||||
lastName: string | null;
|
||||
email: string | null;
|
||||
locale: string | null;
|
||||
} | null;
|
||||
billingAddress: RawAddress | null;
|
||||
shippingAddress: RawAddress | null;
|
||||
lineItems: RawLineItem[];
|
||||
taxLines: RawTaxLine[];
|
||||
taxesIncluded: boolean;
|
||||
subtotalSet: { shopMoney: RawMoney } | null;
|
||||
totalTaxSet: { shopMoney: RawMoney } | null;
|
||||
totalPriceSet: { shopMoney: RawMoney } | null;
|
||||
purchasingEntity: {
|
||||
company?: {
|
||||
name: string;
|
||||
vatId: string | null;
|
||||
address: RawAddress | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
export interface RawAddress {
|
||||
name: string | null;
|
||||
company: string | null;
|
||||
address1: string | null;
|
||||
address2: string | null;
|
||||
zip: string | null;
|
||||
city: string | null;
|
||||
province: string | null;
|
||||
countryCode: string | null;
|
||||
}
|
||||
|
||||
export interface RawMoney {
|
||||
amount: string;
|
||||
currencyCode: string;
|
||||
}
|
||||
|
||||
export interface RawLineItem {
|
||||
title: string;
|
||||
sku: string | null;
|
||||
quantity: number;
|
||||
originalUnitPriceSet: { shopMoney: RawMoney };
|
||||
taxLines: RawTaxLine[];
|
||||
}
|
||||
|
||||
export interface RawTaxLine {
|
||||
title: string | null;
|
||||
rate: number | null;
|
||||
ratePercentage: number | null;
|
||||
priceSet: { shopMoney: RawMoney };
|
||||
}
|
||||
|
||||
const QUERY = `#graphql
|
||||
query OrderForInvoice($id: ID!) {
|
||||
order(id: $id) {
|
||||
id
|
||||
name
|
||||
number
|
||||
createdAt
|
||||
processedAt
|
||||
currencyCode
|
||||
displayFinancialStatus
|
||||
taxesIncluded
|
||||
customer {
|
||||
firstName
|
||||
lastName
|
||||
email
|
||||
locale
|
||||
}
|
||||
billingAddress {
|
||||
name
|
||||
company
|
||||
address1
|
||||
address2
|
||||
zip
|
||||
city
|
||||
province
|
||||
countryCode: countryCodeV2
|
||||
}
|
||||
shippingAddress {
|
||||
name
|
||||
company
|
||||
address1
|
||||
address2
|
||||
zip
|
||||
city
|
||||
province
|
||||
countryCode: countryCodeV2
|
||||
}
|
||||
subtotalPriceSet { shopMoney { amount currencyCode } }
|
||||
totalTaxSet { shopMoney { amount currencyCode } }
|
||||
totalPriceSet { shopMoney { amount currencyCode } }
|
||||
taxLines {
|
||||
title
|
||||
rate
|
||||
ratePercentage
|
||||
priceSet { shopMoney { amount currencyCode } }
|
||||
}
|
||||
lineItems(first: 250) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
sku
|
||||
quantity
|
||||
originalUnitPriceSet { shopMoney { amount currencyCode } }
|
||||
taxLines {
|
||||
title
|
||||
rate
|
||||
ratePercentage
|
||||
priceSet { shopMoney { amount currencyCode } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
purchasingEntity {
|
||||
... on PurchasingCompany {
|
||||
company {
|
||||
name
|
||||
}
|
||||
location {
|
||||
taxRegistrationId
|
||||
billingAddress {
|
||||
address1
|
||||
address2
|
||||
zip
|
||||
city
|
||||
countryCode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface RawAdminResponse {
|
||||
data?: {
|
||||
order?: {
|
||||
id: string;
|
||||
name: string;
|
||||
number: number;
|
||||
createdAt: string;
|
||||
processedAt: string | null;
|
||||
currencyCode: string;
|
||||
displayFinancialStatus: string | null;
|
||||
taxesIncluded: boolean;
|
||||
customer: {
|
||||
firstName: string | null;
|
||||
lastName: string | null;
|
||||
email: string | null;
|
||||
locale: string | null;
|
||||
} | null;
|
||||
billingAddress: RawAddress | null;
|
||||
shippingAddress: RawAddress | null;
|
||||
subtotalPriceSet: { shopMoney: RawMoney } | null;
|
||||
totalTaxSet: { shopMoney: RawMoney } | null;
|
||||
totalPriceSet: { shopMoney: RawMoney } | null;
|
||||
taxLines: RawTaxLine[];
|
||||
lineItems: { edges: { node: RawLineItem }[] };
|
||||
purchasingEntity: {
|
||||
company?: { name: string } | null;
|
||||
location?: {
|
||||
taxRegistrationId: string | null;
|
||||
billingAddress: RawAddress | null;
|
||||
} | null;
|
||||
} | null;
|
||||
} | null;
|
||||
};
|
||||
}
|
||||
|
||||
export async function loadOrderForInvoice(
|
||||
admin: AdminApiContext,
|
||||
orderGid: string,
|
||||
): Promise<RawOrderForInvoice> {
|
||||
const response = await admin.graphql(QUERY, { variables: { id: orderGid } });
|
||||
const json = (await response.json()) as RawAdminResponse;
|
||||
const order = json.data?.order;
|
||||
if (!order) {
|
||||
throw new Error(`Order ${orderGid} not found.`);
|
||||
}
|
||||
|
||||
const purchasingCompany = order.purchasingEntity?.company
|
||||
? {
|
||||
name: order.purchasingEntity.company.name,
|
||||
vatId: order.purchasingEntity.location?.taxRegistrationId ?? null,
|
||||
address: order.purchasingEntity.location?.billingAddress ?? null,
|
||||
}
|
||||
: null;
|
||||
|
||||
return {
|
||||
id: order.id,
|
||||
name: order.name,
|
||||
orderNumber: order.number,
|
||||
createdAt: order.createdAt,
|
||||
processedAt: order.processedAt,
|
||||
currencyCode: order.currencyCode,
|
||||
displayFinancialStatus: order.displayFinancialStatus,
|
||||
taxesIncluded: order.taxesIncluded,
|
||||
customer: order.customer,
|
||||
billingAddress: order.billingAddress,
|
||||
shippingAddress: order.shippingAddress,
|
||||
subtotalSet: order.subtotalPriceSet,
|
||||
totalTaxSet: order.totalTaxSet,
|
||||
totalPriceSet: order.totalPriceSet,
|
||||
taxLines: order.taxLines || [],
|
||||
lineItems: (order.lineItems?.edges || []).map((e) => e.node),
|
||||
purchasingEntity: { company: purchasingCompany },
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user