How to filter AssetType from AssetEntry in liferay 6.1? - liferay-6

I used the following code to retrieve all the journal articles based on a specific category:
long catId = category.getCategoryId();
AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
long[] anyCatIds = {catId};
assetEntryQuery.setAnyCategoryIds(anyCatIds);
// Line A
List<AssetEntry> assetEntryList = AssetEntryLocalServiceUtil.getEntries(assetEntryQuery);
for(AssetEntry ae : assetEntryList)
{
// Line B
JournalArticleResource journalArticleResourceObj = JournalArticleResourceLocalServiceUtil.getJournalArticleResource(ae.getClassPK());
JournalArticle journalArticleObj = JournalArticleLocalServiceUtil.getArticle(themeDisplay.getParentGroupId(), journalArticleResourceObj.getArticleId());
journalArticleList.add(journalArticleObj.getArticleId());
}
Howver, since the AssetEntry will fetch all the entries, including Blogs, and so on, the above code will throw an exception at Line B if I add a blog entry that uses the same category, since the blog entry does not have JournalArticleResource.
So, I was wondering if it is possible to filter only JournalArticle type will be fetch at Line A, then I don't have to worry about Line B anymore.
I have tried but no luck so far.
Does any one have some ideas?

Use assetEntryQuery.setClassName(JournalArticle.class.getName());

Related

Salesforce trigger-Not able to understand

