How to create a dynamic - calculated - field in Salesforce? - salesforce

Salesforce:
Every account has an agreement with my company. Once they have an agreement in place, they can start ordering products.
In the account record, I have a date field called "Agreement Approved On".
Ordered products are represented as "assets".
I want to create another field in the account record called "First Order Amount". This field should be populated dynamically, and should calculate the following:
Look for all of the account's assets created after the date field "Agreement Approved On".
Summarize the total of all assets ordered during the first order (within the same day).
Within the same day:
Let's assume the agreement was approved on January 1 2017. The
account started ordering on January 5 2017.
During January 5 2017, the account made 5 orders (8 different
assets), total is $1,000. This is the first order total - within the same
day.
After January 5 2017, the account made more orders, but they don't
count towards "first order amount".
So my question is - how do I create this "First Order Amount" field?
Thanks!

You need to setup a oncreate trigger on Asset taht will update the first order total amount field on Account.
In the trigger check whether now() > agreement approve date. If yes, check if there are any other assets with dateCreated < TODAY.
These two conditions will check whether there are any existing account assets and if the date is > agreement date. If there are existing assets, it means this is not the first order.
You can then get all asset amounts and add them and write the final amount to the account field.
See https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_context_variables.htm
for trigger syntax
and https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm for date functions and literals.

Related

Apex/Salesforce/flow: Be able to increase price and clone/update product automatically

I asked a similar question before but I am still struggling and was not able to do what I was required to do and am coming back to this community for help.
I am trying to increase the price of the products on a quote in salesforce CPQ/Billing based on a field and to do this automatically.
The Setup
In Salesforce CPQ, If you go to account -> Contract -> Sales Service: There is a field called Price Increase %(PROD_Price_Increase__c)
A contract can have multiple quotes
What I want to do
When a quote has reached the final step a contract is created. In the contract I have the option to click a button called Amend. Which allows me to take the products in the existing quotes and amend it.
I want to create a batch job that does the following:
The Contract has these fields: Start Date (PROD_Start_Date__c), Price increase Date (PROD_Increase_Date__c), End Date (PROD_End_Date__c).
-- If the Price Increase Date is 12 months after the start date, these are the contracts that will need to be updated
-- For example, If the start date is 15 Feb 2023, Price increase is 1 Jan 2024, end date is 15 Feb 2025. Since the increase date is not 12 months, these contract should be ignored.
Main Task
When products who have a price increase 12 months after the start date, the contract should be able to 'amend' and update the quantity of the products and clone the products.
In the contract, the action buttons on top have "Amend". once clicked, it shows all the subscriptions products, you click next then it comes into the edit quote page.
Once here it shows all the products that were part of the contract and its quote. The net price filed for the original products will be '0'. These products will need to be cloned and the quantity for these to be applied to the cloned products. Once the quantity has been copied over, the original products quantity should change to 0.
After these products have a quantity of 0, the clone products should have the price increase. The value I mentioned from earlier Price Increase % (ROD_Price_Increase__c) value should be added to the Discount filed in the quote but as a minus value since we are doing an increase of price.
Once this has been done, we can submit/order the quote. This creates a new quote. Once the new quote has been created, I want to be able to update a filed in the quote - a checkbox that says order. I want to be able to check the value on it.
This all should be done automatically like though Apex and Flows.
Sorry for this long text and request. I apologise and know some of the information not be out of box or confusing. Its one of these challenges I have been facing with trying to automate this.

Counting values in between two dates in Quicksight

I have a dataset in Quicksight that looks something like this;
I am trying to create a report of daily/weekly/monthly active users. For example, if the date/week/month is in the range of user's first_login & last_login, it should count that user. E.g. the report of Date: 15th March, should show all 3 users as per this dateset.
The report is in the form of Pivot table as below:
Currently, I am counting the distinct Client_ID for Last_login activity. But it keeps decreasing because the Dataset only saves/updates the latest last_login of the user.
Is there any way to modify the formula in a way to count users, who's first and last login fall within the date range?

