• Rachel Linder 20
  • NEWBIE
  • 20 Points
  • Member since 2019

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 18
    Questions
  • 19
    Replies
Iam trying to complete challenge 7 of Lightning Experience Reports & Dashboards Specialist. I am using a new playground created yesterday per the instructions in the Superbadge. I just completed creating the dashboard and when clicking Check Challenge I am getting the following error:

User-added imagePlease help so I can complete this challenge.
I have this formula field I am trying to build. Here is the current formula that is throwing the compilation error above:
 
IF( 
   ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
     IF( 
        AND(Opportunity_Record_Type__c = 'Amendment',
           OR(Line_Level_Detail__c <> 'New Logo',
              Line_Level_Detail__c <> 'Cross Sell',
              Line_Level_Detail__c <> 'Upgrade / Downgrade',
              Line_Level_Detail__c  <> 'Services',
              Line_Level_Detail__c  <> 'Product Churn',
              Line_Level_Detail__c  <> 'Product Deprecated',
              Line_Level_Detail__c  <> 'Customer Credit')), TotalPrice,
            IF(
               AND(Opportunity_Record_Type__c  <>  'Amendment',  Line_Level_Type__c  <> 'Removed Product', 
                 OR(Line_Level_Detail__c <> 'New Logo',
                    Line_Level_Detail__c <> 'Cross Sell',
                    Line_Level_Detail__c <> 'Upgrade / Downgrade',
                    Line_Level_Detail__c  <> 'Services',
                    Line_Level_Detail__c  <> 'Product Churn',
                    Line_Level_Detail__c  <> 'Product Deprecated',
                    Line_Level_Detail__c  <> 'Customer Credit')), TotalPrice,
                IF(
                   AND(Opportunity_Record_Type__c  <>  'Amendment',  Line_Level_Type__c = 'Removed Product',
                     OR(Line_Level_Detail__c = 'Upgrade / Downgrade',
                        Line_Level_Detail__c = 'Migration',
                        Line_Level_Detail__c = 'Bundle Adj')), Combined_Renewed_Subscription_Total_Amt__c ,        

           0)
)
)
)

I know that the compilation error is due to things such as formulas on formulas, etc. But is there anything I can do to re-write it.
Hello,
I am converting the following ask into a formula field:
  1. If Stage = Closed Lost, $0, otherwise
  2. If line level detail = Customer Credit, Product Churn or Product Deprecated, $0, otherwise
  3. if Amendment, use Total Price (no change), otherwise
  4. if Renewal and Line Type = Removed Product and Line Level Detail = Bundle Adjs, then “$0”, otherwise
  5. Total Price + ARR Removed
I have it written as such and I am receiving the error - 'Error: Incorrect Number if Parameters for function IF(). Expected 3, received 1"
 
IF(
   ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
     If( 
        Line_Level_Detail__c='Customer Credit' || Line_Level_Detail__c='Product Churn'  || Line_Level_Detail__c = 'Product Deprecated'), 0,
         IF(
            Opportunity_Record_Type__c  = 'Amendment'),  TotalPrice,
            IF(
               AND
                  ( Opportunity_Record_Type__c = 'Renewal',  Line_Level_Type__c = 'Removed Product',  Line_Level_Detail__c = 'Bundle Adjs'), 0,
                    TotalPrice  +  ARR_Removed__c
)
)
What am I missing in this formula?
 
We have a checkbox field that uses a formula to decide when to check it or not. We have a case where formula "fails" all IF statetments until you reach the "Opportunity Year 1 Term equals 12, Opportunity Year 2 Term equals 12, and Quote Line Year equals Year 1". When it reacheds that statement it should check the box but this is not happening. Does anyone have any suggestions:
 
IF (
    Bookings_Override_True__c  = TRUE, TRUE,
      IF(
        Bookings_Override_False__c = TRUE, FALSE,
          IF(
            AND( Opportunity_Record_Type__c = 'Amendment', Line_Level_Detail__c = 'Customer Credit'), FALSE,
              IF(
                AND(Opportunity_Record_Type__c = 'Amendment', Line_Level_Detail__c <> 'Customer Credit'), TRUE,
                  IF(
                    AND(Opportunity_Record_Type__c <> 'Amendment',  Bookings_Override_False__c  = FALSE,  Bookings_Override_True__c  = FALSE, 
                      Line_Level_Detail__c = 'Services'), TRUE,
                        IF(
                          AND(Opportunity_Record_Type__c <> 'Amendment',  Bookings_Override_False__c  = FALSE,  Bookings_Override_True__c  = FALSE, 
                            Line_Level_Detail__c <> 'Services',  Line_Level_Type__c  = 'Removed Product'), TRUE, 
                              IF(
                                AND(  Opportunity.Year_1_Term__c   = 12, Opportunity.Year_2_Term__c  = 12,  QuoteLineYear__c  = 'Year 1'), TRUE,
                                  IF(
                                    AND(  Opportunity.Year_1_Term__c   <= 12, ISNULL( Opportunity.Year_2_Term__c ),  Year_Hidden__c  = 'Year 1'), true, 
                                      IF(
                                        AND(  Opportunity.Year_1_Term__c  < 12, Opportunity.Year_2_Term__c  = 12,  Year_Hidden__c  = 'Year 2'), true,
                                         false ) 
)
)
)
)
)
)
)
)

 
We have several CPQ product rules that are validation rules. When in the Quote Line Editor we have a rep that adds a product. When clicking Save the product rule will fire the red validation error message at the top of the page.

Is there a way that you can automate the creation of a case when that error message appears?
I am creating a formula field that is totally 4 other formula fields and receiving the following error: "Error: Compiled formula is too big to execute (7,784 characters). Maximum size is 5,000 characters"

Here is the formula I am creating:
ARR_New__c  +  ARR_Price_Change_RN__c  +  ARR_Quantity_Change_RN__c  +  ARR_Removed__c
How can I reduce the compile size?

Here is what each one of the 4 formula fields above looks like:

ARR NEW (Compiled Size: 730 Characters)
IF(ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
       If( 
          AND 
            (NOT 
                (Line_Level_Detail__c='Services'), Line_Level_Type__c= 'New Product'), UnitPrice * Quantity , 0))
ARR Price Change (RN) (Compiled Size: 2,738 characters)
If (
    ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
IF( 
   AND(
       Line_Level_Type__c= 'Renewed Product',  NOT(CONTAINS( Pricing_Method_Change__c, 'Block'))),  Quantity *( UnitPrice - Renewed_Subscription_Net_Price__c),
IF(
   AND(
       Line_Level_Type__c= 'Renewed Product', CONTAINS( Pricing_Method_Change__c, 'Block')), TotalPrice - Renewed_Subscription_Total_Amount__c, 0)
)
)
ARR Quantity Change (RN) (Compiled Size: 1,345 characters)
IF(
    ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
IF(
    AND(Line_Level_Type__c='Renewed Product', NOT(CONTAINS( Pricing_Method_Change__c, 'Block'))),
         Renewed_Subscription_Net_Price__c *( Quantity  -  Quantity_Upon_Creation__c ),0))