Below is the code written by my collegue who doesnt work in the firm anymore. I am inserting records in object with data loader and I can see success message but I do not see any records in my object. I am not able to understand what below trigger is doing.Please someone help me understand as I am new to salesforce.
trigger DataLoggingTrigger on QMBDataLogging__c (after insert) {
Map<string,Schema.RecordTypeInfo> recordTypeInfo = Schema.SObjectType.QMB_Initial_Letter__c.getRecordTypeInfosByName();
List<QMBDataLogging__c> logList = (List<QMBDataLogging__c>)Trigger.new;
List<Sobject> sobjList = (List<Sobject>)Type.forName('List<'+'QMB_Initial_Letter__c'+'>').newInstance();
Map<string, QMBLetteTypeToVfPage__c> QMBLetteTypeToVfPage = QMBLetteTypeToVfPage__c.getAll();
Map<String,QMBLetteTypeToVfPage__c> mapofLetterTypeRec = new Map<String,QMBLetteTypeToVfPage__c>();
set<Id>processdIds = new set<Id>();
for(string key : QMBLetteTypeToVfPage.keyset())
{
if(!mapofLetterTypeRec.containsKey(key)) mapofLetterTypeRec.put(QMBLetteTypeToVfPage.get(Key).Letter_Type__c, QMBLetteTypeToVfPage.get(Key));
}
for(QMBDataLogging__c log : logList)
{
Sobject logRecord = (sobject)log;
Sobject QMBLetterRecord = new QMB_Initial_Letter__c();
if(mapofLetterTypeRec.containskey(log.Field1__c))
{
string recordTypeId = recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).isAvailable() ? recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).getRecordTypeId() : recordTypeInfo.get('Master').getRecordTypeId();
string fieldApiNames = mapofLetterTypeRec.containskey(log.Field1__c) ? mapofLetterTypeRec.get(log.Field1__c).FieldAPINames__c : '';
//QMBLetterRecord.put('Letter_Type__c',log.Name);
QMBLetterRecord.put('RecordTypeId',tgh);
processdIds.add(log.Id);
if(string.isNotBlank(fieldApiNames) && fieldApiNames.contains(','))
{
Integer i = 1;
for(string fieldApiName : fieldApiNames.split(','))
{
string logFieldApiName = 'Field'+i+'__c';
fieldApiName = fieldApiName.trim();
system.debug('fieldApiName=='+fieldApiName);
Schema.DisplayType fielddataType = getFieldType('QMB_Initial_Letter__c',fieldApiName);
if(fielddataType == Schema.DisplayType.Date)
{
Date dateValue = Date.parse(string.valueof(logRecord.get(logFieldApiName)));
QMBLetterRecord.put(fieldApiName,dateValue);
}
else if(fielddataType == Schema.DisplayType.DOUBLE)
{
string value = (string)logRecord.get(logFieldApiName);
Double dec = Double.valueOf(value.replace(',',''));
QMBLetterRecord.put(fieldApiName,dec);
}
else if(fielddataType == Schema.DisplayType.CURRENCY)
{
Decimal decimalValue = Decimal.valueOf((string)logRecord.get(logFieldApiName));
QMBLetterRecord.put(fieldApiName,decimalValue);
}
else if(fielddataType == Schema.DisplayType.INTEGER)
{
string value = (string)logRecord.get(logFieldApiName);
Integer integerValue = Integer.valueOf(value.replace(',',''));
QMBLetterRecord.put(fieldApiName,integerValue);
}
else if(fielddataType == Schema.DisplayType.DATETIME)
{
DateTime dateTimeValue = DateTime.valueOf(logRecord.get(logFieldApiName));
QMBLetterRecord.put(fieldApiName,dateTimeValue);
}
else
{
QMBLetterRecord.put(fieldApiName,logRecord.get(logFieldApiName));
}
i++;
}
}
}
sobjList.add(QMBLetterRecord);
}
if(!sobjList.isEmpty())
{
insert sobjList;
if(!processdIds.isEmpty()) DeleteDoAsLoggingRecords.deleteTheProcessRecords(processdIds);
}
Public static Schema.DisplayType getFieldType(string objectName,string fieldName)
{
SObjectType r = ((SObject)(Type.forName('Schema.'+objectName).newInstance())).getSObjectType();
DescribeSObjectResult d = r.getDescribe();
return(d.fields.getMap().get(fieldName).getDescribe().getType());
}
}
You might be looking in the wrong place. Check if there's an unit test written for this thing (there should be one, especially if it's deployed to production), it should help you understand how it's supposed to be used.
You're inserting records of QMBDataLogging__c but then it seems they're immediately deleted in DeleteDoAsLoggingRecords.deleteTheProcessRecords(processdIds). Whether whatever this thing was supposed to do succeeds or not.
This seems to be some poor man's CSV parser or generic "upload anything"... that takes data stored in QMBDataLogging__c and creates QMB_Initial_Letter__c out of it.
QMBLetteTypeToVfPage__c.getAll() suggests you could go to Setup -> Custom Settings, try to find this thing and examine. Maybe it has some values in production but in your sandbox it's empty and that's why essentially nothing works? Or maybe some values that are there are outdated?
There's some comparison if what you upload into Field1__c can be matched to what's in that custom setting. I guess you load some kind of subtype of your QMB_Initial_Letter__c in there. Record Type name and list of fields to read from your log record is also fetched from custom setting based on that match.
Then this thing takes what you pasted, looks at the list of fields in from the custom setting and parses it.
Let's say the custom setting contains something like
Name = XYZ, FieldAPINames__c = 'Name,SomePicklist__c,SomeDate__c,IsActive__c'
This thing will look at first record you inserted, let's say you have the CSV like that
Field1__c,Field2__c,Field3__c,Field4__c
XYZ,Closed,2022-09-15,true
This thing will try to parse and map it so eventually you create record that a "normal" apex code would express as
new QMB_Initial_Letter__c(
Name = 'XYZ',
SomePicklist__c = 'Closed',
SomeDate__c = Date.parse('2022-09-15'),
IsActive__c = true
);
It's pretty fragile, as you probably already know. And because parsing CSV is an art - I expect it to absolutely crash and burn when text with commas in it shows up (some text,"text, with commas in it, should be quoted",more text).
In theory admin can change mapping in setup - but then they'd need to add new field anyway to the loaded file. Overcomplicated. I guess somebody did it to solve issue with Record Type Ids - but there are better ways to achieve that and still have normal CSV file with normal columns and strong type matching, not just chucking everything in as strings.
In theory this lets you have "jagged" csv files (row 1 having 5 fields, row 2 having different record type and 17 fields? no problem)
Your call whether it's salvageable or you'd rather ditch it and try normal loading of QMB_Initial_Letter__c records. (get back to your business people and ask for requirements?) If you do have variable number of columns at source - you'd need to standardise it or group the data so only 1 "type" of records (well, whatever's in that "Field1__c") goes into each file.

