I am doing this right now, pushing configuration from a web application directly into PcValueSet… It’s not easy, there are pitfalls, definitely not supported, and may or may not work depending on how you use your configurator (specifically, if you only ever reference your inputs’ .Value property, and not Description, or others…). With all that said, it’s not impossible… I have 7 configurator sequences all working using this method at the moment.
1- First, get a template of the XML configuration from PcValueSet for each page of your configurator, and replace every value with a placeholder tag, to be filled in later. Also get a template of the input properties XML, you can just use it as is, provided you don’t use any of the properties enumerated in there. If you do, or if you really want to do it 100%, you need to also put in placeholders in there to be populated…
2- Check the approved status of the configurator from PcStatus and get its ConfigVersion
3- Get the next configuration sequence number from the SysSequence table, it’s the “PcValueGrpSeq” CurrentValue, to which you add the Increment, and update SysSequence.CurrentValue, which is your GroupSeq for your new configuration.
4- Create the PcValueGrp entry, using your GroupSeq value.
5- Create a PcValueHead entry for each configurator in the sequence. You can get the RuleTag value from the PcStruct table.
6- Fill in the XML template(s) from earlier and create one PcValueSet entry for each page.
7- Once everything is saved, update the QuoteDtl.GroupSeq value, along with LastConfigDate, LastConfigTime, and LastConfigUserID.
Be prepared to have to debug this thoroughly by comparing XML outputs a lot. You should also wrap all of that into a transaction that can be rolled back if anything goes wrong. You don’t want to leave partial configs in the database, or orphaned records, etc…
Also, I have found one quirk, which is that when I call OnChangeofEngineered on the configured detail line, if I don’t set the GroupSeq to 0 before, and restore it after, through direct DB update, when I then call Update it deletes the config. The service is expecting some context flags, but I wasn’t able to find how to set them properly, so I cheated by setting GroupSeq to 0 before update. This is the decompiled condition in question, from the QuoteDtl write trigger:
if (QuoteDtl.GroupSeq > 0
&& !string.IsNullOrEmpty(OldQuoteDtl.RevisionNum)
&& !QuoteDtl.RevisionNum.KeyEquals(OldQuoteDtl.RevisionNum)
&& !ErpCallContext.ContainsKey("ConfigurationRuntime-UpdateQuote")
&& !ErpCallContext.ContainsKey("ConfigRuntime-ExecuteRules")
&& !ErpCallContext.ContainsKey("ConfigChangePartNum"))
This is just to give you an idea of what you’ll have to do to make this work… It DOES work nicely, all the way through MRP processing, but it’s a large piece of code to create, and I would only consider this if you are already very comfortable with Epicor data structures, and you really absolutely need to do it. It was a fun challenge for me, but I realize now it could have been a complete nightmare if the configurators had been built differently.