ARR Removed (Compiled Size: 2,925)
IF (
    AND(
         (ISPICKVAL(Opportunity.StageName, "Closed Lost")), Line_Level_Type__c  <>  'New Product'), Combined_Renewed_Subscription_Total_Amt__c  *-1,
            IF (
              AND(
                 Line_Level_Type__c = 'Removed Product', Opportunity_Record_Type__c = 'Amendment',  Line_Level_Detail__c  <> 'Services'), TotalPrice,
                   IF (
                      AND (
                           Line_Level_Type__c = 'Removed Product', Opportunity_Record_Type__c = 'Renewal'),  Combined_Renewed_Subscription_Total_Amt__c  *-1,0)
)
)

 
We have an  Apex Class that runs nightly through a batch. We created a Lightning Quick Action so that this can also be invoked at any time during the day if needed.

We created it in our Dev box. But in order to test it we had to rebuild it in our full copy Sandbox. We created from scratch because we couldn't find a way to move this via a change set. 

When we click the button to test it it opens a blank window. Here is the screenshot of where the button sits:

User-added image

Here is a screenshot of what happens when we click the button:

User-added image

"SendToOrderDirectBatchPublicClass"
public class SendtoOrderDirectBatchPublicClass {
    @AuraEnabled
    public void getmyExecuteBatch() {
        
        SendToOrder_Subscriptions runSendToOrder_Subscriptions = new SendToOrder_Subscriptions();
        database.executebatch(runSendToOrder_Subscriptions,100);
        
        ContractRenewalManager runContractRenewalManager = new ContractRenewalManager();
        database.executeBatch(runContractRenewalManager,1);
    }
}

"SnedToOrderSubscriptions" (current name can we rename to correct Sned to Send?)
Description
A Lightning Component Bundle

Navigate to the bundle's definitions in the action bar to the right.

"SnedToOrderSubscriptionsController.js
({
    "clickClose" : function(cmp) {
       // Close the action panel
       var dismissActionPanel = $A.get("e.force:closeQuickAction");
       dismissActionPanel.fire();
   },

   "doInit" : function(cmp) {
        // create a one-time use instance of the DirectBatch action
        // in the server-side controller

        var action = cmp.get("c.myExecuteBatch");

        // Create a callback that is executed after 
        // the server-side action returns

        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                // Alert the user with the value returned 
                // from the server
                alert("Success from server: " + response.getReturnValue());
            }
            else if (state === "INCOMPLETE") {
                // do something
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                        alert("Error from server:" + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });

        $A.enqueueAction(action);
    }
})

"SnedToOrderSubscriptions.cmp"
<!--quickLaunchBatch.cmp-->
<aura:component controller="SendToOrderDirectBatchPublicClass" implements="force:lightningQuickAction">

    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <h1>Batch launched!</h1><br/>

    <lightning:button label="Close" onclick="{!c.clickClose}"/>

</aura:component>
I am not a developer so I am not sure where the problem is. Also, if possible we would like this button to be placed on a List View page. Will this change how this is built?



 
I am receiving the following error around a price rule I have created:

User-added image

This price rule is being used in conuntion with lookup queries and a product rule. See screenshots below. The quote this is showing up on contains 3 products that cannot be sold in this particular billing state. I need my validation error message to show that explains that a product is not available in a particular state.

Also, we have multi year quotes where these products may be within each year (year 1, year 2, year 3). I was told the reason for the error is there are multiple rows returned from the table that satisfies my entry criteria. For eg: If you have Product A & Florida present 2 times in the table it will result in error. Make sure the entry criteria you use produces single outcome from the table. 

I do not know how what I need to change in order to the entry criteria to produce a single outcome. Here are the screenshots i mentioned above:

PRICE RULE
User-added image
User-added image

PRODUCT RULE
User-added image
User-added image


What is it that would need to be corrected in order for us to not receive the above error but instead to receive the error in the product rule validation?

We are using the Lookup Data object that comes with CPQ.
I went through the process of creating a Lightning Quick Action in our Dev box. We now want to move it from our Dev box to our full copy Sandbox. Can this be done with a change set? Or do I need to recreate it in the Sandbox?
Let me preface this with - we are hoping to find a simpler way to manage this. Maybe a product rule that uses lookup queries. As this is currently  holding up the release of a product for selling and quoting.

Also, note that these are all standalone products and not bundled products.

We have 9 product rules that are set to restrict specific products from being sold in certain states. We are trying to add a product to these rules to restrict where they are sold. For example, this particular product it CAN BE sold in CA, MI, NY, AZ, IL, and NJ. I added this product to the three rules that would allow this product to be sold in CA and MI (in the screenshots Product Rule 1 (CA), Product Rule 2 (CA and MI), and Product Rule 3 (MI)).

Below are the product rules:

User-added imageUser-added image

I then wanted to test to see the result of adding the product to a quote for those states.

When I add the product to a California quote I get the following error: "Product unavailable for this state. Please remove to continue. (ISE, ISI)" That error is the validation message for Product Rule 3 for Michigan. Why would it give the error for Michigan when the quote is for California and it can be sold in California?

I then tested adding the product to a Michigan quote and I get the following error: "Product unavailable for this state. Please remove to continue. (SPARCS, ISI)". That error is the validation message for Product Rule 1 for California. Why would it give the error for California when the quote is for Michigan and the product can be sold in Michigan?

I believe it has to do with evaluation order. The evaluation order for Product Rule 1 (CA) is 380, the evaluation order for Product Rule 2 (CA and MI) is 400, and the evaluation order for Product Rule 3 (MI) is 390.

What we do need to do is to be able to add this product to all rules where it needs to be sold as well as possibly add a rule for additional states. Is there a better way to handle this instead of several individual product rules?

We need direction on the best way to handle state restrictions for standalone products as well as bundles. 

Can this be done by creating a product rule that uses lookup queries? If so, I have started to try and design this. This is what I believe would need to be done using lookup queries within a product rule:
  1. We would need to somehow default the Quote Billing State to a configuration attribute.
  2. How would we build the configuration attribute if we do the above?
  3. We would use the Lookup Data object that is provided with CPQ. I have created some required fields for the lookup query - Billing State and Billing City. We would still use the standard Product Field, Type Field, and required field. In the lookup data object the type would be Show or Hide & Remove.
  4. Build a product rule. Here is a sample of a product rule that I started. Hoping I am on the right track.
  5. User-added image
  6. Lookup Query - I am not sure how to build that as I believe it will need refer to the configuration attribute as the match type, Billing State as the Tested Configuration Attribute, Operator of Equals, and Lookup Field would be the Billing State.
Any direction with screenshots would be extremely helpful.
We have created a permissions set to provide a specific profile read and edit access to the 'Renewal Forecast' and 'Renewal Quoted' checkboxes on the Contract object. But when we login as the user to test we get an error.

We set the permission set up by completeing the following:
  1. Click Object Settings
  2. Click Contracts
  3. Edit the Object
  4. Click Read and Edit
  5. Clicked Read Access and Edit Access for the 'Renewal Forecast' and 'Renewal Quoted' fields
Please note that for that profile the Field Level Security for both of these fields has 'Visible' and 'Read Only' unchecked. The Org Wide Setting for 'Account and Contract' is Private.

The error we are receiving is below. Please note that the we (administrators) can check either one of the boxes with no error:

User-added image

We have been trying to narrow this down to find the issue with no luck.

Any ideas to what we may have possibly missed?
We need a discount rule to discount based on the number/count of all options within a bundle on a quote.

For example you could have the following bundles on a quote:
Bundle A (parent)
Component 1
Component 2
Component 3
Component 4
Bundle B (parent)
Component 1
Component 3
Component 4

