a little bit farther

This commit is contained in:
Ben Miller
2024-11-14 08:36:08 -07:00
parent 220ee45e22
commit ca48bb6572
2 changed files with 174 additions and 47 deletions

View File

@ -1,8 +1,16 @@
// prettier-ignore // prettier-ignore
import { Shop, ShopifyProduct, ShopifyProductsQuery, ShopifyProductsResponse, ShopifyProductSetInput, ShopifyProductVariant } from "./shopifyApi" import {
Shop,
ShopifyProduct,
ShopifyProductsQuery,
ShopifyProductsResponse,
ShopifyProductSetInput,
ShopifyVariant,
ShopifyProductSetQuery,
VariantOptionValueInput,
} from "./shopifyApi"
import { getCellRangeByColumnName, getRowByColumnValue } from "./sheetUtils" import { getCellRangeByColumnName, getRowByColumnValue } from "./sheetUtils"
export class Product { export class Product {
shopify_id: string = "" shopify_id: string = ""
title: string = "" title: string = ""
@ -19,6 +27,9 @@ export class Product {
weight_grams: number = 0 weight_grams: number = 0
photos: string = "" photos: string = ""
shopify_product: ShopifyProduct shopify_product: ShopifyProduct
shopify_default_variant_id: string
shopify_default_option_id: string
shopify_default_option_value_id: string
constructor(sku: string = "") { constructor(sku: string = "") {
if (sku == "") { if (sku == "") {
@ -58,14 +69,11 @@ export class Product {
} }
MatchToShopifyProduct(shop: Shop) { MatchToShopifyProduct(shop: Shop) {
if (this.shopify_id.startsWith("gid://shopify/Product/")) { /* if (this.shopify_id.startsWith("gid://shopify/Product/")) {
return return
} } */
let query = new ShopifyProductsQuery( let query = new ShopifyProductsQuery("sku:" + this.sku, ["id", "title"])
"sku:" + this.sku,
["id", "title"]
)
console.log(query.JSON) console.log(query.JSON)
let response = shop.shopifyGraphQLAPI(query.JSON) let response = shop.shopifyGraphQLAPI(query.JSON)
console.log(response) console.log(response)
@ -80,6 +88,32 @@ export class Product {
} }
this.shopify_product = productsResponse.products.edges[0].node this.shopify_product = productsResponse.products.edges[0].node
this.shopify_id = this.shopify_product.id.toString() this.shopify_id = this.shopify_product.id.toString()
this.shopify_default_variant_id =
productsResponse.products.edges[0].node.variants.nodes[0].id
console.log(JSON.stringify(productsResponse, null, 2))
console.log(JSON.stringify(productsResponse.products, null, 2))
console.log(JSON.stringify(productsResponse.products.edges[0], null, 2))
console.log(
JSON.stringify(productsResponse.products.edges[0].node, null, 2)
)
console.log(
JSON.stringify(
productsResponse.products.edges[0].node.options[0],
null,
2
)
)
console.log(
JSON.stringify(
productsResponse.products.edges[0].node.options[0].id,
null,
2
)
)
this.shopify_default_option_id =
productsResponse.products.edges[0].node.options[0].id
this.shopify_default_option_value_id =
productsResponse.products.edges[0].node.options[0].optionValues[0].id
let productInventorySheet = let productInventorySheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("product_inventory") SpreadsheetApp.getActiveSpreadsheet().getSheetByName("product_inventory")
let row = getRowByColumnValue("product_inventory", "sku", this.sku) let row = getRowByColumnValue("product_inventory", "sku", this.sku)
@ -90,24 +124,32 @@ export class Product {
ToShopifyProductSet() { ToShopifyProductSet() {
let sps = new ShopifyProductSetInput() let sps = new ShopifyProductSetInput()
sps.category = this.category //TODO: map category IDs
//sps.category = this.category
sps.id = this.shopify_id sps.id = this.shopify_id
sps.productType = this.product_type sps.productType = this.product_type
sps.tags = this.tags sps.tags = this.tags
sps.title = this.title sps.title = this.title
sps.descriptionHtml = this.description sps.descriptionHtml = this.description
sps.variants = [] sps.variants = []
let variant = new ShopifyProductVariant() let variant = new ShopifyVariant()
variant.id = 1 //TODO: handle multiple variants
variant.id = this.shopify_default_variant_id
variant.sku = this.sku variant.sku = this.sku
variant.price = this.price variant.price = this.price
variant.weight = this.weight_grams
sps.variants.push(variant) sps.variants.push(variant)
let opt = new ShopifyVa
let options = new VariantOptionValueInput()
options.id = this.shopify_default_option_value_id
return sps return sps
} }
UpdateShopifyProduct(shop: Shop) { UpdateShopifyProduct(shop: Shop) {
let sps = this.ToShopifyProductSet() let sps = this.ToShopifyProductSet()
console.log("sps: " + JSON.stringify(sps)) console.log("sps: " + JSON.stringify(sps))
let query = new ShopifyProductSetQuery(sps)
console.log(JSON.stringify(query))
let response = shop.shopifyGraphQLAPI(query.JSON)
console.log(JSON.stringify(response, null, 2))
} }
} }

View File

@ -552,10 +552,13 @@ export class Shop {
var url = this.buildURL(endpoint) var url = this.buildURL(endpoint)
console.log(UrlFetchApp.getRequest(url, options)) console.log(UrlFetchApp.getRequest(url, options))
var resp = UrlFetchApp.fetch(url, options) var resp = UrlFetchApp.fetch(url, options)
console.log(resp.getContentText()) let content = resp.getContentText()
console.log(content)
let content_json = JSON.parse(content)
console.log(JSON.stringify(content_json, null, 2))
return { return {
content: JSON.parse(resp.getContentText()), content: content_json,
headers: resp.getHeaders(), headers: resp.getHeaders(),
} }
} }
@ -614,7 +617,7 @@ export class ShopifyProduct {
body_html: string body_html: string
created_at: Date created_at: Date
handle: string handle: string
id: number id: string
images: ProductImage[] images: ProductImage[]
options: ProductOption[] options: ProductOption[]
product_type: string product_type: string
@ -625,10 +628,14 @@ export class ShopifyProduct {
template_suffix: string template_suffix: string
title: string title: string
updated_at: Date updated_at: Date
variants: ShopifyProductVariant[] variants: ShopifyVariantNodes
vendor: string vendor: string
} }
export class ShopifyVariantNodes {
nodes: ShopifyProductVariant[]
}
class ProductImage { class ProductImage {
id: number id: number
product_id: number product_id: number
@ -642,11 +649,25 @@ class ProductImage {
} }
class ProductOption { class ProductOption {
id: number id: string
product_id: number product_id: number
name: string name: string
position: number position: number
values: string[] values: string[]
optionValues?: ShopifyProductOptionValues
}
export class ShopifyProductOptionValues {
id?: string
name?: string
}
export class ShopifyVariantOptionValueInput {
id?: string
linkedMetafieldValue?: string
name?: string
optionId?: string
optionName?: string
} }
export class ShopifyProductVariant { export class ShopifyProductVariant {
@ -657,7 +678,7 @@ export class ShopifyProductVariant {
grams: number grams: number
weight: number weight: number
weight_unit: string weight_unit: string
id: number id: string
inventory_item_id: number inventory_item_id: number
inventory_management: string inventory_management: string
inventory_policy: string inventory_policy: string
@ -680,9 +701,39 @@ class Products {
class ProductEdge { class ProductEdge {
node: ShopifyProduct node: ShopifyProduct
variants?: ShopifyVariants
options?: ShopifyProductOption[]
cursor: string cursor: string
} }
export class ShopifyProductOption {
id?: string
name?: string
optionValues?: ShopifyProductOptionValue[]
values?: ShopifyProductOptionValue[]
}
export class ShopifyProductOptionValue {
id?: string
name?: string
}
export class ShopifyVariants {
nodes?: ShopifyVariant[]
node?: ShopifyVariant
}
export class ShopifyVariant {
id?: string
sku?: string
price?: number
compareAtPrice?: number
barcode?: string
position?: number
nodes?: ShopifyProductVariant[]
optionValues?: VariantOptionValueInput[]
}
class PageInfo { class PageInfo {
hasNextPage: boolean hasNextPage: boolean
hasPreviousPage: boolean hasPreviousPage: boolean
@ -714,7 +765,22 @@ export class ShopifyProductsQuery {
this.GQL = `{ this.GQL = `{
products(first: ${pageSize}${cursorText}${queryText}) { products(first: ${pageSize}${cursorText}${queryText}) {
edges { edges {
node { ${fields.join(" ")} } node {
${fields.join(" ")}
variants(first:1) {
nodes {
id
}
}
options {
id
name
optionValues {
id
name
}
}
}
} }
pageInfo { pageInfo {
hasNextPage hasNextPage
@ -736,38 +802,35 @@ export class ShopifyProductsResponse {
} }
export class ShopifyProductSetQuery { export class ShopifyProductSetQuery {
GQL: string GQL: string = `mutation setProduct($productSet: ProductSetInput!) {
JSON: JSON productSet(input: $productSet) {
constructor( product {
query: string = "", id
fields: string[] = ["id", "title", "handle"],
cursor: string = "",
pageSize: number = 10
) {
let cursorText: string
if (cursor == "") {
cursorText = ""
} else {
cursorText = `, after: "${cursor}"`
} }
let queryText: string productSetOperation {
if (query == "") { id
queryText = "" status
} else { userErrors {
queryText = `, query: "${query}"` code
field
message
} }
this.GQL = `{
products(first: ${pageSize}${cursorText}${queryText}) {
edges {
node { ${fields.join(" ")} }
} }
pageInfo { userErrors {
hasNextPage code
endCursor field
message
} }
} }
}` }`
let j = `{"query": ${formatGqlForJSON(this.GQL)}}` JSON: JSON
constructor(product: ShopifyProductSetInput, synchronous: boolean = true) {
let j = `{
"query": ${formatGqlForJSON(this.GQL)},
"variables": {
"productSet": ${JSON.stringify(product)}
}
}`
console.log(j) console.log(j)
this.JSON = JSON.parse(j) this.JSON = JSON.parse(j)
} }
@ -782,8 +845,30 @@ export class ShopifyProductSetInput {
status: string = "DRAFT" status: string = "DRAFT"
tags: string tags: string
title: string title: string
variants: ShopifyProductVariant[]
vendor: string vendor: string
variants: ShopifyVariant[]
productOptions: ShopifyProductOption[]
}
export class ProductVariantSetInput {
barcode: string
compareAtPrice: number
id: string
optionValues: VariantOptionValueInput[] = []
position?: number
price?: number
requiresComponents?: boolean
sku?: string
taxable?: boolean
taxCode?: string
}
export class VariantOptionValueInput {
id?: string
linkedMetafieldValue?: string
name?: string
optionId?: string
optionName?: string
} }
function formatGqlForJSON(gql: string) { function formatGqlForJSON(gql: string) {