Trying to convert Apex Query List to string not sure if this is correct - triggers

I am trying to execute a SOQL query that may return a list. If list is null I want to set default value. I am new to apex so not sure if this is correct.
Here is what I have:
// SET USERNAME STRING
string username = '%'+UserInfo.getFirstName()+'%';
//SET DEFAULT PRODUCTid
Id ProductID = '01t46000000nPO0AAM';
//MAP IDMAPPRODUCT2
Map<Id> idmapproduct2 = new Map<Id>([Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username]); system.debug(idmapproduct2);
//CHECK IF MAP IS NULL AND IF NOT SET IT TO PRODUCT ID
if(idmapproduct2 != null)
{ProductID = idmapproduct2;}

In this case you dont ned a Map and your use of Map is incorrect. Use a list instead.
List<Product2> idmapproduct2 = [Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username LIMIT 1]; system.debug(idmapproduct2);
//CHECK IF MAP IS NULL AND IF NOT SET IT TO PRODUCT ID
if(idmapproduct2.size() != 0){
ProductID = idmapproduct2[0].Id;
}

use below lines....
List<Product2> prodList = new List<Product2>([Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username Limit 1]);
if(prodList.size() > 0) ProductID = prodList[0].Id;

Related

How to map newest records from the list by each id?

I have a method in apex class that will get attachments (ContentDocument) from e-mail of case and will add it to another case. There are 2 questions below in order to finish my code:
How to create logic to get list of e-mails where I need only the newest e-mail for each case?
How can I create logic to get list of srID passed in this method?
Both questions are mentioned in the proper part of the code below:
public static void AttFromParenttoClonedCaseList(list<ID>srID){
list< ContentDocumentLink> attchlist2=new list< ContentDocumentLink>();
Map<Id, Case> mapCasess = new Map<Id, Case>();
Map<Id, EmailMessage> mapEmail = new map<Id, EmailMessage>();
Map<Id, EmailMessage> mapemailmessageId = new Map<Id, EmailMessage>();
List<String> externalIdCases = new List<String>();
List<String> casesID = new List<String>();
List<Case> ListCaseNumber = new List<Case>([SELECT ID, External_ID__c From Case WHERE ID IN :srID]);
for (Case mpC : ListCaseNumber){
mapCasess.put(mpC.id, mpC);
}
for (Case Listcase : ListCaseNumber) {
externalIdCases.add(Listcase.External_ID__c);
}
List<Case> ListCaseID = new List<Case>([SELECT ID From Case WHERE ID IN :externalIdCases]);
for (Case listIdcases : ListCaseID) {
casesId.add(listIdcases.id);
}
Map<id, EmailMessage> listEmailMessage = new Map<id, EmailMessage>([SELECT parentID, ID From EmailMessage WHERE parentID IN :casesId order by parentid, createddate desc]);
\\How to create logic to get list of e-mails where I need only the newest e-mail for each case (base on list listEmailMessage above)?
List<ContentDocumentLink> contentdocumentId = new List<ContentDocumentLink>([SELECT ID, ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId IN :/*list of emailmessages*/]);
for (ContentDocumentLink links : contentdocumentId){
ContentDocumentLink linkAtt = new ContentDocumentLink();
linkAtt.LinkedEntityId = \\how can I create logic to get list of srID passed in this method?
linkAtt.ContentDocumentId = links.ContentDocumentId;
linkAtt.ShareType = 'V';
linkAtt.Visibility = 'AllUsers';
attchlist2.add(linkAtt);
}
if (attchlist2.size() > 0)
insert attchlist2;
}
How to create logic to get list of e-mails where I need only the
newest e-mail for each case?
Something like this should be a good start
SELECT Id, CaseNumber, Subject,
(SELECT Id, FromAddress, ContentDocumentIds
FROM EmailMessages
WHERE Incoming = true
ORDER BY CreatedDate DESC
LIMIT 1)
FROM Case
LIMIT 10
It's simpler to treat it as "parent + related list, filtered, sorted" than "give me all emails for this parent, I'll build a Map or something with them, manually loop through them, compare dates to pick most recent...". I haven't worked with Emails for a while so you might need more filters but it's a good start.
how can I create logic to get list of srID passed in this method?
Not sure I understand. You want to re-link attachments from old case's emails to new case? See if that ContentDocumentIds is enough to build new links. If not - loop through results of my query, collect all EmailMessage Ids and query ContentDocumentLinks WHERE LinkedEntityId IN :emailMessageIds?
Check if this compiles?
// I don't really need it as a Map, list seems to be fine. But looks like you wanted Maps so I went with map.
// Map might be useful if External_ID__c is not a lookup.
// If you want a list (or set) of Ids from a query the very easy trick is to do
// Set<Id> myIds = new Map<Id, Account>([SELECT Id FROM Account LIMIT 5]).keyset();
// Anyway.
// "External_ID__c" is a lookup to Case or something else? Assuming it's just a lookup, bit like "ParentId".
Map<Id, Case> originals = new Map<Id, Case>([SELECT Id, CaseNumber, External_ID__c, External_ID__r.CaseNumber,
(SELECT Id, FromAddress, ContentDocumentIds
FROM EmailMessages
WHERE Incoming = true
ORDER BY CreatedDate DESC
LIMIT 1)
FROM Case
WHERE Id IN :srId AND External_ID__c != null]);
List<ContentDocumentLink> links = new List<ContentDocumentLink>();
for(Case original : originals.values()){
System.debug('source: ' + original);
System.debug('target: ' + original.External_ID__r.CaseNumber);
if(!original.EmailMessages.isEmpty()){
List<String> documentIds = original.EmailMessages[0].ContentDocumentIds;
for(String i : documentIds){
links.add(new ContentDocumentLink(
LinkedEntityId = original.External_ID__c,
ContentDocumentId = i,
ShareType = 'V',
Visibility = 'AllUsers'
));
}
}
}
insert links;

