public async Task <SuperHSProduct> CreateModifiedMonitoredSuperProductNotification(MonitoredProductFieldModifiedNotification notification, VerifiedUserContext user) { if (notification == null || notification?.Product == null) { throw new Exception("Unable to process notification with no product"); } var _product = await _oc.Products.PatchAsync(notification.Product.ID, new PartialProduct { Active = false }, user.AccessToken); var document = new Document <MonitoredProductFieldModifiedNotification>(); document.Doc = notification; document.ID = $"{notification.Product.ID}_{CosmosInteropID.New()}"; // Create notifictaion in the cms await _cms.Documents.Create(_documentSchemaID, document, await GetAdminToken()); // Assign the notification to the product // TODO: this doesn't work because need to own thing being assigned to AND have DocumentAdmin and we don't want to give suppliers DocumentAdmin // await _cms.Documents.SaveAssignment("MonitoredProductFieldModifiedNotification", new DocumentAssignment() { DocumentID = document.ID, ResourceType = ResourceType.Products, ResourceID = _product.ID }, user.AccessToken); return(await _productCommand.Get(_product.ID, user.AccessToken)); }
public async Task <SuperHSProduct> Post(SuperHSProduct superProduct, VerifiedUserContext user) { // Determine ID up front so price schedule ID can match superProduct.Product.ID = superProduct.Product.ID ?? CosmosInteropID.New(); await ValidateVariantsAsync(superProduct, user.AccessToken); // Create Specs var defaultSpecOptions = new List <DefaultOptionSpecAssignment>(); var specRequests = await Throttler.RunAsync(superProduct.Specs, 100, 5, s => { defaultSpecOptions.Add(new DefaultOptionSpecAssignment { SpecID = s.ID, OptionID = s.DefaultOptionID }); s.DefaultOptionID = null; return(_oc.Specs.SaveAsync <Spec>(s.ID, s, accessToken: user.AccessToken)); }); // Create Spec Options foreach (Spec spec in superProduct.Specs) { await Throttler.RunAsync(spec.Options, 100, 5, o => _oc.Specs.SaveOptionAsync(spec.ID, o.ID, o, accessToken: user.AccessToken)); } // Patch Specs with requested DefaultOptionID await Throttler.RunAsync(defaultSpecOptions, 100, 10, a => _oc.Specs.PatchAsync(a.SpecID, new PartialSpec { DefaultOptionID = a.OptionID }, accessToken: user.AccessToken)); // Create Price Schedule PriceSchedule _priceSchedule = null; //All products must have a price schedule for orders to be submitted. The front end provides a default Price of $0 for quote products that don't have one. superProduct.PriceSchedule.ID = superProduct.Product.ID; try { _priceSchedule = await _oc.PriceSchedules.CreateAsync <PriceSchedule>(superProduct.PriceSchedule, user.AccessToken); } catch (OrderCloudException ex) { if (ex.HttpStatus == System.Net.HttpStatusCode.Conflict) { throw new Exception($"Product SKU {superProduct.PriceSchedule.ID} already exists. Please try a different SKU."); } } superProduct.Product.DefaultPriceScheduleID = _priceSchedule.ID; // Create Product if (user.Supplier != null) { var supplierName = await GetSupplierNameForXpFacet(user.Supplier.ID, user.AccessToken); superProduct.Product.xp.Facets.Add("supplier", new List <string>() { supplierName }); } var _product = await _oc.Products.CreateAsync <HSProduct>(superProduct.Product, user.AccessToken); // Make Spec Product Assignments await Throttler.RunAsync(superProduct.Specs, 100, 5, s => _oc.Specs.SaveProductAssignmentAsync(new SpecProductAssignment { ProductID = _product.ID, SpecID = s.ID }, accessToken: user.AccessToken)); // Generate Variants await _oc.Products.GenerateVariantsAsync(_product.ID, accessToken : user.AccessToken); // Patch Variants with the User Specified ID(SKU) AND necessary display xp values await Throttler.RunAsync(superProduct.Variants, 100, 5, v => { var oldVariantID = v.ID; v.ID = v.xp.NewID ?? v.ID; v.Name = v.xp.NewID ?? v.ID; if ((superProduct?.Product?.Inventory?.VariantLevelTracking) == true && v.Inventory == null) { v.Inventory = new PartialVariantInventory { QuantityAvailable = 0 }; } if (superProduct.Product?.Inventory == null) { //If Inventory doesn't exist on the product, don't patch variants with inventory either. return(_oc.Products.PatchVariantAsync(_product.ID, oldVariantID, new PartialVariant { ID = v.ID, Name = v.Name, xp = v.xp }, accessToken: user.AccessToken)); } else { return(_oc.Products.PatchVariantAsync(_product.ID, oldVariantID, new PartialVariant { ID = v.ID, Name = v.Name, xp = v.xp, Inventory = v.Inventory }, accessToken: user.AccessToken)); } }); // List Variants var _variants = await _oc.Products.ListVariantsAsync <HSVariant>(_product.ID, accessToken : user.AccessToken); // List Product Specs var _specs = await _oc.Products.ListSpecsAsync <Spec>(_product.ID, accessToken : user.AccessToken); // Return the SuperProduct return(new SuperHSProduct { Product = _product, PriceSchedule = _priceSchedule, Specs = _specs.Items, Variants = _variants.Items, }); }