How to create a Variant programmatically with price together

Vote:
 
Hi,

In our project we have a validation rule to ensure that every variant has at least one price assigned to it.

I am trying to create a variant in code, but I cannot create a price for it before it is being saved in the database. How can I achieve this? My code is something like:

            var newVariant = _contentRepository.GetDefault < MyVariant > (anotherVariant.ParentLink, anotherVariant.ContentTypeID, anotherVariant.Language);

            .... setting Name, Code etc.

            Price existingPrice = anotherVariant.GetDefaultPrice();
            PriceDetailValue priceValue = new PriceDetailValue
            {
                CatalogKey = new CatalogKey(newVariant .Code),
                MarketId = existingPrice.MarketId,
                CustomerPricing = CustomerPricing.AllCustomers,
                ValidFrom = DateTime.Now,
                MinQuantity = 0,
                UnitPrice = new Money(existingPrice.UnitPrice.Amount + 1, existingPrice.UnitPrice.Currency)
            };
            _priceDetailService.Save(priceValue);
            _contentRepository.Publish(newVariant);

I get a foreign key violation exception at the IPriceDetailService.Save() call, that the code does not exist in DB. I could not find any other way to get a hold on to a PriceReference. There must be a way how the Commerce UI creates a new variant in one step, because that one is working fine. Using Commerce 12.14.

#229631
Edited, Oct 20, 2020 15:12
Vote:
 
var newVariant = _contentRepository.GetDefault < MyVariant > (anotherVariant.ParentLink, anotherVariant.ContentTypeID, anotherVariant.Language);
 _contentRepository.Publish(newVariant);
            Price existingPrice = anotherVariant.GetDefaultPrice();
            PriceDetailValue priceValue = new PriceDetailValue
            {
                CatalogKey = new CatalogKey(newVariant.Code),
                MarketId = existingPrice.MarketId,
                CustomerPricing = CustomerPricing.AllCustomers,
                ValidFrom = DateTime.Now,
                MinQuantity = 0,
                UnitPrice = new Money(existingPrice.UnitPrice.Amount + 1, existingPrice.UnitPrice.Currency)
            };
            _priceDetailService.Save(priceValue);
           
This should work
#229633
Oct 20, 2020 15:38
Vote:
 
Ok I did not elaborate on this, but saving without a price does not work either because of the custom validation rule, that every variant must have a price defined.
public class VariationContentValidator : IValidate < VariationContent >
{
	public IEnumerable < ValidationError > Validate(VariationContent instance)
	{
		if (instance.GetPrices().Count == 0)
		{
			yield return new ValidationError
			{
				Severity = ValidationErrorSeverity.Error,
				ErrorMessage = Custom.MissingPrice,
				PropertyName = "Price"
			};
		}
	}
}
#229670
Edited, Oct 21, 2020 6:34
Vote:
 

Well that is a strange rule to have. But you perhaps you can skip the check if VariationContent.ContentLink is null or empty (i.e. it's not created yet).

#229671
Oct 21, 2020 7:55
Vote:
 
Thanks for your help, this hack seems to be the easiest way to solve the problem. I guess Commerce UI calls some internal API.
#229677
Oct 21, 2020 9:54
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.