sqflite IN operator with AND operator

I have following query which select from employee table where name is "max" and ID not in 123 and 444.
Not in IDs can grow in future. But I am receiving error as
Error
( 8023): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: DatabaseException(near "?": syntax error (code 1 SQLITE_ERROR): , while compiling:
Query
List<String> a = [];
a.add("123");
a.add("444");
var table = await mydb.rawQuery(
"SELECT value from employee WHERE employeename = ? AND id NOT IN ? ORDER BY timestamp DESC",
["max", a]);
If the LIST is unpredictable, one way is that you can use JOIN to create your select statement with required value of NOT IN. Below is one sample.
void main() {
List<String> a = [];
a.add("123");
a.add("444");
var select =
'SELECT value from employee WHERE employeename = ? AND id NOT IN (\'' +
(a.join('\',\'')).toString() +
'\') ORDER BY timestamp DESC';
var table = await mydb.rawQuery(select, ["max"]);
}
If you print the variable select you will get
SELECT value from employee WHERE employeename = ? AND id NOT IN ('123','444')
ORDER BY timestamp DESC.
Then you can pass the above statement to rawquery and get your result.
P.S:Use your single quote and double quote accordingly.
I'd go for #arun-palanisamy 's solution, see his comment. Props go to him. I just tried the following -- with Groovy/Postgres, but the error seems to be the same, so you might want to give it a try:
String[] a = ['123', '444']
// your code, throws 'ERROR: syntax error at or near "$2"':
// def table = sql.execute("SELECT value from employee WHERE employeename = ? AND id NOT IN ? ORDER BY timestamp DESC", ["max", a])
// code of arun-palanisamy, compiles:
def table = sql.execute("SELECT value from employee WHERE employeename = ? AND id NOT IN (${a.join(', ')}) ORDER BY timestamp DESC", ["max", a])
Side notes:
You might want to try a different type for a, such as Array in my code, or even a HashMap.
There are examples (like here) where the number of ? are generated dynamically.
Update: Go for this answer, we posted simultaneously

Flask Translate Choice in Form To ForeignKey Pointing to Another Table

This part of the app works, buts it's ugly and not sustainable. Need a more evolved solution.
PROBLEM I AM TRYING TO SOLVE:
This part of the application enables users to access a form to enter purchases they've made and store them in a Postgres DB. I am using Flask SQLAlchemy ORM.
Within my purchase table exists a field store_id, that has a ForeignKey relationship to my store table. I don't want my user to select a store ID # in the form, so I am using a SelectField to enable them to choose the store name instead. However, I can't seem to find a sustainable way to translate the store name back to its associated ID. Right now I am using the ugly IF statements seen below.
What is a better way to map/translate store name to ID which is already housed in the "store" table in my DB?
MY MODEL:
class Purchase(db.Model):
id = db.Column(db.Integer, primary_key=True)
item = db.Column(db.String(80))
quantity = db.Column(db.Integer)
unit_cost = db.Column(db.Integer)
total_cost= db.Column(db.Integer)
date = db.Column(db.DateTime)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))
MY FORM:
class CreatePurchase(FlaskForm):
item = StringField('Item', validators=[DataRequired()])
quantity = IntegerField('Quantity', validators=[DataRequired()])
unit_cost = IntegerField('Unit Cost', validators=[DataRequired()])
total_cost = IntegerField('Total Cost', validators=[DataRequired()])
store_id = SelectField("Store Selector", choices=[('0','Select Store'),('1','Furgesons'), ('2','Ocean State'), ('3','Chewy'), ('4','Amazon'), ('5', 'Rumford')])
date = DateField('Purchase Date', validators=[DataRequired()])
submit = SubmitField('Enter')
MY ROUTE:
#main.route('/enter_purchases', methods=['GET', 'POST'])
def enter_purchase():
form = CreatePurchase()
x = str(form.store_id) # this is a store name from our form
p = 0
if "Ocean State" in x:
p = 2
elif "Amazon" in x:
p = 4
elif "Furgesons" in x:
p = 1
elif "Chewy" in x:
p = 3
elif "Rumford" in x:
p = 5
if form.validate_on_submit():
purchase = Purchase(item=form.item.data, quantity=form.quantity.data, unit_cost=form.unit_cost.data,
total_cost=form.total_cost.data, date=form.date.data,store_id=p)
db.session.add(purchase)
db.session.commit()
flash('New purchase added successfully')
return redirect(url_for('main.success'))
return render_template('enter_purchases.html', form=form)
You have a store table, with a numeric id (as the PK) and a name attribute:
class Store(db.Model):
store_id = ..
store_name = ..
You populate your form with all of the unique values from the store_name. This needs to be a dynamically generated form, so instead of using a form that is statically created do something like:
def CreatePurchase()
class TempForm(FlaskForm):
item = StringField('Item', validators=[DataRequired()])
quantity = IntegerField('Quantity', validators=[DataRequired()])
unit_cost = IntegerField('Unit Cost', validators=[DataRequired()])
total_cost = IntegerField('Total Cost', validators=[DataRequired()])
date = DateField('Purchase Date', validators=[DataRequired()])
submit = SubmitField('Enter')
choices = ## some SQLalchemy code to get all unique store_names from the table
TempForm.store_id = SelectField("Store Selector", choices=choices)
return TempForm()
Then form.store_id will provide the right id, but display the string name of the store in the form.
The key in this setup is making sure you use the right SQLalchemy code to populate the SelectField dynamically. Basically for each store in the table you can just iterate through something like this:
choices = list()
for store in Store.query.all(): # <- assumes store_id and store_names are unique
choices.append((store.store_id, store.store_name))