If the bundles contain any configuration of the 4 components number we need the following discounts to be applied to the components within that bundle:
  1. if it contains 2 components - 5% discount should be applied to all of the components within that particular bundle.
  2. if it contains 3 components - 7.5% discount should be applied to all of the components within that particular bundle.
  3. if it cotains 4 or more components - 10% discouint should be applied to all of 3 the components within that particular quote line bundle.
So, it should apply the disouncts as follows to each bundle:
Bundle A (parent)
Component 1 - 10:%
Component 2 - 10%
Component 3 - 10%
Component 4 - 10%
Bundle B (parent)
Component 1 - 7.5%
Component 3 - 7.5%
Component 4 - 7.5%
 
I am attaching screenshots of the Summary Variable to count the product options, the price rule and price action to populate the quote line field with the value, and the Discount Schedule to be used to discount.

SUMMARY VARIABLE
User-added imagePRICE RULE
User-added image

PRICE ACTION
User-added image

DISCOUNT SCHEDULE
User-added image
We are creating configurable bundles. Here are the parts products and configurations:

Products Being Used in the Bundles
  1. eC- List Price $5.00 / Effective Price (Standalone) $4.00
  2. FAST - List Price $7.50 / Effective Price (Standalone) $7.50
  3. (DnA or Suite) +  (Inspect Plus or Inspect Premium) + Camera Scanning for Suite - List Price $7.25 / Effective Price (Standalone) $6.75
    1. Looks likethis - DnA / Suite + Content + Camera Scanning- this product is comprised of the following:
      1. DnA or Suite
      2. Content - Inspect Plus or Inspect Premium
      3. Camera Scanning - only available for Suite
  4. AD - List Price $5.00 / Effective Price (Standalone) $1.75 
They can be confirgured as follows:
  1. DnA or Suite + eC + FAST + AD - Bundle Price $20.00
  2. DnA or Suite + eC + FAST - Bundle Price $18.25
  3. DnA or Suite +eC - Bundle Price $10.75
  4. DnA or Suite + FAST - Bundle Price $14.25
Above are the configurations. They then want to apply a discount based on the number of products purchased. 
  1. Two Products - 5%
  2. Three Products - 7.5%
  3. Four or More Products - 10%
We were thinking about creating bundles for each of the 8 combinations and then we need to figure out how to add the discount based on the number of bundles added. We can't us the Quantity field to determine the number of bundles sold as that is based on a student count.

We have this started/created via Features, Options, Option Constraints and some product rules. Here is the product setup:
User-added imageUser-added imageFirst, sales rep has to choose DNA or SUITE.
If SUITE is chosen then they have choose a content product (Inspect Plus or Inspect Premium) and a camera scanning product (GradeCam only)

Second, they can then choose anyone of the following. But the only configurations allowed for the bundle are above:
eC (standalone product)
FAST (standalone product)
AD (standalone product)

We are at the point where we need to have a some sort of validation (maybe a product rule) that would not allow the following combinations:
  1. DNA or Suite + eC + AD
  2. DNA or Suite + FAST + AD
  3. DNA or SUITE + AD
If this shoulc be done through a product rule what would the product rule look like?
 
I am extremely new to Flow. And my org has a flow that updated a checkbox on the opportunity product. I am trying to understand/figure out how to add some additional criteria at the beginning of the flow. 

How can I get some help? I know I need to be able to show the flow and each item within the flow in order to get the help needed. Not sure how I can post this here. 

Here is a screenshot of the flow (i am not sure if it is going to be hard to read):

User-added image

How can I possibly get some help with this?
We have a formula field on the Subscription record called "ARR Contribution". The formula is: 
Total_Amount__c /
          BLANKVALUE(
                      SBQQ__ProrateMultiplier__c,
                      CEILING((((SBQQ__SubscriptionEndDate__c - 
SBQQ__SubscriptionStartDate__c) / 365) * 12)) / SBQQ__Product__r.SBQQ__SubscriptionTerm__c
)
The formula does not calculate properly if the Subscription Start Date and Subscription End Date are equal (ie, 7/1/2019 start date and 7/1/2019 end date). If the dates are not equal it calculates as expected.

I created a second ARR Contribution field in sandbox called "ARR Contribution 2" to test a revised formula. The revised formula is:
Total_Amount__c/
IF(Start_Date__c = End_Date__c,
1,
BLANKVALUE( SBQQ__ProrateMultiplier__c, CEILING((((SBQQ__SubscriptionEndDate__c - SBQQ__SubscriptionStartDate__c) / 365) * 12)) / SBQQ__Product__r.SBQQ__SubscriptionTerm__c )
)
When the dates are equal (start date of 1/1/2019 and end date of 1/1/2019) the "ARR Contribution 2" field populates with the Total Amount value as expected.

But if I update the dates so that, for  example, the start date is 7/1/2018 and the end date is 6/30/2019, I was expecting that the "ARR Contribution 2" field would be completed because the Prorate Multiplier is blank. But what is happening is that it is putting the $5,000 value in the first "ARR Contribution" field. I would expect that at that point both ARR Contribution fields would say $5,000.

See screenshots below:

Start Date 7/1/2018 and End Date 7/1/2018 (equal dates)
User-added image

User-added image

Start Date 7/1/2018 and End Date 6/30/2019 (not equal dates)
User-added image

User-added image

Why are my results moving between the two fields? What needs to be tweaked in the formula for my "ARR Contribution 2" field. So, that the expected result for either case populates on the second field.
We created some pro-rating scenarios via Price Rules. The price rules are for a specific price book and based on Subscription start and end Dates.
Here are all of the scenarios but we tested on the scenario under #2:
  1. Starting after 6/30/2020 and forward there will be no discount for all products in the XYZ Price Book
  2. Starting 11/1/2019 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 8 (start date equals 11/1/2019 and end date date equals 6/30/2020)
  3. Starting 12/1/2019 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 7 (start date equals 12/1/2019 and end date date equals 6/30/2020)
  4. Starting 1/1/2020 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 6 (start date equals 1/1/2020 and end date date equals 6/30/2020)
  5. Starting 2/1/2020 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 5 (start date equals 2/1/2020 and end date date equals 6/30/2020)
  6. Starting 3/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 4 (start date equals 3/1/2020 and end date date equals 6/30/2020)
  7. Starting 4/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 3 (start date equals 4/1/2020 and end date date equals 6/30/2020)
  8. Starting 5/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 2 (start date equals 5/1/2020 and end date date equals 6/30/2020)
  9. Starting 6/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 1 (start date equals 6/1/2020 and end date date equals 6/30/2020)
Here is how the price rule is built:

User-added image
When testing the scenario we completed these steps when adding a product to a quote:
  1. Original Dates set upon quote creation of 7/1/2020 through 6/30/2021. And saved. No discount applied - Perfect
  2. Within the Quote Line Editor we changed the dates to be 11/1/2019 through 6/30/2020 and saved. Expecting the above price rule to fire. It does and applies appropriate discount of 33.33% and sets the default subscription term to 8 - Perfect
  3. Within the Quote Line Editor we changed the dates to be 7/1/2019 through 6/30/2020 and saved. Expecting the discount to be removed and default subscription term set back to 12 and price set back to the list price. Result was that the Pricing increased and discount still showed in the Quote Line Editor. Here is the screenshot of the products in the quote line editor (the 3rd product is not subscription but the first two are). The first product discount removed but the Net Unit Price and Net Total are more than list price. The second product discount remained and the Net Unit Price and the Net Total are more than the list price.
