Apex - SalesForce - Accessing a Parent object field through Junction object - orm

Hello Folks,
I am working on customizing some functionality on the Force.com platform. I have a question for you; I am not too sure if this is possible!
What I have? : 2 custom objects - abc and pqr. Abc is the junction object between the Standard object Account and pqr i.e. Account is the parent of abc and then Pqr is the parent of abc. I am retrieving everything through these objects into a List of type Account (i.e. from Account object).
What I need? : I can access the abc object in Apex i.e. the First child of Account. Is there a possibility to access the fields of pqr through account?
What I have tried : Accessing the object through relationship name - Account.abc_r[0].pqr_r[0].FIELDNAME
But it hasnt worked. Could some salesforce/apex developer help me with this?

You should be able to get the information you need using a subquery. The real question here is how your query is setup. Your query will need to access all levels of the data model for it to be available. If you are relying on data returned in a trigger or standard controller then I would recommend requiring the account object to get access to the additional information.
So I would expect to see something along the lines of:
List<Account> accounts = [SELECT Id, Name, (SELECT Id, pqr__r.Id, pqr__r.Name FROM abc__r) FROM Account];
for (Account acct : accounts) {
string someValue = acct.abc__r[0].pqr__r.Name;
}
Keep in mind though that as a best practice you shouldn't access the child records the way I did above because if there are no ABC records that object will be null so as a best practice you will want to test for that ahead of time. Same goes for PQR object data.

The answer to this question is the following:
List<Account> accounts = [SELECT Id, Name, (SELECT Id, pqr__r.Id, pqr__r.Name FROM abc__r) FROM Account];
for (Account acct : accounts) {
for(Abc__c abc : acct.abc__r)
{
String someValue = abc.pqr__r.Name;
}
}
Note: Here, abc_r is the relationship of object Abc_c with Account. Please comment on this if you have any questions.

Related

Grouping in GraphQL query

I am new to GraphQl and learning it. Currently I have single database Table - student_courses as shown below:
student_id| student_name | course_code | course_name
1 ABC S-101 DataStructures
1 ABC S-150 NLP
1 ABC S-250 Machine learning
2 PQR S-101 DataStructures
3 XYZ S-101 DataStructures
3 XYZ S-150 NLP
I have mapped the model to single GraphQL object. So I am getting GraphQL API response as individual json objects for each row in table.
I wanted to understand how to group the results of this table by student_id, student_name and get results in below format:
student_id, student_name, {course_code : course_name}
For eg: 1, "ABC", {"S-101":"DataStructures", "S-150":"NLP", "S-250":"Machine learning"}
My current GraphQL query -
{
student_courses() {
data {
student_id
student_name
course_code
course_name
}
}
}
It is hard to answer with the little you say about your database and about your backend: graphql is not intelligent about the data.
Some reminders first:
To serve a GraphQL api you need a "graphql backend" you may be using a framework like prisma, apollo server, or if your database is a PostgreSql I recommend postgraphile.
These framework receive and parse Graphql queries, and "resolve" every sub part of a query with a function called a "resolver".
They may also help you connect to the database and generate part of the code that you need to get the data.
For example if you have a query like this:
average {
points
}
You need a resolver to get you the "average" field, and another resolver to get the "points" sub field of the "average" object.
Back to your question
Grouping results would be something that you code in your resolver, the graphql engine would not "know" how to ask your database to make a join or a group query.
On postgraphile you can use the pg-aggregates plugin that can do this for you (because it is specialized on binding itself with postgresql database).
You would be able to resolve Graphql queries like this.
query GroupedAggregatesByDerivative {
allMatchStats {
byDay: groupedAggregates(groupBy: [CREATED_AT_TRUNCATED_TO_DAY]) {
keys # The timestamp truncated to the beginning of the day
average {
points
}
}
byHour: groupedAggregates(groupBy: [CREATED_AT_TRUNCATED_TO_HOUR]) {
keys # The timestamp truncated to the beginning of the hour
average {
points
}
}
}
}
In practise that will mean that your resolver will take a parameter called "groupBy" and depending on its value return different data.
Remark: on the Graphql schema side the allMatchStats query will have to be modified so that it takes the byDay field as input and its output will not be a "match" but another custom defined type that contains the average field for example. (note that on the case above the postgraphile plugin, generates all this for you)

Django: Annotate table with field across a M2M mapping to another table