Map to avoid Duplicate records

I have a Holiday Custom object,it contains Unique Dates based on
country based How to retrieve the value in Map
I have tried:
List<Holiday__c> holidays = new List<Holiday__c>([Select id, Date__c,Country__c from Holiday__c]);
Map<date, Holiday__c> mapOfHolidays = new Map<date, Holiday__c>();
for (Holiday__c holiday: holidays) mapOfHolidays.put(holiday.Date__c , holiday);
Suppose date for example 3/8/17 is for country france and Italy,If i put Key Value as Date__c,Map does not contain Key as duplicates,But for each country unique Dates are there
So what i have to use Key and Value in Map,I want to retrieve the date using Map,please anyone Help for me the answer
trigger ignoreweekends on order (before insert,before update) {
Set<id> accountIds = new Set<Id>();
for (order ord : Trigger.new) {
accountids.add(ord.AccountId);
}
map<id, account> mapOfAccounts = new map<id, account>([select id,JDE_Date_Delivery_Offset__c from account where id IN: accountIds]);
List<Holiday__c> holidays = new List<Holiday__c>([Select id, Date__c from Holiday__c]);
Map<date, Holiday__c> mapOfHolidays = new Map<date, Holiday__c>();
for (Holiday__c holiday: holidays) mapOfHolidays.put(holiday.Date__c , holiday);
for (order so : Trigger.new) {
Account acc = mapOfAccounts.get(so.AccountId);
for(integer i=0;i<=acc.JDE_Date_Delivery_Offset__c;i++) {
Datetime dt = DateTime.newInstance(Date.today() +acc.JDE_Date_Delivery_Offset__c.longvalue(), Time.newInstance(0, 0, 0, 0));
String dayOfWeek=dt.format('EEEE');
if(dayOfWeek == 'saturday' || dayOfWeek == 'sunday'|| mapOfHolidays.containskey(mapOfHolidays.Date__c))
acc.JDE_Date_Delivery_Offset__c = acc.JDE_Date_Delivery_Offset__c+ 1;
so.JDE_Synchronization_Date__c = Date.today().addDays(acc.JDE_Date_Delivery_Offset__c.intValue());
}
}
}
If I understood correctly, for one unique date you have multiple countries.
For this you can create a map of Date as key and List as value instead of creating a Map of Date and Holiday_c.
For example :
Map<Date, List<Holiday__c>> mapofHolidays = new HashMap<Date, List<Holiday__c>>();
After that you can retrieve all countries for a unique date and do the required processing.

