From 096eb80999d33531b3b499b98d150530570f50c8 Mon Sep 17 00:00:00 2001 From: Ben Miller Date: Thu, 31 Jul 2025 21:21:20 -0600 Subject: [PATCH] add product dimensions --- package-lock.json | 6 +- product_inventory.code-workspace | 4 +- src/Product.ts | 100 ++++++++++++++++++++++++++++++- src/global.ts | 1 + src/productTemplate.ts | 5 +- 5 files changed, 109 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7a18e8..396a0dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -430,9 +430,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/product_inventory.code-workspace b/product_inventory.code-workspace index 1c2f936..b3de8c8 100644 --- a/product_inventory.code-workspace +++ b/product_inventory.code-workspace @@ -9,7 +9,7 @@ ], "settings": { "prettier.semi": false, - "cloudcode.duetAI.project": "beepmill-code", - "cloudcode.project": "beepmill-code" + "cloudcode.project": "beepmill-code", + "geminicodeassist.project": "beepmill-code" } } \ No newline at end of file diff --git a/src/Product.ts b/src/Product.ts index 331fb98..c7cefda 100644 --- a/src/Product.ts +++ b/src/Product.ts @@ -5,8 +5,9 @@ import { ShopifyProductsQuery, ShopifyProductsResponse, ShopifyProductSetInput, - ShopifyVariant, + ShopifyProductVariant, ShopifyProductSetQuery, + ShopifyVariant, VariantOptionValueInput, formatGqlForJSON, } from "./shopifyApi" @@ -30,6 +31,9 @@ export class Product { function: string = "" type: string = "" weight_grams: number = 0 + product_width_cm: number = 0 + product_depth_cm: number = 0 + product_height_cm: number = 0 photos: string = "" shopify_product: shopify.Product shopify_default_variant_id: string = "" @@ -135,6 +139,13 @@ export class Product { if (this.compare_at_price > 0) { variant.compareAtPrice = this.compare_at_price } + variant.nodes = [] + let variantWeight = new ShopifyProductVariant() + if (this.weight_grams > 0) { + variantWeight.weight = this.weight_grams + variantWeight.weight_unit = "GRAMS" + variant.nodes.push(variantWeight) + } sps.variants.push(variant) console.log("ToShopifyProductSet:\n" + JSON.stringify(sps, null, 2)) //TODO: add initial inventory @@ -180,6 +191,93 @@ export class Product { shop.UpdateInventoryItemQuantity(item, 1, config) console.log(JSON.stringify(response, null, 2)) } + // update dimension metafields + this.UpdateDimensionMetafields(shop) + } + + UpdateDimensionMetafields(shop: Shop) { + console.log("UpdateDimensionMetafields()") + if (!this.shopify_id) { + console.log("Cannot update metafields without a Shopify Product ID.") + return + } + + const metafieldsToSet: shopify.MetafieldsSetInput[] = [] + + if (this.product_height_cm > 0) { + metafieldsToSet.push({ + key: "product_height_cm", + namespace: "custom", + ownerId: this.shopify_id, + type: "dimension", + value: JSON.stringify({ + value: this.product_height_cm, + unit: "cm", + }), + }) + } + + if (this.product_width_cm > 0) { + metafieldsToSet.push({ + key: "product_width_cm", + namespace: "custom", + ownerId: this.shopify_id, + type: "dimension", + value: JSON.stringify({ + value: this.product_width_cm, + unit: "cm", + }), + }) + } + + if (this.product_depth_cm > 0) { + metafieldsToSet.push({ + key: "product_depth_cm", + namespace: "custom", + ownerId: this.shopify_id, + type: "dimension", + value: JSON.stringify({ + value: this.product_depth_cm, + unit: "cm", + }), + }) + } + + if (metafieldsToSet.length === 0) { + console.log("No dimension metafields to update.") + return + } + + const query = /* GraphQL */ ` + mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) { + metafieldsSet(metafields: $metafields) { + metafields { + id + key + namespace + value + } + userErrors { + field + message + code + } + } + } + ` + + const variables = { + metafields: metafieldsToSet, + } + + const json = `{ + "query": ${formatGqlForJSON(String(query))}, + "variables": ${JSON.stringify(variables)} + }` + + console.log("Setting dimension metafields with query:\n" + json) + const response = shop.shopifyGraphQLAPI(JSON.parse(json)) + console.log("metafieldsSet response: " + JSON.stringify(response, null, 2)) } PublishToShopifyOnlineStore(shop: Shop) { diff --git a/src/global.ts b/src/global.ts index bfda5a1..fd27715 100644 --- a/src/global.ts +++ b/src/global.ts @@ -1,6 +1,7 @@ /// import { onOpen } from "./onOpen" +import { matchProductToShopifyOnEditHandler } from "./OnEditHandler" import { getShopifyProducts } from "./shopifyApi" import { runShopifyOrders } from "./shopifyApi" import { diff --git a/src/productTemplate.ts b/src/productTemplate.ts index b059b06..5faa865 100644 --- a/src/productTemplate.ts +++ b/src/productTemplate.ts @@ -16,7 +16,10 @@ export function productTemplate(row: number) { "tags", "base_price", "shipping", - "weight (grams)", + "weight_grams", + "product_width_cm", + "product_depth_cm", + "product_height_cm", ] let productInventorySheet =