PriceBookEntry required field missing when creating QuoteLineItems - salesforce

I am kind of new to CPQ and have been trying to create a Quote Line Item with no success.
Opportunity OpportunityOne = [SELECT Id, PriceBook2Id FROM Opportunity WHERE
Id='0067F000008qOJzQAM' LIMIT 1];
Quote QuoteOne = [SELECT Id FROM Quote WHERE Name =:'TestQuote' LIMIT 1];
Product2 Product = [SELECT Id FROM Product2 WHERE Id
=: '01t7F0000032Y89QAE' LIMIT 1];
System.debug('Opportunity: '+OpportunityOne);
System.debug('Quote:'+QuoteOne);
System.debug('Product2:'+Product);
QuoteLineItem QuoteLineItemOne = new QuoteLineItem();
QuoteLineItemOne.QuoteId = QuoteOne.Id;
QuoteLineItemOne.Quantity = 100;
QuoteLineItemOne.UnitPrice = 2000;
QuoteLineItemOne.Product2Id = Product.Id;
insert QuoteLineItemOne;
Why does it keep saying price book entry is missing. It is annoying. Insert fails and I see no object requiring a price book entry field.
Please help me with this.

You'll need to roll the apex API version back to version 38 or earlier in order to create quote lines this way (using product2Id field). As you can see in the object reference from version 39 onwards you'll need to populate the pricebookentryId field instead and leave product2Id null. To get the pricebookEntryId you'll just need an extra query eg.
PriceBookEntry pbe = [SELECT id FROM PricebookEntry
WHERE Product2Id =: Product.id AND Pricebook2Id =: OpportunityOne.pricebook2Id LIMIT 1];
Then just set the pricebookentryId field on your quotelineitem instead of product2Id

Related

Custom Label value not working in SOQL Query

I am trying to use custom label value in SOQL Query. Query is not accepting custom label value. it is expecting number.
Integer num_days = Integer.valueOf(System.Label.Num_of_Days);
Select id, name FROM contact WHERE LastModifiedDate >= LAST_N_DAYS :num_days
Thanks,
Anil Kumar
The full syntax of the "constant" you're using already has a semicolon in it: LAST_N_DAYS:7 etc. The whole thing has to be a text known at compile time, not just the part before :
This won't even compile, with 1 or 2 semicolons.
Integer x = 7;
List<Account> accs = [SELECT Id FROM Account WHERE CreatedDate = LAST_N_DAYS:x];
System.debug(accs);
You'll need to use dynamic SOQL or use your custom label to construct a date variable
String x = '7';
List<Account> accs = Database.query('SELECT Id FROM Account WHERE CreatedDate = LAST_N_DAYS:' + x);
System.debug(accs);
DateTime cutoff = System.today().addDays(- Integer.valueOf(x));
System.debug(cutoff);
System.debug([SELECT Id FROM Account WHERE CreatedDate <= TODAY AND CreatedDate >= :cutoff]);

Multiple AggregateResult Querys

Hi guys,
I'm currently trying to join two objects in a same query or result.
My question is if it's possible to show or debug the sum of FIELD A FROM LEAD + sum of FIELD B FROM two different Objects.
Here's an example I'm working on:
Btw I really appreciate your time and comments, and if i'm making a mistake pls let me know, thank you.
public static void example() {
String sQueryOne;
String sQueryTwo;
AggregateResult[] objOne;
AggregateResult[] objTwo;
//I tried to save the following querys into a sObject List
List<SObject> bothObjects = new List<SObject>();
sQueryOne = 'Select Count(Id) records, Sum(FieldA) fieldNA From Lead';
objOne = Database.query(sQueryOne);
sQueryTwo = 'Select Count(Id) records, Sum(FieldA) fieldNB From Opportunity';
objTwo = Database.query(sQueryTwo);
bothObjects.addAll(objOne);
bothObjects.addAll(objTwo);
for(sObject totalRec : bothObjects) {
//There's a Wrapper(className) I created which contains some variables(totalSum)
className finalRes = new className();
finalRes.totalSum = (Integer.valueOf(fieldNA)) + (Integer.valueOf(fieldNB));
System.debug('The sum is: '+finalRes.totalSum);
For example if I call a System debug with the previous variable finalRes.totalSum it's just showing the first value(fieldNA) duplicated.
The following debug shows the current values of the sObject List which I want to sum for example FIELD0 = from leads, FIELD0 = from Opportunities.
}
}
You access the columns in AggregateResult by calling get('columnAlias'). If you didn't specify an alias they'll be autonumbered by SF as expr0, expr1... When in doubt you can always go System.debug(results);
Some more info: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_agg_fns.htm
This might give you some ideas:
List<AggregateResult> results = new List<AggregateResult>{
[SELECT COUNT(Id) records, SUM(NumberOfEmployees) fieldA, SUM(AnnualRevenue) fieldB FROM Account],
[SELECT COUNT(Id) records, SUM(Amount) fieldA, SUM(TotalOpportunityQuantity) fieldB FROM Opportunity],
[SELECT COUNT(Id) records, SUM(NumberOfEmployees) fieldA, SUM(AnnualRevenue) fieldB FROM Lead]
/* hey, not my fault these are only 2 standard numeric fields on Lead.
It doesn't matter that they're identical to Account fields, what matters is what their SUM(...) aliases are
*/
};
List<Decimal> totals = new List<Decimal>{0,0,0};
for(AggregateResult ar : results){
totals[0] += (Decimal) ar.get('records');
totals[1] += (Decimal) ar.get('fieldA');
totals[2] += (Decimal) ar.get('fieldB');
}
System.debug(totals); // (636, 8875206.0, 9819762558.0) in my dev org
(I'm not saying it's perfect, your wrapper class sounds like better idea or maybe even Map<String, Decimal>. Depends what are you going to do with the results)

