Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProductVariant CompareAtPrice can't be set to empty #373

Closed
lantram opened this issue Jun 13, 2019 · 4 comments
Closed

ProductVariant CompareAtPrice can't be set to empty #373

lantram opened this issue Jun 13, 2019 · 4 comments
Labels
object updating Bugs and strange behavior around updating objects, primarly related to #284

Comments

@lantram
Copy link

lantram commented Jun 13, 2019

Perhaps I'm missing something, but it doesn't seem possible to set CompareAtPrice to null or empty. :?

decimal? price = _largest(variant.Price, variant.CompareAtPrice);
await variantService.UpdateAsync(variant.Id.Value,
    new ProductVariant()
    {
        Price = price,
        CompareAtPrice = null
    });
@nozzlegear
Copy link
Owner

nozzlegear commented Jun 13, 2019

This is related #284. The CompareAtPrice property is not included if the value is null, which means it can't be unset. That's a bug obviously, but the fix isn't any better since by including the null value you can then accidentally remove it when updating a variant too. I'm actively working on finding a better solution for updating objects, since either setting has undesired behavior that can bite the dev if they don't know what to watch for.

For now you should be able to work around the behavior by creating your own class for the data you're sending, and then extend the ProductVariantService with a custom method that accepts that class. Something like this:

public class ProductVariantCompareAtPrice
{
    [JsonProperty("price")]
    public decimal Price { get; set; }

	[JsonProperty("compare_at_price", DefaultValueHandling = DefaultValueHandling.Include)]
	public decimal? CompareAtPrice { get; set; }
}

public class CustomProductVariantService : ProductVariantService
{
    public CustomProductVariantService(string domain, string token) : base(domain, token) { }

    public async Task<ProductVariant> UpdateCompareAtPriceAsync(long variantId, ProductVariantCompareAtPrice data)
    {
		var req = PrepareRequest($"variants/{variantId}.json");
		var content = new JsonContent(new
		{
			variant = data
		});

		return await ExecuteRequestAsync<ProductVariant>(req, HttpMethod.Put, content, "variant");
    }
}

(Edit: updated with correct DefaultValueHandling attribute.)

@nozzlegear nozzlegear added the object updating Bugs and strange behavior around updating objects, primarly related to #284 label Jun 13, 2019
@lantram
Copy link
Author

lantram commented Jun 13, 2019

I wrote a horrible kludge that seems to work good enough for now.

public class ProductVariantServiceEx : ProductVariantService
{
    public ProductVariantServiceEx(string myShopifyUrl, string shopAccessToken) : base(myShopifyUrl, shopAccessToken) { }

    public virtual async Task<ProductVariant> UpdateAsync(long productVariantId, ProductVariant variant)
    {
        // BUGFIX: KLUDGE: If variant.CompareAtPrice is set to 0, then force it to empty
        string json = await (new JsonContent(new { variant })).ReadAsStringAsync();
        if (json.Contains("\"compare_at_price\":0.0}")
        || json.Contains("\"compare_at_price\":0.0,"))
        {
            json = json.Replace("\"compare_at_price\":0.0", "\"compare_at_price\":\"\"");

            return await ExecuteRequestAsync<ProductVariant>(
                PrepareRequest($"variants/{productVariantId}.json"),
                HttpMethod.Put,
                new StringContent(json, Encoding.UTF8, "application/json"),
                "variant");
        }
        else
        {
            return await base.UpdateAsync(productVariantId, variant);
        }
    }
}

@nozzlegear
Copy link
Owner

That should do, glad you found a workaround!

@lantram
Copy link
Author

lantram commented Jun 13, 2019

Yep. It seems to work pretty well. Whenever I know I want to update CompareAtPrice, I simply use ProductVariantServiceEx instead of ProductVariantService. Problem solved.

In general, I could use ProductVariantServiceEx all the time - since 0.0 as a CompareAtPrice isn't really valid (or at least anything useful) - but whatever, it works when I know I need it. : )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
object updating Bugs and strange behavior around updating objects, primarly related to #284
Projects
None yet
Development

No branches or pull requests

2 participants