|
| 1 | +<h2>Full example</h2> |
| 2 | +<pre><code>// source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_shopping_cart_example_code.htm |
| 3 | + |
| 4 | +trigger calculate on Item__c (after insert, after update, after delete) { |
| 5 | + |
| 6 | +// Use a map because it doesn't allow duplicate values |
| 7 | + |
| 8 | +Map<ID, Shipping_Invoice__C> updateMap = new Map<ID, Shipping_Invoice__C>(); |
| 9 | + |
| 10 | +// Set this integer to -1 if we are deleting |
| 11 | +Integer subtract ; |
| 12 | + |
| 13 | +// Populate the list of items based on trigger type |
| 14 | +List<Item__c> itemList; |
| 15 | + if(trigger.isInsert || trigger.isUpdate){ |
| 16 | + itemList = Trigger.new; |
| 17 | + subtract = 1; |
| 18 | + } |
| 19 | + else if(trigger.isDelete) |
| 20 | + { |
| 21 | + // Note -- there is no trigger.new in delete |
| 22 | + itemList = trigger.old; |
| 23 | + subtract = -1; |
| 24 | + } |
| 25 | + |
| 26 | +// Access all the information we need in a single query |
| 27 | +// rather than querying when we need it. |
| 28 | +// This is a best practice for bulkifying requests |
| 29 | + |
| 30 | +set<Id> AllItems = new set<id>(); |
| 31 | + |
| 32 | +for(item__c i :itemList){ |
| 33 | +// Assert numbers are not negative. |
| 34 | +// None of the fields would make sense with a negative value |
| 35 | + |
| 36 | +System.assert(i.quantity__c > 0, 'Quantity must be positive'); |
| 37 | +System.assert(i.weight__c >= 0, 'Weight must be non-negative'); |
| 38 | +System.assert(i.price__c >= 0, 'Price must be non-negative'); |
| 39 | + |
| 40 | +// If there is a duplicate Id, it won't get added to a set |
| 41 | +AllItems.add(i.Shipping_Invoice__C); |
| 42 | +} |
| 43 | + |
| 44 | +// Accessing all shipping invoices associated with the items in the trigger |
| 45 | +List<Shipping_Invoice__C> AllShippingInvoices = [SELECT Id, ShippingDiscount__c, |
| 46 | + SubTotal__c, TotalWeight__c, Tax__c, GrandTotal__c |
| 47 | + FROM Shipping_Invoice__C WHERE Id IN :AllItems]; |
| 48 | + |
| 49 | +// Take the list we just populated and put it into a Map. |
| 50 | +// This will make it easier to look up a shipping invoice |
| 51 | +// because you must iterate a list, but you can use lookup for a map, |
| 52 | +Map<ID, Shipping_Invoice__C> SIMap = new Map<ID, Shipping_Invoice__C>(); |
| 53 | + |
| 54 | +for(Shipping_Invoice__C sc : AllShippingInvoices) |
| 55 | +{ |
| 56 | + SIMap.put(sc.id, sc); |
| 57 | +} |
| 58 | + |
| 59 | +// Process the list of items |
| 60 | + if(Trigger.isUpdate) |
| 61 | + { |
| 62 | + // Treat updates like a removal of the old item and addition of the |
| 63 | + // revised item rather than figuring out the differences of each field |
| 64 | + // and acting accordingly. |
| 65 | + // Note updates have both trigger.new and trigger.old |
| 66 | + for(Integer x = 0; x < Trigger.old.size(); x++) |
| 67 | + { |
| 68 | + Shipping_Invoice__C myOrder; |
| 69 | + myOrder = SIMap.get(trigger.old[x].Shipping_Invoice__C); |
| 70 | + |
| 71 | + // Decrement the previous value from the subtotal and weight. |
| 72 | + myOrder.SubTotal__c -= (trigger.old[x].price__c * |
| 73 | + trigger.old[x].quantity__c); |
| 74 | + myOrder.TotalWeight__c -= (trigger.old[x].weight__c * |
| 75 | + trigger.old[x].quantity__c); |
| 76 | + |
| 77 | + // Increment the new subtotal and weight. |
| 78 | + myOrder.SubTotal__c += (trigger.new[x].price__c * |
| 79 | + trigger.new[x].quantity__c); |
| 80 | + myOrder.TotalWeight__c += (trigger.new[x].weight__c * |
| 81 | + trigger.new[x].quantity__c); |
| 82 | + } |
| 83 | + |
| 84 | + for(Shipping_Invoice__C myOrder : AllShippingInvoices) |
| 85 | + { |
| 86 | + |
| 87 | + // Set tax rate to 9.25% Please note, this is a simple example. |
| 88 | + // Generally, you would never hard code values. |
| 89 | + // Leveraging Custom Settings for tax rates is a best practice. |
| 90 | + // See Custom Settings in the Apex Developer Guide |
| 91 | + // for more information. |
| 92 | + myOrder.Tax__c = myOrder.Subtotal__c * .0925; |
| 93 | + |
| 94 | + // Reset the shipping discount |
| 95 | + myOrder.ShippingDiscount__c = 0; |
| 96 | + |
| 97 | + // Set shipping rate to 75 cents per pound. |
| 98 | + // Generally, you would never hard code values. |
| 99 | + // Leveraging Custom Settings for the shipping rate is a best practice. |
| 100 | + // See Custom Settings in the Apex Developer Guide |
| 101 | + // for more information. |
| 102 | + myOrder.Shipping__c = (myOrder.totalWeight__c * .75); |
| 103 | + myOrder.GrandTotal__c = myOrder.SubTotal__c + myOrder.tax__c + |
| 104 | + myOrder.Shipping__c; |
| 105 | + updateMap.put(myOrder.id, myOrder); |
| 106 | + } |
| 107 | + } |
| 108 | + else |
| 109 | + { |
| 110 | + for(Item__c itemToProcess : itemList) |
| 111 | + { |
| 112 | + Shipping_Invoice__C myOrder; |
| 113 | + |
| 114 | + // Look up the correct shipping invoice from the ones we got earlier |
| 115 | + myOrder = SIMap.get(itemToProcess.Shipping_Invoice__C); |
| 116 | + myOrder.SubTotal__c += (itemToProcess.price__c * |
| 117 | + itemToProcess.quantity__c * subtract); |
| 118 | + myOrder.TotalWeight__c += (itemToProcess.weight__c * |
| 119 | + itemToProcess.quantity__c * subtract); |
| 120 | + } |
| 121 | + |
| 122 | + for(Shipping_Invoice__C myOrder : AllShippingInvoices) |
| 123 | + { |
| 124 | + |
| 125 | + // Set tax rate to 9.25% Please note, this is a simple example. |
| 126 | + // Generally, you would never hard code values. |
| 127 | + // Leveraging Custom Settings for tax rates is a best practice. |
| 128 | + // See Custom Settings in the Apex Developer Guide |
| 129 | + // for more information. |
| 130 | + myOrder.Tax__c = myOrder.Subtotal__c * .0925; |
| 131 | + |
| 132 | + // Reset shipping discount |
| 133 | + myOrder.ShippingDiscount__c = 0; |
| 134 | + |
| 135 | + // Set shipping rate to 75 cents per pound. |
| 136 | + // Generally, you would never hard code values. |
| 137 | + // Leveraging Custom Settings for the shipping rate is a best practice. |
| 138 | + // See Custom Settings in the Apex Developer Guide |
| 139 | + // for more information. |
| 140 | + myOrder.Shipping__c = (myOrder.totalWeight__c * .75); |
| 141 | + myOrder.GrandTotal__c = myOrder.SubTotal__c + myOrder.tax__c + |
| 142 | + myOrder.Shipping__c; |
| 143 | + |
| 144 | + updateMap.put(myOrder.id, myOrder); |
| 145 | + |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + // Only use one DML update at the end. |
| 150 | + // This minimizes the number of DML requests generated from this trigger. |
| 151 | + update updateMap.values(); |
| 152 | +}</code></pre> |
0 commit comments