Additional documentation in Quip
Important notes:
- You will need to create your Sales Agreement and populate the Quote__c field before invoking this package logic. This preserves the ability to continue to use your method of choice for Sales Agreement header creation.
- This needs to be added to a flow or a trigger to work. There is no automation included in this package.
- If you install the managed package, prepend the
MfgConnect
namespace to all fields and class names below
This connector is used to facilitate the conversion of a Quote to one or many Sales Agreements. Its primary purpose is to convert Quote Lines to Sales Agreement Products on already created Sales Agreement records. When invoked, it does the following:
- Queries all quote lines related to the Quote ID in the
Quote__c
field on the provided Sales Agreements - For each quote line, a new Sales Agreement Product is created using either the mappings you provide in custom metadata, or a custom mapping plugin noted in the
QuoteLineToSalesAgreementProductMapping__c
setting in the package settings- If the
Match QLI Account to SA Account
setting is enabled, only quote lines with the same Account ID (AccountId__c
) as the Sales Agreement (AccountId
) will be added to the Sales Agreement. IfMatch QLI Key to SA Key
is enabled only quote lines with the sameSales Agreement Key
as the Sales Agreement will be added to the Sales Agreement. Note that both settings can be used at the same time. This helps you facilitate the conversion of one quote to multiple Sales Agreements (e.g. one quote has multiple ship to addresses that need different sales agreements). Note that to use this you will still need to- Make the Sales Agreements
- Make sure that the
AccountId__c
on the quote line is populated - If you would like to use a field other than the Sales Agreement
AccountId
to match accounts with your quote lines, you can specify this field in theSales Agreement Account Field API Name
custom setting - If you use the
Match QLI Key to SA Key
setting then you will need to make sure that theSales Agreement Key
fields on both the Sales Agreement and Quote Line records are populated
- The package comes with default mappings that represent the minimum required fields to make a Sales Agreement Product in Manufacturing Cloud. You can update the default mappings and make additional mapping records are needed. Note that the custom metadata mappings are ignored if you use an Apex Mapping Plugin
- If the
- If a Sales Agreement Product already exists for the Quote Line’s PriceBookEntryId, the records are merged. This is because a PriceBookEntry can only exist once per Sales Agreement.
- The new Sales Agreement Products are inserted.
- CPQ Support
- Changing default product schedules
Important: This needs to be added to a flow or a trigger to work. There is no automation included in this package.
This code can be installed via managed package, or installed directly from source. In order to install this, your org must have:
In order to use this package, the running user needs the following two permission sets assigned
- Manufacturing Sales Agreements (part of Manufacturing Cloud)
- Manufacturing Cloud Connecter for Sales (part of this package)
The functionality can be invoked in two ways
- Invocable Apex Action (Flow)
- From Apex (Code)
Currently, the connector will inserts new price book entries. It does not handle updates and therefore should only be run once per Sales Agreement (unless all products are removed from a Sales Agreement before running again).
This should only be used with a screen flow or after save flow.
The Flow Action is named Create Sales Agreement Products from Quote
. It is bulkified.
- Input: One or many Sales Agreements
- Return: None
In the event of an error within the action, an exception will be thrown. This should be handled with a fault connector.
This should only be run in the in the after insert context or from outside of a trigger context.
An example of adding this to a trigger can be seen below:
trigger SalesAgreementTrigger on SalesAgreement(after insert) {
switch on Trigger.operationType {
when AFTER_INSERT {
QuoteToSalesAgreementService.createSalesAgreementProducts(Trigger.new);
}
}
}
The package comes with default mappings that are stored in custom metadata. These mappings can be created and/or modified to meet your requirements.
You can create a custom mapping plugin that allows you to:
- Set the field mappings from quote line to sales agreement product
- Determine which fields should have a weighted average when merged by price book entry
- Determine which fields should be summed when merged by price book entry
An example of a mapping plugin can be seen below. Note this contains the default mappings:
global with sharing class MyMappingPlugin implements MfgConnect.FieldMappingConfiguration {
global static Map<String, String> sourceToTargetMapping() {
return new Map<String, String>{
'PriceBookEntryId' => 'PriceBookEntryId',
'ProductName__c' => 'Name',
'Quantity' => 'InitialPlannedQuantity',
'UnitPrice' => 'SalesPrice'
};
}
global static Set<String> fieldsToSumOnMerge() {
return new Set<String>{ 'InitialPlannedQuantity' };
}
global static Set<String> fieldsToWeightedAverageOnMerge() {
return new Set<String>{ 'SalesPrice' };
}
}
After creating a mapping plugin, you can copy the name of the Apex Class to the appropriate setting in the settings page.
Here is an example test class for your plugin:
@isTest
private class MyMappingPlugin_Test {
@isTest
static void mappingPlugin() {
try {
Map<String, String> sourceToTargetMapping = MyMappingPlugin.sourceToTargetMapping();
Set<String> fieldsToSumOnMerge = MyMappingPlugin.fieldsToSumOnMerge();
Set<String> fieldsToWeightedAverageOnMerge = MyMappingPlugin.fieldsToWeightedAverageOnMerge();
System.assert(true);
} catch (Exception e) {
System.assert(false);
}
}
}
- Install recommended extensions in
.vscode/extensions.json
- Make sure below workspace settings exist in
.vscode/settings.json
{
"editor.codeActionsOnSave": { "source.fixAll": true },
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"apexPMD.rulesets": ["pmd/pmd_rules.xml"]
}
Note: the connector does not do anything out of the box. It needs to be invoked via apex or flow (see Setup and Usage)
- Run
npm install
(only required after cloning project for the first time) - Create scratch org
- Push source
sfdx force:source:push
- Assign permission sets
sfdx force:user:permset:assign -n "ManufacturingSalesAgreementsPsl,ManufacturingCloudConnecterForSales"
- Seed sample data
sfdx force:apex:execute -f scripts/apex/data-setup.apex
- Add products to your newly created quote
- Perform development/testing as needed
There is no SObject (e.g. Sales Agreement) page layout metadata in this project. You will need to manually add the custom fields from this package to your layouts if you would like them to be visible.
New package version command: sf package version create --wait 30 --package 0Ho8b0000008OJICA2 --installation-key-bypass --code-coverage
THIS APPLICATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, CONSEQUENTIAL OR SIMILAR DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS APPLICATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SUBJECT TO THE FOREGOING, THIS APPLICATION MAY BE FREELY REPRODUCED, DISTRIBUTED, TRANSMITTED, USED, MODIFIED, BUILT UPON, OR OTHERWISE EXPLOITED BY OR ON BEHALF OF SALESFORCE.COM OR ITS AFFILIATES, ANY CUSTOMER OR PARTNER OF SALESFORCE.COM OR ITS AFFILIATES, OR ANY DEVELOPER OF APPLICATIONS THAT INTERFACE WITH THE SALESFORCE.COM APPLICATION, FOR ANY PURPOSE, COMMERCIAL OR NON-COMMERCIAL, RELATED TO USE OF THE SALESFORCE.COM APPLICATION, AND IN ANY WAY, INCLUDING BY METHODS THAT HAVE NOT YET BEEN INVENTED OR CONCEIVED.