The following process has been designed to manually correct data that may have been created due to a known issue that was introduced in the 20Spring and 20Spring.1 release. The fix for this issue has been released in the December 31st, 2020 patch and the process below will provide guidance on correcting any incorrect data that may have been created. Please see the
Product Alert: 20Spring Subscription Batchable services for more details and real-time updates.
1. Delete the existing Subscription Plans (SP) records for the related Sales Orders (SOs)
- Use the script below to remove the affected SPs:
- Use the script below and update the CreatedDate if you would like to narrow this to a specific time range of when 20Spring was installed in your environment:
OrderApi__Sales_Order_Line__c[] sols =
[SELECT ID,OrderApi__Sales_Order__c, OrderApi__Is_Posted__c,
OrderApi__Sale_Price__c, OrderApi__Overall_Total__c,
OrderApi__Price_Override__c, OrderApi__Is_Installment_Calculated__c
FROM OrderApi__Sales_Order_Line__c
WHERE OrderApi__Is_Renewal__c = true
AND OrderApi__Balance_Due__c > 0
AND OrderApi__Subscription_Plan__c != null
AND OrderApi__Subscription_Plan__r.OrderApi__Enable_Schedule__c = true
AND OrderApi__Subscription_Plan__r.OrderApi__Schedule_Frequency__c != null
AND CreatedDate > 2020-01-01T00:00:00.000z];
System.debug('>>> # of SOL record>>>'+sols.size());
Set<Id> postedSOIds = new Set<Id>();
Set<Id> pendingSOIds = new Set<Id>();
Set<Id> allSOIds = new Set<Id>();
for (OrderApi__Sales_Order_Line__c sol : sols) {
if (sol.OrderApi__Sale_Price__c == sol.OrderApi__Overall_Total__c) {
allSOIds.add(sol.OrderApi__Sales_Order__c);
if (sol.OrderApi__Is_Posted__c){
postedSOIds.add(sol.OrderApi__Sales_Order__c);
}
else {
pendingSOIds.add(sol.OrderApi__Sales_Order__c);
//System.debug('>>>else here for SOs that are NOT Posted>>>'+sol.OrderApi__Sales_Order__c);
}
allSOIds.add(sol.OrderApi__Sales_Order__c);
}
}
System.debug('>>> # of POSTED SO records>>>'+postedSOIds.size());
System.debug('>>> # of Pending SO records>>>'+pendingSOIds.size());
System.debug('>>> # of ALL SO records>>>'+allSOIds.size());
OrderApi__Scheduled_Payment__c[] sps = [SELECT Id
FROM OrderApi__Scheduled_Payment__c
WHERE OrderApi__Sales_Order__c IN: postedSOIds];
System.debug('>>> # of SP records for the related SOs>>>'+sps.size());
// DELETE SP RECORDS, AND WE WILL CREATE NEW ONES
delete sps;
2. Create a SalesForce report with all of the Sales Orders (SOs):
Create a new report with SF Report Type: Sales Orders with Sales Order Lines and Subscription Plan
- All Sales Orders
- Fields needs: Sales Order ID, SOL ID, Posting Entity, Schedule Type, Posting Status, Posted Date, Is Posted, Generate Installment, Sale Price, Overall Total (SOL), Price Override, Is Installment Calculated
- Filter by:
- OrderApi__Is_Renewal__c = true
- AND OrderApi__Balance_Due__c > 0
- AND OrderApi__Subscription_Plan__c != null
- AND OrderApi__Subscription_Plan__r.OrderApi__Enable_Schedule__c = true
- AND OrderApi__Subscription_Plan__r.OrderApi__Schedule_Frequency__c != null
- You can also add a filter for CreateDate if you are looking for a specific date range
- Run, save, and Export Details
- (Either in report or Excel) To identify if (sol.OrderApi__Sale_Price__c == sol.OrderApi__Overall_Total__c ), create a new column in csv file
- Use compare formula
- e.g. if my Sale Price is Column G, Overall Total is Column H, then the formula for row 2 is “=G2=H2”
- Keep all rows that returned TRUE from the compare formula
- Delete the rows returned FALSE
- Remove compare column
- Save this CSV file to 2 files
- Master CSV file for SO - only keep columns for SO fields
- Master CSV file for SOL - only keep columns for SOL fields
3. Make a Copy for Master CSV file for the Sales Orders (SOs):
- Update Posting Entity = Receipt
- Update Posting Status = Pending
- Update Is Posted = FALSE
- Update Generate Installments = FALSE
- Update Posted Date = null
- Save
4. Update Sales Orders (SO) via Data Loader:
- Go to data loader and log into the org
- Select “Update”
- Select object Sales Order (OrderApi__Sales_Order__c)
- Choose the updated CSV from the last step
- Create or Edit Mapping
- Auto-Match Fields to Column, and manually map the SO Id
- Select “Finish” to execute
- Check status and make sure all succeeded
5. Make a Copy of the Master CSV file for SOL:
- Update Price Override = FALSE
- Update Is Installment Calculated = FALSE
- Save
6. Update SOL via Data Loader:
- Go to data loader and log into the org
- If the org has customization on SO/SOL, we suggest limiting batch size during data loading. To set it up, in Data Loader > Settings:
- Update Batch Size = 1 for this update
- Enable “Insert NULL values”
- Select “Update”
- Select object Sales Order Line (OrderApi__Sales_Order_Line__c)
- Choose the updated CSV from the last step (update_sol.csv)
- Create or Edit Mapping
- Auto-Match Fields to Column, and manually map the SOL Id
- Select “Finish” to execute
- Check status and make sure all succeeded
7. Go to Master CSV file for SO:
- Update Is Posted = TRUE
- Update Generate Installments = TRUE
- Update Posting Entity = Invoice
- Update Schedule Type = null
8. Update SO via Data Loader:
- Go to data loader and log into the org
- If the org has customization on SO/SOL, we suggest limiting batch size during data loading. To set it up, in Data Loader > Settings:
- Update Batch Size = 1 for this update
- Enable “Insert NULL values”
- Select “Update”
- Select object Sales Order (OrderApi__Sales_Order__c)
- Choose the updated CSV
- Create or Edit Mapping
- Auto-Match Fields to Column, and manually map the SO Id
- Select “Finish” to execute
- Check status and make sure all succeeded