How do I find the annual number of new event guests in a list that spans over many years with repeat guests (Google Data Studio)?

I have a list of guests that come to my events. The list contains 10 years worth of events and guests. I want to know how many new guests are brand new each year, such that they've never attended my events before. How do I calculate this in the calculated field?
For example, John attended my event in 2011, 2012, and 2013. This means John was my new guest in 2011, but not 2012 or 2013. Therefore, the count of new guests in 2011 increments by one.
It is safe to assume that John uses the same email each time he registers for my event. Therefore, my resulting table should look like this:
Email
First Year of Attendance
johndoe#live.com
2011
0) Summary
Use EITHER #1 OR #2
#1: Use if two fields are required (Email and First_Year)
#2: Use if three fields are required (Email, Year and First_Year)
1) Aggregate Year by MIN
If the goal is only to show the 2 fields in the Table, then simply add the Year field as a Metric and aggregate by MIN:
2) Data Blending
To display all three fields in a single Table, one approach is using a Self Data Blend; the below does the trick where Email represents the field with Emails (such as johndoe#live.com) and Year the field with Year values, which can be a Number field (for example 2011) or a Date field (such as 01 Jan 2011):
2.1) Data Blending
Data Source 1
Join Key: Email
Dimension: Year
Data Source 2
Join Key: Email
Metric: First_Year; Rename: Year; Aggregation: MIN
2.2) Table
Data Source: Blended Data Source
Dimension 1: Email
Dimension 2: First_Year
Dimension 3: Year
Editable Google Data Studio Report (Embedded Google Sheets Data Source) and a GIF to elaborate:

Google Data Studio date aggregation - average number of daily users over time

This should be simple so I think I am missing it. I have a simple line chart that shows Users per day over 28 days (X axis is date, Y axis is number of users). I am using hard-coded 28 days here just to get it to work.
I want to add a scorecard for average daily users over the 28 day time frame. I tried to use a calculated field AVG(Users) but this shows an error for re-aggregating an aggregated value. Then I tried Users/28, but the result oddly is the value of Users for today. The division seems to be completely ignored.
What is the best way to show average number of daily users over a time frame? Average daily users over 10 days, 20 day, etc.
Try to create a new metric that counts the dates eg
Count of Date = COUNT(Date) or
Count of Date = COUNT_DISTINCT(Date) in case you have duplicated dates
Then create another metric for average users
Users AVG = (Users / Count of Date)
The average depends on the timeframe you have selected. If you are selecting the last 28 days the average is for those 28 days (dates), if you filter 20 days the average is for those 20 days etc.
Hope that helps.
I have been able to do this in an extremely crude and ugly manner using Google Sheets as a means to do the calculation and serve as a data source for Data studio.
This may be useful for other people trying to do the same thing. This assumes you know how to work with GA data in Sheets and are starting with a Report Configuration. There must be a better way.
Example for Average Number of Daily Users over the last 7 days:
Edit the Report Configuration fields:
Report Name: create one report per day, in this case 7 reports. Name them (for example) Users-1 through Users-7. These are your Row 2 values. You'll have 7 columns, with the first report name in column B.
Start Date and End Date: use TODAY()-X where X is the number of days previous to define the start and end dates for each report. Each report will contain the user count for one day. Report Users-1 will use TODAY()-1 for start and end, etc.
Metrics: enter the metrics e.g. ga:users and ga:new users
Create the reports
Use 'Run reports' to have the result sheets created and populated.
Create a sheet for an interim data set you will use as the basis for the average calculation. The first column is date, the remaining columns are for the metrics, in this case Users and New Users.
Populate the interim data set with the dates and values. You will reference the Report Configuration to get the dates, and you will pull the metrics from each of the individual reports. At this stage you have a sheet with date in first columns and values in subsequent columns with a row for each day's values. Be sure to use a header.
Finally, create a sheet that averages the values in the interim data set. This sheet will have a column for each metric, with one value per column. The one value is calculated from the series in the interim data set, for example =AVG(interim_sheet_reference:range) or any other calculation you'd like to do.
At last, you can use Data Studio to connect to this data source and use the values. For counts of users such as this example, you would use Sum as the aggregation field type when you are creating the data source.
It's super ugly but it works.