User-added image

Here is how the Product is setup in the price book:
User-added image
Here is the Quote Line Result after the 3 steps above were completed:

User-added imageWhat are we doing wrong? Is this not the correct way to setup pro-rate scenarios? It was suggested that we apply the discount to the non-prorated list unit price, and we put that value into "Special Price" (another non-prorated field). That way the system calculates the proration for you with the end result being "Regular Price" (special price times prorate multiplier). If we were to do do this route, would it be a Process Builder with the following field updates for updating the Special Price filed with the list unit price, updating the default term? Where would you place the discount (as in what field)?

​​​​​​​Any direction on troubleshooting or correction would be terrific. Apologies for the wordiness just wanted to try to be as detailed as possible.
We are looking to add a field to the Opportunity called Contract Terms. We want this field to look at all products associated with the opportunity and find the earlieast start date and the latest end date?

Any ideas?
I am just a couple days on with this company. They have the following Apex Class that runs nightly through a batch. We would like the ability to create a Lightning Action/Quick Action to place on the page layout so that this can also be invoked at any time during the day if needed.
 
global class NightlyJobs Implements Schedulable {
    
    global void execute (SchedulableContext sc) {
        
        SendToOrder_Subscriptions runSendToOrder_Subscriptions = new SendToOrder_Subscriptions();
        database.executebatch(runSendToOrder_Subscriptions,100);
        
        ContractRenewalManager runContractRenewalManager = new ContractRenewalManager();
        database.executebatch(runContractRenewalManager,1);
        
    }
    
    
}
This seems to reference the following sets of Apex as well:

ContractRenewalManager
global class ContractRenewalManager implements Database.Batchable<sObject>, Database.Stateful {

    global Integer totalContractsUpdated = 0;

    global Database.QueryLocator start(Database.BatchableContext BC) {

        datetime eligibilityDate = system.now().addMonths(4);
        string eligibilityDateFormatted = eligibilityDate.format('yyyy-MM-dd');

        // Build Contracts Dataset
        string queryContracts = 'SELECT id, SBQQ__RenewalForecast__c FROM Contract WHERE EndDate <= ' + eligibilityDateFormatted + ' AND SBQQ__RenewalForecast__c = false AND Disable_Renewal_Auto_Creation__c = false AND Status = \'Activated\'';
        return Database.getQueryLocator(queryContracts);
    }

    global void execute(Database.BatchableContext BC, List<Contract> scope) {

        // Vars
        List<Contract> listContractsToUpdate = new List<Contract>();
        List<Exception__c> list_newExceptions = new List<Exception__c>();

        // Loop through all Contracts
        for (Contract eachContract: scope) {

            eachContract.SBQQ__RenewalForecast__c = true;
            listContractsToUpdate.add(eachContract);

        }
        // UPDATE - Contract Records
        List<Database.SaveResult> listContractsToUpdate_SaveResults = database.update(listContractsToUpdate, false);

        // RESULTS
        for (Database.SaveResult eachResult: listContractsToUpdate_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Updated Contract Record ==>> ' + eachResult.getId());
                totalContractsUpdated++;
                // ON FAIL
            } else {
                for (Database.Error eachError: eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Set Renewal Forecast to TRUE', Object__c = 'Contract (Update)', Process__c = 'ContractRenewalManager (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Contract ID: ' + eachResult.getId());
                    list_newExceptions.add(newException);
                }
            }
        }

        insert list_newExceptions;

    }

    global void finish(Database.BatchableContext BC) {

        system.debug('DEBUG ---->>>> Total Contracts Updated: ' + totalContractsUpdated);

    }
}

SendToOrderSubscriptions
global class SendToOrder_Subscriptions implements Database.Batchable<sObject>, Database.Stateful {
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        string queryAccounts = 'SELECT id FROM Account WHERE id IN (SELECT SBQQ__Account__c FROM SBQQ__Subscription__c WHERE SBQQ__Quantity__c > 0 AND Send_To_Order__c = true AND Added_To_Order__c = false AND Status__c != \'Cancelled\')';
        return Database.getQueryLocator(queryAccounts);
    }
    
    global void execute(Database.BatchableContext BC, List<Account> scope) {
        
        // Prepare data ----
        List<Account> thisScopeAccounts = new List<Account>();
        thisScopeAccounts.addAll(scope);
        id standardPricebookId;         
        
        if (Test.isRunningTest()) {
            standardPricebookId = Test.getStandardPricebookId();
        } else {
            standardPricebookId = [SELECT id FROM Pricebook2 WHERE isStandard = true].id;
        }
        
        List<PricebookEntry> listofPBEs = [SELECT id, Product2id, Pricebook2id FROM PricebookEntry WHERE Pricebook2id = :standardPricebookId];
        Map<id,id> pricebookEntryids = new Map<id,id>();
        List<Exception__c> newExceptions = new List<Exception__c>();
        
        for (PricebookEntry eachPBE : listofPBEs) {
            pricebookEntryids.put(eachPBE.Product2id,eachPBE.id);           
        }
        
        List<SBQQ__Subscription__c> thisScopeSubscriptions = [SELECT id, SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Accounting_Quantity__c, 
                                                              SBQQ__Product__c, Display_Name__c, Product_Description__c, SBQQ__SubscriptionStartDate__c, 
                                                              SBQQ__SubscriptionEndDate__c, SBQQ__ListPrice__c, SBQQ__QuoteLine__c, SBQQ__NetPrice__c, 
                                                              Transaction_Number__c, Purchase_Order__c 
                                                              FROM SBQQ__Subscription__c 
                                                              WHERE SBQQ__Quantity__c > 0 AND Send_To_Order__c = true AND Added_To_Order__c = false AND Status__c != 'Cancelled' 
                                                              AND SBQQ__Account__c IN :thisScopeAccounts];
        
        
        List<AggregateResult> aggregatedSubscriptions = [SELECT SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Bill_To_Account__r.Billing_Contact__c, MIN(SBQQ__SubscriptionStartDate__c) StartDate, MAX(SBQQ__SubscriptionEndDate__c) EndDate FROM SBQQ__Subscription__c WHERE SBQQ__Account__c IN :thisScopeAccounts AND Send_To_Order__c = true AND Added_To_Order__c = false GROUP BY SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Bill_To_Account__r.Billing_Contact__c];
        List<Order> newOrders = new List<Order>();
        
        // Create Orders
        for (AggregateResult eachNewOrder : aggregatedSubscriptions) {
            Order newOrder = new Order(
                Accountid = (id)eachNewOrder.get('SBQQ__Account__c'),
                Bill_To_Account__c = (id)eachNewOrder.get('Bill_To_Account__c'),
                Business_Entity__c = (id)eachNewOrder.get('Business_Entity__c'),
                BillToContactId = (id)eachNewOrder.get('Billing_Contact__c'),
                EffectiveDate = (date)eachNewOrder.get('StartDate'),
                EndDate = (date)eachNewOrder.get('EndDate'),
                Pricebook2id = standardPricebookId,
                Type = 'Subscription Order',
                Status = 'Draft'
            );
            newOrders.add(newOrder);
        }
        
        // INSERT Orders from source record aggregate data
        List<Database.SaveResult> newOrders_SaveResults = database.insert(newOrders, false);
        integer orderInsertIndex = 0;
        
        // RESULTS
        for (Database.SaveResult eachResult : newOrders_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Inserted Order Record ==>> ' + eachResult.getId());
                // ON FAIL
            } else {
                for (Database.Error eachError : eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Inserting Order records', Object__c = 'Order (Insert)', Process__c = 'SendToOrder_Subscriptions (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Account ID: ' + newOrders[orderInsertIndex].Accountid);
                    newExceptions.add(newException);
                }
            }
            orderInsertIndex++;
        } 
        
        // Create Order Lines
        List<OrderItem> newOrderLines = new List<OrderItem>();
        
        for (Order eachOrder : newOrders) {
            
            for (SBQQ__Subscription__c eachSubscription : thisScopeSubscriptions) {
                
                if (eachOrder.AccountId == eachSubscription.SBQQ__Account__c && 
                    eachOrder.Bill_To_Account__c == eachSubscription.Bill_To_Account__c && 
                    eachOrder.Business_Entity__c == eachSubscription.Business_Entity__c) {
                        
                        OrderItem newOrderLine = new OrderItem(
                            Orderid = eachOrder.id,
                            SBQQ__Subscription__c = eachSubscription.id,
                            Description = eachSubscription.Product_Description__c,
                            Display_Name__c = eachSubscription.Display_Name__c,
                            ServiceDate = eachSubscription.SBQQ__SubscriptionStartDate__c,
                            EndDate = eachSubscription.SBQQ__SubscriptionEndDate__c,
                            Quantity = eachSubscription.Accounting_Quantity__c,
                            SBQQ__QuotedListPrice__c = eachSubscription.SBQQ__ListPrice__c,
                            UnitPrice = eachSubscription.SBQQ__NetPrice__c,
                            PricebookEntryid = pricebookEntryids.get(eachSubscription.SBQQ__Product__c),
                            Transaction_Number__c = eachSubscription.Transaction_Number__c,
                            Purchase_Order__c = eachSubscription.Purchase_Order__c
                        ); 
                        newOrderLines.add(newOrderLine);
                    }
            }
        }
        
        // INSERT OrderItem records from source records
        List<Database.SaveResult> newOrderLines_SaveResults = database.insert(newOrderLines, false);
        integer orderLinesInsertIndex = 0;
        
        // RESULTS
        for (Database.SaveResult eachResult : newOrderLines_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Inserted OrderItem Record ==>> ' + eachResult.getId());
                // ON FAIL
            } else {
                for (Database.Error eachError : eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Inserting OrderItem records', Object__c = 'OrderItem (Insert)', Process__c = 'SendToOrder_Subscriptions (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Subscription ID: ' + newOrderLines[orderLinesInsertIndex].SBQQ__Subscription__c);
                    newExceptions.add(newException);
                }
            }
            orderLinesInsertIndex++;
        } 

        database.insert(newExceptions,false);

    }
    
    global void finish(Database.BatchableContext BC) {
        
        // Chain to SendToOrder_Assets Apex Class
        if (!Test.isRunningTest()) {
            SendToOrder_Assets runSendToOrder_Assets = new SendToOrder_Assets();
            database.executebatch(runSendToOrder_Assets,100);
        }
        
    }
}

