Created
February 13, 2023 01:00
-
-
Save sjb9774/caeda1946de4298100e2313cae0c9153 to your computer and use it in GitHub Desktop.
Modified main.rs for Shopify Product Discount Function example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
query Input { | |
discountNode { | |
metafield(namespace: "my-discount-namespace", key: "my-discount-amount") { | |
value | |
} | |
} | |
cart { | |
lines { | |
merchandise { | |
__typename | |
... on ProductVariant { | |
id | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// compare to https://github.com/Shopify/shopify-function-rust/blob/main/example/src/main.rs | |
use shopify_function::prelude::*; | |
use shopify_function::Result; | |
use serde::{Deserialize, Serialize}; | |
generate_types!( | |
query_path = "./input.graphql", | |
schema_path = "./schema.graphql" | |
); | |
type MyDiscountType = String; | |
#[derive(Serialize, Deserialize, Default, PartialEq)] | |
#[serde(rename_all(deserialize = "camelCase"))] | |
struct MyDiscountDetails { | |
discount_type: MyDiscountType, | |
value: String | |
} | |
// Use nested structs to mimic the JSON structure of the metafield so it can be deserialized into out types using serde_json::from_str | |
#[derive(Serialize, Deserialize, Default, PartialEq)] | |
#[serde(rename_all(deserialize = "camelCase"))] | |
struct Configuration { | |
discount: MyDiscountDetails | |
} | |
impl Configuration { | |
fn from_str(value: &str) -> Self { | |
serde_json::from_str(value).expect("Unable to parse configuration value from metafield") | |
} | |
} | |
#[shopify_function] | |
fn function(input: input::ResponseData) -> Result<output::FunctionResult> { | |
// Prep a response that indicates no discounts applied | |
let no_discount = output::FunctionResult { | |
discounts: vec![], | |
discount_application_strategy: output::DiscountApplicationStrategy::FIRST, | |
}; | |
// If there is a metafield value defined, parse out our config otherwise immediately return "no discount" response | |
let config = match input.discount_node.metafield { | |
Some(input::InputDiscountNodeMetafield { value }) => | |
Configuration::from_str(&value), | |
None => return Ok(no_discount), | |
}; | |
let config_discount_type = &config.discount.discount_type; | |
let config_discount_amount = &config.discount.value; | |
let _p_string = "percentage".to_string(); | |
// confirm we can match the discount type to "percentage" — notably nothing happens if the discount type is anything else | |
// assuming we have a "percentage" discount then output_discount is set as a Percentage object with a discount value equal to our configured value | |
let output_discount = match config_discount_type { | |
_p_string => output::Percentage { value: config_discount_amount.to_string() } | |
}; | |
let first_merch = &input.cart.lines[0].merchandise; | |
// if there's at least one item in the cart (should always be) and if so track the id of that first item | |
let first_id = match first_merch { | |
input::InputCartLinesMerchandise::ProductVariant(variant) => &variant.id, | |
_ => "" | |
}; | |
// Return a response applying our configured discount amount to the first line item in the cart with no quantity limit | |
return Ok(output::FunctionResult { | |
discounts: vec![output::Discount { | |
message: Some("Your Shopify Function is working!".to_string()), | |
targets: vec![ | |
output::Target { product_variant: Some(output::ProductVariantTarget {id: first_id.to_string(), quantity: None }) } | |
], | |
value: output::Value { percentage: Some(output_discount), fixed_amount: None } | |
}], | |
discount_application_strategy: output::DiscountApplicationStrategy::FIRST, | |
}); | |
} | |
#[cfg(test)] | |
mod tests; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment