function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Alex LazarevAlex Lazarev 

Get Sale ID to acquire child objects items quantity and check then with stock

Hello guys,

Continuing with my trials of solving the problematic with initial skills of apex development I have the next problematic:

I'm trying to get Sales__c Id with status 'Sold', with the Sale Id check inside the Order_Item__c that belongs to the Sale values Vehicle_Name__c,Item_Quantity__c.

Then search by Vehicle_Name__c inside Vehicle__c and check if Vehicle__c.Quantity__c <= Order_Item__c.Item_Quantity__c

This is what I managed to do so far but its not working and I have no clue on how to continue.

Could someone help me please with the code?
 
trigger SaleCheckout on Sales__c (before update) {
    
    //Map<Id,Sales__c> salesSold = new Map<Id,Sales__c>([SELECT Id FROM Sales__c WHERE Sale_Satus__c = 'Sold']);
    List<Sales__c> sale = [SELECT Id FROM Sales__c WHERE Sale_Satus__c = 'Sold'];
    System.debug(' List<Sales__c> salesSold = ' + sale);
    
    Set<String> s = New Set<String>();
    for(Sales__c sales : sale) {
        s.add(sales.Id);
    }
     
    Map<Id,Order_Item__c> orders = new Map<Id,Order_Item__c>([SELECT Id,Vehicle_Name__c,Item_Quantity__c FROM Order_Item__c WHERE Sale__c  IN : s.Id]);


}

 
Best Answer chosen by Alex Lazarev
Amit Singh 1Amit Singh 1
I have updated the code as per your requirement but one thing I wanted to let you know that once error is thrown all operation will be rollback.
trigger SaleCheckout on Sales__c (before update) {

    Set<String> sale = new Set<String>();
    Map<Id,Sales__c> salesMap = new Map<Id,Sales__c>();
    for (Sales__c s : Trigger.new){
        sale.add(s.Id);
        salesMap.put(s.Id,s);
        //Sale ID
        System.debug('1-- Sale ID: '+ sale);        
    }

    List<Order_Item__c> orders = [SELECT Id,Vehicle_Name__c,Item_Quantity__c,Sale__c FROM Order_Item__c WHERE Sale__c  IN : sale];
    // Orders with Sale ID
	System.debug('2-- Orders IDs: ' + orders);
	Set<Id> vechicleIdSet = new Set<Id>();
	For(Order_Item__c ord : orders){
		If(ord.Vehicle_Name__c!=null)vechicleIdSet.add(ord.Vehicle_Name__c);
	}
    System.debug('2-- Orders IDs: ' + orders);
	Map<Id, Vehicle__c> vechicleQuantityMap = new Map<Id, Vehicle__c>();
    For(Vehicle__c vech : [Select Id, Name, Quantity__c FROM Vehicle__c Where ID In:vechicleIdSet]){
		vechicleQuantityMap.put(vech.Id,vech);
	}
    For(Order_Item__c ord : orders){
	    Vehicle__c vechicle = vechicleQuantityMap.get(ord.Vehicle_Name__c);
		Double quantity = Double.valueOf(vechicle.Quantity__c);
		vechicle.Quantity__c = ord.Item_Quantity__c;
		If(quantity<= ord.Item_Quantity__c){
			Trigger.newMap.get(ord.Sale__c).addError('You cannot sale without items stock');
		}
	}
	Update vechicleQuantityMap.values();

}
Thanks!
Amit Singh
 

All Answers

Alex LazarevAlex Lazarev
Updated the code, I think its simplier and its on the right direction this time, now that I have the Order Items that belong to the Sale, how to continue?
 
trigger SaleCheckout on Sales__c (before update) {

    Set<String> sale = new Set<String>();

    for (Sales__c s : Trigger.new){
        sale.add(s.Id);

        //Sale ID
        System.debug('1-- Sale ID: '+ sale);        
    }

    List<Order_Item__c> orders = [SELECT Id,Vehicle_Name__c,Item_Quantity__c FROM Order_Item__c WHERE Sale__c  IN : sale];
    // Orders with Sale ID
    System.debug('2-- Orders IDs: ' + orders);



}

 
Amit Singh 1Amit Singh 1
Correct if I am wrong. Vehicle_Name__c is a lookup field on Oredr_Item__c Object. right?

