I have created a employee id tabview list i have to change it to dictionary - mvvm

First image
i have used list with mvvm but my seniors told me use
dict<string, Employee> =
{
{"Employee 1" ,{id, emailid , name , father name , employee id , adddress}}
{"Employee 2" ,{id, emailid , name , father name , employee id , adddress}}
{"Employee 3" ,{id, emailid , name , father name , employee id , adddress}}
{"Employee 4" ,{id, emailid , name , father name , employee id , adddress}}
{"Employee 5" ,{id, emailid , name , father name , employee id , adddress}}
}
i am not able to change it to dictionary can anyone do it or give me some reference

Dictionaries are key-value collections. For every item, you have to specify a unique id.
For example:
var EmployeesDictionary = new Dictionary<string, Employee>();
EmployeesDictionary["empId"] = new Employee();
In your case you could populate your collection like that:
private record Employee(
int Id,
string EmpTab,
string EmailId,
string Name,
string FatherName,
string EmpId,
string Address);
private void LoadEmployees()
{
var EmployeesDictionary = new Dictionary<int, Employee>();
for (int i = 0; i < 5; i++)
{
EmployeesDictionary.Add(i, new Employee(
Id: i,
EmpTab: "EmptTab",
EmailId: "Email",
Name: "Name",
FatherName: "FatherName",
EmpId: "EmpId",
Address: "Address"));
}
}
You also could convert your list using LINQ:
private record Employee(
int Id,
string EmpTab,
string EmailId,
string Name,
string FatherName,
string EmpId,
string Address);
private void LoadEmplEmployees()
{
var EmployeesDictionary = new List<Employee>();
for (int i = 0; i < 5; i++)
{
EmployeesDictionary.Add(new Employee(
Id: i,
EmpTab: "EmptTab",
EmailId: "Email",
Name: "Name",
FatherName: "FatherName",
EmpId: "EmpId",
Address: "Address"));
}
EmployeesDictionary.ToDictionary(e => e.Id, e => e);
}
Dictionary Reference
LINQ ToDictionary Reference

Related

Is there best solution for get entity from PostgreSQL

I have two entities
Author entity with atributes Id, firstName, secondName, lastName and transiet attribute numberBooks
Book entity with attirbutes Id, name and authorIds which is array of uuid
Question:
Is there best solution to get list of authors with numberBooks. NumberBooks need calculate from book entity
My solution is
//Author service
fun getListAuthors(): List<Author> {
val result = repository.findAllByDeletedAtIsNull()
setNumberBooksToAuthors(result)
return result
}
private fun setNumberBooksToAuthors(authors: List<Author>) {
val authorNumberBooks = repository.getAuthorsByDeletedAtIsNull(authors.map { it.id!! }.toList())
.map {
UUID.fromString(it["id"]) to Integer.parseInt(it["count"])
}.toMap()
for (author in authors) {
if (authorNumberBooks.containsKey(author.id)) {
author.numberBooks = authorNumberBooks[author.id]!!
}
}
}
//Author repository
#Query(
"SELECT CAST(author.id as varchar), CAST((SELECT COUNT(*) FROM books as b " +
"WHERE author.id = ANY(b.author_ids) AND b.deleted_at IS NULL) as varchar) " +
"from book_authors as author " +
"WHERE author.deleted_at IS NULL AND author.id in :authorIds", nativeQuery = true
)
fun getAuthorsByDeletedAtIsNull(authorIds: List<UUID>): MutableList<MutableMap<String, String>>

Salesforce Test class getting System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set Error