I need to show all data form pinjaman_id but only last data in every pinjaman_id form database

I'm using laravel, I want to make show all last data based on pinjaman_id this mean I only need last data of pinjaman_id, so pinjaman_id cant show duplicate, I just need the last one, and show them all last data with diffirent pinjaman_id
$pinjaman = DB::table('invoice')->where('pinjaman_id', 67)->orderBy('tgl_tempo', 'desc')->first();
if I'm using this, its only show last data in pinjaman_id = 67, I need to show them all but only last data based on tgl_tempo desc
$pinjaman = DB::table('invoice')->where('pinjaman_id', ??)->orderBy('tgl_tempo', 'desc')->first();
this is image my database
You have to use raw query to get the correct data then use UNION ALL to get other data
$results = DB::select("(SELECT * FROM invoice WHERE pinjaman_id= 67 order by tgl_tempo DESC limit 1) UNION ALL (SELECT * FROM invoice WHERE pinjaman_id != 67)") ;
try this one
$query = "select * from invoice where id IN (select MAX(id) from invoice where user_id = :userId group by pinjaman_id) order by tgl_tempo desc ";
$result = DB::select(DB::raw($query),['userId' => 1]);

Trying to avoid Governor limits in no of SOQL queries

i have 2 custom objects appointment_c and TimeDrive_c.
Appointment has fields
startdate__c
contact__c
TimeDrive__c has
Target_date__c
contact__c
CreatedDate
Here is what i need to do
I need to get all get all records with in a specific date range
select id, Target_date__c, Contact__c, Name, CreatedDate
from TimeDrive__c where Target_date__c >=:startdate and
Target_date__c <=:enddate
i need to loop through each record in this list and check if there are appointments for this contact which has startdate fall between targetdate and createddate
Here is the bit i have done till now
timeDriverLst = [select id, Target_date__c, Contact__c, Name, CreatedDate
from TimeDrive__c where Target_date__c >=:startdate and
Target_date__c <=:enddate ];
if(timeDriverLst.size() >0){
for(integer i =0; i < timeDriverLst.size(); i++)
{
mapTime.put(timeDriverLst[i].id, timeDriverLst[i]);
/* appLst = [Select Name, Contact__c from Appointment__c where (StartDate__c > = :timeDriverLst[i].CreatedDate
and StartDateTime__c <=:timeDriverLst[i].Target_date__c) and Contact__c = :timeDriverLst[i].Contact__c ];
*/
}
I know i shouldnt have a SOQL query within a for loop. How can i avoid this and achieve the requirement.
An ugly, but possibly usable solution: You could get all the contact ids from the time driver list and also find the earliest created date. Then you could pull out all the appointments whose contact id is in the contact id list and whose date is between the earliest created date and the target date. Then you would need to do a double loop, checking each appointment against each time driver. (Ordering the appts by contact or by date as you retrieve them might help here).

SOQL - Querying for a list of users the current user is following

In my app I display a list of the current users. I request it like this:
Attempt 1
List<User> Following = [SELECT Id, Name, SmallPhotoUrl
FROM User
WHERE Id IN (
SELECT ParentId
FROM EntitySubscription
WHERE SubscriberId = :UserInfo.getUserId())
AND Id != :UserInfo.getUserId()
LIMIT 96];
This does exactly what it's supposed to when logged in as an admin but I found out that non-admins get an error:
Implementation restriction: EntitySubscription only allows security
evaluation for non-admin users when LIMIT is specified and at most
1000
OK, no big deal, I'll just slap a LIMIT on there like so:
Attempt 2
List<User> Following = [SELECT Id, Name, SmallPhotoUrl
FROM User
WHERE Id IN (
SELECT ParentId
FROM EntitySubscription
WHERE SubscriberId = :UserInfo.getUserId()
LIMIT 1000)
AND Id != :UserInfo.getUserId()
LIMIT 96];
Easy, right? WRONG. This gives the following:
expecting a right parentheses, found 'LIMIT'
OK...
I then tried breaking it out like so:
Attempt 3
List<EntitySubscription> sub = [SELECT ParentId
FROM EntitySubscription
WHERE SubscriberId = :UserInfo.getUserId()
LIMIT 1000];
List<Id> ids = new List<Id>();
for(EntitySubscription s : sub){
ids.add(s.ParentId);
}
List<User> Following = [SELECT Id, Name, SmallPhotoUrl
FROM User
WHERE Id IN (:ids)
AND Id != :UserInfo.getUserId()
LIMIT 96];
I crossed my fingers and...
Invalid bind expression type of LIST<Id> for column of type Id
Hmm, I'd seen examples where this seemed to be possible, such as on the developerforce boards, so I'm at a bit of a loss now.
So here we are. I need to select a list of user names and pictures that a particular user is following on Chatter. If there is a completely different way to go about it I'm open to it.
Try removing the parenthesis around the bind, i.e. change:
WHERE Id IN (:ids)
to:
WHERE Id IN :ids
And also simplify the query by just making sure that your list of IDs doesn't contain the current user's ID:
List<EntitySubscription> sub = [SELECT ParentId
FROM EntitySubscription
WHERE SubscriberId = :UserInfo.getUserId() AND ParentId != :UserInfo.getUserId()
LIMIT 1000];
Set<Id> ids = new Set<Id>();
for(EntitySubscription s : sub){
ids.add(s.ParentId);
}
Hope that helps!

Resources