96 lines
3.0 KiB
JavaScript
96 lines
3.0 KiB
JavaScript
// app/utils/shopify-products.server.js
|
||
|
||
/**
|
||
* Given a Turn14 item object and a Shopify Admin client,
|
||
* creates the product + media + joins the specified collection +
|
||
* sets price + sets SKU.
|
||
*/
|
||
export async function createFullProductFromTurn14Item(admin, item, collectionId) {
|
||
// 1️⃣ Create product + media + join collection
|
||
const createRes = await admin.graphql(
|
||
`mutation CreateFullProduct($product: ProductCreateInput!, $media: [CreateMediaInput!]) {
|
||
productCreate(product: $product, media: $media) {
|
||
product {
|
||
id
|
||
variants(first:1) {
|
||
nodes {
|
||
id
|
||
inventoryItem { id }
|
||
}
|
||
}
|
||
}
|
||
userErrors { field message }
|
||
}
|
||
}`,
|
||
{
|
||
variables: {
|
||
product: {
|
||
title: item.attributes.product_name,
|
||
descriptionHtml: item.attributes.part_description,
|
||
vendor: item.attributes.brand.name,
|
||
productType: item.attributes.category,
|
||
handle: item.attributes.part_number.toLowerCase(),
|
||
tags: [item.attributes.category, item.attributes.subcategory],
|
||
collectionsToJoin: collectionId ? [collectionId] : [],
|
||
status: "ACTIVE",
|
||
},
|
||
media: [{
|
||
originalSource: item.attributes.images?.[0]?.url,
|
||
mediaContentType: "IMAGE",
|
||
alt: `${item.attributes.product_name} image`,
|
||
}],
|
||
},
|
||
}
|
||
);
|
||
const { productCreate } = await createRes.json();
|
||
if (productCreate.userErrors.length) {
|
||
throw new Error(productCreate.userErrors.map(e => e.message).join(", "));
|
||
}
|
||
const newProduct = productCreate.product;
|
||
const variantNode = newProduct.variants.nodes[0];
|
||
const variantId = variantNode.id;
|
||
const inventoryItemId = variantNode.inventoryItem.id;
|
||
|
||
// 2️⃣ Update price
|
||
const priceRes = await admin.graphql(
|
||
`mutation UpdatePrice($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
|
||
productVariantsBulkUpdate(productId: $productId, variants: $variants) {
|
||
productVariants { id price }
|
||
userErrors { field message }
|
||
}
|
||
}`,
|
||
{
|
||
variables: {
|
||
productId: newProduct.id,
|
||
variants: [{ id: variantId, price: parseFloat(item.attributes.price) || 0 }],
|
||
},
|
||
}
|
||
);
|
||
const { productVariantsBulkUpdate } = await priceRes.json();
|
||
if (productVariantsBulkUpdate.userErrors.length) {
|
||
throw new Error(productVariantsBulkUpdate.userErrors.map(e => e.message).join(", "));
|
||
}
|
||
|
||
// 3️⃣ Set SKU
|
||
const skuRes = await admin.graphql(
|
||
`mutation SetSKU($id: ID!, $input: InventoryItemInput!) {
|
||
inventoryItemUpdate(id: $id, input: $input) {
|
||
inventoryItem { sku }
|
||
userErrors { field message }
|
||
}
|
||
}`,
|
||
{
|
||
variables: {
|
||
id: inventoryItemId,
|
||
input: { sku: item.attributes.part_number },
|
||
},
|
||
}
|
||
);
|
||
const { inventoryItemUpdate } = await skuRes.json();
|
||
if (inventoryItemUpdate.userErrors.length) {
|
||
throw new Error(inventoryItemUpdate.userErrors.map(e => e.message).join(", "));
|
||
}
|
||
|
||
return { productId: newProduct.id };
|
||
}
|