I have written a trigger and handler class (which uses a future method) and it works well. I am really struggling to write the test class for it. My first problem is that the code coverage is high (before tweaks it was 0% in the handler class). After tweaking, I am getting the following error:
System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set
I am not sure how to solve this and I am a pretty new dev so not sure what to do next . Can someone please help?
Here is my code:
Trigger:
trigger AccountTriggerKeepAcctTeam on Account (before update) {
List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in : Trigger.new AND TeamMemberRole != 'Account Executive'];
for(Account acc: Trigger.new){
Account oldAccount = Trigger.oldMap.get(acc.Id);
if(acc.OwnerId != oldAccount.OwnerId){
system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc)));
String str = JSON.serialize(listAcc);
//delete team member records if required
AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(str);
}
}
}
Handler:
public class AccountTriggerKeepAcctTeamHandler {
#future
public static void retainOldTeamMemberOnOwnerChange(String str){
system.debug('Future call '+str);
List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
for(AccountTeamMember objAccTeamMember : newlistAcc){
objAccTeamMember.Id= null;
}
system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
Upsert newlistAcc;
}
}
Test class:
#isTest
public class AccountTriggerKeepAcctTeamTest {
//#TestSetup
static testMethod void AcctOwnerChange(){
List<User> userList = TestDataFactory.createUser(true, 2);
Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
User u1 = new User(Alias = 'standt', Email='standarduser#testorg1.com',
EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
LocaleSidKey='en_US', ProfileId = p.Id,
TimeZoneSidKey='America/Los_Angeles', UserName='standarduser#testorg01.com');
insert u1;
User u2 = new User(Alias = 'standt', Email='standarduser#testorg2.com',
EmailEncodingKey='UTF-8', LastName='Testing2', LanguageLocaleKey='en_US',
LocaleSidKey='en_US', ProfileId = p.Id,
TimeZoneSidKey='America/Los_Angeles', UserName='standarduser#testorg92.com');
insert u2;
System.runAs(u1){
Allowed_Account_Owner_Change__c setting = new Allowed_Account_Owner_Change__c();
setting.Allowed_to_change_Account_Owner__c = true;
insert setting;
fferpcore__ExchangeRateGroup__c exrg = new fferpcore__ExchangeRateGroup__c(CurrencyISOCode = 'USD', fferpcore__DefaultCurrency__c = 'USD - U.S. Dollar', Name = 'FF Shared Test Group', fferpcore__SelectedCurrencies__c = 'USD - U.S. Dollar');
insert exrg;
c2g__codaCompany__c company = new c2g__codaCompany__c();
company.Name = 'ApexTestCompany';
company.RecordTypeId = Schema.SObjectType.c2g__codaCompany__c.RecordTypeInfosByName.get('SUT').RecordTypeId;
insert company;
company.c2g__ExchangeRateGroup__c = exrg.Id;
update company;
Account acc = new Account(Name = 'Test Acc2', NumberOfEmployees = 500);//TestDataFactory.createAccountwithCurrencyMaster(true);
acc.OwnerId = userinfo.getUserId();
insert acc;
AccountTeamMember accTeam = new AccountTeamMember();
accTeam.UserId = acc.OwnerId;
accTeam.AccountAccessLevel = 'Read';
accTeam.AccountId = acc.Id;
insert accTeam;
System.debug('## User '+userinfo.getUserName());
//create opportunity
//}
// }
// static testMethod void testAcctOwnerChange(){
// User u = [Select id, LastName from User where LastName = 'Testing2'];
// Account acc = [Select id, OwnerId from Account Limit 1];
Test.startTest();
acc.OwnerId = u2.id;
update acc;
AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(JSON.serialize(acc));
//System.assertEquals(accTeam.UserId,u2.Id);
Test.stopTest();
//AccountTeamMember atm = [Select userId,AccountId, AccountAccessLevel from AccountTeamMember where AccountId =: acc.Id];
}
}
Can someone please help? I am a beginner apex dev
Trigger Attempt for Alin's test class:
trigger AccountTriggerKeepAcctTeam on Account (before update) {
Set<Id> accteammbrId = new Set<Id>();
List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in : Trigger.new AND TeamMemberRole != 'Account Executive'];
for(Account acc: Trigger.new){
Account oldAccount = Trigger.oldMap.get(acc.Id);
if(acc.OwnerId != oldAccount.OwnerId){
//system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc)));
//String str = JSON.serialize(listAcc);
for(AccountTeamMember actmbr : listAcc){
accteammbrId.add(actmbr.Id);
}
//delete team member records if required
AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(accteammbrId);
}
}
}
public class AccountTriggerKeepAcctTeamHandler {
#future
public static void retainOldTeamMemberOnOwnerChange(Set<Id> AccteambrId){
List<AccountTeamMember> newlistAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in :AccteambrId];
//system.debug('Future call '+str);
//List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
for(AccountTeamMember objAccTeamMember : newlistAcc){
objAccTeamMember.Id= null;
}
//system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
system.debug('Account records to insert' + newlistAcc);
Upsert newlistAcc;
}
}
I don't understand why you have to serialize the list in the first place.
Change your retainOldTeamMemberOnOwnerChange to accept a List as parameter and don't use the JSON at all.
Then in your test class you create an account, assign an account team to it and change the owner. After that you will query the List of associated AccountTeamMember and assert it with regards to the AccountTeamMember before the ownership of the account was changed.
If it's not clear enough I can give you a code example, but I think the exercise will be good for you.
Edit: I see. My bad. This is what I use for test coverage. I can also provide code sample from the trigger if needed.
Trigger:
trigger AccountTrigger on Account (before update, After Update) {
if(trigger.isBefore){
if(trigger.isUpdate){
AccountTriggerHandler.retainAccountTeam(trigger.new, trigger.oldMap);
}
}
}
Handler:
public class AccountTriggerHandler {
public static void retainAccountTeam(List<Account> newList, Map<Id, Account> oldMap) {
Set<Id> accountsWithNewOwners = new Set<Id>();
for(Account acc : newList){
if(acc.OwnerId != oldMap.get(acc.Id).OwnerId){
accountsWithNewOwners.add(acc.Id);
}
}
if(accountsWithNewOwners.size() > 0){
List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember WHERE AccountId IN :accountsWithNewOwners];
system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc)));
String str = JSON.serialize(listAcc);
// delete team member records if required
retainOldTeamMemberOnOwnerChange(str);
}
}
//Before Update calls the future method that basically reinserts the Account Team member records. You can also consider deleting the Account Team Member records before calling the future method.
#future
public static void retainOldTeamMemberOnOwnerChange(String str){
system.debug('Future call '+str);
List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
for(AccountTeamMember objAccTeamMember : newlistAcc){
objAccTeamMember.Id= null;
}
system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
Upsert newlistAcc;
}
}
Test method:
static testMethod void test_retainAccountTeam(){
Id mhbkRTId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('MHBK').getRecordTypeId();
Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
User u = new User(
Alias = 'rivacon',
Email = 'rivaConnector#testorg.com',
EmailEncodingKey = 'UTF-8',
LastName = 'Connector',
FirstName = 'Riva',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
ProfileId = p.Id,
TimeZoneSidKey = 'America/Los_Angeles',
UserName = 'rivaConnector#testorg.com');
insert u;
User u2 = new User(
Alias = 'updated',
Email = 'rivaConnector#testorg.com',
EmailEncodingKey = 'UTF-8',
LastName = 'Connector',
FirstName = 'Riva2',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
ProfileId = p.Id,
TimeZoneSidKey = 'America/Los_Angeles',
UserName = 'rivaConnector2#testorg.com');
insert u2;
system.runAs(u){
Account acc = new Account(RecordTypeId = mhbkRTId,Name = 'test',Branch__c='London',Industry='Banking',Year_Founded__c='1900',BillingStreet = '1 Long Rd',BillingCity = 'City',CurrencyIsoCode = 'GBP');
insert acc;
AccountTeamMember atm = new AccountTeamMember();
atm.AccountId = acc.Id;
//atm.Name ='Test ATM';
atm.TeamMemberRole = 'Sales Assistant';
atm.UserId = u.Id;
insert atm;
Test.startTest();
acc.OwnerId = u2.Id;
update acc;
Test.stopTest();
System.debug('usr1 ' + u.id);
System.debug('usr2 ' + u2.id);
Account updatedAccount = [SELECT OwnerId FROM Account WHERE Id = :acc.Id];
system.assertEquals(u2.Id, updatedAccount.OwnerId);
List<AccountTeamMember> teamMembers = [SELECT Id, AccountAccessLevel, AccountId, UserId, TeamMemberRole, Title FROM AccountTeamMember WHERE AccountId = :acc.Id];
system.assertEquals(1, teamMembers.size());
system.assertEquals(teamMembers[0].TeamMemberRole, atm.TeamMemberRole);
}

Using value/variable used in if.clause after the if

I want to create a new address model. Doing so, beforehand I check a data structure if this contains specific information and then extract them and store it into a variable. After all if-clauses I want to use these variables to create a new object of type Address. However, all the in-between stored variables are not recognized:
final List type = c['types'];
if (type.contains('street_number')) {
final streetNumber = c['long_name'];
}
if (type.contains('route')) {
final street = c['long_name'];
}
if (type.contains('locality')) {
final city = c['long_name'];
}
if (type.contains('postal_code')) {
final zipCode = c['long_name'];
}
final address = Address(
country: null,
postalCode: zipCode, //Undefinex name 'zipCode'
city: city,
streetNumber: streetNumber,
long: null,
lat: null);
});
Variables which are declared in a code block will be removed after that block. So you have to declare that Variables before those blocks:
dynamic streetNumber;
if (type.contains('street_number')) {
streetNumber = c['long_name'];
}
dynamic street;
if (type.contains('route')) {
street = c['long_name'];
}
dynamic city;
if (type.contains('locality')) {
city = c['long_name'];
}
dynamic zipCode;
if (type.contains('postal_code')) {
zipCode = c['long_name'];
}