How would we get started in creating a Lightning Action/Quick Action? Is this possible?
Iam trying to complete challenge 7 of Lightning Experience Reports & Dashboards Specialist. I am using a new playground created yesterday per the instructions in the Superbadge. I just completed creating the dashboard and when clicking Check Challenge I am getting the following error:

User-added imagePlease help so I can complete this challenge.
I have this formula field I am trying to build. Here is the current formula that is throwing the compilation error above:
 
IF( 
   ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
     IF( 
        AND(Opportunity_Record_Type__c = 'Amendment',
           OR(Line_Level_Detail__c <> 'New Logo',
              Line_Level_Detail__c <> 'Cross Sell',
              Line_Level_Detail__c <> 'Upgrade / Downgrade',
              Line_Level_Detail__c  <> 'Services',
              Line_Level_Detail__c  <> 'Product Churn',
              Line_Level_Detail__c  <> 'Product Deprecated',
              Line_Level_Detail__c  <> 'Customer Credit')), TotalPrice,
            IF(
               AND(Opportunity_Record_Type__c  <>  'Amendment',  Line_Level_Type__c  <> 'Removed Product', 
                 OR(Line_Level_Detail__c <> 'New Logo',
                    Line_Level_Detail__c <> 'Cross Sell',
                    Line_Level_Detail__c <> 'Upgrade / Downgrade',
                    Line_Level_Detail__c  <> 'Services',
                    Line_Level_Detail__c  <> 'Product Churn',
                    Line_Level_Detail__c  <> 'Product Deprecated',
                    Line_Level_Detail__c  <> 'Customer Credit')), TotalPrice,
                IF(
                   AND(Opportunity_Record_Type__c  <>  'Amendment',  Line_Level_Type__c = 'Removed Product',
                     OR(Line_Level_Detail__c = 'Upgrade / Downgrade',
                        Line_Level_Detail__c = 'Migration',
                        Line_Level_Detail__c = 'Bundle Adj')), Combined_Renewed_Subscription_Total_Amt__c ,        

           0)
)
)
)

I know that the compilation error is due to things such as formulas on formulas, etc. But is there anything I can do to re-write it.
I am creating a formula field that is totally 4 other formula fields and receiving the following error: "Error: Compiled formula is too big to execute (7,784 characters). Maximum size is 5,000 characters"

Here is the formula I am creating:
ARR_New__c  +  ARR_Price_Change_RN__c  +  ARR_Quantity_Change_RN__c  +  ARR_Removed__c
How can I reduce the compile size?

Here is what each one of the 4 formula fields above looks like:

ARR NEW (Compiled Size: 730 Characters)
IF(ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
       If( 
          AND 
            (NOT 
                (Line_Level_Detail__c='Services'), Line_Level_Type__c= 'New Product'), UnitPrice * Quantity , 0))
ARR Price Change (RN) (Compiled Size: 2,738 characters)
If (
    ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
IF( 
   AND(
       Line_Level_Type__c= 'Renewed Product',  NOT(CONTAINS( Pricing_Method_Change__c, 'Block'))),  Quantity *( UnitPrice - Renewed_Subscription_Net_Price__c),
IF(
   AND(
       Line_Level_Type__c= 'Renewed Product', CONTAINS( Pricing_Method_Change__c, 'Block')), TotalPrice - Renewed_Subscription_Total_Amount__c, 0)
)
)
ARR Quantity Change (RN) (Compiled Size: 1,345 characters)
IF(
    ISPICKVAL(Opportunity.StageName,"Closed Lost"),0,
IF(
    AND(Line_Level_Type__c='Renewed Product', NOT(CONTAINS( Pricing_Method_Change__c, 'Block'))),
         Renewed_Subscription_Net_Price__c *( Quantity  -  Quantity_Upon_Creation__c ),0))
