In this post I would like to show you how to create a Released product using X++. I have used the EcoResProductV2Entity to create the product. The reason for this is, by using the Entity default validations will be triggered and the references will be created automatically. If you want to use the table directly use EcoResProductMaster and create the product. Dont use EcoResDistinctProduct. If you use EcoResDistinctProduct latter it will difficult to create the product variants. It will check for Product master.
The hierarchy is,
EcoResProductMaster,
EcoResProduct,
EcoResDistinctProduct.
internal final class ReleasedProductCopy
{
/// <summary>
/// Copy the selected product
/// </summary>
/// <param name = "_inventTable">Old product InventTable buffer</param>
/// <param name = "_prodNameCon">Product name and search name container</param>
public void copyProduct(InventTable _inventTable, container _prodNameCon)
{
EcoResProduct product, origProduct;
EcoResDescription productDesciption;
EcoResDistinctProductVariant ecoResDistinctProductVariant;
EcoResProductName productName = conPeek(_prodNameCon, 1);
if (_inventTable.RecId)
{
origProduct = _inventTable.Product();
productDesciption = origProduct.productDescription();
ttsbegin;
product = this.createNewProduct(origProduct, _prodNameCon);
if (product)
{
//Create or update all language translations
this.createOrUpdateTranslation(origProduct, product, productName, productDesciption);
//Release the created master prodcut
this.releaseProduct(product);
if (origProduct.productSubtype() == EcoResProductSubtype::ProductMaster)
{
//Create product variants
ecoResDistinctProductVariant = this.createProductVariants(origProduct, product);
}
//Update the released prodcut information
this.createRetailKit(origProduct, product, ecoResDistinctProductVariant);
Info(strFmt("@ItemCopy:NewProductInfo", product.DisplayProductNumber));
}
ttscommit;
}
}
/// <summary>
/// Create a new product from the exiting product
/// </summary>
/// <param name = "_origProduct">Origin product buffer</param>
/// <param name = "_prodNameSearchName">Product name and Search name buffer</param>
/// <returns>New product buffer</returns>
public EcoResProduct createNewProduct(EcoResProduct _origProduct, container _prodNameSearchName)
{
EcoResProductV2Entity ecoResProductEntity;
EcoResProductDimensionGroup ecoResProductDimensionGroup;
EcoResStorageDimensionGroup ecoResStorageDimensionGroup;
EcoResTrackingDimensionGroup ecoResTrackingDimensionGroup;
EcoResProductDimensionGroupProduct ecoResProductDimensionGroupProduct;
EcoResStorageDimensionGroupProduct ecoResStorageDimensionGroupProduct;
EcoResTrackingDimensionGroupProduct ecoResTrackingDimensionGroupProduct;
EcoResProductMasterModelingPolicy ecoResProductMasterModelingPolicy;
EcoResCategory ecoResCategory;
EcoResProductCategory ecoResProductCategory;
EcoResProduct origProduct;
EcoResProductMaster ecoResProductMaster;
WHSEcoResProductTransportationCodes wHSEcoResProductTransportationCodes;
EcoResProductServiceWarranty ecoResProductServiceWarranty;
EcoResDescription productDesciption;
NumberSequenceReference numberSequenceReference = EcoResProductParameters::numRefProductNumber();
NumberSequenceTable numberSequenceTable = numberSequenceReference.numberSequenceTable();
NumberSeq numberSeq = NumberSeq::newGetNumFromId(numberSequenceTable.RecId);
origProduct = _origProduct;
productDesciption = origProduct.productDescription();
select firstonly Name, RecId from ecoResProductDimensionGroup
join ecoResProductDimensionGroupProduct
where ecoResProductDimensionGroupProduct.ProductDimensionGroup == ecoResProductDimensionGroup.RecId
&& ecoResProductDimensionGroupProduct.Product == origProduct.RecId;
select firstonly Name, RecId from ecoResStorageDimensionGroup
join ecoResStorageDimensionGroupProduct
where ecoResStorageDimensionGroupProduct.StorageDimensionGroup == ecoResStorageDimensionGroup.RecId
&& ecoResStorageDimensionGroupProduct.Product == origProduct.RecId;
select firstonly Name, RecId from ecoResTrackingDimensionGroup
join ecoResTrackingDimensionGroupProduct
where ecoResTrackingDimensionGroupProduct.TrackingDimensionGroup == ecoResTrackingDimensionGroup.RecId
&& ecoResTrackingDimensionGroupProduct.Product == origProduct.RecId;
select firstonly ecoResProductMaster
where ecoResProductMaster.RecId == origProduct.RecId;
select firstonly ecoResProductMasterModelingPolicy
where ecoResProductMasterModelingPolicy.ProductMaster == ecoResProductMaster.RecId;
select firstonly Name from ecoResCategory
join ecoResProductCategory
where ecoResProductCategory.Product == origProduct.RecId;
select firstonly STCCCode, HarmonizedCode, NMFCCode from wHSEcoResProductTransportationCodes
where wHSEcoResProductTransportationCodes.Product == origProduct.RecId;
select firstonly ecoResProductServiceWarranty
where ecoResProductServiceWarranty.DistinctProduct == origProduct.RecId;
ecoResProductEntity.ProductNumber = numberSeq.num();
ecoResProductEntity.ProductName = conPeek(_prodNameSearchName, 1);
ecoResProductEntity.ProductSearchName = conPeek(_prodNameSearchName, 2);
ecoResProductEntity.ProductDescription = productDesciption;
ecoResProductEntity.ProductType = origProduct.ProductType;
ecoResProductEntity.ProductSubType = origProduct.productSubtype();
ecoResProductEntity.VariantConfigurationTechnology = ecoResProductMaster.VariantConfigurationTechnology;
ecoResProductEntity.ProductDimensionGroupName = ecoResProductDimensionGroup.Name;
ecoResProductEntitY.StorageDimensionGroupName = ecoResStorageDimensionGroup.Name;
ecoResProductEntity.TrackingDimensionGroupName = ecoResTrackingDimensionGroup.Name;
ecoResProductEntity.ServiceType = origProduct.ServiceType;
ecoResProductEntity.IsCatchWeightProduct = origProduct.PdsCWProduct;
ecoResProductEntity.IsProductVariantUnitConversionEnabled = ecoResProductMaster.IsProductVariantUnitConversionEnabled;
ecoResProductEntity.ProductColorGroupId = ecoResProductMaster.RetailColorGroupId;
ecoResProductEntity.ProductSizeGroupId = ecoResProductMaster.RetailSizeGroupId;
ecoResProductEntity.ProductStyleGroupId = ecoResProductMaster.RetailStyleGroupId;
ecoResProductEntity.AreIdenticalConfigurationsAllowed = ecoResProductMasterModelingPolicy.IsReuseConfigurationEnabled;
ecoResProductEntity.IsAutomaticVariantGenerationEnabled = ecoResProductMasterModelingPolicy.IsVariantGenerationEnabled;
ecoResProductEntity.RetailProductCategoryName = ecoResCategory.Name;
ecoResProductEntity.STCCCode = wHSEcoResProductTransportationCodes.STCCCode;
ecoResProductEntity.HarmonizedSystemCode = wHSEcoResProductTransportationCodes.HarmonizedCode;
ecoResProductEntity.NMFCCode = wHSEcoResProductTransportationCodes.NMFCCode;
ecoResProductEntity.WarrantyDurationTime = ecoResProductServiceWarranty.DurationTime;
ecoResProductEntity.WarrantyDurationTimeUnit = ecoResProductServiceWarranty.DurationTimeUnit;
ecoResProductEntity.insert();
EcoResProductNumber productNumber = ecoResProductEntity.ProductNumber;
return EcoResProduct::findByProductNumber(productNumber);
}
/// <summary>
/// Create new product variant
/// </summary>
/// <param name = "_oldProduct">source product</param>
/// <param name = "_newProduct">Destination product</param>
/// <returns>New variant buffer</returns>
public EcoResDistinctProductVariant createProductVariants(EcoResProduct _oldProduct, EcoResProduct _newProduct)
{
EcoResConfiguration ecoResConfiguration;
EcoResProductMasterConfiguration ecoResProductMasterConfiguration;
EcoResDistinctProductVariant ecoResDistinctProductVariant;
EcoResProductVariantConfiguration ecoResProductVariantConfiguration;
EcoResProductMasterColor ecoResProductMasterColor, ecoResProductMasterColorOld;
EcoResProductMasterStyle ecoResProductMasterStyle, ecoResProductMasterStyleOld;
EcoResProductMasterSize ecoResProductMasterSize, ecoResProductMasterSizeOld;
RefRecId ecoResDistinctProductVariantRecId;
EcoResProductReleaseManagerBase releaseManager;
container productDimensions;
select firstonly RecId from ecoResConfiguration
where ecoResConfiguration.Name == _newProduct.DisplayProductNumber;
if (!ecoResConfiguration.RecId)
{
ecoResConfiguration.Name = _newProduct.DisplayProductNumber;
ecoResConfiguration.insert();
}
select firstonly RecId from ecoResProductMasterConfiguration
where ecoResProductMasterConfiguration.ConfigProductMaster == _newProduct.RecId
&& ecoResProductMasterConfiguration.Configuration == ecoResConfiguration.RecId;
if (!ecoResProductMasterConfiguration.RecId)
{
ecoResProductMasterConfiguration.ConfigProductMaster = _newProduct.RecId;
ecoResProductMasterConfiguration.Configuration = ecoResConfiguration.RecId;
ecoResProductMasterConfiguration.ConfigProductDimensionAttribute = EcoResProductDimensionAttribute::inventDimFieldId2DimensionAttributeRecId(fieldNum(InventDim, ConfigId));
ecoResProductMasterConfiguration.insert();
}
select firstonly ecoResProductMasterColorOlD
where ecoResProductMasterColorOld.ColorProductMaster == _oldProduct.RecId;
//Color assigned to product master
ecoResProductMasterColor.clear();
ecoResProductMasterColor.initValue();
ecoResProductMasterColor.Color = ecoResProductMasterColorOld.Color;
ecoResProductMasterColor.ColorProductDimensionAttribute = EcoResProductDimensionAttribute::inventDimFieldId2DimensionAttributeRecId(fieldNum(InventDim, InventColorId));
ecoResProductMasterColor.ColorProductMaster = _newProduct.RecId;
ecoResProductMasterColor.insert();
select firstonly ecoResProductMasterStyleOld
where ecoResProductMasterStyleOld.StyleProductMaster == _oldProduct.RecId;
//Style assigned to product master
ecoResProductMasterStyle.clear();
ecoResProductMasterStyle.initValue();
ecoResProductMasterStyle.Style = ecoResProductMasterStyleOld.Style;
ecoResProductMasterStyle.StyleProductDimensionAttribute = EcoResProductDimensionAttribute::inventDimFieldId2DimensionAttributeRecId(fieldNum(InventDim, InventStyleId));
ecoResProductMasterStyle.StyleProductMaster = _newProduct.RecId;
ecoResProductMasterStyle.insert();
select firstonly ecoResProductMasterSizeOld
where ecoResProductMasterSizeOld.SizeProductMaster == _oldProduct.RecId;
//Size assigned to product master
ecoResProductMasterSize.clear();
ecoResProductMasterSize.initValue();
ecoResProductMasterSize.Size = ecoResProductMasterSizeOld.Size;
ecoResProductMasterSize.SizeProductDimensionAttribute = EcoResProductDimensionAttribute::inventDimFieldId2DimensionAttributeRecId(fieldNum(InventDim, InventSizeId));
ecoResProductMasterSize.SizeProductMaster = _newProduct.RecId;
ecoResProductMasterSize.insert();
EcoResDistinctProduct ecoResDistinctProduct;
select firstonly ecoResDistinctProduct
where ecoResDistinctProduct.RecId == _oldProduct.RecId;
productDimensions = EcoResProductVariantDimValue::getDimensionValuesContainerForConfiguration(ecoResConfiguration.Name);
//Product variant
ecoResDistinctProductVariant.clear();
ecoResDistinctProductVariant.initValue();
ecoResDistinctProductVariant.DisplayProductNumber = EcoResProductNumberBuilderVariant::buildFromProductNumberAndDimensions(
_newProduct.productNumber(),
productDimensions);
ecoResDistinctProductVariant.ProductType = _newProduct.ProductType;
ecoResDistinctProductVariant.ProductMaster = _newProduct.RecId;
//Product variant configuration
ecoResProductVariantConfiguration.clear();
ecoResProductVariantConfiguration.initValue();
ecoResProductVariantConfiguration.initFromDistinctProductVariant(ecoResDistinctProductVariant);
ecoResProductVariantConfiguration.ProductDimensionAttribute = EcoResProductDimensionAttribute::inventDimFieldId2DimensionAttributeRecId(fieldNum(InventDim, ConfigId));
ecoResProductVariantConfiguration.Configuration = ecoResConfiguration.RecId;
ecoResDistinctProductVariantRecId = EcoResProductVariantManager::createProductVariant(_newProduct.RecId, ecoResDistinctProductVariant.DisplayProductNumber, productDimensions);
//Find newly created Product Variant
ecoResDistinctProductVariant = ecoResDistinctProductVariant::find(ecoResDistinctProductVariantRecId);
//Now release the Product variant
releaseManager = EcoResProductReleaseManagerBase::newFromProduct(ecoResDistinctProductVariant);
releaseManager.release();
return ecoResDistinctProductVariant;
}
/// <summary>
/// Copy or update translation
/// </summary>
/// <param name = "_ecoResProdcutSource">Source product</param>
/// <param name = "_ecoResProdcutDestination">Destination product</param>
/// <param name = "_productName">Product name</param>
/// <param name = "_productDesciption">Product description</param>
public void createOrUpdateTranslation(EcoResProduct _ecoResProdcutSource,
EcoResProduct _ecoResProdcutDestination,
EcoResProductName _productName,
EcoResDescription _productDesciption)
{
//Create one or more translations
EcoResProductTranslation::createOrUpdateTranslation(_ecoResProdcutDestination.RecId, _productName, _productDesciption);
EcoResProductRecId newproductRecId = _ecoResProdcutDestination.RecId;
EcoResProductTranslation ecoResProductTranslation, ecoResProductTranslationOld;
LanguageId systemLanguageId = SystemParameters::getSystemLanguageId();
insert_recordset ecoResProductTranslation(Description,LanguageId ,Name ,Product)
select Description,LanguageId ,Name , newproductRecId from ecoResProductTranslationOld
where ecoResProductTranslationOld.LanguageId != systemLanguageId
&& ecoResProductTranslationOld.Product == _ecoResProdcutSource.RecId;
}
/// <summary>
/// Release the new product in current company
/// </summary>
/// <param name = "_ecoResProdcut">new Ecoresporduct buffer</param>
public void releaseProduct(EcoResProduct _ecoResProdcut)
{
EcoResProductReleaseSessionManager productReleaseSessionManager;
EcoResReleaseSessionRecId releaseSessionRecId;
Args args;
CompanyInfo companyInfo = CompanyInfo::find();
// Release the master product for the current company
productReleaseSessionManager = EcoResProductReleaseSessionManager::newReleaseSession();
releaseSessionRecId = productReleaseSessionManager.parmReleaseSessionRecId();
productReleaseSessionManager.addProduct(_ecoResProdcut.RecId);
productReleaseSessionManager.addLegalEntityForProduct(companyInfo.RecId, _ecoResProdcut.RecId);
args = new Args(formStr(EcoResProductRelease));
args.record(EcoResReleaseSession::find(releaseSessionRecId));
// the first boolean parameter is for showing a log for errors
// the second boolean parameter is for executing the release with a batch
if (EcoResProductReleaseSessionBatch::runJob(args, true, false))
{
productReleaseSessionManager.cleanUp();
}
}
/// <summary>
/// Create retail kit
/// </summary>
/// <param name = "_origProduct">Origin item number</param>
/// <param name = "_newProduct">New item number</param>
/// <param name = "_ecoResDistinctProductVariant">Product variant</param>
public void createRetailKit(EcoResProduct _origProduct, EcoResProduct _newProduct, EcoResDistinctProductVariant _ecoResDistinctProductVariant)
{
RetailKit retailKit, retailKitOld;
RetailKitComponent retailKitComponent, retailKitComponentOrig;
RetailKitVariantComponent retailKitVariantComponent, retailKitVariantComponentOld;
EcoResDistinctProductRecId newKitVariant;
newKitVariant = _newProduct.RecId;
select firstonly retailKitOld
where retailKitOld.ProductMaster == _origProduct.RecId;
if (retailKitOld)
{
retailKit.data(retailKitOld);
retailKit.ProductMaster = _newProduct.RecId;
retailKit.insert();
if (retailKit)
{
while select retailKitComponentOrig
join retailKitVariantComponentOld
where retailKitComponentOrig.Kit == retailKitOld.RecId
&& retailKitVariantComponentOld.ComponentRecId == retailKitComponentOrig.RecId
{
buf2Buf(retailKitComponentOrig, retailKitComponent);
retailKitComponent.Kit = retailKit.RecId;
retailKitComponent.insert();
if (retailKitComponent)
{
buf2Buf(retailKitVariantComponentOld, retailKitVariantComponent);
retailKitVariantComponent.ComponentRecId = retailKitComponent.RecId;
retailKitVariantComponent.KitVariant = _ecoResDistinctProductVariant.RecId;
retailKitVariantComponent.insert();
}
}
}
}
}
}