Complex classes like OrderStep often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OrderStep, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class OrderStep extends DataObject implements EditableEcommerceObject |
||
|
|||
13 | { |
||
14 | <<<<<<< HEAD |
||
15 | function calculateddefertimeinseconds(){ |
||
16 | return $this->DeferTimeInSeconds; |
||
17 | } |
||
18 | ======= |
||
19 | >>>>>>> f490c01eeb47f01d8bc83cd8d7a32172c433e06b |
||
20 | |||
21 | /** |
||
22 | * standard SS variable. |
||
23 | * |
||
24 | * @return array |
||
25 | */ |
||
26 | private static $db = array( |
||
27 | 'Name' => 'Varchar(50)', |
||
28 | 'Code' => 'Varchar(50)', |
||
29 | 'Description' => 'Text', |
||
30 | 'EmailSubject' => 'Varchar(200)', |
||
31 | 'CustomerMessage' => 'HTMLText', |
||
32 | //customer privileges |
||
33 | 'CustomerCanEdit' => 'Boolean', |
||
34 | 'CustomerCanCancel' => 'Boolean', |
||
35 | 'CustomerCanPay' => 'Boolean', |
||
36 | //What to show the customer... |
||
37 | 'ShowAsUncompletedOrder' => 'Boolean', |
||
38 | 'ShowAsInProcessOrder' => 'Boolean', |
||
39 | 'ShowAsCompletedOrder' => 'Boolean', |
||
40 | 'HideStepFromCustomer' => 'Boolean', |
||
41 | //sorting index |
||
42 | 'Sort' => 'Int', |
||
43 | 'DeferTimeInSeconds' => 'Int', |
||
44 | 'DeferFromSubmitTime' => 'Boolean' |
||
45 | ); |
||
46 | |||
47 | |||
48 | |||
49 | /** |
||
50 | * standard SS variable. |
||
51 | * |
||
52 | * @return array |
||
53 | */ |
||
54 | private static $indexes = array( |
||
55 | 'Code' => true, |
||
56 | 'Sort' => true, |
||
57 | ); |
||
58 | |||
59 | /** |
||
60 | * standard SS variable. |
||
61 | * |
||
62 | * @return array |
||
63 | */ |
||
64 | private static $has_many = array( |
||
65 | 'Orders' => 'Order', |
||
66 | 'OrderEmailRecords' => 'OrderEmailRecord', |
||
67 | ); |
||
68 | |||
69 | /** |
||
70 | * standard SS variable. |
||
71 | * |
||
72 | * @return array |
||
73 | */ |
||
74 | private static $field_labels = array( |
||
75 | 'Sort' => 'Sorting Index', |
||
76 | 'CustomerCanEdit' => 'Customer can edit order', |
||
77 | 'CustomerCanPay' => 'Customer can pay order', |
||
78 | 'CustomerCanCancel' => 'Customer can cancel order', |
||
79 | ); |
||
80 | |||
81 | /** |
||
82 | * standard SS variable. |
||
83 | * |
||
84 | * @return array |
||
85 | */ |
||
86 | private static $summary_fields = array( |
||
87 | 'NameAndDescription' => 'Step', |
||
88 | 'ShowAsSummary' => 'Phase', |
||
89 | ); |
||
90 | |||
91 | /** |
||
92 | * standard SS variable. |
||
93 | * |
||
94 | * @return array |
||
95 | */ |
||
96 | private static $casting = array( |
||
97 | 'Title' => 'Varchar', |
||
98 | 'CustomerCanEditNice' => 'Varchar', |
||
99 | 'CustomerCanPayNice' => 'Varchar', |
||
100 | 'CustomerCanCancelNice' => 'Varchar', |
||
101 | 'ShowAsUncompletedOrderNice' => 'Varchar', |
||
102 | 'ShowAsInProcessOrderNice' => 'Varchar', |
||
103 | 'ShowAsCompletedOrderNice' => 'Varchar', |
||
104 | 'HideStepFromCustomerNice' => 'Varchar', |
||
105 | 'HasCustomerMessageNice' => 'Varchar', |
||
106 | 'ShowAsSummary' => 'HTMLText', |
||
107 | 'NameAndDescription' => 'HTMLText' |
||
108 | ); |
||
109 | |||
110 | /** |
||
111 | * standard SS variable. |
||
112 | * |
||
113 | * @return array |
||
114 | */ |
||
115 | private static $searchable_fields = array( |
||
116 | 'Name' => array( |
||
117 | 'title' => 'Name', |
||
118 | 'filter' => 'PartialMatchFilter', |
||
119 | ), |
||
120 | 'Code' => array( |
||
121 | 'title' => 'Code', |
||
122 | 'filter' => 'PartialMatchFilter', |
||
123 | ), |
||
124 | ); |
||
125 | |||
126 | |||
127 | /** |
||
128 | * casted variable. |
||
129 | * |
||
130 | * @return string |
||
131 | */ |
||
132 | public function Title() |
||
133 | { |
||
134 | return $this->getTitle(); |
||
135 | } |
||
136 | public function getTitle() |
||
137 | { |
||
138 | return $this->Name; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * casted variable. |
||
143 | * |
||
144 | * @return string |
||
145 | */ |
||
146 | public function CustomerCanEditNice() |
||
147 | { |
||
148 | return $this->getCustomerCanEditNice(); |
||
149 | } |
||
150 | public function getCustomerCanEditNice() |
||
151 | { |
||
152 | if ($this->CustomerCanEdit) { |
||
153 | return _t('OrderStep.YES', 'Yes'); |
||
154 | } |
||
155 | |||
156 | return _t('OrderStep.NO', 'No'); |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * casted variable. |
||
161 | * |
||
162 | * @return string |
||
163 | */ |
||
164 | public function CustomerCanPayNice() |
||
165 | { |
||
166 | return $this->getCustomerCanPayNice(); |
||
167 | } |
||
168 | public function getCustomerCanPayNice() |
||
169 | { |
||
170 | if ($this->CustomerCanPay) { |
||
171 | return _t('OrderStep.YES', 'Yes'); |
||
172 | } |
||
173 | |||
174 | return _t('OrderStep.NO', 'No'); |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * casted variable. |
||
179 | * |
||
180 | * @return string |
||
181 | */ |
||
182 | public function CustomerCanCancelNice() |
||
183 | { |
||
184 | return $this->getCustomerCanCancelNice(); |
||
185 | } |
||
186 | public function getCustomerCanCancelNice() |
||
187 | { |
||
188 | if ($this->CustomerCanCancel) { |
||
189 | return _t('OrderStep.YES', 'Yes'); |
||
190 | } |
||
191 | |||
192 | return _t('OrderStep.NO', 'No'); |
||
193 | } |
||
194 | |||
195 | public function ShowAsUncompletedOrderNice() |
||
196 | { |
||
197 | return $this->getShowAsUncompletedOrderNice(); |
||
198 | } |
||
199 | public function getShowAsUncompletedOrderNice() |
||
200 | { |
||
201 | if ($this->ShowAsUncompletedOrder) { |
||
202 | return _t('OrderStep.YES', 'Yes'); |
||
203 | } |
||
204 | |||
205 | return _t('OrderStep.NO', 'No'); |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * casted variable. |
||
210 | * |
||
211 | * @return string |
||
212 | */ |
||
213 | public function ShowAsInProcessOrderNice() |
||
214 | { |
||
215 | return $this->getShowAsInProcessOrderNice(); |
||
216 | } |
||
217 | public function getShowAsInProcessOrderNice() |
||
218 | { |
||
219 | if ($this->ShowAsInProcessOrder) { |
||
220 | return _t('OrderStep.YES', 'Yes'); |
||
221 | } |
||
222 | |||
223 | return _t('OrderStep.NO', 'No'); |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * casted variable. |
||
228 | * |
||
229 | * @return string |
||
230 | */ |
||
231 | public function ShowAsCompletedOrderNice() |
||
232 | { |
||
233 | return $this->getShowAsCompletedOrderNice(); |
||
234 | } |
||
235 | public function getShowAsCompletedOrderNice() |
||
236 | { |
||
237 | if ($this->ShowAsCompletedOrder) { |
||
238 | return _t('OrderStep.YES', 'Yes'); |
||
239 | } |
||
240 | |||
241 | return _t('OrderStep.NO', 'No'); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * do not show in steps at all. |
||
246 | * @return boolean |
||
247 | */ |
||
248 | public function HideFromEveryone() |
||
249 | { |
||
250 | return false; |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * casted variable. |
||
255 | * |
||
256 | * @return string |
||
257 | */ |
||
258 | public function HideStepFromCustomerNice() |
||
259 | { |
||
260 | return $this->getHideStepFromCustomerNice(); |
||
261 | } |
||
262 | |||
263 | public function getHideStepFromCustomerNice() |
||
264 | { |
||
265 | if ($this->HideStepFromCustomer) { |
||
266 | return _t('OrderStep.YES', 'Yes'); |
||
267 | } |
||
268 | |||
269 | return _t('OrderStep.NO', 'No'); |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * standard SS variable. |
||
274 | * |
||
275 | * @return string |
||
276 | */ |
||
277 | private static $singular_name = 'Order Step'; |
||
278 | public function i18n_singular_name() |
||
279 | { |
||
280 | return _t('OrderStep.ORDERSTEP', 'Order Step'); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * standard SS variable. |
||
285 | * |
||
286 | * @return string |
||
287 | */ |
||
288 | private static $plural_name = 'Order Steps'; |
||
289 | public function i18n_plural_name() |
||
290 | { |
||
291 | return _t('OrderStep.ORDERSTEPS', 'Order Steps'); |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Standard SS variable. |
||
296 | * |
||
297 | * @var string |
||
298 | */ |
||
299 | private static $description = 'A step that any order goes through.'; |
||
300 | |||
301 | /** |
||
302 | * SUPER IMPORTANT TO KEEP ORDER! |
||
303 | * standard SS variable. |
||
304 | * |
||
305 | * @return string |
||
306 | */ |
||
307 | private static $default_sort = '"Sort" ASC'; |
||
308 | |||
309 | /** |
||
310 | * returns all the order steps |
||
311 | * that the admin should / can edit.... |
||
312 | * |
||
313 | * @return DataList |
||
314 | */ |
||
315 | public static function admin_manageable_steps() |
||
316 | { |
||
317 | $lastStep = OrderStep::get()->Last(); |
||
318 | return OrderStep::get()->filter(array('CustomerCanEdit' => 0))->exclude(array('ID' => $lastStep->ID)); |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * return StatusIDs (orderstep IDs) from orders that are bad.... |
||
323 | * (basically StatusID values that do not exist) |
||
324 | * |
||
325 | * @return array |
||
326 | */ |
||
327 | public static function bad_order_step_ids() |
||
328 | { |
||
329 | $badorderStatus = Order::get() |
||
330 | ->leftJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"') |
||
331 | ->where('"OrderStep"."ID" IS NULL AND "StatusID" > 0') |
||
332 | ->column('StatusID'); |
||
333 | if (is_array($badorderStatus)) { |
||
334 | return array_unique(array_values($badorderStatus)); |
||
335 | } else { |
||
336 | return array(-1); |
||
337 | } |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * turns code into ID. |
||
342 | * |
||
343 | * @param string $code |
||
344 | * @param int |
||
345 | */ |
||
346 | public static function get_status_id_from_code($code) |
||
347 | { |
||
348 | $otherStatus = OrderStep::get() |
||
349 | ->filter(array('Code' => $code)) |
||
350 | ->First(); |
||
351 | if ($otherStatus) { |
||
352 | return $otherStatus->ID; |
||
353 | } |
||
354 | |||
355 | return 0; |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | *@return array |
||
360 | **/ |
||
361 | public static function get_codes_for_order_steps_to_include() |
||
362 | { |
||
363 | $newArray = array(); |
||
364 | $array = EcommerceConfig::get('OrderStep', 'order_steps_to_include'); |
||
365 | if (is_array($array) && count($array)) { |
||
366 | foreach ($array as $className) { |
||
367 | $code = singleton($className)->getMyCode(); |
||
368 | $newArray[$className] = strtoupper($code); |
||
369 | } |
||
370 | } |
||
371 | |||
372 | return $newArray; |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * returns a list of ordersteps that have not been created yet. |
||
377 | * |
||
378 | * @return array |
||
379 | **/ |
||
380 | public static function get_not_created_codes_for_order_steps_to_include() |
||
381 | { |
||
382 | $array = EcommerceConfig::get('OrderStep', 'order_steps_to_include'); |
||
383 | if (is_array($array) && count($array)) { |
||
384 | foreach ($array as $className) { |
||
385 | $obj = $className::get()->First(); |
||
386 | if ($obj) { |
||
387 | unset($array[$className]); |
||
388 | } |
||
389 | } |
||
390 | } |
||
391 | |||
392 | return $array; |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | *@return string |
||
397 | **/ |
||
398 | public function getMyCode() |
||
399 | { |
||
400 | $array = Config::inst()->get($this->ClassName, 'defaults', Config::UNINHERITED); |
||
401 | if (!isset($array['Code'])) { |
||
402 | user_error($this->class.' does not have a default code specified'); |
||
403 | } |
||
404 | |||
405 | return $array['Code']; |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * IMPORTANT:: MUST HAVE Code must be defined!!! |
||
410 | * standard SS variable. |
||
411 | * |
||
412 | * @return array |
||
413 | */ |
||
414 | private static $defaults = array( |
||
415 | 'CustomerCanEdit' => 0, |
||
416 | 'CustomerCanCancel' => 0, |
||
417 | 'CustomerCanPay' => 1, |
||
418 | 'ShowAsUncompletedOrder' => 0, |
||
419 | 'ShowAsInProcessOrder' => 0, |
||
420 | 'ShowAsCompletedOrder' => 0, |
||
421 | 'Code' => 'ORDERSTEP', |
||
422 | ); |
||
423 | |||
424 | /** |
||
425 | * standard SS method. |
||
426 | */ |
||
427 | public function populateDefaults() |
||
428 | { |
||
429 | parent::populateDefaults(); |
||
430 | $this->Description = $this->myDescription(); |
||
431 | } |
||
432 | |||
433 | /** |
||
434 | *@return FieldList |
||
435 | **/ |
||
436 | public function getCMSFields() |
||
437 | { |
||
438 | $fields = parent::getCMSFields(); |
||
439 | //replacing |
||
440 | if ($this->canBeDefered()) { |
||
441 | if ($this->DeferTimeInSeconds) { |
||
442 | $fields->addFieldToTab( |
||
443 | 'Root.Queue', |
||
444 | HeaderField::create( |
||
445 | 'WhenWillThisRun', |
||
446 | $this->humanReadeableDeferTimeInSeconds() |
||
447 | ) |
||
448 | ); |
||
449 | } |
||
450 | $fields->addFieldToTab( |
||
451 | 'Root.Queue', |
||
452 | $deferTimeInSecondsField = TextField::create( |
||
453 | 'DeferTimeInSeconds', |
||
454 | _t('OrderStep.DeferTimeInSeconds', 'Seconds in queue') |
||
455 | ) |
||
456 | ->setRightTitle( |
||
457 | _t( |
||
458 | 'OrderStep.TIME_EXPLANATION', |
||
459 | '86,400 seconds is one day ... |
||
460 | <br />To make it easier, you can also enter things like <em>1 week</em>, <em>3 hours</em>, or <em>7 minutes</em>. |
||
461 | <br />Non-second entries will automatically be converted to seconds.' |
||
462 | ) |
||
463 | ) |
||
464 | ); |
||
465 | if ($this->DeferTimeInSeconds) { |
||
466 | $fields->addFieldToTab( |
||
467 | 'Root.Queue', |
||
468 | $deferTimeInSecondsField = CheckboxField::create( |
||
469 | 'DeferFromSubmitTime', |
||
470 | _t('OrderStep.DeferFromSubmitTime', 'Calculated from submit time?') |
||
471 | ) |
||
472 | ->setDescription( |
||
473 | _t( |
||
474 | 'OrderStep.DeferFromSubmitTime_HELP', |
||
475 | 'The time in the queue can be calculated from the moment the current orderstep starts or from the moment the order was submitted (in this case, check the box above) ' |
||
476 | ) |
||
477 | ) |
||
478 | ); |
||
479 | } |
||
480 | } |
||
481 | if ($this->hasCustomerMessage()) { |
||
482 | $rightTitle = _t( |
||
483 | 'OrderStep.EXPLAIN_ORDER_NUMBER_IN_SUBJECT', |
||
484 | 'You can use [OrderNumber] as a tag that will be replaced with the actual Order Number.' |
||
485 | ); |
||
486 | $fields->addFieldToTab( |
||
487 | 'Root.CustomerMessage', |
||
488 | TextField::create('EmailSubject', _t('OrderStep.EMAILSUBJECT', 'Email Subject')) |
||
489 | ->setRightTitle($rightTitle) |
||
490 | ); |
||
491 | if ($testEmailLink = $this->testEmailLink()) { |
||
492 | $fields->addFieldToTab('Root.CustomerMessage', new LiteralField('testEmailLink', '<h3><a href="'.$testEmailLink.'" data-popup="true" target="_blank">'._t('OrderStep.VIEW_EMAIL_EXAMPLE', 'View email example in browser').'</a></h3>')); |
||
493 | } |
||
494 | |||
495 | $fields->addFieldToTab('Root.CustomerMessage', $htmlEditorField = new HTMLEditorField('CustomerMessage', _t('OrderStep.CUSTOMERMESSAGE', 'Customer Message (if any)'))); |
||
496 | } else { |
||
497 | $fields->removeFieldFromTab('Root', 'OrderEmailRecords'); |
||
498 | $fields->removeFieldFromTab('Root.Main', 'EmailSubject'); |
||
499 | $fields->removeFieldFromTab('Root.Main', 'CustomerMessage'); |
||
500 | } |
||
501 | //adding |
||
502 | if (!$this->exists() || !$this->isDefaultStatusOption()) { |
||
503 | $fields->removeFieldFromTab('Root.Main', 'Code'); |
||
504 | $fields->addFieldToTab('Root.Main', new DropdownField('ClassName', _t('OrderStep.TYPE', 'Type'), self::get_not_created_codes_for_order_steps_to_include()), 'Name'); |
||
505 | } |
||
506 | if ($this->isDefaultStatusOption()) { |
||
507 | $fields->replaceField('Code', $fields->dataFieldByName('Code')->performReadonlyTransformation()); |
||
508 | } |
||
509 | //headers |
||
510 | $fields->addFieldToTab('Root.Main', new HeaderField('WARNING1', _t('OrderStep.CAREFUL', 'CAREFUL! please edit details below with care'), 2), 'Description'); |
||
511 | $fields->addFieldToTab('Root.Main', new HeaderField('WARNING2', _t('OrderStep.CUSTOMERCANCHANGE', 'What can be changed during this step?'), 3), 'CustomerCanEdit'); |
||
512 | $fields->addFieldToTab('Root.Main', new HeaderField('WARNING5', _t('OrderStep.ORDERGROUPS', 'Order groups for customer?'), 3), 'ShowAsUncompletedOrder'); |
||
513 | $fields->addFieldToTab('Root.Main', new HeaderField('HideStepFromCustomerHeader', _t('OrderStep.HIDE_STEP_FROM_CUSTOMER_HEADER', 'Customer Interaction'), 3), 'HideStepFromCustomer'); |
||
514 | //final cleanup |
||
515 | $fields->removeFieldFromTab('Root.Main', 'Sort'); |
||
516 | $fields->addFieldToTab('Root.Main', new TextareaField('Description', _t('OrderStep.DESCRIPTION', 'Explanation for internal use only')), 'WARNING1'); |
||
517 | |||
518 | return $fields; |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * link to edit the record. |
||
523 | * |
||
524 | * @param string | Null $action - e.g. edit |
||
525 | * |
||
526 | * @return string |
||
527 | */ |
||
528 | public function CMSEditLink($action = null) |
||
529 | { |
||
530 | return Controller::join_links( |
||
531 | Director::baseURL(), |
||
532 | '/admin/shop/'.$this->ClassName.'/EditForm/field/'.$this->ClassName.'/item/'.$this->ID.'/', |
||
533 | $action |
||
534 | ); |
||
535 | } |
||
536 | |||
537 | /** |
||
538 | * tells the order to display itself with an alternative display page. |
||
539 | * in that way, orders can be displayed differently for certain steps |
||
540 | * for example, in a print step, the order can be displayed in a |
||
541 | * PRINT ONLY format. |
||
542 | * |
||
543 | * When the method return null, the order is displayed using the standard display page |
||
544 | * |
||
545 | * @see Order::DisplayPage |
||
546 | * |
||
547 | * @return null|object (Page) |
||
548 | **/ |
||
549 | public function AlternativeDisplayPage() |
||
550 | { |
||
551 | return; |
||
552 | } |
||
553 | |||
554 | /** |
||
555 | * Allows the opportunity for the Order Step to add any fields to Order::getCMSFields |
||
556 | * Usually this is added before ActionNextStepManually. |
||
557 | * |
||
558 | * @param FieldList $fields |
||
559 | * @param Order $order |
||
560 | * |
||
561 | * @return FieldList |
||
562 | **/ |
||
563 | public function addOrderStepFields(FieldList $fields, Order $order) |
||
564 | { |
||
565 | return $fields; |
||
566 | } |
||
567 | |||
568 | /** |
||
569 | *@return ValidationResult |
||
570 | **/ |
||
571 | public function validate() |
||
572 | { |
||
573 | $result = parent::validate(); |
||
574 | $anotherOrderStepWithSameNameOrCode = OrderStep::get() |
||
575 | ->filter( |
||
576 | array( |
||
577 | 'Name' => $this->Name, |
||
578 | 'Code' => strtoupper($this->Code), |
||
579 | ) |
||
580 | ) |
||
581 | ->exclude(array('ID' => intval($this->ID))) |
||
582 | ->First(); |
||
583 | if ($anotherOrderStepWithSameNameOrCode) { |
||
584 | $result->error(_t('OrderStep.ORDERSTEPALREADYEXISTS', 'An order status with this name already exists. Please change the name and try again.')); |
||
585 | } |
||
586 | |||
587 | return $result; |
||
588 | } |
||
589 | |||
590 | /************************************************** |
||
591 | * moving between statusses... |
||
592 | **************************************************/ |
||
593 | /** |
||
594 | *initStep: |
||
595 | * makes sure the step is ready to run.... (e.g. check if the order is ready to be emailed as receipt). |
||
596 | * should be able to run this function many times to check if the step is ready. |
||
597 | * |
||
598 | * @see Order::doNextStatus |
||
599 | * |
||
600 | * @param Order object |
||
601 | * |
||
602 | * @return bool - true if the current step is ready to be run... |
||
603 | **/ |
||
604 | public function initStep(Order $order) |
||
605 | { |
||
606 | user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING); |
||
607 | |||
608 | return true; |
||
609 | } |
||
610 | |||
611 | /** |
||
612 | *doStep: |
||
613 | * should only be able to run this function once |
||
614 | * (init stops you from running it twice - in theory....) |
||
615 | * runs the actual step. |
||
616 | * |
||
617 | * @see Order::doNextStatus |
||
618 | * |
||
619 | * @param Order object |
||
620 | * |
||
621 | * @return bool - true if run correctly. |
||
622 | **/ |
||
623 | public function doStep(Order $order) |
||
624 | { |
||
625 | user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING); |
||
626 | |||
627 | return true; |
||
628 | } |
||
629 | |||
630 | /** |
||
631 | * nextStep: |
||
632 | * returns the next step (after it checks if everything is in place for the next step to run...). |
||
633 | * |
||
634 | * @see Order::doNextStatus |
||
635 | * |
||
636 | * @param Order $order |
||
637 | * |
||
638 | * @return OrderStep | Null (next step OrderStep object) |
||
639 | **/ |
||
640 | public function nextStep(Order $order) |
||
641 | { |
||
642 | $nextOrderStepObject = OrderStep::get() |
||
643 | ->filter(array('Sort:GreaterThan' => $this->Sort)) |
||
644 | ->First(); |
||
645 | if ($nextOrderStepObject) { |
||
646 | return $nextOrderStepObject; |
||
647 | } |
||
648 | |||
649 | return; |
||
650 | } |
||
651 | |||
652 | /************************************************** |
||
653 | * Boolean checks |
||
654 | **************************************************/ |
||
655 | |||
656 | /** |
||
657 | * Checks if a step has passed (been completed) in comparison to the current step. |
||
658 | * |
||
659 | * @param string $code: the name of the step to check |
||
660 | * @param bool $orIsEqualTo if set to true, this method will return TRUE if the step being checked is the current one |
||
661 | * |
||
662 | * @return bool |
||
663 | **/ |
||
664 | public function hasPassed($code, $orIsEqualTo = false) |
||
665 | { |
||
666 | $otherStatus = OrderStep::get() |
||
667 | ->filter(array('Code' => $code)) |
||
668 | ->First(); |
||
669 | if ($otherStatus) { |
||
670 | if ($otherStatus->Sort < $this->Sort) { |
||
671 | return true; |
||
672 | } |
||
673 | if ($orIsEqualTo && $otherStatus->Code == $this->Code) { |
||
674 | return true; |
||
675 | } |
||
676 | } else { |
||
677 | user_error("could not find $code in OrderStep", E_USER_NOTICE); |
||
678 | } |
||
679 | |||
680 | return false; |
||
681 | } |
||
682 | |||
683 | /** |
||
684 | * @param string $code |
||
685 | * |
||
686 | * @return bool |
||
687 | **/ |
||
688 | public function hasPassedOrIsEqualTo($code) |
||
689 | { |
||
690 | return $this->hasPassed($code, true); |
||
691 | } |
||
692 | |||
693 | /** |
||
694 | * @param string $code |
||
695 | * |
||
696 | * @return bool |
||
697 | **/ |
||
698 | public function hasNotPassed($code) |
||
699 | { |
||
700 | return (bool) !$this->hasPassed($code, true); |
||
701 | } |
||
702 | |||
703 | /** |
||
704 | * Opposite of hasPassed. |
||
705 | * |
||
706 | * @param string $code |
||
707 | * |
||
708 | * @return bool |
||
709 | **/ |
||
710 | public function isBefore($code) |
||
711 | { |
||
712 | return (bool) $this->hasPassed($code, false) ? false : true; |
||
713 | } |
||
714 | |||
715 | /** |
||
716 | *@return bool |
||
717 | **/ |
||
718 | protected function isDefaultStatusOption() |
||
719 | { |
||
720 | return in_array($this->Code, self::get_codes_for_order_steps_to_include()); |
||
721 | } |
||
722 | |||
723 | /************************************************** |
||
724 | |||
725 | **************************************************/ |
||
726 | |||
727 | /** |
||
728 | * @var string |
||
729 | */ |
||
730 | protected $emailClassName = ''; |
||
731 | |||
732 | /** |
||
733 | * returns the email class used for emailing the |
||
734 | * customer during a specific step (IF ANY!). |
||
735 | * |
||
736 | * @return string |
||
737 | */ |
||
738 | public function getEmailClassName() |
||
739 | { |
||
740 | return $this->emailClassName; |
||
741 | } |
||
742 | |||
743 | /** |
||
744 | * return true if done already or mailed successfully now. |
||
745 | * |
||
746 | * @param order $order |
||
747 | * @param string $subject |
||
748 | * @param string $message |
||
749 | * @param bool $resend |
||
750 | * @param bool | string $adminOnlyOrToEmail you can set to false = send to customer, true: send to admin, or email = send to email |
||
751 | * @param string $emailClassName |
||
752 | * |
||
753 | * @return boolean; |
||
754 | */ |
||
755 | protected function sendEmailForStep( |
||
756 | $order, |
||
757 | $subject, |
||
758 | $message = '', |
||
759 | $resend = false, |
||
760 | $adminOnlyOrToEmail = false, |
||
761 | $emailClassName = '' |
||
762 | ) { |
||
763 | if (!$this->hasBeenSent($order) || $resend) { |
||
764 | if (!$subject) { |
||
765 | $subject = $this->EmailSubject; |
||
766 | } |
||
767 | if (!$emailClassName) { |
||
768 | $emailClassName = $this->getEmailClassName(); |
||
769 | } |
||
770 | $adminOnlyOrToEmailIsEmail = $adminOnlyOrToEmail && filter_var($adminOnlyOrToEmail, FILTER_VALIDATE_EMAIL); |
||
771 | if ($this->hasCustomerMessage() || $adminOnlyOrToEmailIsEmail) { |
||
772 | return $order->sendEmail( |
||
773 | $subject, |
||
774 | $message, |
||
775 | $resend, |
||
776 | $adminOnlyOrToEmail, |
||
777 | $emailClassName |
||
778 | ); |
||
779 | } else { |
||
780 | if (!$emailClassName) { |
||
781 | $emailClassName = 'Order_ErrorEmail'; |
||
782 | } |
||
783 | //looks like we are sending an error, but we are just using this for notification |
||
784 | $message = _t('OrderStep.THISMESSAGENOTSENTTOCUSTOMER', 'NOTE: This message was not sent to the customer.').'<br /><br /><br /><br />'.$message; |
||
785 | $outcome = $order->sendAdminNotification( |
||
786 | $subject, |
||
787 | $message, |
||
788 | $resend, |
||
789 | $emailClassName |
||
790 | ); |
||
791 | } |
||
792 | if ($outcome || Director::isDev()) { |
||
793 | return true; |
||
794 | } |
||
795 | |||
796 | return false; |
||
797 | } |
||
798 | |||
799 | return true; |
||
800 | } |
||
801 | |||
802 | /** |
||
803 | * sets the email class used for emailing the |
||
804 | * customer during a specific step (IF ANY!). |
||
805 | * |
||
806 | * @param string |
||
807 | */ |
||
808 | public function setEmailClassName($s) |
||
809 | { |
||
810 | $this->emailClassName = $s; |
||
811 | } |
||
812 | |||
813 | /** |
||
814 | * returns a link that can be used to test |
||
815 | * the email being sent during this step |
||
816 | * this method returns NULL if no email |
||
817 | * is being sent OR if there is no suitable Order |
||
818 | * to test with... |
||
819 | * |
||
820 | * @return string |
||
821 | */ |
||
822 | protected function testEmailLink() |
||
823 | { |
||
824 | if ($this->getEmailClassName()) { |
||
825 | $orders = Order::get() |
||
826 | ->where('"OrderStep"."Sort" >= '.$this->Sort) |
||
827 | ->sort('IF("OrderStep"."Sort" > '.$this->Sort.', 0, 1) ASC, "OrderStep"."Sort" ASC, RAND() ASC') |
||
828 | ->innerJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"'); |
||
829 | if ($orders->count()) { |
||
830 | if ($order = $orders->First()) { |
||
831 | return OrderConfirmationPage::get_email_link($order->ID, $this->getEmailClassName(), $actuallySendEmail = false, $alternativeOrderStepID = $this->ID); |
||
832 | } |
||
833 | } |
||
834 | } |
||
835 | } |
||
836 | |||
837 | /** |
||
838 | * Has an email been sent to the customer for this |
||
839 | * order step. |
||
840 | *"-10 days". |
||
841 | * |
||
842 | * @param Order $order |
||
843 | * @param bool $checkDateOfOrder |
||
844 | * |
||
845 | * @return bool |
||
846 | **/ |
||
847 | public function hasBeenSent(Order $order, $checkDateOfOrder = true) |
||
848 | { |
||
849 | //if it has been more than a XXX days since the order was last edited (submitted) then we do not send emails as |
||
850 | //this would be embarrasing. |
||
851 | if ($checkDateOfOrder) { |
||
852 | if ($log = $order->SubmissionLog()) { |
||
853 | $lastEditedValue = $log->LastEdited; |
||
854 | } else { |
||
855 | $lastEditedValue = $order->LastEdited; |
||
856 | } |
||
857 | if ((strtotime($lastEditedValue) < strtotime('-'.EcommerceConfig::get('OrderStep', 'number_of_days_to_send_update_email').' days'))) { |
||
858 | return true; |
||
859 | } |
||
860 | } |
||
861 | $count = OrderEmailRecord::get() |
||
862 | ->Filter(array( |
||
863 | 'OrderID' => $order->ID, |
||
864 | 'OrderStepID' => $this->ID, |
||
865 | 'Result' => 1, |
||
866 | )) |
||
867 | ->count(); |
||
868 | |||
869 | return $count ? true : false; |
||
870 | } |
||
871 | |||
872 | /** |
||
873 | * For some ordersteps this returns true... |
||
874 | * |
||
875 | * @return bool |
||
876 | **/ |
||
877 | protected function hasCustomerMessage() |
||
878 | { |
||
879 | return false; |
||
880 | } |
||
881 | |||
882 | |||
883 | /** |
||
884 | * Formatted answer for "hasCustomerMessage". |
||
885 | * |
||
886 | * @return string |
||
887 | */ |
||
888 | public function HasCustomerMessageNice() |
||
889 | { |
||
890 | return $this->getHasCustomerMessageNice(); |
||
891 | } |
||
892 | public function getHasCustomerMessageNice() |
||
893 | { |
||
894 | return $this->hasCustomerMessage() ? _t('OrderStep.YES', 'Yes') : _t('OrderStep.NO', 'No'); |
||
895 | } |
||
896 | |||
897 | /** |
||
898 | * Formatted answer for "hasCustomerMessage". |
||
899 | * |
||
900 | * @return string |
||
901 | */ |
||
902 | public function ShowAsSummary() |
||
903 | { |
||
904 | return $this->getShowAsSummary(); |
||
905 | } |
||
906 | |||
907 | /** |
||
908 | * |
||
909 | * |
||
910 | * @return string |
||
911 | */ |
||
912 | public function getShowAsSummary() |
||
913 | { |
||
914 | $v = '<strong>'; |
||
915 | if ($this->ShowAsUncompletedOrder) { |
||
916 | $v .= _t('OrderStep.UNCOMPLETED', 'Uncompleted'); |
||
917 | } elseif ($this->ShowAsInProcessOrder) { |
||
918 | $v .= _t('OrderStep.INPROCESS', 'In process'); |
||
919 | } elseif ($this->ShowAsCompletedOrder) { |
||
920 | $v .= _t('OrderStep.COMPLETED', 'Completed'); |
||
921 | } |
||
922 | $v .= '</strong>'; |
||
923 | $canArray = array(); |
||
924 | if ($this->CustomerCanEdit) { |
||
925 | $canArray[] = _t('OrderStep.EDITABLE', 'edit'); |
||
926 | } |
||
927 | if ($this->CustomerCanPay) { |
||
928 | $canArray[] = _t('OrderStep.PAY', 'pay'); |
||
929 | } |
||
930 | if ($this->CustomerCanCancel) { |
||
931 | $canArray[] = _t('OrderStep.CANCEL', 'cancel'); |
||
932 | } |
||
933 | if (count($canArray)) { |
||
934 | $v .= '<br />'._t('OrderStep.CUSTOMER_CAN', 'Customer Can').': '.implode(', ', $canArray).''; |
||
935 | } |
||
936 | if ($this->hasCustomerMessage()) { |
||
937 | $v .= '<br />'._t('OrderStep.CUSTOMER_MESSAGES', 'Includes message to customer'); |
||
938 | } |
||
939 | if ($this->DeferTimeInSeconds) { |
||
940 | $v .= '<br />'.$this->humanReadeableDeferTimeInSeconds(); |
||
941 | } |
||
942 | |||
943 | return DBField::create_field('HTMLText', $v); |
||
944 | } |
||
945 | |||
946 | /** |
||
947 | * @return string |
||
948 | */ |
||
949 | protected function humanReadeableDeferTimeInSeconds() |
||
950 | { |
||
951 | if ($this->canBeDefered()) { |
||
952 | $field = DBField::create_field('SS_DateTime', strtotime('+ '.$this->DeferTimeInSeconds.' seconds')); |
||
953 | $descr0 = _t('OrderStep.THE', 'The').' '.'<span style="color: #338DC1">'.$this->getTitle().'</span>'; |
||
954 | $descr1 = _t('OrderStep.DELAY_VALUE', 'Order Step, for any order, will run'); |
||
955 | $descr2 = $field->ago(); |
||
956 | $descr3 = $this->DeferFromSubmitTime ? |
||
957 | _t('OrderStep.FROM_ORDER_SUBMIT_TIME', 'from the order being submitted') : |
||
958 | _t('OrderStep.FROM_START_OF_ORDSTEP', 'from the order arriving on this step'); |
||
959 | return $descr0. ' ' . $descr1.' <span style="color: #338DC1">'.$descr2.'</span> '.$descr3.'.'; |
||
960 | } |
||
961 | // $dtF = new \DateTime('@0'); |
||
962 | // $dtT = new \DateTime("@".$this->DeferTimeInSeconds); |
||
963 | // |
||
964 | // return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds'); |
||
965 | } |
||
966 | |||
967 | /** |
||
968 | * Formatted answer for "hasCustomerMessage". |
||
969 | * |
||
970 | * @return string |
||
971 | */ |
||
972 | public function NameAndDescription() |
||
973 | { |
||
974 | return $this->getNameAndDescription(); |
||
975 | } |
||
976 | |||
977 | public function getNameAndDescription() |
||
978 | { |
||
979 | $v = '<strong>'.$this->Name.'</strong><br /><em>'.$this->Description.'</em>'; |
||
980 | |||
981 | return DBField::create_field('HTMLText', $v); |
||
982 | } |
||
983 | |||
984 | /** |
||
985 | * This allows you to set the time to something other than the standard DeferTimeInSeconds |
||
986 | * value based on the order provided. |
||
987 | * |
||
988 | * @param Order |
||
989 | * |
||
990 | * @return int |
||
991 | */ |
||
992 | public function CalculatedDeferTimeInSeconds($order) |
||
993 | { |
||
994 | return $this->DeferTimeInSeconds; |
||
995 | } |
||
996 | |||
997 | /** |
||
998 | * can this order step be delayed? |
||
999 | * in general, if there is a customer message |
||
1000 | * we should be able to delay it |
||
1001 | * |
||
1002 | * This method can be overridden in any orderstep |
||
1003 | * @return bool |
||
1004 | **/ |
||
1005 | protected function canBeDefered() |
||
1006 | { |
||
1007 | return $this->hasCustomerMessage(); |
||
1008 | } |
||
1009 | |||
1010 | |||
1011 | /************************************************** |
||
1012 | * Order Status Logs |
||
1013 | **************************************************/ |
||
1014 | |||
1015 | /** |
||
1016 | * The OrderStatusLog that is relevant to the particular step. |
||
1017 | * |
||
1018 | * @var string |
||
1019 | */ |
||
1020 | protected $relevantLogEntryClassName = ''; |
||
1021 | |||
1022 | /** |
||
1023 | * @return string |
||
1024 | */ |
||
1025 | public function getRelevantLogEntryClassName() |
||
1026 | { |
||
1027 | return $this->relevantLogEntryClassName; |
||
1028 | } |
||
1029 | |||
1030 | /** |
||
1031 | * @param string |
||
1032 | */ |
||
1033 | public function setRelevantLogEntryClassName($s) |
||
1034 | { |
||
1035 | $this->relevantLogEntryClassName = $s; |
||
1036 | } |
||
1037 | |||
1038 | /** |
||
1039 | * returns the OrderStatusLog that is relevant to this step. |
||
1040 | * |
||
1041 | * @param Order $order |
||
1042 | * |
||
1043 | * @return OrderStatusLog | null |
||
1044 | */ |
||
1045 | public function RelevantLogEntry(Order $order) |
||
1046 | { |
||
1047 | if ($className = $this->getRelevantLogEntryClassName()) { |
||
1048 | return $this->RelevantLogEntries($order)->Last(); |
||
1049 | } |
||
1050 | } |
||
1051 | |||
1052 | /** |
||
1053 | * returns the OrderStatusLogs that are relevant to this step. |
||
1054 | * |
||
1055 | * @param Order $order |
||
1056 | * |
||
1057 | * @return DataObjectSet | null |
||
1058 | */ |
||
1059 | public function RelevantLogEntries(Order $order) |
||
1060 | { |
||
1061 | if ($className = $this->getRelevantLogEntryClassName()) { |
||
1062 | return $className::get()->filter(array('OrderID' => $order->ID)); |
||
1063 | } |
||
1064 | } |
||
1065 | |||
1066 | /************************************************** |
||
1067 | * Silverstripe Standard Data Object Methods |
||
1068 | **************************************************/ |
||
1069 | |||
1070 | /** |
||
1071 | * Standard SS method |
||
1072 | * These are only created programmatically. |
||
1073 | * |
||
1074 | * @param Member $member |
||
1075 | * |
||
1076 | * @return bool |
||
1077 | */ |
||
1078 | public function canCreate($member = null) |
||
1079 | { |
||
1080 | return false; |
||
1081 | } |
||
1082 | |||
1083 | /** |
||
1084 | * Standard SS method. |
||
1085 | * |
||
1086 | * @param Member $member |
||
1087 | * |
||
1088 | * @return bool |
||
1089 | */ |
||
1090 | public function canView($member = null) |
||
1091 | { |
||
1092 | if (! $member) { |
||
1093 | $member = Member::currentUser(); |
||
1094 | } |
||
1095 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
1096 | if ($extended !== null) { |
||
1097 | return $extended; |
||
1098 | } |
||
1099 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
1100 | return true; |
||
1101 | } |
||
1102 | |||
1103 | return parent::canEdit($member); |
||
1104 | } |
||
1105 | |||
1106 | /** |
||
1107 | * the default for this is TRUE, but for completed order steps |
||
1108 | * |
||
1109 | * we do not allow this. |
||
1110 | * |
||
1111 | * @param Order $order |
||
1112 | * @param Member $member optional |
||
1113 | * @return bool |
||
1114 | */ |
||
1115 | public function canOverrideCanViewForOrder($order, $member = null) |
||
1116 | { |
||
1117 | //return true if the order can have customer input |
||
1118 | // orders recently saved can also be views |
||
1119 | return |
||
1120 | $this->CustomerCanEdit || |
||
1121 | $this->CustomerCanCancel || |
||
1122 | $this->CustomerCanPay; |
||
1123 | } |
||
1124 | |||
1125 | /** |
||
1126 | * standard SS method. |
||
1127 | * |
||
1128 | * @param Member | NULL |
||
1129 | * |
||
1130 | * @return bool |
||
1131 | */ |
||
1132 | public function canEdit($member = null) |
||
1133 | { |
||
1134 | if (! $member) { |
||
1135 | $member = Member::currentUser(); |
||
1136 | } |
||
1137 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
1138 | if ($extended !== null) { |
||
1139 | return $extended; |
||
1140 | } |
||
1141 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
1142 | return true; |
||
1143 | } |
||
1144 | |||
1145 | return parent::canEdit($member); |
||
1146 | } |
||
1147 | |||
1148 | /** |
||
1149 | * Standard SS method. |
||
1150 | * |
||
1151 | * @param Member $member |
||
1152 | * |
||
1153 | * @return bool |
||
1154 | */ |
||
1155 | public function canDelete($member = null) |
||
1156 | { |
||
1157 | //cant delete last status if there are orders with this status |
||
1158 | $nextOrderStepObject = $this->NextOrderStep(); |
||
1159 | if ($nextOrderStepObject) { |
||
1160 | //do nothing |
||
1161 | } else { |
||
1162 | $orderCount = Order::get() |
||
1163 | ->filter(array('StatusID' => intval($this->ID) - 0)) |
||
1164 | ->count(); |
||
1165 | if ($orderCount) { |
||
1166 | return false; |
||
1167 | } |
||
1168 | } |
||
1169 | if ($this->isDefaultStatusOption()) { |
||
1170 | return false; |
||
1171 | } |
||
1172 | if (! $member) { |
||
1173 | $member = Member::currentUser(); |
||
1174 | } |
||
1175 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
1176 | if ($extended !== null) { |
||
1177 | return $extended; |
||
1178 | } |
||
1179 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
1180 | return true; |
||
1181 | } |
||
1182 | |||
1183 | return parent::canEdit($member); |
||
1184 | } |
||
1185 | |||
1186 | /** |
||
1187 | * standard SS method. |
||
1188 | */ |
||
1189 | public function onBeforeWrite() |
||
1190 | { |
||
1191 | parent::onBeforeWrite(); |
||
1192 | //make sure only one of three conditions applies ... |
||
1193 | if ($this->ShowAsUncompletedOrder) { |
||
1194 | $this->ShowAsInProcessOrder = false; |
||
1195 | $this->ShowAsCompletedOrder = false; |
||
1196 | } elseif ($this->ShowAsInProcessOrder) { |
||
1197 | $this->ShowAsUncompletedOrder = false; |
||
1198 | $this->ShowAsCompletedOrder = false; |
||
1199 | } elseif ($this->ShowAsCompletedOrder) { |
||
1200 | $this->ShowAsUncompletedOrder = false; |
||
1201 | $this->ShowAsInProcessOrder = false; |
||
1202 | } |
||
1203 | if (! $this->canBeDefered()) { |
||
1204 | $this->DeferTimeInSeconds = 0; |
||
1205 | $this->DeferFromSubmitTime = 0; |
||
1206 | } else { |
||
1207 | if (is_numeric($this->DeferTimeInSeconds)) { |
||
1208 | $this->DeferTimeInSeconds = intval($this->DeferTimeInSeconds); |
||
1209 | } else { |
||
1210 | $this->DeferTimeInSeconds = strtotime('+'.$this->DeferTimeInSeconds); |
||
1211 | if ($this->DeferTimeInSeconds > 0) { |
||
1212 | $this->DeferTimeInSeconds = $this->DeferTimeInSeconds - time(); |
||
1213 | } |
||
1214 | } |
||
1215 | } |
||
1216 | $this->Code = strtoupper($this->Code); |
||
1217 | } |
||
1218 | |||
1219 | /** |
||
1220 | * move linked orders to the next status |
||
1221 | * standard SS method. |
||
1222 | */ |
||
1223 | public function onBeforeDelete() |
||
1224 | { |
||
1225 | parent::onBeforeDelete(); |
||
1226 | $previousOrderStepObject = null; |
||
1227 | $nextOrderStepObject = $this->NextOrderStep(); |
||
1228 | //backup |
||
1229 | if ($nextOrderStepObject) { |
||
1230 | //do nothing |
||
1231 | } else { |
||
1232 | $previousOrderStepObject = $this->PreviousOrderStep(); |
||
1233 | } |
||
1234 | if ($previousOrderStepObject) { |
||
1235 | $ordersWithThisStatus = Order::get()->filter(array('StatusID' => $this->ID)); |
||
1236 | if ($ordersWithThisStatus && $ordersWithThisStatus->count()) { |
||
1237 | foreach ($ordersWithThisStatus as $orderWithThisStatus) { |
||
1238 | $orderWithThisStatus->StatusID = $previousOrderStepObject->ID; |
||
1239 | $orderWithThisStatus->write(); |
||
1240 | } |
||
1241 | } |
||
1242 | } |
||
1243 | } |
||
1244 | |||
1245 | /** |
||
1246 | * standard SS method. |
||
1247 | */ |
||
1248 | public function onAfterDelete() |
||
1249 | { |
||
1250 | parent::onAfterDelete(); |
||
1251 | $this->requireDefaultRecords(); |
||
1252 | } |
||
1253 | |||
1254 | protected function NextOrderStep() |
||
1255 | { |
||
1256 | return OrderStep::get() |
||
1257 | ->filter(array('Sort:GreaterThan' => $this->Sort)) |
||
1258 | ->First(); |
||
1259 | } |
||
1260 | |||
1261 | protected function PreviousOrderStep() |
||
1262 | { |
||
1263 | return OrderStep::get() |
||
1264 | ->filter(array('Sort:LessThan' => $this->Sort)) |
||
1265 | ->First(); |
||
1266 | } |
||
1267 | |||
1268 | /** |
||
1269 | * standard SS method |
||
1270 | * USED TO BE: Unpaid,Query,Paid,Processing,Sent,Complete,AdminCancelled,MemberCancelled,Cart. |
||
1271 | */ |
||
1272 | public function requireDefaultRecords() |
||
1273 | { |
||
1274 | parent::requireDefaultRecords(); |
||
1275 | $orderStepsToInclude = EcommerceConfig::get('OrderStep', 'order_steps_to_include'); |
||
1276 | $codesToInclude = self::get_codes_for_order_steps_to_include(); |
||
1277 | $indexNumber = 0; |
||
1278 | if ($orderStepsToInclude && count($orderStepsToInclude)) { |
||
1279 | if ($codesToInclude && count($codesToInclude)) { |
||
1280 | foreach ($codesToInclude as $className => $code) { |
||
1281 | $code = strtoupper($code); |
||
1282 | $filter = array('ClassName' => $className); |
||
1283 | $indexNumber += 10; |
||
1284 | $itemCount = OrderStep::get()->filter($filter)->Count(); |
||
1285 | if ($itemCount) { |
||
1286 | $obj = OrderStep::get()->filter($filter)->First(); |
||
1287 | if ($obj->Code != $code) { |
||
1288 | $obj->Code = $code; |
||
1289 | $obj->write(); |
||
1290 | } |
||
1291 | $parentObj = singleton('OrderStep'); |
||
1292 | if ($obj->Description == $parentObj->myDescription()) { |
||
1293 | $obj->Description = $obj->myDescription(); |
||
1294 | $obj->write(); |
||
1295 | } |
||
1296 | } else { |
||
1297 | $obj = $className::create(); |
||
1298 | $obj->Code = $code; |
||
1299 | $obj->Description = $obj->myDescription(); |
||
1300 | $obj->write(); |
||
1301 | DB::alteration_message("Created \"$code\" as $className.", 'created'); |
||
1302 | } |
||
1303 | $obj = OrderStep::get() |
||
1304 | ->filter(array('Code' => strtoupper($code))) |
||
1305 | ->First(); |
||
1306 | if ($obj) { |
||
1307 | if ($obj->Sort != $indexNumber) { |
||
1308 | $obj->Sort = $indexNumber; |
||
1309 | $obj->write(); |
||
1310 | } |
||
1311 | } else { |
||
1312 | user_error("There was an error in creating the $code OrderStep"); |
||
1313 | } |
||
1314 | } |
||
1315 | } |
||
1316 | } |
||
1317 | $steps = OrderStep::get(); |
||
1318 | foreach ($steps as $step) { |
||
1319 | if (!$step->Description) { |
||
1320 | $step->Description = $step->myDescription(); |
||
1321 | $step->write(); |
||
1322 | } |
||
1323 | } |
||
1324 | } |
||
1325 | |||
1326 | /** |
||
1327 | * returns the standard EcommerceDBConfig for use within OrderSteps. |
||
1328 | * |
||
1329 | * @return EcommerceDBConfig |
||
1330 | */ |
||
1331 | protected function EcomConfig() |
||
1332 | { |
||
1333 | return EcommerceDBConfig::current_ecommerce_db_config(); |
||
1334 | } |
||
1335 | |||
1336 | /** |
||
1337 | * Explains the current order step. |
||
1338 | * |
||
1339 | * @return string |
||
1346 |