ARR Removed (Compiled Size: 2,925)
IF (
    AND(
         (ISPICKVAL(Opportunity.StageName, "Closed Lost")), Line_Level_Type__c  <>  'New Product'), Combined_Renewed_Subscription_Total_Amt__c  *-1,
            IF (
              AND(
                 Line_Level_Type__c = 'Removed Product', Opportunity_Record_Type__c = 'Amendment',  Line_Level_Detail__c  <> 'Services'), TotalPrice,
                   IF (
                      AND (
                           Line_Level_Type__c = 'Removed Product', Opportunity_Record_Type__c = 'Renewal'),  Combined_Renewed_Subscription_Total_Amt__c  *-1,0)
)
)

 
I went through the process of creating a Lightning Quick Action in our Dev box. We now want to move it from our Dev box to our full copy Sandbox. Can this be done with a change set? Or do I need to recreate it in the Sandbox?
Let me preface this with - we are hoping to find a simpler way to manage this. Maybe a product rule that uses lookup queries. As this is currently  holding up the release of a product for selling and quoting.

Also, note that these are all standalone products and not bundled products.

We have 9 product rules that are set to restrict specific products from being sold in certain states. We are trying to add a product to these rules to restrict where they are sold. For example, this particular product it CAN BE sold in CA, MI, NY, AZ, IL, and NJ. I added this product to the three rules that would allow this product to be sold in CA and MI (in the screenshots Product Rule 1 (CA), Product Rule 2 (CA and MI), and Product Rule 3 (MI)).

Below are the product rules:

User-added imageUser-added image

I then wanted to test to see the result of adding the product to a quote for those states.

When I add the product to a California quote I get the following error: "Product unavailable for this state. Please remove to continue. (ISE, ISI)" That error is the validation message for Product Rule 3 for Michigan. Why would it give the error for Michigan when the quote is for California and it can be sold in California?

I then tested adding the product to a Michigan quote and I get the following error: "Product unavailable for this state. Please remove to continue. (SPARCS, ISI)". That error is the validation message for Product Rule 1 for California. Why would it give the error for California when the quote is for Michigan and the product can be sold in Michigan?

I believe it has to do with evaluation order. The evaluation order for Product Rule 1 (CA) is 380, the evaluation order for Product Rule 2 (CA and MI) is 400, and the evaluation order for Product Rule 3 (MI) is 390.

What we do need to do is to be able to add this product to all rules where it needs to be sold as well as possibly add a rule for additional states. Is there a better way to handle this instead of several individual product rules?

We need direction on the best way to handle state restrictions for standalone products as well as bundles. 

Can this be done by creating a product rule that uses lookup queries? If so, I have started to try and design this. This is what I believe would need to be done using lookup queries within a product rule:
  1. We would need to somehow default the Quote Billing State to a configuration attribute.
  2. How would we build the configuration attribute if we do the above?
  3. We would use the Lookup Data object that is provided with CPQ. I have created some required fields for the lookup query - Billing State and Billing City. We would still use the standard Product Field, Type Field, and required field. In the lookup data object the type would be Show or Hide & Remove.
  4. Build a product rule. Here is a sample of a product rule that I started. Hoping I am on the right track.
  5. User-added image
  6. Lookup Query - I am not sure how to build that as I believe it will need refer to the configuration attribute as the match type, Billing State as the Tested Configuration Attribute, Operator of Equals, and Lookup Field would be the Billing State.
Any direction with screenshots would be extremely helpful.
We have created a permissions set to provide a specific profile read and edit access to the 'Renewal Forecast' and 'Renewal Quoted' checkboxes on the Contract object. But when we login as the user to test we get an error.

We set the permission set up by completeing the following:
  1. Click Object Settings
  2. Click Contracts
  3. Edit the Object
  4. Click Read and Edit
  5. Clicked Read Access and Edit Access for the 'Renewal Forecast' and 'Renewal Quoted' fields
Please note that for that profile the Field Level Security for both of these fields has 'Visible' and 'Read Only' unchecked. The Org Wide Setting for 'Account and Contract' is Private.

The error we are receiving is below. Please note that the we (administrators) can check either one of the boxes with no error:

User-added image

We have been trying to narrow this down to find the issue with no luck.

Any ideas to what we may have possibly missed?
We need a discount rule to discount based on the number/count of all options within a bundle on a quote.

For example you could have the following bundles on a quote:
Bundle A (parent)
Component 1
Component 2
Component 3
Component 4
Bundle B (parent)
Component 1
Component 3
Component 4

If the bundles contain any configuration of the 4 components number we need the following discounts to be applied to the components within that bundle:
  1. if it contains 2 components - 5% discount should be applied to all of the components within that particular bundle.
  2. if it contains 3 components - 7.5% discount should be applied to all of the components within that particular bundle.
  3. if it cotains 4 or more components - 10% discouint should be applied to all of 3 the components within that particular quote line bundle.
So, it should apply the disouncts as follows to each bundle:
Bundle A (parent)
Component 1 - 10:%
Component 2 - 10%
Component 3 - 10%
Component 4 - 10%
Bundle B (parent)
Component 1 - 7.5%
Component 3 - 7.5%
Component 4 - 7.5%
 
I am attaching screenshots of the Summary Variable to count the product options, the price rule and price action to populate the quote line field with the value, and the Discount Schedule to be used to discount.

SUMMARY VARIABLE
User-added imagePRICE RULE
User-added image

PRICE ACTION
User-added image

DISCOUNT SCHEDULE
User-added image
We are creating configurable bundles. Here are the parts products and configurations:

Products Being Used in the Bundles
  1. eC- List Price $5.00 / Effective Price (Standalone) $4.00
  2. FAST - List Price $7.50 / Effective Price (Standalone) $7.50
  3. (DnA or Suite) +  (Inspect Plus or Inspect Premium) + Camera Scanning for Suite - List Price $7.25 / Effective Price (Standalone) $6.75
    1. Looks likethis - DnA / Suite + Content + Camera Scanning- this product is comprised of the following:
      1. DnA or Suite
      2. Content - Inspect Plus or Inspect Premium
      3. Camera Scanning - only available for Suite
  4. AD - List Price $5.00 / Effective Price (Standalone) $1.75 
They can be confirgured as follows:
  1. DnA or Suite + eC + FAST + AD - Bundle Price $20.00
  2. DnA or Suite + eC + FAST - Bundle Price $18.25
  3. DnA or Suite +eC - Bundle Price $10.75
  4. DnA or Suite + FAST - Bundle Price $14.25
Above are the configurations. They then want to apply a discount based on the number of products purchased. 
  1. Two Products - 5%
  2. Three Products - 7.5%
  3. Four or More Products - 10%
We were thinking about creating bundles for each of the 8 combinations and then we need to figure out how to add the discount based on the number of bundles added. We can't us the Quantity field to determine the number of bundles sold as that is based on a student count.

We have this started/created via Features, Options, Option Constraints and some product rules. Here is the product setup:
User-added imageUser-added imageFirst, sales rep has to choose DNA or SUITE.
If SUITE is chosen then they have choose a content product (Inspect Plus or Inspect Premium) and a camera scanning product (GradeCam only)

Second, they can then choose anyone of the following. But the only configurations allowed for the bundle are above:
eC (standalone product)
FAST (standalone product)
AD (standalone product)

We are at the point where we need to have a some sort of validation (maybe a product rule) that would not allow the following combinations:
  1. DNA or Suite + eC + AD
  2. DNA or Suite + FAST + AD
  3. DNA or SUITE + AD
If this shoulc be done through a product rule what would the product rule look like?
 