How to get rid of lots of soql queries using maps

Im finding it really hard to understand maps, I have read lots of examples but they always seem not to relate to what I need to do - I've just about understood how to use oldmap.trigger in a very simple use case.
So anyways I have a trigger on a object Data_ProtectionIA , its parent is Data Agreement, and then its parent is Data request.
I need to update Data agreement and Data request when DPIA gets updated, I have the below so far which I know is a very long winded way to do it, but now I also have to add further updates for when DPIA gets updated to something else and for me to do this like I have done would mean doubling this code again when it is already unnecesarily long.
If someone could please simplify this code into maps then I think I would be able to understand maps properly, I just cant find examples of what I need to do. Many thanks in advance
(So at the moment I am getting the grandchild record and then creating a list of parent records to loop through and then getting a list of all their parent records and then looping through that. - even if you could just show me from child to parent (not even, child parent to grandparent that would be very helpful)
public static void setDRStatus(List<Data_Protection_IA__c> dpia, Map<ID,Data_Protection_IA__c> oldMap ){
List<ID> childDAID = new List<ID>();
for(Data_Protection_IA__c pDA: dpia){
if(pDA.DPIA_Status__c == 'Fully Approved' && oldMap.get(pDA.Id).DPIA_Status__c != 'Fully Approved'){
childDAID.add(pDA.DataProcessingAgreement__c);
}
}
List<Data_Agreement__c> childDA = new List<Data_Agreement__c>();
ChildDA = [Select id, Data_Sharing_Status__c from Data_Agreement__c where id in:childDAID];
List<Data_Agreement__c> listToUpdate = new List <Data_Agreement__c>();
List<ID> dAId = new List <ID>();
system.debug('ChildDA'+ childDA);
for(Data_Agreement__c cda : ChildDA){
cda.Data_Sharing_Status__c = 'DPIA Fully Approved';
listToUpdate.add(cda);
dAId.add(cda.id);
}
update listToUpdate;
List<Data_Request__c> dRList = [SELECT id, Data_Sharing_Status__c,Existing_Data_Agreement__c
FROM Data_Request__c where Existing_Data_Agreement__c in:dAId];
List<Data_Request__c> listToUpdatedr = new List <Data_Request__c>();
system.debug('DRList'+ dRList);
for(Data_Request__c dr :dRList){
dr.Data_Sharing_Status__c = 'DPIA Approved';
listToUpdatedr.add(dr);
}
update listToUpdatedr;
}
----------------------------------------
Here is an example I had previously tried
So I started following an example and got to here
Set<Id> daIds = new Set<Id> {};
for (Data_Protection_IA__c p : dpia)
{
daIds.add(p.DataProcessingAgreement__c );
}
Map<ID, Data_Agreement__c> m = new Map<ID, Data_Agreement__c>(
[select id, from Data_Agreement__c where id in : daIds]);
list<Data_Agreement__c> dAupdates = new List <Data_Agreement__c>();
list<Contact> contactupdates = new List <Contact>();
for (Data_Protection_IA__c p1 :dpia)
{
m.get(p1.Data_Agreement__c) = 'DPIA Fully Approved');
}
but at the last line I think this map is tying to get the field Data_agreement from dpia object, but there is no data agreement field on dpia object. as dpia is the child. there is only a field for dpia on the data agreement object

How to read UnitPrice from invoice line in QBO API v3 .NET