I want to get competition.name from a list of submissions.
In my setup, competitions and teams share a M2M relationship (with an associated competition-team object. Each competition-team pair can submit any number of submissions. I now have a dashboard page which I am trying to create a table of all submissions by the team accompanied by the respective competition's name. The output should look like:
| Submission Name | Submission Date etc. | Competition Name |
| Sub01 | 2020-12-30 2000 | Competition01 |
I have trouble retrieving the competition name from the submissions. Here are my models:
class Competition(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
class CompetitionTeam(models.Model):
competition_id = models.ForeignKey('Competition', on_delete=models.CASCADE, to_field='id', db_column='competition_id')
team_id = models.ForeignKey('Team', on_delete=models.CASCADE, to_field='id', null=True, db_column='team_id')
class CompetitionSubmission(models.Model):
competitionteam_id = models.ForeignKey(CompetitionTeam, on_delete=models.CASCADE, db_column='competitionteam_id')
I wish to annotate a set of submissions with their respective competition names. I tried with:
submissions.annotate(competition_name=Subquery(Competition.objects.filter(id=Subquery(CompetitionTeam.objects.get(id=OuterRef('competitionteam_id')).competition_id)).values('name')))
"ValueError: This queryset contains a reference to an outer query and may only be used in a subquery."
I also tested with the following command:
CompetitionSubmission.objects.prefetch_related('competitionteam_id__competition_id')
It runs but the command seems to do nothing. I will update this post with other methods I try.
Thank you.
EDIT
submissions.annotate(competition_name=Subquery(Competition.objects.filter(id=Subquery(CompetitionTeam.objects.filter(id=OuterRef(OuterRef('competitionteam_id_id'))).values('competition_id'))).values('name')))
Seems to work correctly.
You can traverse ForeignKeys directly using double underscores.
CompetitionSubmission.objects.values(
'competitionteam_id',
'competitionteam_id__competition_id',
'competitionteam_id__competition_id__name',
'competitionteam_id__team_id',
'competitionteam_id__team_id__name',
)
This will only produce a single database query. Django ORM takes care of everything.
P.S. I would avoid using '_id' in field names as Django model fields are supposed to be referring to related objects themselves. Django automatically adds extra attributes with '_id' that contains the related object's id. Please see https://docs.djangoproject.com/en/3.1/ref/models/fields/#database-representation

SAP Business One DI API at item creation should inherit some fields from item group

In SAP Business One client, imagine you want to add a new item. You set code, name and group. When you set the group SAP proposes to inherit some fields from such item group. You can choose yes or no.
If you do the same thing with DI API, of course there isn't such a proposal. DI API give for granted that you don't want to inherit fields from the item group.
Is there a way to tell DI API to inherit fields from the item group? Or are we obliged to copy them one by one in our program?
As far as i know this method for maintaining item information from the item group is not exposed to the sdk.
I know that the general ledger information can be maintained using
.GLMethod = SAPbobsCOM.BoGLMethods.glm_ItemClass
but for the other 10(ish) fields you will have to manually set them in your code.
.PlanningSystem = BoPlanningSystem.bop_MRP
.ProcurementMethod = BoProcurementMethod.bom_Make
.OrderIntervals = "Week"
.OrderMultiple = 5
.MinOrderQuantity = 3
.LeadTime = 20
.ToleranceDays = 3
.CostAccountingMethod = BoInventorySystem.bis_Standard

MVC4 Postal - Accessing User Email Address searching by UserId

I have a site where user A can book a lesson with a teacher, I then want to have an email sent to the teachers saying user A wants to book a lesson with you etc.
I have postal up and running sending emails without issue,
however, I don't know how to access the email address of the teacher to send the email.
The email address is saved as part of the built in UserProfile table. I have the teacher's UserId (as it's stored in a separate teacher table).
So is there a way to access the teachers email ,searching by UserId?
In any other table I would use t in db.Teacher.find(id) but this doesn't work within the Account Controller.
This was built using the default MVC4 internet website template using the built in simple membership. Let me know if more information is needed.
I've added the following to the AccountController;
private UsersContext db = new UsersContext();
public ActionResult EmailNotification(int id)
{
var user = from l in db.UserProfiles.Find(id)
select l;
}
db.UserProfiles.Find(id) however gives the following error;
Could not find an implementation of the query pattern for source type 'LessonUp.Models.UserProfile'. 'Select' not found.
Which I assume is a result of it not being created through the entity framework?
I think your query needs to be something like the following:
var result = from q in context.UserProfiles
where q.UserId == id
select q;

Siebel - How to get all accounts of an employee with eScript?

how can I get all accounts of am employee?
In the "Siebel Object Interaces Reference" I found an example, how to get all industries of an account:
var myAccountBO = TheApplication().GetBusObject("Account");
var myAccountBC = myAccountBO.GetBusComp("Account");
var myAssocBC = myAccountBC.GetMVGBusComp("Industry");
So I would like to do something like:
var myEmployeeBO = TheApplication().GetBusObject("Employee");
var myEmployeeBC = myAccountBO.GetBusComp("Employee");
var myAssocBC = myAccountBC.GetMVGBusComp("Account");
But I get an error
Semantic Warning around line 23:No such predefined property Account in class BusComp[Employee].MVGFields.
I can see in Tools that there is no Multi Value Link called "Account" in Business Component "Employee", so I can actually understand the error message.
So I wonder how I can get all accounts of an employee.
I found the Business Component "User" which has a Multi Value Link to "Organisation" and another link "User/Account".
Is this what I am looking for?
How can I know? Where is documentation which tells me about the semantics of links? (Is this described in "Siebel data model reference"? I cannot download this document, although I have signed in...) This link could also link a user to the organization it belongs to.
If one of these links IS what I am looking for, what would be the way to go to get the "User" Business Component of a corresponding "Employee" Business Component?
Many questions of a Siebel newb...Thanks for your patience.
Nang. An easy way to approach this (and to learn it) is to figure out how you'd do it in the UI. Then move onto figuring out how to do the same thing in script.
When you say, "get all account of an employee," do you really mean get all accounts where a particular employee is on the account team? In the UI, that would be done by going to: Accounts > All Accounts Across Organizations, and querying for that specific user in the "Account Team" multi-value field.
From that same view, go to Help > About View in the application menu. You'll see in the popup that the view uses the Account business object and the Account business component. A quick examination of the applet you queried on will show you that the "Account Team" field on the applet is really the "Sales Rep" field on the Account business component. Here's how to mimic what we did in the UI, in script:
var boAccount = TheApplication().GetBusObject("Account");
var bcAccount = boAccount.GetBusComp("Account");
bcAccount.SetViewMode(AllView); // like All .. Across Orgs
bcAccount.ClearToQuery();
bcAccount.SetSearchSpec("Sales Rep", "NANG");
bcAccount.ExecuteQuery();
Then you can walk through the list of accounts and do something with each one like this:
// for each account
for (var bIsRowActive = bcAccount.FirstRecord();
bIsRowActive; b = bcAccount.NextRecord())
{
// do something here
}
I hope you're enjoying Siebel.