We have a formula field on the Subscription record called "ARR Contribution". The formula is: 
Total_Amount__c /
          BLANKVALUE(
                      SBQQ__ProrateMultiplier__c,
                      CEILING((((SBQQ__SubscriptionEndDate__c - 
SBQQ__SubscriptionStartDate__c) / 365) * 12)) / SBQQ__Product__r.SBQQ__SubscriptionTerm__c
)
The formula does not calculate properly if the Subscription Start Date and Subscription End Date are equal (ie, 7/1/2019 start date and 7/1/2019 end date). If the dates are not equal it calculates as expected.

I created a second ARR Contribution field in sandbox called "ARR Contribution 2" to test a revised formula. The revised formula is:
Total_Amount__c/
IF(Start_Date__c = End_Date__c,
1,
BLANKVALUE( SBQQ__ProrateMultiplier__c, CEILING((((SBQQ__SubscriptionEndDate__c - SBQQ__SubscriptionStartDate__c) / 365) * 12)) / SBQQ__Product__r.SBQQ__SubscriptionTerm__c )
)
When the dates are equal (start date of 1/1/2019 and end date of 1/1/2019) the "ARR Contribution 2" field populates with the Total Amount value as expected.

But if I update the dates so that, for  example, the start date is 7/1/2018 and the end date is 6/30/2019, I was expecting that the "ARR Contribution 2" field would be completed because the Prorate Multiplier is blank. But what is happening is that it is putting the $5,000 value in the first "ARR Contribution" field. I would expect that at that point both ARR Contribution fields would say $5,000.

See screenshots below:

Start Date 7/1/2018 and End Date 7/1/2018 (equal dates)
User-added image

User-added image

Start Date 7/1/2018 and End Date 6/30/2019 (not equal dates)
User-added image

User-added image

Why are my results moving between the two fields? What needs to be tweaked in the formula for my "ARR Contribution 2" field. So, that the expected result for either case populates on the second field.
We created some pro-rating scenarios via Price Rules. The price rules are for a specific price book and based on Subscription start and end Dates.
Here are all of the scenarios but we tested on the scenario under #2:
  1. Starting after 6/30/2020 and forward there will be no discount for all products in the XYZ Price Book
  2. Starting 11/1/2019 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 8 (start date equals 11/1/2019 and end date date equals 6/30/2020)
  3. Starting 12/1/2019 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 7 (start date equals 12/1/2019 and end date date equals 6/30/2020)
  4. Starting 1/1/2020 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 6 (start date equals 1/1/2020 and end date date equals 6/30/2020)
  5. Starting 2/1/2020 there will be a 33.33% discount for all products in the XYZ Price Book and the default term would be 5 (start date equals 2/1/2020 and end date date equals 6/30/2020)
  6. Starting 3/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 4 (start date equals 3/1/2020 and end date date equals 6/30/2020)
  7. Starting 4/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 3 (start date equals 4/1/2020 and end date date equals 6/30/2020)
  8. Starting 5/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 2 (start date equals 5/1/2020 and end date date equals 6/30/2020)
  9. Starting 6/1/2020 there will be a 66.67% discount for all products in the XYZ Price Book and the default term would be 1 (start date equals 6/1/2020 and end date date equals 6/30/2020)
Here is how the price rule is built:

User-added image
When testing the scenario we completed these steps when adding a product to a quote:
  1. Original Dates set upon quote creation of 7/1/2020 through 6/30/2021. And saved. No discount applied - Perfect
  2. Within the Quote Line Editor we changed the dates to be 11/1/2019 through 6/30/2020 and saved. Expecting the above price rule to fire. It does and applies appropriate discount of 33.33% and sets the default subscription term to 8 - Perfect
  3. Within the Quote Line Editor we changed the dates to be 7/1/2019 through 6/30/2020 and saved. Expecting the discount to be removed and default subscription term set back to 12 and price set back to the list price. Result was that the Pricing increased and discount still showed in the Quote Line Editor. Here is the screenshot of the products in the quote line editor (the 3rd product is not subscription but the first two are). The first product discount removed but the Net Unit Price and Net Total are more than list price. The second product discount remained and the Net Unit Price and the Net Total are more than the list price.
User-added image

Here is how the Product is setup in the price book:
User-added image
Here is the Quote Line Result after the 3 steps above were completed:

User-added imageWhat are we doing wrong? Is this not the correct way to setup pro-rate scenarios? It was suggested that we apply the discount to the non-prorated list unit price, and we put that value into "Special Price" (another non-prorated field). That way the system calculates the proration for you with the end result being "Regular Price" (special price times prorate multiplier). If we were to do do this route, would it be a Process Builder with the following field updates for updating the Special Price filed with the list unit price, updating the default term? Where would you place the discount (as in what field)?

​​​​​​​Any direction on troubleshooting or correction would be terrific. Apologies for the wordiness just wanted to try to be as detailed as possible.
I am just a couple days on with this company. They have the following Apex Class that runs nightly through a batch. We would like the ability to create a Lightning Action/Quick Action to place on the page layout so that this can also be invoked at any time during the day if needed.
 
global class NightlyJobs Implements Schedulable {
    
    global void execute (SchedulableContext sc) {
        
        SendToOrder_Subscriptions runSendToOrder_Subscriptions = new SendToOrder_Subscriptions();
        database.executebatch(runSendToOrder_Subscriptions,100);
        
        ContractRenewalManager runContractRenewalManager = new ContractRenewalManager();
        database.executebatch(runContractRenewalManager,1);
        
    }
    
    
}
This seems to reference the following sets of Apex as well:

ContractRenewalManager
global class ContractRenewalManager implements Database.Batchable<sObject>, Database.Stateful {

    global Integer totalContractsUpdated = 0;

    global Database.QueryLocator start(Database.BatchableContext BC) {

        datetime eligibilityDate = system.now().addMonths(4);
        string eligibilityDateFormatted = eligibilityDate.format('yyyy-MM-dd');

        // Build Contracts Dataset
        string queryContracts = 'SELECT id, SBQQ__RenewalForecast__c FROM Contract WHERE EndDate <= ' + eligibilityDateFormatted + ' AND SBQQ__RenewalForecast__c = false AND Disable_Renewal_Auto_Creation__c = false AND Status = \'Activated\'';
        return Database.getQueryLocator(queryContracts);
    }

    global void execute(Database.BatchableContext BC, List<Contract> scope) {

        // Vars
        List<Contract> listContractsToUpdate = new List<Contract>();
        List<Exception__c> list_newExceptions = new List<Exception__c>();

        // Loop through all Contracts
        for (Contract eachContract: scope) {

            eachContract.SBQQ__RenewalForecast__c = true;
            listContractsToUpdate.add(eachContract);

        }
        // UPDATE - Contract Records
        List<Database.SaveResult> listContractsToUpdate_SaveResults = database.update(listContractsToUpdate, false);

        // RESULTS
        for (Database.SaveResult eachResult: listContractsToUpdate_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Updated Contract Record ==>> ' + eachResult.getId());
                totalContractsUpdated++;
                // ON FAIL
            } else {
                for (Database.Error eachError: eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Set Renewal Forecast to TRUE', Object__c = 'Contract (Update)', Process__c = 'ContractRenewalManager (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Contract ID: ' + eachResult.getId());
                    list_newExceptions.add(newException);
                }
            }
        }

        insert list_newExceptions;

    }

    global void finish(Database.BatchableContext BC) {

        system.debug('DEBUG ---->>>> Total Contracts Updated: ' + totalContractsUpdated);

    }
}

