Newer Version Available
納入先請求書のコード例
次のトリガおよびテストクラスは、納入先請求書のアプリケーション例を構成します。
Calculate トリガ
1trigger calculate on Item__c (after insert, after update, after delete) {
2
3// Use a map because it doesn't allow duplicate values
4
5Map<ID, Shipping_Invoice__C> updateMap = new Map<ID, Shipping_Invoice__C>();
6
7// Set this integer to -1 if we are deleting
8Integer subtract ;
9
10// Populate the list of items based on trigger type
11List<Item__c> itemList;
12 if(trigger.isInsert || trigger.isUpdate){
13 itemList = Trigger.new;
14 subtract = 1;
15 }
16 else if(trigger.isDelete)
17 {
18 // Note -- there is no trigger.new in delete
19 itemList = trigger.old;
20 subtract = -1;
21 }
22
23// Access all the information we need in a single query
24// rather than querying when we need it.
25// This is a best practice for bulkifying requests
26
27set<Id> AllItems = new set<id>();
28
29for(item__c i :itemList){
30// Assert numbers are not negative.
31// None of the fields would make sense with a negative value
32
33System.assert(i.quantity__c > 0, 'Quantity must be positive');
34System.assert(i.weight__c >= 0, 'Weight must be non-negative');
35System.assert(i.price__c >= 0, 'Price must be non-negative');
36
37// If there is a duplicate Id, it won't get added to a set
38AllItems.add(i.Shipping_Invoice__C);
39}
40
41// Accessing all shipping invoices associated with the items in the trigger
42List<Shipping_Invoice__C> AllShippingInvoices = [SELECT Id, ShippingDiscount__c,
43 SubTotal__c, TotalWeight__c, Tax__c, GrandTotal__c
44 FROM Shipping_Invoice__C WHERE Id IN :AllItems];
45
46// Take the list we just populated and put it into a Map.
47// This will make it easier to look up a shipping invoice
48// because you must iterate a list, but you can use lookup for a map,
49Map<ID, Shipping_Invoice__C> SIMap = new Map<ID, Shipping_Invoice__C>();
50
51for(Shipping_Invoice__C sc : AllShippingInvoices)
52{
53 SIMap.put(sc.id, sc);
54}
55
56// Process the list of items
57 if(Trigger.isUpdate)
58 {
59 // Treat updates like a removal of the old item and addition of the
60 // revised item rather than figuring out the differences of each field
61 // and acting accordingly.
62 // Note updates have both trigger.new and trigger.old
63 for(Integer x = 0; x < Trigger.old.size(); x++)
64 {
65 Shipping_Invoice__C myOrder;
66 myOrder = SIMap.get(trigger.old[x].Shipping_Invoice__C);
67
68 // Decrement the previous value from the subtotal and weight.
69 myOrder.SubTotal__c -= (trigger.old[x].price__c *
70 trigger.old[x].quantity__c);
71 myOrder.TotalWeight__c -= (trigger.old[x].weight__c *
72 trigger.old[x].quantity__c);
73
74 // Increment the new subtotal and weight.
75 myOrder.SubTotal__c += (trigger.new[x].price__c *
76 trigger.new[x].quantity__c);
77 myOrder.TotalWeight__c += (trigger.new[x].weight__c *
78 trigger.new[x].quantity__c);
79 }
80
81 for(Shipping_Invoice__C myOrder : AllShippingInvoices)
82 {
83
84 // Set tax rate to 9.25% Please note, this is a simple example.
85 // Generally, you would never hard code values.
86 // Leveraging Custom Settings for tax rates is a best practice.
87 // See Custom Settings in the Apex Developer Guide
88 // for more information.
89 myOrder.Tax__c = myOrder.Subtotal__c * .0925;
90
91 // Reset the shipping discount
92 myOrder.ShippingDiscount__c = 0;
93
94 // Set shipping rate to 75 cents per pound.
95 // Generally, you would never hard code values.
96 // Leveraging Custom Settings for the shipping rate is a best practice.
97 // See Custom Settings in the Apex Developer Guide
98 // for more information.
99 myOrder.Shipping__c = (myOrder.totalWeight__c * .75);
100 myOrder.GrandTotal__c = myOrder.SubTotal__c + myOrder.tax__c +
101 myOrder.Shipping__c;
102 updateMap.put(myOrder.id, myOrder);
103 }
104 }
105 else
106 {
107 for(Item__c itemToProcess : itemList)
108 {
109 Shipping_Invoice__C myOrder;
110
111 // Look up the correct shipping invoice from the ones we got earlier
112 myOrder = SIMap.get(itemToProcess.Shipping_Invoice__C);
113 myOrder.SubTotal__c += (itemToProcess.price__c *
114 itemToProcess.quantity__c * subtract);
115 myOrder.TotalWeight__c += (itemToProcess.weight__c *
116 itemToProcess.quantity__c * subtract);
117 }
118
119 for(Shipping_Invoice__C myOrder : AllShippingInvoices)
120 {
121
122 // Set tax rate to 9.25% Please note, this is a simple example.
123 // Generally, you would never hard code values.
124 // Leveraging Custom Settings for tax rates is a best practice.
125 // See Custom Settings in the Apex Developer Guide
126 // for more information.
127 myOrder.Tax__c = myOrder.Subtotal__c * .0925;
128
129 // Reset shipping discount
130 myOrder.ShippingDiscount__c = 0;
131
132 // Set shipping rate to 75 cents per pound.
133 // Generally, you would never hard code values.
134 // Leveraging Custom Settings for the shipping rate is a best practice.
135 // See Custom Settings in the Apex Developer Guide
136 // for more information.
137 myOrder.Shipping__c = (myOrder.totalWeight__c * .75);
138 myOrder.GrandTotal__c = myOrder.SubTotal__c + myOrder.tax__c +
139 myOrder.Shipping__c;
140
141 updateMap.put(myOrder.id, myOrder);
142
143 }
144 }
145
146 // Only use one DML update at the end.
147 // This minimizes the number of DML requests generated from this trigger.
148 update updateMap.values();
149}ShippingDiscount トリガ
1trigger ShippingDiscount on Shipping_Invoice__C (before update) {
2 // Free shipping on all orders greater than $100
3
4 for(Shipping_Invoice__C myShippingInvoice : Trigger.new)
5 {
6 if((myShippingInvoice.subtotal__c >= 100.00) &&
7 (myShippingInvoice.ShippingDiscount__c == 0))
8 {
9 myShippingInvoice.ShippingDiscount__c =
10 myShippingInvoice.Shipping__c * -1;
11 myShippingInvoice.GrandTotal__c += myShippingInvoice.ShippingDiscount__c;
12 }
13 }
14}納入先請求書のテスト
1@IsTest
2private class TestShippingInvoice{
3
4 // Test for inserting three items at once
5 public static testmethod void testBulkItemInsert(){
6 // Create the shipping invoice. It's a best practice to either use defaults
7 // or to explicitly set all values to zero so as to avoid having
8 // extraneous data in your test.
9 Shipping_Invoice__C order1 = new Shipping_Invoice__C(subtotal__c = 0,
10 totalweight__c = 0, grandtotal__c = 0,
11 ShippingDiscount__c = 0, Shipping__c = 0, tax__c = 0);
12
13 // Insert the order and populate with items
14 insert Order1;
15 List<Item__c> list1 = new List<Item__c>();
16 Item__c item1 = new Item__C(Price__c = 10, weight__c = 1, quantity__c = 1,
17 Shipping_Invoice__C = order1.id);
18 Item__c item2 = new Item__C(Price__c = 25, weight__c = 2, quantity__c = 1,
19 Shipping_Invoice__C = order1.id);
20 Item__c item3 = new Item__C(Price__c = 40, weight__c = 3, quantity__c = 1,
21 Shipping_Invoice__C = order1.id);
22 list1.add(item1);
23 list1.add(item2);
24 list1.add(item3);
25 insert list1;
26
27 // Retrieve the order, then do assertions
28 order1 = [SELECT id, subtotal__c, tax__c, shipping__c, totalweight__c,
29 grandtotal__c, shippingdiscount__c
30 FROM Shipping_Invoice__C
31 WHERE id = :order1.id];
32
33 System.assert(order1.subtotal__c == 75,
34 'Order subtotal was not $75, but was '+ order1.subtotal__c);
35 System.assert(order1.tax__c == 6.9375,
36 'Order tax was not $6.9375, but was ' + order1.tax__c);
37 System.assert(order1.shipping__c == 4.50,
38 'Order shipping was not $4.50, but was ' + order1.shipping__c);
39 System.assert(order1.totalweight__c == 6.00,
40 'Order weight was not 6 but was ' + order1.totalweight__c);
41 System.assert(order1.grandtotal__c == 86.4375,
42 'Order grand total was not $86.4375 but was '
43 + order1.grandtotal__c);
44 System.assert(order1.shippingdiscount__c == 0,
45 'Order shipping discount was not $0 but was '
46 + order1.shippingdiscount__c);
47 }
48
49 // Test for updating three items at once
50 public static testmethod void testBulkItemUpdate(){
51
52 // Create the shipping invoice. It's a best practice to either use defaults
53 // or to explicitly set all values to zero so as to avoid having
54 // extraneous data in your test.
55 Shipping_Invoice__C order1 = new Shipping_Invoice__C(subtotal__c = 0,
56 totalweight__c = 0, grandtotal__c = 0,
57 ShippingDiscount__c = 0, Shipping__c = 0, tax__c = 0);
58
59 // Insert the order and populate with items.
60 insert Order1;
61 List<Item__c> list1 = new List<Item__c>();
62 Item__c item1 = new Item__C(Price__c = 1, weight__c = 1, quantity__c = 1,
63 Shipping_Invoice__C = order1.id);
64 Item__c item2 = new Item__C(Price__c = 2, weight__c = 2, quantity__c = 1,
65 Shipping_Invoice__C = order1.id);
66 Item__c item3 = new Item__C(Price__c = 4, weight__c = 3, quantity__c = 1,
67 Shipping_Invoice__C = order1.id);
68 list1.add(item1);
69 list1.add(item2);
70 list1.add(item3);
71 insert list1;
72
73 // Update the prices on the 3 items
74 list1[0].price__c = 10;
75 list1[1].price__c = 25;
76 list1[2].price__c = 40;
77 update list1;
78
79 // Access the order and assert items updated
80 order1 = [SELECT id, subtotal__c, tax__c, shipping__c, totalweight__c,
81 grandtotal__c, shippingdiscount__c
82 FROM Shipping_Invoice__C
83 WHERE Id = :order1.Id];
84
85 System.assert(order1.subtotal__c == 75,
86 'Order subtotal was not $75, but was '+ order1.subtotal__c);
87 System.assert(order1.tax__c == 6.9375,
88 'Order tax was not $6.9375, but was ' + order1.tax__c);
89 System.assert(order1.shipping__c == 4.50,
90 'Order shipping was not $4.50, but was '
91 + order1.shipping__c);
92 System.assert(order1.totalweight__c == 6.00,
93 'Order weight was not 6 but was ' + order1.totalweight__c);
94 System.assert(order1.grandtotal__c == 86.4375,
95 'Order grand total was not $86.4375 but was '
96 + order1.grandtotal__c);
97 System.assert(order1.shippingdiscount__c == 0,
98 'Order shipping discount was not $0 but was '
99 + order1.shippingdiscount__c);
100
101 }
102
103 // Test for deleting items
104 public static testmethod void testBulkItemDelete(){
105
106 // Create the shipping invoice. It's a best practice to either use defaults
107 // or to explicitly set all values to zero so as to avoid having
108 // extraneous data in your test.
109 Shipping_Invoice__C order1 = new Shipping_Invoice__C(subtotal__c = 0,
110 totalweight__c = 0, grandtotal__c = 0,
111 ShippingDiscount__c = 0, Shipping__c = 0, tax__c = 0);
112
113 // Insert the order and populate with items
114 insert Order1;
115 List<Item__c> list1 = new List<Item__c>();
116 Item__c item1 = new Item__C(Price__c = 10, weight__c = 1, quantity__c = 1,
117 Shipping_Invoice__C = order1.id);
118 Item__c item2 = new Item__C(Price__c = 25, weight__c = 2, quantity__c = 1,
119 Shipping_Invoice__C = order1.id);
120 Item__c item3 = new Item__C(Price__c = 40, weight__c = 3, quantity__c = 1,
121 Shipping_Invoice__C = order1.id);
122 Item__c itemA = new Item__C(Price__c = 1, weight__c = 3, quantity__c = 1,
123 Shipping_Invoice__C = order1.id);
124 Item__c itemB = new Item__C(Price__c = 1, weight__c = 3, quantity__c = 1,
125 Shipping_Invoice__C = order1.id);
126 Item__c itemC = new Item__C(Price__c = 1, weight__c = 3, quantity__c = 1,
127 Shipping_Invoice__C = order1.id);
128 Item__c itemD = new Item__C(Price__c = 1, weight__c = 3, quantity__c = 1,
129 Shipping_Invoice__C = order1.id);
130 list1.add(item1);
131 list1.add(item2);
132 list1.add(item3);
133 list1.add(itemA);
134 list1.add(itemB);
135 list1.add(itemC);
136 list1.add(itemD);
137 insert list1;
138
139 // Seven items are now in the shipping invoice.
140 // The following deletes four of them.
141 List<Item__c> list2 = new List<Item__c>();
142 list2.add(itemA);
143 list2.add(itemB);
144 list2.add(itemC);
145 list2.add(itemD);
146 delete list2;
147
148 // Retrieve the order and verify the deletion
149 order1 = [SELECT id, subtotal__c, tax__c, shipping__c, totalweight__c,
150 grandtotal__c, shippingdiscount__c
151 FROM Shipping_Invoice__C
152 WHERE Id = :order1.Id];
153
154 System.assert(order1.subtotal__c == 75,
155 'Order subtotal was not $75, but was '+ order1.subtotal__c);
156 System.assert(order1.tax__c == 6.9375,
157 'Order tax was not $6.9375, but was ' + order1.tax__c);
158 System.assert(order1.shipping__c == 4.50,
159 'Order shipping was not $4.50, but was ' + order1.shipping__c);
160 System.assert(order1.totalweight__c == 6.00,
161 'Order weight was not 6 but was ' + order1.totalweight__c);
162 System.assert(order1.grandtotal__c == 86.4375,
163 'Order grand total was not $86.4375 but was '
164 + order1.grandtotal__c);
165 System.assert(order1.shippingdiscount__c == 0,
166 'Order shipping discount was not $0 but was '
167 + order1.shippingdiscount__c);
168 }
169 // Testing free shipping
170 public static testmethod void testFreeShipping(){
171
172 // Create the shipping invoice. It's a best practice to either use defaults
173 // or to explicitly set all values to zero so as to avoid having
174 // extraneous data in your test.
175 Shipping_Invoice__C order1 = new Shipping_Invoice__C(subtotal__c = 0,
176 totalweight__c = 0, grandtotal__c = 0,
177 ShippingDiscount__c = 0, Shipping__c = 0, tax__c = 0);
178
179 // Insert the order and populate with items.
180 insert Order1;
181 List<Item__c> list1 = new List<Item__c>();
182 Item__c item1 = new Item__C(Price__c = 10, weight__c = 1,
183 quantity__c = 1, Shipping_Invoice__C = order1.id);
184 Item__c item2 = new Item__C(Price__c = 25, weight__c = 2,
185 quantity__c = 1, Shipping_Invoice__C = order1.id);
186 Item__c item3 = new Item__C(Price__c = 40, weight__c = 3,
187 quantity__c = 1, Shipping_Invoice__C = order1.id);
188 list1.add(item1);
189 list1.add(item2);
190 list1.add(item3);
191 insert list1;
192
193 // Retrieve the order and verify free shipping not applicable
194 order1 = [SELECT id, subtotal__c, tax__c, shipping__c, totalweight__c,
195 grandtotal__c, shippingdiscount__c
196 FROM Shipping_Invoice__C
197 WHERE Id = :order1.Id];
198
199 // Free shipping not available on $75 orders
200 System.assert(order1.subtotal__c == 75,
201 'Order subtotal was not $75, but was '+ order1.subtotal__c);
202 System.assert(order1.tax__c == 6.9375,
203 'Order tax was not $6.9375, but was ' + order1.tax__c);
204 System.assert(order1.shipping__c == 4.50,
205 'Order shipping was not $4.50, but was ' + order1.shipping__c);
206 System.assert(order1.totalweight__c == 6.00,
207 'Order weight was not 6 but was ' + order1.totalweight__c);
208 System.assert(order1.grandtotal__c == 86.4375,
209 'Order grand total was not $86.4375 but was '
210 + order1.grandtotal__c);
211 System.assert(order1.shippingdiscount__c == 0,
212 'Order shipping discount was not $0 but was '
213 + order1.shippingdiscount__c);
214
215 // Add items to increase subtotal
216 item1 = new Item__C(Price__c = 25, weight__c = 20, quantity__c = 1,
217 Shipping_Invoice__C = order1.id);
218 insert item1;
219
220 // Retrieve the order and verify free shipping is applicable
221 order1 = [SELECT id, subtotal__c, tax__c, shipping__c, totalweight__c,
222 grandtotal__c, shippingdiscount__c
223 FROM Shipping_Invoice__C
224 WHERE Id = :order1.Id];
225
226 // Order total is now at $100, so free shipping should be enabled
227 System.assert(order1.subtotal__c == 100,
228 'Order subtotal was not $100, but was '+ order1.subtotal__c);
229 System.assert(order1.tax__c == 9.25,
230 'Order tax was not $9.25, but was ' + order1.tax__c);
231 System.assert(order1.shipping__c == 19.50,
232 'Order shipping was not $19.50, but was '
233 + order1.shipping__c);
234 System.assert(order1.totalweight__c == 26.00,
235 'Order weight was not 26 but was ' + order1.totalweight__c);
236 System.assert(order1.grandtotal__c == 109.25,
237 'Order grand total was not $86.4375 but was '
238 + order1.grandtotal__c);
239 System.assert(order1.shippingdiscount__c == -19.50,
240 'Order shipping discount was not -$19.50 but was '
241 + order1.shippingdiscount__c);
242 }
243
244 // Negative testing for inserting bad input
245 public static testmethod void testNegativeTests(){
246
247 // Create the shipping invoice. It's a best practice to either use defaults
248 // or to explicitly set all values to zero so as to avoid having
249 // extraneous data in your test.
250 Shipping_Invoice__C order1 = new Shipping_Invoice__C(subtotal__c = 0,
251 totalweight__c = 0, grandtotal__c = 0,
252 ShippingDiscount__c = 0, Shipping__c = 0, tax__c = 0);
253
254 // Insert the order and populate with items.
255 insert Order1;
256 Item__c item1 = new Item__C(Price__c = -10, weight__c = 1, quantity__c = 1,
257 Shipping_Invoice__C = order1.id);
258 Item__c item2 = new Item__C(Price__c = 25, weight__c = -2, quantity__c = 1,
259 Shipping_Invoice__C = order1.id);
260 Item__c item3 = new Item__C(Price__c = 40, weight__c = 3, quantity__c = -1,
261 Shipping_Invoice__C = order1.id);
262 Item__c item4 = new Item__C(Price__c = 40, weight__c = 3, quantity__c = 0,
263 Shipping_Invoice__C = order1.id);
264
265 try{
266 insert item1;
267 }
268 catch(Exception e)
269 {
270 system.assert(e.getMessage().contains('Price must be non-negative'),
271 'Price was negative but was not caught');
272 }
273
274 try{
275 insert item2;
276 }
277 catch(Exception e)
278 {
279 system.assert(e.getMessage().contains('Weight must be non-negative'),
280 'Weight was negative but was not caught');
281 }
282
283 try{
284 insert item3;
285 }
286 catch(Exception e)
287 {
288 system.assert(e.getMessage().contains('Quantity must be positive'),
289 'Quantity was negative but was not caught');
290 }
291
292 try{
293 insert item4;
294 }
295 catch(Exception e)
296 {
297 system.assert(e.getMessage().contains('Quantity must be positive'),
298 'Quantity was zero but was not caught');
299 }
300 }
301}