entity Framework Seeding related data

I'm trying to figure out how to seed one to many data elements in the seed method of Entity Framework.
context.AddressTypes.AddOrUpdate(
p => p.Name,
new AddressType { Name = "Original" },
new AddressType { Name = "Shipping" },
new AddressType { Name = "Billing" }
);
context.Addresses.AddOrUpdate(
a => a.Address1,
new Address { Address1 = "123 West Main",
City = "Hannibal",
Region = "MO",
PostalCode = "12345",
Country = "USA",
Type = new AddressType { Id=1 } }
);
How do I add one of the three address types to the address object I am seeding? If I do it the way I have shown it creates a new object in the AddressTypes table.

concatenate strings in LINQ query

Suppose I want to set FullName property using string.Format like this:
var userList = users.Select(user => new User()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName
FullName = string.Format("{0} {1}", user.UserName, user.FirstName)
}).ToList();
This obviously doesn't work because LINQ doesn't know about string.Format.
My question is what are the other options beside going over the list in memory and setting FullName for each item?
userList.ForEach(u => u.FullName = string.Format("{0} {1}", user.UserName, user.FirstName))
UPDATE: to see what I need, please see my conversation with #octavioccl below
you can use it:
FullName = user.UserName + " " + user.FirstName
But I think that it could be better solution (of cource if it's possible for you):
public class User
{
public int Id {get;set;}
public string UserName {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string FullName
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
}
}
then in your query build it:
var userList = users.Select(user => new User()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName
}).ToList();
String.Format is not supported in EF, try this way:
FullName = user.UserName + " " + user.FirstName
In this link you will find all CLR methods that are supported
Another object is to project to an anonymous type without that property, then project to the final type in linq-to-objects:
var userList = users.Select(user => new {
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName
})
.AsEnumerable()
.Select(user => new User()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName
FullName = string.Format("{0} {1}", user.UserName, user.FirstName)
})
.ToList();