Use below code.
trigger SaleCheckout on Sales__c (before update) {

    Set<String> sale = new Set<String>();

    for (Sales__c s : Trigger.new){
        sale.add(s.Id);

        //Sale ID
        System.debug('1-- Sale ID: '+ sale);        
    }

    List<Order_Item__c> orders = [SELECT Id,Vehicle_Name__c,Item_Quantity__c FROM Order_Item__c WHERE Sale__c  IN : sale];
    // Orders with Sale ID
	System.debug('2-- Orders IDs: ' + orders);
	Set<Id> vechicleIdSet = new Set<Id>();
	For(Order_Item__c ord : orders){
		If(ord.Vehicle_Name__c!=null)vechicleIdSet.add(ord.Vehicle_Name__c);
	}
    System.debug('2-- Orders IDs: ' + orders);
	Map<Id, Double> vechicleQuantityMap = new Map<Id, Double>();
    For(Vehicle__c vech : [Select Id, Name, Quantity__c FROM Vehicle__c Where ID In:vechicleIdSet]){
		vechicleQuantityMap.put(vech.Id,Double.valueOf(vech.Quantity__c));
	}
    For(Order_Item__c ord : orders){
		Double quantity = vechicleQuantityMap.get(ord.Vehicle_Name__c);
		If(quantity<= ord.Item_Quantity__c){
			// Your Logic Here
		}
	}

}
Hope this helps :)
Thanks!
AMit Singh
 
Alex LazarevAlex Lazarev
Amit, it is a great resolution, also en excelent lesson. 

I have one more question, since on the last FOR
 
For(Order_Item__c ord : orders){
        Double quantity = vechicleQuantityMap.get(ord.Vehicle_Name__c);
        If(quantity<= ord.Item_Quantity__c){
            // Your Logic Here
        }
    }

I need to place an error but on Sales__c custom object inside the if. But this for only refeers to Order_Item__c.
 
If(quantity<= ord.Item_Quantity__c){
        ord.addError('You cannot sale without items stock'); 
        //it is pointing to ord but it should do it to Sales__c obj
}

How can I refeer to the original object to place the error message properly?
 
Amit Singh 1Amit Singh 1
Use below code.
trigger SaleCheckout on Sales__c (before update) {

    Set<String> sale = new Set<String>();
    Map<Id,Sales__c> salesMap = new Map<Id,Sales__c>();
    for (Sales__c s : Trigger.new){
        sale.add(s.Id);
        salesMap.put(s.Id,s);
        //Sale ID
        System.debug('1-- Sale ID: '+ sale);        
    }

    List<Order_Item__c> orders = [SELECT Id,Vehicle_Name__c,Item_Quantity__c,Sale__c FROM Order_Item__c WHERE Sale__c  IN : sale];
    // Orders with Sale ID
	System.debug('2-- Orders IDs: ' + orders);
	Set<Id> vechicleIdSet = new Set<Id>();
	For(Order_Item__c ord : orders){
		If(ord.Vehicle_Name__c!=null)vechicleIdSet.add(ord.Vehicle_Name__c);
	}
    System.debug('2-- Orders IDs: ' + orders);
	Map<Id, Double> vechicleQuantityMap = new Map<Id, Double>();
    For(Vehicle__c vech : [Select Id, Name, Quantity__c FROM Vehicle__c Where ID In:vechicleIdSet]){
		vechicleQuantityMap.put(vech.Id,Double.valueOf(vech.Quantity__c));
	}
    For(Order_Item__c ord : orders){
		Double quantity = vechicleQuantityMap.get(ord.Vehicle_Name__c);
		If(quantity<= ord.Item_Quantity__c){
			Sales__c sc = salesMap.get(ord.Sale__c);
			sc.addError('You cannot sale without items stock');
		}
	}

}
Hope this helps and Mark as best if this helps :)
Thanks!
Amit Singh
 
Alex LazarevAlex Lazarev
I did the same using the Trigger.newMap
 
For(Order_Item__c ord : orders){
            Double quantity = vechicleQuantityMap.get(ord.Vehicle_Name__c);
            If(quantity < ord.Item_Quantity__c){
                Trigger.newMap.get(ord.Sale__c).addError('You cannot sale without items stock');
            } else {
                
            }
        }