Entity Framework - Select * from Entities where Id = (select max(Id) from Entities)

I have an entity set called Entities which has a field Name and a field Version. I wish to return the object having the highest version for the selected Name.
SQL wise I'd go
Select *
from table
where name = 'name' and version = (select max(version)
from table
where name = 'name')
Or something similar. Not sure how to achieve that with EF. I'm trying to use CreateQuery<> with a textual representation of the query if that helps.
Thanks
EDIT:
Here's a working version using two queries. Not what I want, seems very inefficient.
var container = new TheModelContainer();
var query = container.CreateQuery<SimpleEntity>(
"SELECT VALUE i FROM SimpleEntities AS i WHERE i.Name = 'Test' ORDER BY i.Version desc");
var entity = query.Execute(MergeOption.OverwriteChanges).FirstOrDefault();
query =
container.CreateQuery<SimpleEntity>(
"SELECT VALUE i FROM SimpleEntities AS i WHERE i.Name = 'Test' AND i.Version =" + entity.Version);
var entity2 = query.Execute(MergeOption.OverwriteChanges);
Console.WriteLine(entity2.GetType().ToString());
Can you try something like this?
using(var container = new TheModelContainer())
{
string maxEntityName = container.Entities.Max(e => e.Name);
Entity maxEntity = container.Entities
.Where(e => e.Name == maxEntityName)
.FirstOrDefault();
}
That would select the maximum value for Name from the Entities set first, and then grab the entity from the entity set that matches that name.
I think from a simplicity point of view, this should be same result but faster as does not require two round trips through EF to sql server, you always want to execute query as few times as possible for latency, as the Id field is primary key and indexed, should be performant
using(var db = new DataContext())
{
var maxEntity = db.Entities.OrderByDecending(x=>x.Id).FirstOrDefault()
}
Should be equivalent of sql query
SELECT TOP 1 * FROM Entities Order By id desc
so to include search term
string predicate = "name";
using(var db = new DataContext())
{
var maxEntity = db.Entities
.Where(x=>x.Name == predicate)
.OrderByDecending(x=>x.Id)
.FirstOrDefault()
}
I think something like this..?
var maxVersion = (from t in table
where t.name == "name"
orderby t.version descending
select t.version).FirstOrDefault();
var star = from t in table
where t.name == "name" &&
t.version == maxVersion
select t;
Or, as one statement:
var star = from t in table
let maxVersion = (
from v in table
where v.name == "name"
orderby v.version descending
select v.version).FirstOrDefault()
where t.name == "name" && t.version == maxVersion
select t;
this is the easiest way to get max
using (MyDBEntities db = new MyDBEntities())
{
var maxReservationID = _db .LD_Customer.Select(r => r.CustomerID).Max();
}