Data Warehouse: Modelling a future schedule

I'm creating a DW that will contain data on financial securities such as bonds and loans. These securities are associated with payment schedules. For example, a bond could pay quarterly, while a mortgage would usually pay monthly (sometimes biweekly). The payment schedule is created when the security is traded and, in the majority of cases, will remain unchanged. However, the design would need to accommodate those cases where it does change.
I'm currently attempting to model this data and I'm having difficulty coming up with a workable design. One of the most commonly queried fields is "next payment date". Users often want to know when a security will pay next. Therefore, I want to make it as easy as possible for them to get the next payment date and amount for each security.
Also, users often run historical queries in which case they'd want the next payment date and amount as of a specific point in time. For example, they may want to look back at 1/31/09 and query the next payment dates (which would usually be in February 2009 for mortgages). It's also common that they want to query a security's entire payment schedule, which might consist of 360 records (30 year mortgage x 12 payments/year).
Since the next payment date and amount would be changing each month or even biweekly, these fields wouldn't seem to fit into a slow-changing dimension very well. It would probably make more sense to use a fact table, but I'm unsure of how to model it. Any ideas would be greatly appreciated.
Next payment date is an example of a "fact-free fact table". There's no measure, just FK's between at least two dimensions: the security and time.
You can denormalize the security to have a type-1 SCD (overwritten with each load) that has a few important "next payment dates".
I think it's probably better, however, to carry a few important payment dates along with the facts. If you have a "current balance" fact table for loans, then you have an applicable date for this balance, and you can carry previous and next payment dates along with the balance, also.
For the whole payment schedule, you have a special fact-free fact table that just has applicable date and the sequence of payment dates on into the future. That way, when the schedule changes, you can pick the payment sequence as of some particular date.
I would use a table (securityid,startdate, paymentevery, period) it could also include enddate, paymentpershare
period would be 1 for days, 2 for weeks, 3 for months, 4 for years.
So for security 1 that started paying weekly on 3/1/2009, then the date changed to every 20 days on 4/2, then weekly after 5/1/2009, then to monthly on 7/1/2009, it would contain:
1,'3/1/2009',1,2
1,'4/2/2009',20,1
1,'5/1/2009',1,2
1,'7/1/2009',1,3
To get the actual dates, I'd use an algorithm like this:
To know the payment dates on security 1 from 3/5/2009 to 5/17/2008:
Find first entry before 3/5 = 3/1
Loop:
Get next date that's after 3/5 and before the next entry (4/2 - weekly) = 3/8
Get next date that's before next the entry (4/2) = 3/15
Get next date that's before next the entry (4/2) = 3/22
Get next date that's before next the entry (4/2) = 3/29
Next date >4/2 switch to next entry:
Loop:
Get next date that's after 4/2 and before the next entry (5/1 - every 20 days) = 4/22
Next date 5/12 is AFTER next entry 5/1, switch to next entry
Loop:
Get next date that's after 5/1 and before the lastdate (5/17 - weekly) = 5/8
Get next date that's before the lastdate = 5/15
Next date > 5/17
The dates between 3/5/2009 and 5/17/2008 would be 3/8,3/15,3/22,3/29,4/22,5/8,5/15
Why not store the next payment date as the amount of days from the date of the current payment?
Further clarification:
There would be a fact for every past payment linked to some date dimension. Each one of these facts will have a field next payment in which will be an integer. The idea is that the date of the current payment + next payment in will be the date of the next payment fact. This should be able to cater for everything.

Resources