new product defaults are set correctly
This commit is contained in:
7
package-lock.json
generated
7
package-lock.json
generated
@ -11,7 +11,7 @@
|
||||
"@types/google-apps-script": "^1.0.85",
|
||||
"gas-webpack-plugin": "^2.6.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"shopify-admin-api-typings": "^1.2.2",
|
||||
"shopify-admin-api-typings": "github:beepmill/shopify-admin-api-typings",
|
||||
"ts-loader": "^9.5.1",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-cli": "^5.1.4"
|
||||
@ -1474,9 +1474,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/shopify-admin-api-typings": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/shopify-admin-api-typings/-/shopify-admin-api-typings-1.2.2.tgz",
|
||||
"integrity": "sha512-n9NSBPBKX+TSfAr8ibpXKoGdHCUCY6WBKV2FhD9xvjGG3DIqqUylqhC3OXKiWcrTQuyb3WnaRCvl16i3uhJMiQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "git+ssh://git@github.com/beepmill/shopify-admin-api-typings.git#e8ba51acff0a4e66c31ee61d62f5244ad4f4233a",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
"@types/google-apps-script": "^1.0.85",
|
||||
"gas-webpack-plugin": "^2.6.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"shopify-admin-api-typings": "^1.2.2",
|
||||
"shopify-admin-api-typings": "github:beepmill/shopify-admin-api-typings",
|
||||
"ts-loader": "^9.5.1",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-cli": "^5.1.4"
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "../shopify-admin-api-typings"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
|
||||
100
src/Product.ts
100
src/Product.ts
@ -30,7 +30,7 @@ export class Product {
|
||||
type: string = ""
|
||||
weight_grams: number = 0
|
||||
photos: string = ""
|
||||
shopify_product: ShopifyProduct
|
||||
shopify_product: shopify.Product
|
||||
shopify_default_variant_id: string = ""
|
||||
shopify_default_option_id: string = ""
|
||||
shopify_default_option_value_id: string = ""
|
||||
@ -73,52 +73,17 @@ export class Product {
|
||||
}
|
||||
}
|
||||
|
||||
MatchToShopifyProduct(shop: Shop) {
|
||||
/* if (this.shopify_id.startsWith("gid://shopify/Product/")) {
|
||||
return
|
||||
} */
|
||||
|
||||
let query = new ShopifyProductsQuery("sku:" + this.sku, ["id", "title"])
|
||||
console.log(query.JSON)
|
||||
let response = shop.shopifyGraphQLAPI(query.JSON)
|
||||
console.log(response)
|
||||
let productsResponse = new ShopifyProductsResponse(response.content)
|
||||
if (productsResponse.products.edges.length <= 0) {
|
||||
console.log("no products matched")
|
||||
MatchToShopifyProduct(shop: Shop): shopify.Product {
|
||||
let product = shop.GetProductBySku(this.sku)
|
||||
if (product == undefined || product.id == undefined || product.id == "") {
|
||||
console.log("MatchToShopifyProduct: no product matched")
|
||||
return
|
||||
}
|
||||
if (productsResponse.products.edges.length > 1) {
|
||||
console.log("more than one product matched")
|
||||
return
|
||||
}
|
||||
this.shopify_product = productsResponse.products.edges[0].node
|
||||
this.shopify_product = product
|
||||
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
|
||||
this.shopify_default_variant_id = product.variants.nodes[0].id
|
||||
this.shopify_default_option_id = product.options[0].id
|
||||
this.shopify_default_option_value_id = product.options[0].optionValues[0].id
|
||||
let productInventorySheet =
|
||||
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("product_inventory")
|
||||
let row = getRowByColumnValue("product_inventory", "sku", this.sku)
|
||||
@ -134,7 +99,7 @@ export class Product {
|
||||
if (this.shopify_id != "") {
|
||||
sps.id = this.shopify_id
|
||||
}
|
||||
if (this.shopify_status.match('DRAFT|ACTIVE|ARCHIVED')) {
|
||||
if (this.shopify_status.match("DRAFT|ACTIVE|ARCHIVED")) {
|
||||
sps.status = this.shopify_status
|
||||
}
|
||||
sps.productType = this.product_type
|
||||
@ -151,26 +116,50 @@ export class Product {
|
||||
variant.price = this.price
|
||||
sps.variants.push(variant)
|
||||
console.log("ToShopifyProductSet:\n" + JSON.stringify(sps, null, 2))
|
||||
//TODO: add sales channels
|
||||
//TODO: add initial inventory
|
||||
return sps
|
||||
}
|
||||
|
||||
UpdateShopifyProduct(shop: Shop) {
|
||||
console.log("UpdateShopifyProduct()")
|
||||
var newProduct = false
|
||||
let config = new Config()
|
||||
this.MatchToShopifyProduct(shop)
|
||||
if (this.shopify_id == "") {
|
||||
console.log(
|
||||
"UpdateShopifyProduct: no product matched, this will be a new product"
|
||||
)
|
||||
newProduct = true
|
||||
}
|
||||
console.log("UpdateShopifyProduct: calling productSet")
|
||||
let sps = this.ToShopifyProductSet()
|
||||
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))
|
||||
this.MatchToShopifyProduct(shop)
|
||||
let product = response.content.data.productSet.product
|
||||
this.shopify_id = product.id
|
||||
if (newProduct) {
|
||||
console.log("UpdateShopifyProduct: setting defaults on new product")
|
||||
let item: shopify.InventoryItem
|
||||
do {
|
||||
console.log("UpdateShopifyProduct: attempting to get inventory item")
|
||||
item = shop.GetInventoryItemBySku(this.sku)
|
||||
} while (item.id == "")
|
||||
console.log("UpdateShopifyProduct: setting defaults on inventory item")
|
||||
shop.SetInventoryItemDefaults(item, config)
|
||||
console.log("UpdateShopifyProduct: publishing to online store")
|
||||
response = this.PublishToShopifyOnlineStore(shop)
|
||||
this.MatchToShopifyProduct(shop)
|
||||
console.log("UpdateShopifyProduct: adjusting inventory item quantity")
|
||||
shop.UpdateInventoryItemQuantity(item, 1, config)
|
||||
console.log(JSON.stringify(response, null, 2))
|
||||
}
|
||||
// Update to include new changes
|
||||
console.log("UpdateShopifyProduct: updating inventory match")
|
||||
this.MatchToShopifyProduct(shop)
|
||||
}
|
||||
|
||||
PublishToShopifyOnlineStore(shop: Shop) {
|
||||
console.log("PublishToShopifyOnlineStore")
|
||||
let config = new Config()
|
||||
let query = /* GraphQL */ `
|
||||
mutation publishablePublish($id: ID!, $input: [PublicationInput!]!) {
|
||||
@ -191,12 +180,13 @@ export class Product {
|
||||
message
|
||||
}
|
||||
}
|
||||
}`
|
||||
let variables = {
|
||||
"id": this.shopify_id,
|
||||
"input": {
|
||||
"publicationId": config.shopifyStorePublicationId
|
||||
}
|
||||
`
|
||||
let variables = {
|
||||
id: this.shopify_id,
|
||||
input: {
|
||||
publicationId: config.shopifyStorePublicationId,
|
||||
},
|
||||
}
|
||||
let j = `{
|
||||
"query": ${formatGqlForJSON(String(query))},
|
||||
|
||||
@ -7,7 +7,9 @@ export class Config {
|
||||
shopifyAdminApiAccessToken: string
|
||||
shopifyApiURI: string
|
||||
shopifyStorePublicationId: string
|
||||
|
||||
shopifyLocationId: string
|
||||
shopifyCountryCodeOfOrigin: string
|
||||
shopifyProvinceCodeOfOrigin: string
|
||||
|
||||
constructor() {
|
||||
let ss = SpreadsheetApp.getActive()
|
||||
@ -49,5 +51,23 @@ export class Config {
|
||||
"shopifyStorePublicationId",
|
||||
"value"
|
||||
)
|
||||
this.shopifyLocationId = vlookupByColumns(
|
||||
"vars",
|
||||
"key",
|
||||
"shopifyLocationId",
|
||||
"value"
|
||||
)
|
||||
this.shopifyCountryCodeOfOrigin = vlookupByColumns(
|
||||
"vars",
|
||||
"key",
|
||||
"shopifyCountryCodeOfOrigin",
|
||||
"value"
|
||||
)
|
||||
this.shopifyProvinceCodeOfOrigin = vlookupByColumns(
|
||||
"vars",
|
||||
"key",
|
||||
"shopifyProvinceCodeOfOrigin",
|
||||
"value"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,6 +517,160 @@ export class Shop {
|
||||
} while (!done)
|
||||
}
|
||||
|
||||
GetProductBySku(sku: string) {
|
||||
console.log("GetProductBySku('" + sku + "')")
|
||||
let gql = /* GraphQL */ `
|
||||
query productBySku {
|
||||
products(first: 1, query: "sku:${sku}") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
title
|
||||
handle
|
||||
variants(first: 1) {
|
||||
nodes {
|
||||
id
|
||||
sku
|
||||
}
|
||||
}
|
||||
options {
|
||||
id
|
||||
name
|
||||
optionValues {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
let query = buildGqlQuery(gql, {})
|
||||
let response = this.shopifyGraphQLAPI(query)
|
||||
if (response.content.data.products.edges.length <= 0) {
|
||||
console.log("GetProductBySku: no product matched")
|
||||
return
|
||||
}
|
||||
let product = response.content.data.products.edges[0].node
|
||||
console.log("Product found:\n" + JSON.stringify(product, null, 2))
|
||||
return product
|
||||
}
|
||||
|
||||
GetInventoryItemBySku(sku: string) {
|
||||
console.log('GetInventoryItemBySku("' + sku + '")')
|
||||
let gql = /* GraphQL */ `
|
||||
query inventoryItems {
|
||||
inventoryItems(first:1, query:"sku:${sku}") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
tracked
|
||||
sku
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
let query = buildGqlQuery(gql, {})
|
||||
let response = this.shopifyGraphQLAPI(query)
|
||||
let item: shopify.InventoryItem =
|
||||
response.content.data.inventoryItems.edges[0].node
|
||||
console.log(
|
||||
"GetInventoryItemBySku: found item:\n" + JSON.stringify(item, null, 2)
|
||||
)
|
||||
return item
|
||||
}
|
||||
|
||||
UpdateInventoryItemQuantity(
|
||||
item: shopify.InventoryItem,
|
||||
delta: number = 1,
|
||||
config: Config
|
||||
) {
|
||||
console.log("UpdateInventoryItemQuantity(" + JSON.stringify(item) + ")")
|
||||
let gql = /* GraphQL */ `
|
||||
mutation inventoryAdjustQuantities(
|
||||
$input: InventoryAdjustQuantitiesInput!
|
||||
) {
|
||||
inventoryAdjustQuantities(input: $input) {
|
||||
userErrors {
|
||||
field
|
||||
message
|
||||
}
|
||||
inventoryAdjustmentGroup {
|
||||
createdAt
|
||||
reason
|
||||
referenceDocumentUri
|
||||
changes {
|
||||
name
|
||||
delta
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
let variables = {
|
||||
input: {
|
||||
reason: "correction",
|
||||
name: "available",
|
||||
changes: [
|
||||
{
|
||||
delta: delta,
|
||||
inventoryItemId: item.id,
|
||||
locationId: config.shopifyLocationId,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
let query = buildGqlQuery(gql, variables)
|
||||
let response = this.shopifyGraphQLAPI(query)
|
||||
let newItem: shopify.InventoryItem = response.content
|
||||
console.log("new item:\n" + JSON.stringify(newItem, null, 2))
|
||||
return newItem
|
||||
}
|
||||
|
||||
SetInventoryItemDefaults(item: shopify.InventoryItem, config: Config) {
|
||||
let gql = /* GraphQL */ `
|
||||
mutation inventoryItemUpdate($id: ID!, $input: InventoryItemInput!) {
|
||||
inventoryItemUpdate(id: $id, input: $input) {
|
||||
inventoryItem {
|
||||
id
|
||||
unitCost {
|
||||
amount
|
||||
}
|
||||
tracked
|
||||
countryCodeOfOrigin
|
||||
provinceCodeOfOrigin
|
||||
harmonizedSystemCode
|
||||
countryHarmonizedSystemCodes(first: 1) {
|
||||
edges {
|
||||
node {
|
||||
harmonizedSystemCode
|
||||
countryCode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
userErrors {
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
let variables = {
|
||||
id: item.id,
|
||||
input: {
|
||||
tracked: true,
|
||||
countryCodeOfOrigin: config.shopifyCountryCodeOfOrigin,
|
||||
provinceCodeOfOrigin: config.shopifyProvinceCodeOfOrigin,
|
||||
},
|
||||
}
|
||||
let query = buildGqlQuery(gql, variables)
|
||||
let response = this.shopifyGraphQLAPI(query)
|
||||
let newItem: shopify.InventoryItem = response.content
|
||||
return newItem
|
||||
}
|
||||
|
||||
shopifyAPI(endpoint: string, query: {}, next = "") {
|
||||
var options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
|
||||
method: "get",
|
||||
@ -541,6 +695,7 @@ export class Shop {
|
||||
}
|
||||
|
||||
shopifyGraphQLAPI(query: {}, next = "") {
|
||||
console.log("shopifyGraphQLAPI:query: " + JSON.stringify(query))
|
||||
let endpoint = Shop.endpoints.graphql
|
||||
let options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
|
||||
method: "post",
|
||||
@ -552,10 +707,13 @@ export class Shop {
|
||||
muteHttpExceptions: true,
|
||||
}
|
||||
var url = this.buildURL(endpoint)
|
||||
console.log(UrlFetchApp.getRequest(url, options))
|
||||
console.log(
|
||||
"shopifyGraphQLAPI sending request:\n" +
|
||||
JSON.stringify(UrlFetchApp.getRequest(url, options), null, 2)
|
||||
)
|
||||
var resp = UrlFetchApp.fetch(url, options)
|
||||
let content = resp.getContentText()
|
||||
console.log(content)
|
||||
console.log("shopifyGraphQLAPI got response:\n" + content)
|
||||
let content_json = JSON.parse(content)
|
||||
console.log(JSON.stringify(content_json, null, 2))
|
||||
|
||||
@ -737,8 +895,8 @@ export class ShopifyVariant {
|
||||
optionValues: [{}] = [
|
||||
{
|
||||
optionName: "Title",
|
||||
name: "Default Title"
|
||||
}
|
||||
name: "Default Title",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -756,7 +914,7 @@ export class ShopifyProductsQuery {
|
||||
query: string = "",
|
||||
fields: string[] = ["id", "title", "handle"],
|
||||
cursor: string = "",
|
||||
pageSize: number = 10,
|
||||
pageSize: number = 10
|
||||
) {
|
||||
let cursorText: string
|
||||
if (cursor == "") {
|
||||
@ -838,7 +996,8 @@ export class ShopifyProductSetQuery {
|
||||
let j = `{
|
||||
"query": ${formatGqlForJSON(String(this.GQL))},
|
||||
"variables": {
|
||||
"productSet": ${JSON.stringify(product)}
|
||||
"productSet": ${JSON.stringify(product)},
|
||||
"synchronous": ${synchronous}
|
||||
}
|
||||
}`
|
||||
console.log(j)
|
||||
@ -862,9 +1021,9 @@ export class ShopifyProductSetInput {
|
||||
{
|
||||
name: "Title",
|
||||
values: {
|
||||
name: "Default Title"
|
||||
}
|
||||
}
|
||||
name: "Default Title",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -904,4 +1063,11 @@ export function getShopifyProducts() {
|
||||
shop.GetProducts()
|
||||
}
|
||||
|
||||
(global as any)
|
||||
export function buildGqlQuery(gql: string, variables: {}) {
|
||||
let query = `{
|
||||
"query": ${formatGqlForJSON(String(gql))},
|
||||
"variables": ${JSON.stringify(variables)}
|
||||
}`
|
||||
console.log("buildGqlQuery:\n" + query)
|
||||
return JSON.parse(query)
|
||||
}
|
||||
Reference in New Issue
Block a user