SendToOrderSubscriptions
global class SendToOrder_Subscriptions implements Database.Batchable<sObject>, Database.Stateful {
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        string queryAccounts = 'SELECT id FROM Account WHERE id IN (SELECT SBQQ__Account__c FROM SBQQ__Subscription__c WHERE SBQQ__Quantity__c > 0 AND Send_To_Order__c = true AND Added_To_Order__c = false AND Status__c != \'Cancelled\')';
        return Database.getQueryLocator(queryAccounts);
    }
    
    global void execute(Database.BatchableContext BC, List<Account> scope) {
        
        // Prepare data ----
        List<Account> thisScopeAccounts = new List<Account>();
        thisScopeAccounts.addAll(scope);
        id standardPricebookId;         
        
        if (Test.isRunningTest()) {
            standardPricebookId = Test.getStandardPricebookId();
        } else {
            standardPricebookId = [SELECT id FROM Pricebook2 WHERE isStandard = true].id;
        }
        
        List<PricebookEntry> listofPBEs = [SELECT id, Product2id, Pricebook2id FROM PricebookEntry WHERE Pricebook2id = :standardPricebookId];
        Map<id,id> pricebookEntryids = new Map<id,id>();
        List<Exception__c> newExceptions = new List<Exception__c>();
        
        for (PricebookEntry eachPBE : listofPBEs) {
            pricebookEntryids.put(eachPBE.Product2id,eachPBE.id);           
        }
        
        List<SBQQ__Subscription__c> thisScopeSubscriptions = [SELECT id, SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Accounting_Quantity__c, 
                                                              SBQQ__Product__c, Display_Name__c, Product_Description__c, SBQQ__SubscriptionStartDate__c, 
                                                              SBQQ__SubscriptionEndDate__c, SBQQ__ListPrice__c, SBQQ__QuoteLine__c, SBQQ__NetPrice__c, 
                                                              Transaction_Number__c, Purchase_Order__c 
                                                              FROM SBQQ__Subscription__c 
                                                              WHERE SBQQ__Quantity__c > 0 AND Send_To_Order__c = true AND Added_To_Order__c = false AND Status__c != 'Cancelled' 
                                                              AND SBQQ__Account__c IN :thisScopeAccounts];
        
        
        List<AggregateResult> aggregatedSubscriptions = [SELECT SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Bill_To_Account__r.Billing_Contact__c, MIN(SBQQ__SubscriptionStartDate__c) StartDate, MAX(SBQQ__SubscriptionEndDate__c) EndDate FROM SBQQ__Subscription__c WHERE SBQQ__Account__c IN :thisScopeAccounts AND Send_To_Order__c = true AND Added_To_Order__c = false GROUP BY SBQQ__Account__c, Bill_To_Account__c, Business_Entity__c, Bill_To_Account__r.Billing_Contact__c];
        List<Order> newOrders = new List<Order>();
        
        // Create Orders
        for (AggregateResult eachNewOrder : aggregatedSubscriptions) {
            Order newOrder = new Order(
                Accountid = (id)eachNewOrder.get('SBQQ__Account__c'),
                Bill_To_Account__c = (id)eachNewOrder.get('Bill_To_Account__c'),
                Business_Entity__c = (id)eachNewOrder.get('Business_Entity__c'),
                BillToContactId = (id)eachNewOrder.get('Billing_Contact__c'),
                EffectiveDate = (date)eachNewOrder.get('StartDate'),
                EndDate = (date)eachNewOrder.get('EndDate'),
                Pricebook2id = standardPricebookId,
                Type = 'Subscription Order',
                Status = 'Draft'
            );
            newOrders.add(newOrder);
        }
        
        // INSERT Orders from source record aggregate data
        List<Database.SaveResult> newOrders_SaveResults = database.insert(newOrders, false);
        integer orderInsertIndex = 0;
        
        // RESULTS
        for (Database.SaveResult eachResult : newOrders_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Inserted Order Record ==>> ' + eachResult.getId());
                // ON FAIL
            } else {
                for (Database.Error eachError : eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Inserting Order records', Object__c = 'Order (Insert)', Process__c = 'SendToOrder_Subscriptions (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Account ID: ' + newOrders[orderInsertIndex].Accountid);
                    newExceptions.add(newException);
                }
            }
            orderInsertIndex++;
        } 
        
        // Create Order Lines
        List<OrderItem> newOrderLines = new List<OrderItem>();
        
        for (Order eachOrder : newOrders) {
            
            for (SBQQ__Subscription__c eachSubscription : thisScopeSubscriptions) {
                
                if (eachOrder.AccountId == eachSubscription.SBQQ__Account__c && 
                    eachOrder.Bill_To_Account__c == eachSubscription.Bill_To_Account__c && 
                    eachOrder.Business_Entity__c == eachSubscription.Business_Entity__c) {
                        
                        OrderItem newOrderLine = new OrderItem(
                            Orderid = eachOrder.id,
                            SBQQ__Subscription__c = eachSubscription.id,
                            Description = eachSubscription.Product_Description__c,
                            Display_Name__c = eachSubscription.Display_Name__c,
                            ServiceDate = eachSubscription.SBQQ__SubscriptionStartDate__c,
                            EndDate = eachSubscription.SBQQ__SubscriptionEndDate__c,
                            Quantity = eachSubscription.Accounting_Quantity__c,
                            SBQQ__QuotedListPrice__c = eachSubscription.SBQQ__ListPrice__c,
                            UnitPrice = eachSubscription.SBQQ__NetPrice__c,
                            PricebookEntryid = pricebookEntryids.get(eachSubscription.SBQQ__Product__c),
                            Transaction_Number__c = eachSubscription.Transaction_Number__c,
                            Purchase_Order__c = eachSubscription.Purchase_Order__c
                        ); 
                        newOrderLines.add(newOrderLine);
                    }
            }
        }
        
        // INSERT OrderItem records from source records
        List<Database.SaveResult> newOrderLines_SaveResults = database.insert(newOrderLines, false);
        integer orderLinesInsertIndex = 0;
        
        // RESULTS
        for (Database.SaveResult eachResult : newOrderLines_SaveResults) {
            // ON SUCCESS
            if (eachResult.isSuccess()) {
                System.debug('== DEBUG: Inserted OrderItem Record ==>> ' + eachResult.getId());
                // ON FAIL
            } else {
                for (Database.Error eachError : eachResult.getErrors()) {
                    Exception__c newException = new Exception__c(Purpose__c = 'Inserting OrderItem records', Object__c = 'OrderItem (Insert)', Process__c = 'SendToOrder_Subscriptions (Apex Class)', Details__c = eachError.getStatusCode() + ': ' + eachError.getMessage() + '\n' + '\n' + 'Field affected by the error: ' + eachError.getFields() + '\n' + '\n' + 'Note: This error is related to Subscription ID: ' + newOrderLines[orderLinesInsertIndex].SBQQ__Subscription__c);
                    newExceptions.add(newException);
                }
            }
            orderLinesInsertIndex++;
        } 

        database.insert(newExceptions,false);

    }
    
    global void finish(Database.BatchableContext BC) {
        
        // Chain to SendToOrder_Assets Apex Class
        if (!Test.isRunningTest()) {
            SendToOrder_Assets runSendToOrder_Assets = new SendToOrder_Assets();
            database.executebatch(runSendToOrder_Assets,100);
        }
        
    }
}

How would we get started in creating a Lightning Action/Quick Action? Is this possible?