The bizarre properties in the .NET SDK continue to baffle me. How do I read the UnitPrice from an invoice line?
If I do this:
sild = (SalesItemLineDetail)line.AnyIntuitObject;
ln = new QBInvoiceLine(); // My internal line item class
ln.Description = line.Description;
ln.ItemRef = new QBRef() { Id = sild.ItemRef.Value, Name = sild.ItemRef.name };
if (sild.QtySpecified)
ln.Quantity = sild.Qty;
else
ln.Quantity = 0;
if (sild.ItemElementName == ItemChoiceType.UnitPrice)
ln.Rate = (decimal)sild.AnyIntuitObject; // Exception thrown here
The last line throws an invalid cast exception, even though the debugger shows that the value is 20. I've tried other types but get the same exception no matter what I do. So I finally punted and am calculating the rate like so:
ln.Rate = line.Amount / ln.Quantity;
(With proper rounding and checking for divide by zero, of course)
While we're on the subject... I noticed that in many cases ItemElementName == ItemChoiceType.PriceLevelRef. What's up with that? As far as I know, QBO doesn't support price levels, and I certainly wasn't using a price level with this invoice or customer. In this case I was also able to get what I needed from the Amount property.
Try this-
SalesItemLineDetail a1 = (SalesItemLineDetail)invoice11.Line[0].AnyIntuitObject;
object unitprice = a1.AnyIntuitObject;
decimal quantity = a1.Qty;
PriceLevelRef as an 'entity' is not supported. This means CRUD operations are not supported on this entity.
The service might however be returning readonly values in the transactions sometimes, but since this not mentioned in the docs, please consider it as unsupported.
Check that both request/response are in either json or xml format-
You can use the following code to set that-
ServiceContext context = new ServiceContext(appToken, realmId, intuitServiceType, reqvalidator);
context.IppConfiguration.Message.Request.SerializationFormat = Intuit.Ipp.Core.Configuration.SerializationFormat.Json;
context.IppConfiguration.Message.Response.SerializationFormat = Intuit.Ipp.Core.Configuration.SerializationFormat.Json;
Also, in QBO UI, check if Company->sales settings has Track Quantity and Price/rate turned on.

Sequence of Project Deployment in Mule

Does anybody know in what sequence, the mule project are loaded when the Mule starts-up?
It doesn't seem to be in alphabetical order or last updated time.
If you look at the class MuleDeploymentService, you can see the following:
String appString = (String) options.get("app");
if (appString == null)
{
String[] explodedApps = appsDir.list(DirectoryFileFilter.DIRECTORY);
String[] packagedApps = appsDir.list(ZIP_APPS_FILTER);
deployPackedApps(packagedApps);
deployExplodedApps(explodedApps);
}
else
{
String[] apps = appString.split(":");
Description for method File.list states that "there is no guarantee that the name strings in the resulting array will appear in any specific order". So, I guess the answer is in no particular order, or in the order they are listed in using the -app option.

Moodle Database API error : Get quiz marks for all sections of one course for one user

I am trying to get total marks obtained by a particular user, for a particular course for all the sections of that course.
The following query works and gives correct results with mysql, but not with Databse API calls
$sql = "SELECT d.section as section_id,d.name as section_name, sum(a.sumgrades) AS marks FROM mdl_quiz_attempts a, mdl_quiz b, mdl_course_modules c, mdl_course_sections d WHERE a.userid=6 AND b.course=4 AND a.quiz=b.id AND c.instance=a.quiz AND c.module=14 AND a.sumgrades>0 AND d.id=c.section GROUP BY d.section"
I tried different API calls, mainly I would want
$DB->get_records_sql($sql);
The results from API calls are meaningless. Any suggestion?
PS : This is moodle 2.2.
I just tried to do something similar, only without getting the sections. You only need the course and user id. I hope this helps you.
global $DB;
// get all attempts & grades from a user from every quiz of one course
$sql = "SELECT qa.id, qa.attempt, qa.quiz, qa.sumgrades AS grade, qa.timefinish, qa.timemodified, q.sumgrades, q.grade AS maxgrade
FROM {quiz} q, {quiz_attempts} qa
WHERE q.course=".$courseid."
AND qa.quiz = q.id
AND qa.userid = ".$userid."
AND state = 'finished'
ORDER BY qa.timefinish ASC";
$exams = $DB->get_records_sql($sql);
// calculate final grades from sum grades
$grades = array();
foreach($exams as $exam) {
$grade = new stdClass;
$grade->quiz = $exam->quiz;
$grade->attempt = $exam->attempt;
// sum to final
$grade->finalgrade = $exam->grade * ($exam->maxgrade / $exam->sumgrades);
$grade->grademax = $exam->maxgrade;
$grade->timemodified = $exam->timemodified;
array_push($grades, $grade);
}
This works in latest moodle version. Moodle 2.9. Although I am still open for better solution as this is really hacky way of getting deeper analytics about user's performance.