Thank you,

Now I have to update the records in vehicles doing vehicles quantity - ord.Item_Quantity_c
If you have any quick suggestions, i'll be thankful.
Amit Singh 1Amit Singh 1
I have updated the code as per your requirement but one thing I wanted to let you know that once error is thrown all operation will be rollback.
trigger SaleCheckout on Sales__c (before update) {

    Set<String> sale = new Set<String>();
    Map<Id,Sales__c> salesMap = new Map<Id,Sales__c>();
    for (Sales__c s : Trigger.new){
        sale.add(s.Id);
        salesMap.put(s.Id,s);
        //Sale ID
        System.debug('1-- Sale ID: '+ sale);        
    }

    List<Order_Item__c> orders = [SELECT Id,Vehicle_Name__c,Item_Quantity__c,Sale__c FROM Order_Item__c WHERE Sale__c  IN : sale];
    // Orders with Sale ID
	System.debug('2-- Orders IDs: ' + orders);
	Set<Id> vechicleIdSet = new Set<Id>();
	For(Order_Item__c ord : orders){
		If(ord.Vehicle_Name__c!=null)vechicleIdSet.add(ord.Vehicle_Name__c);
	}
    System.debug('2-- Orders IDs: ' + orders);
	Map<Id, Vehicle__c> vechicleQuantityMap = new Map<Id, Vehicle__c>();
    For(Vehicle__c vech : [Select Id, Name, Quantity__c FROM Vehicle__c Where ID In:vechicleIdSet]){
		vechicleQuantityMap.put(vech.Id,vech);
	}
    For(Order_Item__c ord : orders){
	    Vehicle__c vechicle = vechicleQuantityMap.get(ord.Vehicle_Name__c);
		Double quantity = Double.valueOf(vechicle.Quantity__c);
		vechicle.Quantity__c = ord.Item_Quantity__c;
		If(quantity<= ord.Item_Quantity__c){
			Trigger.newMap.get(ord.Sale__c).addError('You cannot sale without items stock');
		}
	}
	Update vechicleQuantityMap.values();

}
Thanks!
Amit Singh
 
This was selected as the best answer
Alex LazarevAlex Lazarev
No Amit, its not a requirement, but it is a huge help to have it as an example for me to handle lots of future situations.

I'll test it in a while and let you know.
Geraldine StarnerGeraldine Starner
Your object structure is unclear. I think you have the following (https://www.cheekywinx.com.au/) objects:
Sales__c with fields: Id, Status
Order_Item__c with fields: Id, Sale__c, Vehicle_Name__c, Item_Quantity__c
Vehicle__c with fields: Id, Name, Quantity__c
I'm not sure why you are referencing vehicles by name instead of Id, but that's your call. If that's the case, something like this should work:
trigger SaleCheckout on Sales__c (before update) { List<Order_Item__c> orders = [SELECT Vehicle_Name__c, Item_Quantity__c FROM Order_Item__c WHERE Sale__c IN :Trigger.new AND Sale__r.Status = 'Sold']; System.debug('2-- Orders IDs: ' + orders); Set<String> vehicleNames = new Set<String>(); for (Order_Item__c order : orders) { vehicleNames.add(order.Vehicle_Name__c); } List<Vehicle__c> vehicles = [SELECT Name, Quantity__c FROM Vehicle__c WHERE Name IN :vehicleNames]; for (Vehicle__c vehicle : vehicles) { for (Order_Item__c order: orders) { if (order.Vehicle_Name__c == vehicle.Name && vehicle.Quantity__c < order.Item_Quatity__c) { //do something here, let's say we want to fail the sale Trigger.newMap.get(order.Sale__c).addError('You are trying to sell more cars than we have! You sold ' + String.valueOf(order.Item_Quantity__c) + ' cars of type ' + order.Vehicle_Name__c + ' and we only have ' + String.valueOf(vehicle.Quantity__c) + ' on the lot!'); } } } }
This assumes that you don't have multiple orders for the same car, in which case you'd probably have to add up the quantities of multiple orders. Keep in mind I just wrote that code out in SO and it can easily contain errors.