Commit | Line | Data |
---|---|---|
7aa78908 | 1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | Copyright CiviCRM LLC. All rights reserved. | | |
5 | | | | |
6 | | This work is published under the GNU AGPLv3 license with some | | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
9 | +--------------------------------------------------------------------+ | |
10 | */ | |
11 | ||
4df23f2a | 12 | use Civi\Api4\LineItem; |
58315149 | 13 | use Civi\Api4\PriceField; |
60e5cf34 | 14 | use Civi\Api4\PriceFieldValue; |
812b2c0c | 15 | use Civi\Api4\PriceSet; |
58315149 | 16 | |
7aa78908 | 17 | /** |
18 | * | |
19 | * @package CRM | |
20 | * @copyright CiviCRM LLC https://civicrm.org/licensing | |
20df462f | 21 | * |
7aa78908 | 22 | * Order class. |
23 | * | |
24 | * This class is intended to become the object to manage orders, including via Order.api. | |
25 | * | |
26 | * As of writing it is in the process of having appropriate functions built up. | |
20df462f | 27 | * It should **NOT** be accessed directly outside of tested core methods as it |
28 | * may change. | |
812b2c0c EM |
29 | * |
30 | * @internal | |
7aa78908 | 31 | */ |
32 | class CRM_Financial_BAO_Order { | |
33 | ||
34 | /** | |
35 | * Price set id. | |
36 | * | |
37 | * @var int | |
38 | */ | |
39 | protected $priceSetID; | |
40 | ||
41 | /** | |
42 | * Selected price items in the format we see in forms. | |
43 | * | |
44 | * ie. | |
45 | * [price_3 => 4, price_10 => 7] | |
46 | * is equivalent to 'option_value 4 for radio price field 3 and | |
47 | * a quantity of 7 for text price field 10. | |
48 | * | |
49 | * @var array | |
50 | */ | |
51 | protected $priceSelection = []; | |
52 | ||
53 | /** | |
54 | * Override for financial type id. | |
55 | * | |
56 | * Used when the financial type id is to be overridden for all line items | |
57 | * (as can happen in backoffice forms) | |
58 | * | |
59 | * @var int | |
60 | */ | |
61 | protected $overrideFinancialTypeID; | |
62 | ||
4df23f2a EM |
63 | /** |
64 | * Overridable financial type id. | |
65 | * | |
66 | * When this is set only this financial type will be overridden. | |
67 | * | |
68 | * This is relevant to repeat transactions where we want to | |
69 | * override the type on the line items if it a different financial type has | |
70 | * been saved against the recurring contribution. However, it the line item | |
71 | * financial type differs from the contribution financial type then we | |
72 | * treat this as deliberately uncoupled and don't flow through changes | |
73 | * in financial type down to the line items. | |
74 | * | |
75 | * This is covered in testRepeatTransactionUpdatedFinancialTypeAndNotEquals. | |
76 | * | |
77 | * @var int | |
78 | */ | |
79 | protected $overridableFinancialTypeID; | |
80 | ||
81 | /** | |
82 | * Get overridable financial type id. | |
83 | * | |
84 | * If only one financial type id can be overridden at the line item level | |
85 | * then get it here, otherwise NULL. | |
86 | * | |
87 | * @return int|null | |
88 | */ | |
89 | public function getOverridableFinancialTypeID(): ?int { | |
90 | return $this->overridableFinancialTypeID; | |
91 | } | |
92 | ||
93 | /** | |
94 | * Set overridable financial type id. | |
95 | * | |
96 | * If only one financial type id can be overridden at the line item level | |
97 | * then set it here. | |
98 | * | |
99 | * @param int|null $overridableFinancialTypeID | |
100 | */ | |
101 | public function setOverridableFinancialTypeID(?int $overridableFinancialTypeID): void { | |
102 | $this->overridableFinancialTypeID = $overridableFinancialTypeID; | |
103 | } | |
104 | ||
ca44bb7e EM |
105 | /** |
106 | * Financial type id to use for any lines where is is not provided. | |
107 | * | |
108 | * @var int | |
109 | */ | |
110 | protected $defaultFinancialTypeID; | |
111 | ||
4df23f2a EM |
112 | /** |
113 | * ID of a contribution to be used as a template. | |
114 | * | |
115 | * @var int | |
116 | */ | |
117 | protected $templateContributionID; | |
118 | ||
119 | /** | |
120 | * Should we permit the line item financial type to be overridden when there is more than one line. | |
121 | * | |
122 | * Historically the answer is 'yes' for v3 order api and 'no' for repeattransaction | |
123 | * and backoffice forms. | |
124 | * | |
125 | * @var bool | |
126 | */ | |
e5e212b5 | 127 | protected $isPermitOverrideFinancialTypeForMultipleLines = FALSE; |
4df23f2a EM |
128 | |
129 | /** | |
130 | * @return bool | |
131 | */ | |
132 | public function isPermitOverrideFinancialTypeForMultipleLines(): bool { | |
133 | return $this->isPermitOverrideFinancialTypeForMultipleLines; | |
134 | } | |
135 | ||
136 | /** | |
137 | * @param bool $isPermitOverrideFinancialTypeForMultipleLines | |
138 | */ | |
139 | public function setIsPermitOverrideFinancialTypeForMultipleLines(bool $isPermitOverrideFinancialTypeForMultipleLines): void { | |
140 | $this->isPermitOverrideFinancialTypeForMultipleLines = $isPermitOverrideFinancialTypeForMultipleLines; | |
141 | } | |
142 | ||
143 | /** | |
144 | * Number of line items. | |
145 | * | |
146 | * @var int | |
147 | */ | |
148 | protected $lineItemCount; | |
149 | ||
150 | /** | |
151 | * @return int | |
152 | */ | |
153 | public function getLineItemCount(): int { | |
154 | if (!isset($this->lineItemCount)) { | |
155 | $this->lineItemCount = count($this->getPriceOptions()) || count($this->lineItems); | |
156 | } | |
157 | return $this->lineItemCount; | |
158 | } | |
159 | ||
160 | /** | |
161 | * @param int $lineItemCount | |
162 | */ | |
163 | public function setLineItemCount(int $lineItemCount): void { | |
164 | $this->lineItemCount = $lineItemCount; | |
165 | } | |
166 | ||
167 | /** | |
168 | * @return int|null | |
169 | */ | |
170 | public function getTemplateContributionID(): ?int { | |
171 | return $this->templateContributionID; | |
172 | } | |
173 | ||
174 | /** | |
175 | * @param int $templateContributionID | |
176 | */ | |
177 | public function setTemplateContributionID(int $templateContributionID): void { | |
178 | $this->templateContributionID = $templateContributionID; | |
179 | } | |
180 | ||
ca44bb7e EM |
181 | /** |
182 | * @return int | |
183 | */ | |
184 | public function getDefaultFinancialTypeID(): int { | |
185 | return $this->defaultFinancialTypeID; | |
186 | } | |
187 | ||
188 | /** | |
189 | * Set the default financial type id to be used when the line has none. | |
190 | * | |
191 | * @param int|null $defaultFinancialTypeID | |
192 | */ | |
193 | public function setDefaultFinancialTypeID(?int $defaultFinancialTypeID): void { | |
194 | $this->defaultFinancialTypeID = $defaultFinancialTypeID; | |
195 | } | |
196 | ||
7aa78908 | 197 | /** |
198 | * Override for the total amount of the order. | |
199 | * | |
200 | * When there is a single line item the order total may be overriden. | |
201 | * | |
202 | * @var float | |
203 | */ | |
204 | protected $overrideTotalAmount; | |
205 | ||
206 | /** | |
207 | * Line items in the order. | |
208 | * | |
209 | * @var array | |
210 | */ | |
211 | protected $lineItems = []; | |
212 | ||
ca1b238b EM |
213 | /** |
214 | * Array of entities ordered. | |
215 | * | |
216 | * @var array | |
217 | */ | |
218 | protected $entityParameters = []; | |
219 | ||
220 | /** | |
221 | * Default price sets for component. | |
222 | * | |
223 | * @var array | |
224 | */ | |
225 | protected $defaultPriceSets = []; | |
226 | ||
227 | /** | |
228 | * Cache of the default price field. | |
229 | * | |
230 | * @var array | |
231 | */ | |
232 | protected $defaultPriceField; | |
233 | ||
60e5cf34 EM |
234 | /** |
235 | * Cache of the default price field value ID. | |
236 | * | |
237 | * @var array | |
238 | */ | |
239 | protected $defaultPriceFieldValueID; | |
240 | ||
ca1b238b EM |
241 | /** |
242 | * Get parameters for the entities bought as part of this order. | |
243 | * | |
244 | * @return array | |
245 | * | |
246 | * @internal core tested code only. | |
247 | * | |
248 | */ | |
249 | public function getEntitiesToCreate(): array { | |
250 | $entities = []; | |
251 | foreach ($this->entityParameters as $entityToCreate) { | |
252 | if (in_array($entityToCreate['entity'], ['participant', 'membership'], TRUE)) { | |
253 | $entities[] = $entityToCreate; | |
254 | } | |
255 | } | |
256 | return $entities; | |
257 | } | |
258 | ||
259 | /** | |
260 | * Set parameters for the entities bought as part of this order. | |
261 | * | |
262 | * @param array $entityParameters | |
263 | * @param int|string $key indexing reference | |
264 | * | |
265 | * @internal core tested code only. | |
266 | * | |
267 | */ | |
268 | public function setEntityParameters(array $entityParameters, $key): void { | |
269 | $this->entityParameters[$key] = $entityParameters; | |
270 | } | |
271 | ||
272 | /** | |
273 | * Add a line item to an entity. | |
274 | * | |
275 | * The v3 api supports more than on line item being stored against a given | |
276 | * set of entity parameters. There is some doubt as to whether this is a | |
277 | * good thing that should be supported in v4 or something that 'seemed | |
278 | * like a good idea at the time' - but this allows the lines to be added from the | |
279 | * v3 api. | |
280 | * | |
281 | * @param string $lineIndex | |
282 | * @param string $entityKey | |
283 | */ | |
284 | public function addLineItemToEntityParameters(string $lineIndex, string $entityKey): void { | |
285 | $this->entityParameters[$entityKey]['entity'] = $this->getLineItemEntity($lineIndex); | |
286 | $this->entityParameters[$entityKey]['line_references'][] = $lineIndex; | |
287 | } | |
288 | ||
7aa78908 | 289 | /** |
290 | * Metadata for price fields. | |
291 | * | |
292 | * @var array | |
293 | */ | |
294 | protected $priceFieldMetadata = []; | |
295 | ||
8193ed74 EM |
296 | /** |
297 | * Metadata for price field values. | |
298 | * | |
299 | * @var array | |
300 | */ | |
301 | protected $priceFieldValueMetadata = []; | |
302 | ||
be2e79c8 | 303 | /** |
304 | * Metadata for price sets. | |
305 | * | |
306 | * @var array | |
307 | */ | |
308 | protected $priceSetMetadata = []; | |
309 | ||
20df462f | 310 | /** |
311 | * Get form object. | |
312 | * | |
812b2c0c EM |
313 | * @internal use in tested core code only. |
314 | * | |
20df462f | 315 | * @return \CRM_Core_Form|NULL |
316 | */ | |
317 | public function getForm(): ?CRM_Core_Form { | |
318 | return $this->form; | |
319 | } | |
320 | ||
321 | /** | |
322 | * Set form object. | |
323 | * | |
812b2c0c EM |
324 | * @internal use in tested core code only. |
325 | * | |
2024d5b9 | 326 | * @param \CRM_Core_Form|null $form |
20df462f | 327 | */ |
328 | public function setForm(?CRM_Core_Form $form): void { | |
329 | $this->form = $form; | |
330 | } | |
331 | ||
332 | /** | |
333 | * The serialize & unserialize functions are to prevent the form being serialized & stored. | |
334 | * | |
335 | * The form could be potentially large & circular. | |
336 | * | |
337 | * We simply serialize the values needed to re-serialize the form. | |
338 | * | |
339 | * @return array | |
340 | */ | |
341 | public function _serialize(): array { | |
342 | return [ | |
343 | 'OverrideTotalAmount' => $this->getOverrideTotalAmount(), | |
344 | 'OverrideFinancialType' => $this->getOverrideFinancialTypeID(), | |
345 | 'PriceSelection' => $this->getPriceSelection(), | |
346 | ]; | |
347 | } | |
348 | ||
349 | /** | |
350 | * Re-instantiate the the class with non-calculated variables. | |
351 | * | |
352 | * @param array $data | |
353 | */ | |
354 | public function _unserialize(array $data): void { | |
355 | foreach ($data as $key => $value) { | |
356 | $fn = 'set' . $key; | |
357 | $this->$fn($value); | |
358 | } | |
359 | } | |
360 | ||
361 | /** | |
362 | * Form object - if present the buildAmount hook will be called. | |
363 | * | |
364 | * @var \CRM_Member_Form_Membership|\CRM_Member_Form_MembershipRenewal | |
365 | */ | |
366 | protected $form; | |
367 | ||
7aa78908 | 368 | /** |
369 | * Get Set override for total amount of the order. | |
370 | * | |
812b2c0c EM |
371 | * @internal use in tested core code only. |
372 | * | |
7aa78908 | 373 | * @return float|false |
374 | */ | |
375 | public function getOverrideTotalAmount() { | |
77274636 EM |
376 | // The override amount is only valid for quick config price sets where more |
377 | // than one field has not been selected. | |
4df23f2a | 378 | if (!$this->overrideTotalAmount || $this->getLineItemCount() > 1) { |
7aa78908 | 379 | return FALSE; |
380 | } | |
77274636 | 381 | return $this->overrideTotalAmount; |
7aa78908 | 382 | } |
383 | ||
4df23f2a EM |
384 | /** |
385 | * Is the line item financial type to be overridden. | |
386 | * | |
387 | * We have a tested scenario for repeatcontribution where the line item | |
388 | * does not match the top level financial type for the order. In this case | |
389 | * any financial type override has been determined to NOT apply to the line items. | |
390 | * | |
391 | * This is locked in via testRepeatTransactionUpdatedFinancialTypeAndNotEquals. | |
392 | * | |
393 | * @param int $financialTypeID | |
394 | * | |
395 | * @return bool | |
396 | */ | |
397 | public function isOverrideLineItemFinancialType(int $financialTypeID) { | |
398 | if (!$this->getOverrideFinancialTypeID()) { | |
399 | return FALSE; | |
400 | } | |
401 | if (!$this->getOverridableFinancialTypeID()) { | |
402 | return TRUE; | |
403 | } | |
404 | return $this->getOverridableFinancialTypeID() === $financialTypeID; | |
405 | } | |
406 | ||
7aa78908 | 407 | /** |
408 | * Set override for total amount. | |
409 | * | |
812b2c0c EM |
410 | * @internal use in tested core code only. |
411 | * | |
4df23f2a | 412 | * @param float|null $overrideTotalAmount |
7aa78908 | 413 | */ |
4df23f2a | 414 | public function setOverrideTotalAmount(?float $overrideTotalAmount): void { |
77274636 | 415 | $this->overrideTotalAmount = $overrideTotalAmount; |
7aa78908 | 416 | } |
417 | ||
418 | /** | |
419 | * Get override for total amount. | |
420 | * | |
812b2c0c EM |
421 | * @internal use in tested core code only. |
422 | * | |
7aa78908 | 423 | * @return int| FALSE |
424 | */ | |
425 | public function getOverrideFinancialTypeID() { | |
4df23f2a EM |
426 | // We don't permit overrides if there is more than one line. |
427 | // The reason for this constraint may be more historical since | |
428 | // the case could be made that if it is set it should be used and | |
429 | // we have built out the tax calculations a lot now. | |
430 | if (!$this->isPermitOverrideFinancialTypeForMultipleLines() && $this->getLineItemCount() > 1) { | |
7aa78908 | 431 | return FALSE; |
432 | } | |
433 | return $this->overrideFinancialTypeID ?? FALSE; | |
434 | } | |
435 | ||
436 | /** | |
437 | * Set override for financial type ID. | |
438 | * | |
812b2c0c EM |
439 | * @internal use in tested core code only. |
440 | * | |
4df23f2a | 441 | * @param int|null $overrideFinancialTypeID |
7aa78908 | 442 | */ |
4df23f2a | 443 | public function setOverrideFinancialTypeID(?int $overrideFinancialTypeID): void { |
7aa78908 | 444 | $this->overrideFinancialTypeID = $overrideFinancialTypeID; |
445 | } | |
446 | ||
447 | /** | |
448 | * Getter for price set id. | |
449 | * | |
812b2c0c EM |
450 | * @internal use in tested core code only. |
451 | * | |
7aa78908 | 452 | * @return int |
812b2c0c EM |
453 | * |
454 | * @throws \API_Exception | |
7aa78908 | 455 | */ |
456 | public function getPriceSetID(): int { | |
812b2c0c EM |
457 | if (!$this->priceSetID) { |
458 | foreach ($this->getPriceOptions() as $fieldID => $valueID) { | |
459 | $this->setPriceSetIDFromSelectedField($fieldID); | |
460 | } | |
691345e9 EM |
461 | if (!$this->priceSetID && $this->getTemplateContributionID()) { |
462 | // Load the line items from the contribution. | |
463 | foreach ($this->getLineItems() as $lineItem) { | |
464 | return $lineItem['price_field_id.price_set_id']; | |
465 | } | |
466 | } | |
812b2c0c | 467 | } |
7aa78908 | 468 | return $this->priceSetID; |
469 | } | |
470 | ||
471 | /** | |
472 | * Setter for price set id. | |
473 | * | |
812b2c0c EM |
474 | * @internal use in tested core code only. |
475 | * | |
7aa78908 | 476 | * @param int $priceSetID |
477 | */ | |
478 | public function setPriceSetID(int $priceSetID) { | |
479 | $this->priceSetID = $priceSetID; | |
480 | } | |
481 | ||
812b2c0c EM |
482 | /** |
483 | * Set price set id to the default. | |
484 | * | |
485 | * @param string $component [membership|contribution] | |
486 | * | |
487 | * @throws \API_Exception | |
488 | * @internal use in tested core code only. | |
489 | */ | |
490 | public function setPriceSetToDefault(string $component): void { | |
ca1b238b | 491 | $this->priceSetID = $this->getDefaultPriceSetForComponent($component); |
812b2c0c EM |
492 | } |
493 | ||
d6c86ce5 EM |
494 | /** |
495 | * Set price set ID based on the contribution page id. | |
496 | * | |
812b2c0c EM |
497 | * @internal use in tested core code only. |
498 | * | |
d6c86ce5 EM |
499 | * @param int $contributionPageID |
500 | * | |
d6c86ce5 EM |
501 | */ |
502 | public function setPriceSetIDByContributionPageID(int $contributionPageID): void { | |
503 | $this->setPriceSetIDByEntity('contribution_page', $contributionPageID); | |
504 | } | |
505 | ||
506 | /** | |
507 | * Set price set ID based on the event id. | |
508 | * | |
812b2c0c EM |
509 | * @internal use in tested core code only. |
510 | * | |
d6c86ce5 EM |
511 | * @param int $eventID |
512 | * | |
513 | * @throws \CiviCRM_API3_Exception | |
514 | */ | |
515 | public function setPriceSetIDByEventPageID(int $eventID): void { | |
516 | $this->setPriceSetIDByEntity('event', $eventID); | |
517 | } | |
518 | ||
519 | /** | |
520 | * Set the price set id based on looking up the entity. | |
812b2c0c EM |
521 | * |
522 | * @internal use in tested core code only. | |
523 | * | |
d6c86ce5 EM |
524 | * @param string $entity |
525 | * @param int $id | |
526 | * | |
527 | */ | |
528 | protected function setPriceSetIDByEntity(string $entity, int $id): void { | |
529 | $this->priceSetID = CRM_Price_BAO_PriceSet::getFor('civicrm_' . $entity, $id); | |
530 | } | |
531 | ||
7aa78908 | 532 | /** |
533 | * Getter for price selection. | |
534 | * | |
812b2c0c EM |
535 | * @internal use in tested core code only. |
536 | * | |
7aa78908 | 537 | * @return array |
538 | */ | |
539 | public function getPriceSelection(): array { | |
540 | return $this->priceSelection; | |
541 | } | |
542 | ||
543 | /** | |
544 | * Setter for price selection. | |
545 | * | |
812b2c0c EM |
546 | * @internal use in tested core code only. |
547 | * | |
7aa78908 | 548 | * @param array $priceSelection |
549 | */ | |
550 | public function setPriceSelection(array $priceSelection) { | |
551 | $this->priceSelection = $priceSelection; | |
552 | } | |
553 | ||
554 | /** | |
555 | * Price options the simplified price fields selections. | |
556 | * | |
557 | * ie. the 'price_' is stripped off the key name and the field ID | |
558 | * is cast to an integer. | |
559 | * | |
812b2c0c EM |
560 | * @internal use in tested core code only. |
561 | * | |
7aa78908 | 562 | * @return array |
563 | */ | |
564 | public function getPriceOptions():array { | |
565 | $priceOptions = []; | |
566 | foreach ($this->getPriceSelection() as $fieldName => $value) { | |
567 | $fieldID = substr($fieldName, 6); | |
568 | $priceOptions[(int) $fieldID] = $value; | |
569 | } | |
570 | return $priceOptions; | |
571 | } | |
572 | ||
573 | /** | |
574 | * Get the metadata for the given field. | |
575 | * | |
812b2c0c EM |
576 | * @internal use in tested core code only. |
577 | * | |
7aa78908 | 578 | * @param int $id |
579 | * | |
580 | * @return array | |
7aa78908 | 581 | */ |
582 | public function getPriceFieldSpec(int $id) :array { | |
de668aa8 | 583 | return $this->getPriceFieldsMetadata()[$id]; |
584 | } | |
585 | ||
8193ed74 EM |
586 | /** |
587 | * Get the metadata for the given field value. | |
588 | * | |
589 | * @internal use in tested core code only. | |
590 | * | |
591 | * @param int $id | |
592 | * | |
593 | * @return array | |
594 | */ | |
595 | public function getPriceFieldValueSpec(int $id) :array { | |
596 | if (!isset($this->priceFieldValueMetadata[$id])) { | |
597 | $this->priceFieldValueMetadata[$id] = PriceFieldValue::get(FALSE)->addWhere('id', '=', $id)->execute()->first(); | |
598 | } | |
599 | return $this->priceFieldValueMetadata[$id]; | |
600 | } | |
601 | ||
de668aa8 | 602 | /** |
603 | * Get the metadata for the fields in the price set. | |
604 | * | |
812b2c0c EM |
605 | * @internal use in tested core code only. |
606 | * | |
de668aa8 | 607 | * @return array |
608 | */ | |
609 | public function getPriceFieldsMetadata(): array { | |
610 | if (empty($this->priceFieldMetadata)) { | |
be2e79c8 | 611 | $this->getPriceSetMetadata(); |
7aa78908 | 612 | } |
de668aa8 | 613 | return $this->priceFieldMetadata; |
7aa78908 | 614 | } |
615 | ||
812b2c0c EM |
616 | /** |
617 | * Set the metadata for the order. | |
618 | * | |
619 | * @param array $metadata | |
620 | */ | |
621 | protected function setPriceFieldMetadata($metadata) { | |
622 | $this->priceFieldMetadata = $metadata; | |
623 | if ($this->getForm()) { | |
624 | CRM_Utils_Hook::buildAmount($this->form->getFormContext(), $this->form, $this->priceFieldMetadata); | |
625 | } | |
626 | } | |
627 | ||
be2e79c8 | 628 | /** |
629 | * Get the metadata for the fields in the price set. | |
630 | * | |
812b2c0c EM |
631 | * @internal use in tested core code only. |
632 | * | |
be2e79c8 | 633 | * @return array |
634 | */ | |
635 | public function getPriceSetMetadata(): array { | |
636 | if (empty($this->priceSetMetadata)) { | |
637 | $priceSetMetadata = CRM_Price_BAO_PriceSet::getCachedPriceSetDetail($this->getPriceSetID()); | |
812b2c0c | 638 | $this->setPriceFieldMetadata($priceSetMetadata['fields']); |
be2e79c8 | 639 | unset($priceSetMetadata['fields']); |
640 | $this->priceSetMetadata = $priceSetMetadata; | |
641 | } | |
642 | return $this->priceSetMetadata; | |
643 | } | |
644 | ||
645 | /** | |
646 | * Get the financial type id for the order. | |
647 | * | |
812b2c0c EM |
648 | * @internal use in tested core code only. |
649 | * | |
be2e79c8 | 650 | * This may differ to the line items.... |
651 | * | |
652 | * @return int | |
653 | */ | |
654 | public function getFinancialTypeID(): int { | |
655 | return (int) $this->getOverrideFinancialTypeID() ?: $this->getPriceSetMetadata()['financial_type_id']; | |
656 | } | |
657 | ||
7aa78908 | 658 | /** |
812b2c0c EM |
659 | * Set the price field selection from an array of params containing price |
660 | * fields. | |
7aa78908 | 661 | * |
812b2c0c EM |
662 | * This function takes the sort of 'anything & everything' parameters that |
663 | * come in from the form layer and filters them before assigning them to the | |
664 | * priceSelection property. | |
7aa78908 | 665 | * |
666 | * @param array $input | |
812b2c0c EM |
667 | * |
668 | * @throws \API_Exception | |
7aa78908 | 669 | */ |
de668aa8 | 670 | public function setPriceSelectionFromUnfilteredInput(array $input): void { |
7aa78908 | 671 | foreach ($input as $fieldName => $value) { |
672 | if (strpos($fieldName, 'price_') === 0) { | |
673 | $fieldID = substr($fieldName, 6); | |
674 | if (is_numeric($fieldID)) { | |
675 | $this->priceSelection[$fieldName] = $value; | |
676 | } | |
677 | } | |
678 | } | |
812b2c0c EM |
679 | if (empty($this->priceSelection) && isset($input['total_amount']) |
680 | && is_numeric($input['total_amount']) && !empty($input['financial_type_id'])) { | |
ca1b238b | 681 | $this->priceSelection['price_' . $this->getDefaultPriceFieldID()] = $input['total_amount']; |
812b2c0c EM |
682 | $this->setOverrideFinancialTypeID($input['financial_type_id']); |
683 | } | |
684 | } | |
685 | ||
686 | /** | |
687 | * Get the id of the price field to use when just an amount is provided. | |
688 | * | |
689 | * @throws \API_Exception | |
ca1b238b EM |
690 | * |
691 | * @return int | |
812b2c0c | 692 | */ |
ca1b238b EM |
693 | public function getDefaultPriceFieldID():int { |
694 | if (!$this->defaultPriceField) { | |
695 | $this->defaultPriceField = PriceField::get(FALSE) | |
696 | ->addWhere('name', '=', 'contribution_amount') | |
697 | ->addWhere('price_set_id.name', '=', 'default_contribution_amount') | |
698 | ->execute()->first(); | |
699 | } | |
700 | return $this->defaultPriceField['id']; | |
7aa78908 | 701 | } |
702 | ||
60e5cf34 EM |
703 | /** |
704 | * Get the id of the price field to use when just an amount is provided. | |
705 | * | |
706 | * @throws \API_Exception | |
707 | * | |
708 | * @return int | |
709 | */ | |
710 | public function getDefaultPriceFieldValueID():int { | |
711 | if (!$this->defaultPriceFieldValueID) { | |
712 | $this->defaultPriceFieldValueID = PriceFieldValue::get(FALSE) | |
713 | ->addWhere('name', '=', 'contribution_amount') | |
714 | ->addWhere('price_field_id.name', '=', 'contribution_amount') | |
715 | ->execute()->first()['id']; | |
716 | } | |
717 | return $this->defaultPriceFieldValueID; | |
718 | } | |
719 | ||
7aa78908 | 720 | /** |
721 | * Get line items. | |
722 | * | |
723 | * return array | |
724 | * | |
725 | * @throws \CiviCRM_API3_Exception | |
726 | */ | |
727 | public function getLineItems():array { | |
728 | if (empty($this->lineItems)) { | |
729 | $this->lineItems = $this->calculateLineItems(); | |
730 | } | |
731 | return $this->lineItems; | |
732 | } | |
733 | ||
77274636 EM |
734 | /** |
735 | * Get line items in a 'traditional' indexing format. | |
736 | * | |
737 | * This ensures the line items are indexed by | |
738 | * price field id - as required by the contribution BAO. | |
739 | * | |
740 | * @throws \CiviCRM_API3_Exception | |
741 | */ | |
742 | public function getPriceFieldIndexedLineItems(): array { | |
743 | $lines = []; | |
744 | foreach ($this->getLineItems() as $item) { | |
745 | $lines[$item['price_field_id']] = $item; | |
746 | } | |
747 | return $lines; | |
748 | } | |
749 | ||
e84c5dc2 | 750 | /** |
751 | * Get line items that specifically relate to memberships. | |
752 | * | |
753 | * return array | |
754 | * | |
755 | * @throws \CiviCRM_API3_Exception | |
756 | */ | |
757 | public function getMembershipLineItems():array { | |
758 | $lines = $this->getLineItems(); | |
759 | foreach ($lines as $index => $line) { | |
760 | if (empty($line['membership_type_id'])) { | |
761 | unset($lines[$index]); | |
762 | continue; | |
763 | } | |
764 | if (empty($line['membership_num_terms'])) { | |
765 | $lines[$index]['membership_num_terms'] = 1; | |
766 | } | |
767 | } | |
768 | return $lines; | |
769 | } | |
770 | ||
aba748e5 | 771 | /** |
772 | * Get an array of all membership types included in the order. | |
773 | * | |
774 | * @return array | |
775 | * | |
776 | * @throws \CiviCRM_API3_Exception | |
777 | */ | |
778 | public function getMembershipTypes(): array { | |
779 | $types = []; | |
780 | foreach ($this->getMembershipLineItems() as $line) { | |
781 | $types[$line['membership_type_id']] = CRM_Member_BAO_MembershipType::getMembershipType((int) $line['membership_type_id']); | |
782 | } | |
783 | return $types; | |
784 | } | |
785 | ||
786 | /** | |
787 | * Get an array of all membership types included in the order. | |
788 | * | |
789 | * @return array | |
790 | * | |
791 | * @throws \CiviCRM_API3_Exception | |
792 | */ | |
793 | public function getRenewableMembershipTypes(): array { | |
794 | $types = []; | |
795 | foreach ($this->getMembershipTypes() as $id => $type) { | |
796 | if (!empty($type['auto_renew'])) { | |
797 | $types[$id] = $type; | |
798 | } | |
799 | } | |
800 | return $types; | |
801 | } | |
802 | ||
7aa78908 | 803 | /** |
804 | * @return array | |
4df23f2a EM |
805 | * |
806 | * @throws \API_Exception | |
7aa78908 | 807 | */ |
808 | protected function calculateLineItems(): array { | |
809 | $lineItems = []; | |
810 | $params = $this->getPriceSelection(); | |
811 | if ($this->getOverrideTotalAmount() !== FALSE) { | |
812 | // We need to do this to keep getLine from doing weird stuff but the goal | |
813 | // is to ditch getLine next round of refactoring | |
814 | // and make the code more sane. | |
815 | $params['total_amount'] = $this->getOverrideTotalAmount(); | |
816 | } | |
817 | ||
812b2c0c EM |
818 | // Dummy value to prevent e-notice in getLine. We calculate tax in this class. |
819 | $params['financial_type_id'] = 0; | |
4df23f2a EM |
820 | if ($this->getTemplateContributionID()) { |
821 | $lineItems = $this->getLinesFromTemplateContribution(); | |
822 | } | |
823 | else { | |
824 | foreach ($this->getPriceOptions() as $fieldID => $valueID) { | |
cb74e389 EM |
825 | if ($valueID !== '') { |
826 | $this->setPriceSetIDFromSelectedField($fieldID); | |
827 | $throwAwayArray = []; | |
828 | // @todo - still using getLine for now but better to bring it to this class & do a better job. | |
829 | $newLines = CRM_Price_BAO_PriceSet::getLine($params, $throwAwayArray, $this->getPriceSetID(), $this->getPriceFieldSpec($fieldID), $fieldID)[1]; | |
830 | foreach ($newLines as $newLine) { | |
831 | $lineItems[$newLine['price_field_value_id']] = $newLine; | |
832 | } | |
4df23f2a | 833 | } |
58315149 | 834 | } |
7aa78908 | 835 | } |
4df23f2a EM |
836 | // Set the line item count here because it is needed to determine whether |
837 | // we can use overrides and would not be set yet if we have loaded them from | |
838 | // a template contribution. | |
839 | $this->setLineItemCount(count($lineItems)); | |
7aa78908 | 840 | |
7aa78908 | 841 | foreach ($lineItems as &$lineItem) { |
4df23f2a EM |
842 | // Set the price set id if not set above. Note that the above |
843 | // requires it for line retrieval but we want to fix that as it | |
844 | // should not be required at that point. | |
845 | $this->setPriceSetIDFromSelectedField($lineItem['price_field_id']); | |
7aa78908 | 846 | // Set any pre-calculation to zero as we will calculate. |
847 | $lineItem['tax_amount'] = 0; | |
4df23f2a | 848 | if ($this->isOverrideLineItemFinancialType($lineItem['financial_type_id']) !== FALSE) { |
7aa78908 | 849 | $lineItem['financial_type_id'] = $this->getOverrideFinancialTypeID(); |
850 | } | |
0a859bb8 | 851 | $lineItem['tax_rate'] = $taxRate = $this->getTaxRate((int) $lineItem['financial_type_id']); |
7aa78908 | 852 | if ($this->getOverrideTotalAmount() !== FALSE) { |
77274636 | 853 | $this->addTotalsToLineBasedOnOverrideTotal((int) $lineItem['financial_type_id'], $lineItem); |
7aa78908 | 854 | } |
855 | elseif ($taxRate) { | |
856 | $lineItem['tax_amount'] = ($taxRate / 100) * $lineItem['line_total']; | |
857 | } | |
8193ed74 | 858 | $lineItem['title'] = $lineItem['label']; |
7aa78908 | 859 | } |
860 | return $lineItems; | |
861 | } | |
862 | ||
863 | /** | |
58315149 | 864 | * Get the total amount for the order. |
7aa78908 | 865 | * |
866 | * @return float | |
867 | * | |
868 | * @throws \CiviCRM_API3_Exception | |
869 | */ | |
870 | public function getTotalTaxAmount() :float { | |
871 | $amount = 0.0; | |
872 | foreach ($this->getLineItems() as $lineItem) { | |
873 | $amount += $lineItem['tax_amount'] ?? 0.0; | |
874 | } | |
875 | return $amount; | |
876 | } | |
877 | ||
58315149 | 878 | /** |
765d02a3 | 879 | * Get the total amount for the order. |
58315149 | 880 | * |
881 | * @return float | |
882 | * | |
883 | * @throws \CiviCRM_API3_Exception | |
884 | */ | |
885 | public function getTotalAmount() :float { | |
886 | $amount = 0.0; | |
887 | foreach ($this->getLineItems() as $lineItem) { | |
53c8b1be | 888 | $amount += ($lineItem['line_total'] ?? 0.0) + ($lineItem['tax_amount'] ?? 0.0); |
58315149 | 889 | } |
890 | return $amount; | |
891 | } | |
892 | ||
765d02a3 EM |
893 | /** |
894 | * Get the total amount relating to memberships for the order. | |
895 | * | |
896 | * @return float | |
897 | * | |
898 | * @throws \CiviCRM_API3_Exception | |
899 | */ | |
900 | public function getMembershipTotalAmount() :float { | |
901 | $amount = 0.0; | |
902 | foreach ($this->getMembershipLineItems() as $lineItem) { | |
903 | $amount += ($lineItem['line_total'] ?? 0.0) + ($lineItem['tax_amount'] ?? 0.0); | |
904 | } | |
905 | return $amount; | |
906 | } | |
907 | ||
dd118b15 | 908 | /** |
909 | * Get the tax rate for the given financial type. | |
910 | * | |
911 | * @param int $financialTypeID | |
912 | * | |
913 | * @return float | |
914 | */ | |
915 | public function getTaxRate(int $financialTypeID) { | |
916 | $taxRates = CRM_Core_PseudoConstant::getTaxRates(); | |
917 | if (!isset($taxRates[$financialTypeID])) { | |
918 | return 0; | |
919 | } | |
920 | return $taxRates[$financialTypeID]; | |
921 | } | |
922 | ||
812b2c0c EM |
923 | /** |
924 | * @param $fieldID | |
925 | * | |
926 | * @throws \API_Exception | |
927 | */ | |
928 | protected function setPriceSetIDFromSelectedField($fieldID): void { | |
929 | if (!isset($this->priceSetID)) { | |
930 | $this->setPriceSetID(PriceField::get(FALSE) | |
931 | ->addSelect('price_set_id') | |
932 | ->addWhere('id', '=', $fieldID) | |
933 | ->execute() | |
934 | ->first()['price_set_id']); | |
935 | } | |
936 | } | |
937 | ||
ca44bb7e EM |
938 | /** |
939 | * Set the line item. | |
940 | * | |
941 | * This function augments the line item where possible. The calling code | |
942 | * should not attempt to set taxes. This function allows minimal values | |
943 | * to be passed for the default price sets - ie if only membership_type_id is | |
944 | * specified the price_field_id and price_value_id will be determined. | |
945 | * | |
946 | * @param array $lineItem | |
947 | * @param int|string $index | |
948 | * | |
949 | * @throws \API_Exception | |
950 | * @internal tested core code usage only. | |
951 | * @internal use in tested core code only. | |
952 | * | |
953 | */ | |
954 | public function setLineItem(array $lineItem, $index): void { | |
77274636 EM |
955 | if (!isset($this->priceSetID)) { |
956 | if (!empty($lineItem['price_field_id'])) { | |
957 | $this->setPriceSetIDFromSelectedField($lineItem['price_field_id']); | |
958 | } | |
959 | else { | |
960 | // we are using either the default membership or default contribution | |
961 | // If membership type is passed in we use the default price field. | |
962 | $component = !empty($lineItem['membership_type_id']) ? 'membership' : 'contribution'; | |
963 | $this->setPriceSetToDefault($component); | |
964 | } | |
ca44bb7e EM |
965 | } |
966 | if (!isset($lineItem['financial_type_id'])) { | |
967 | $lineItem['financial_type_id'] = $this->getDefaultFinancialTypeID(); | |
968 | } | |
969 | if (!is_numeric($lineItem['financial_type_id'])) { | |
970 | $lineItem['financial_type_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', $lineItem['financial_type_id']); | |
971 | } | |
77274636 EM |
972 | if ($this->getOverrideTotalAmount()) { |
973 | $this->addTotalsToLineBasedOnOverrideTotal((int) $lineItem['financial_type_id'], $lineItem); | |
974 | } | |
975 | else { | |
8193ed74 EM |
976 | $lineItem['tax_rate'] = $this->getTaxRate($lineItem['financial_type_id']); |
977 | $lineItem['tax_amount'] = ($lineItem['tax_rate'] / 100) * $lineItem['line_total']; | |
77274636 | 978 | } |
ca44bb7e EM |
979 | if (!empty($lineItem['membership_type_id'])) { |
980 | $lineItem['entity_table'] = 'civicrm_membership'; | |
981 | if (empty($lineItem['price_field_id']) && empty($lineItem['price_field_value_id'])) { | |
ca44bb7e EM |
982 | $lineItem = $this->fillMembershipLine($lineItem); |
983 | } | |
984 | } | |
ca1b238b EM |
985 | if ($this->getPriceSetID() === $this->getDefaultPriceSetForComponent('contribution')) { |
986 | $this->fillDefaultContributionLine($lineItem); | |
987 | } | |
8193ed74 EM |
988 | if (empty($lineItem['label'])) { |
989 | $lineItem['label'] = PriceFieldValue::get(FALSE)->addWhere('id', '=', (int) $lineItem['price_field_value_id'])->addSelect('label')->execute()->first()['label']; | |
990 | } | |
991 | if (empty($lineItem['price_field_id']) && !empty($lineItem['membership_type_id'])) { | |
992 | // We have to 'guess' the price field since the calling code hasn't | |
993 | // passed it in (which it really should but ... history). | |
994 | foreach ($this->priceFieldMetadata as $pricefield) { | |
995 | foreach ($pricefield['options'] ?? [] as $option) { | |
996 | if ((int) $option['membership_type_id'] === $lineItem['membership_type_id']) { | |
997 | $lineItem['price_field_id'] = $pricefield['id']; | |
998 | $lineItem['price_field_value_id'] = $option['id']; | |
999 | } | |
1000 | } | |
1001 | } | |
1002 | } | |
1003 | if (empty($lineItem['title'])) { | |
1004 | // Title is used in output for workflow templates. | |
1005 | $htmlType = !empty($this->priceFieldMetadata) ? $this->getPriceFieldSpec($lineItem['price_field_id'])['html_type'] : NULL; | |
1006 | $lineItem['title'] = (!$htmlType || $htmlType === 'Text') ? $lineItem['label'] : $this->getPriceFieldSpec($lineItem['price_field_id'])['label'] . ' : ' . $lineItem['label']; | |
1007 | if (!empty($lineItem['price_field_value_id'])) { | |
1008 | $description = $this->priceFieldValueMetadata[$lineItem['price_field_value_id']]['description'] ?? ''; | |
1009 | if ($description) { | |
1010 | $lineItem['title'] .= ' ' . CRM_Utils_String::ellipsify($description, 30); | |
1011 | } | |
1012 | } | |
1013 | } | |
ca44bb7e EM |
1014 | $this->lineItems[$index] = $lineItem; |
1015 | } | |
1016 | ||
1017 | /** | |
1018 | * Set a value on a line item. | |
1019 | * | |
1020 | * @internal only use in core tested code. | |
1021 | * | |
1022 | * @param string $name | |
1023 | * @param mixed $value | |
1024 | * @param string|int $index | |
1025 | */ | |
1026 | public function setLineItemValue(string $name, $value, $index): void { | |
1027 | $this->lineItems[$index][$name] = $value; | |
1028 | } | |
1029 | ||
1030 | /** | |
1031 | * @param int|string $index | |
1032 | * | |
1033 | * @return string | |
1034 | */ | |
1035 | public function getLineItemEntity($index):string { | |
1036 | // @todo - ensure entity_table is set in setLineItem, go back to enotices here. | |
1037 | return str_replace('civicrm_', '', ($this->lineItems[$index]['entity_table'] ?? 'contribution')); | |
1038 | } | |
1039 | ||
1040 | /** | |
1041 | * Get the ordered line item. | |
1042 | * | |
1043 | * @param string|int $index | |
1044 | * | |
1045 | * @return array | |
1046 | */ | |
1047 | public function getLineItem($index): array { | |
1048 | return $this->lineItems[$index]; | |
1049 | } | |
1050 | ||
1051 | /** | |
1052 | * Fills in additional data for the membership line. | |
1053 | * | |
1054 | * The minimum requirement is the membership_type_id and that priceSetID is set. | |
1055 | * | |
1056 | * @param array $lineItem | |
1057 | * | |
1058 | * @return array | |
1059 | */ | |
1060 | protected function fillMembershipLine(array $lineItem): array { | |
1061 | $fields = $this->getPriceFieldsMetadata(); | |
77274636 EM |
1062 | foreach ($fields as $field) { |
1063 | if (!isset($lineItem['price_field_value_id'])) { | |
1064 | foreach ($field['options'] as $option) { | |
1065 | if ((int) $option['membership_type_id'] === (int) $lineItem['membership_type_id']) { | |
1066 | $lineItem['price_field_id'] = $field['id']; | |
8193ed74 | 1067 | $lineItem['price_field_id.label'] = $field['label']; |
77274636 EM |
1068 | $lineItem['price_field_value_id'] = $option['id']; |
1069 | $lineItem['qty'] = 1; | |
1070 | } | |
ca44bb7e EM |
1071 | } |
1072 | } | |
77274636 EM |
1073 | if (isset($lineItem['price_field_value_id'], $field['options'][$lineItem['price_field_value_id']])) { |
1074 | $option = $field['options'][$lineItem['price_field_value_id']]; | |
1075 | } | |
ca44bb7e | 1076 | } |
ca44bb7e EM |
1077 | $lineItem['unit_price'] = $lineItem['line_total'] ?? $option['amount']; |
1078 | $lineItem['label'] = $lineItem['label'] ?? $option['label']; | |
1079 | $lineItem['field_title'] = $lineItem['field_title'] ?? $option['label']; | |
1080 | $lineItem['financial_type_id'] = $lineItem['financial_type_id'] ?: ($this->getDefaultFinancialTypeID() ?? $option['financial_type_id']); | |
1081 | return $lineItem; | |
1082 | } | |
1083 | ||
77274636 EM |
1084 | /** |
1085 | * Add total_amount and tax_amount to the line from the override total. | |
1086 | * | |
1087 | * @param int $financialTypeID | |
1088 | * @param array $lineItem | |
1089 | * | |
1090 | * @return void | |
1091 | */ | |
1092 | protected function addTotalsToLineBasedOnOverrideTotal(int $financialTypeID, array &$lineItem): void { | |
0a859bb8 | 1093 | $lineItem['tax_rate'] = $taxRate = $this->getTaxRate($financialTypeID); |
77274636 EM |
1094 | if ($taxRate) { |
1095 | // Total is tax inclusive. | |
1096 | $lineItem['tax_amount'] = ($taxRate / 100) * $this->getOverrideTotalAmount() / (1 + ($taxRate / 100)); | |
e66cf74b | 1097 | $lineItem['line_total'] = $this->getOverrideTotalAmount() - $lineItem['tax_amount']; |
77274636 EM |
1098 | } |
1099 | else { | |
e66cf74b DRJ |
1100 | $lineItem['line_total'] = $this->getOverrideTotalAmount(); |
1101 | } | |
1102 | if (!empty($lineItem['qty'])) { | |
1103 | $lineItem['unit_price'] = $lineItem['line_total'] / $lineItem['qty']; | |
1104 | } | |
1105 | else { | |
1106 | $lineItem['unit_price'] = $lineItem['line_total']; | |
77274636 EM |
1107 | } |
1108 | } | |
1109 | ||
4df23f2a EM |
1110 | /** |
1111 | * Get the line items from a template. | |
1112 | * | |
1113 | * @return \Civi\Api4\Generic\Result | |
1114 | * | |
1115 | * @throws \API_Exception | |
1116 | */ | |
1117 | protected function getLinesFromTemplateContribution(): array { | |
1118 | $lines = $this->getLinesForContribution(); | |
1119 | foreach ($lines as &$line) { | |
1120 | // The apiv4 insists on adding id - so let it get all the details | |
1121 | // and we will filter out those that are not part of a template here. | |
1122 | unset($line['id'], $line['contribution_id']); | |
1123 | } | |
1124 | return $lines; | |
1125 | } | |
1126 | ||
502822e7 EM |
1127 | /** |
1128 | * Get the constructed line items formatted for the v3 Order api. | |
1129 | * | |
1130 | * @return array | |
1131 | * | |
1132 | * @internal core tested code only. | |
1133 | * | |
1134 | * @throws \CiviCRM_API3_Exception | |
1135 | */ | |
1136 | public function getLineItemForV3OrderApi(): array { | |
1137 | $lineItems = []; | |
1138 | foreach ($this->getLineItems() as $key => $line) { | |
1139 | $lineItems[] = [ | |
1140 | 'line_item' => [$line['price_field_value_id'] => $line], | |
1141 | 'params' => $this->entityParameters[$key] ?? [], | |
1142 | ]; | |
1143 | } | |
1144 | return $lineItems; | |
1145 | } | |
1146 | ||
4df23f2a EM |
1147 | /** |
1148 | * @return array | |
1149 | * @throws \API_Exception | |
1150 | * @throws \Civi\API\Exception\UnauthorizedException | |
1151 | */ | |
1152 | protected function getLinesForContribution(): array { | |
1153 | return (array) LineItem::get(FALSE) | |
1154 | ->addWhere('contribution_id', '=', $this->getTemplateContributionID()) | |
1155 | ->setSelect([ | |
1156 | 'contribution_id', | |
1157 | 'entity_id', | |
1158 | 'entity_table', | |
1159 | 'price_field_id', | |
8193ed74 | 1160 | 'price_field_id.label', |
691345e9 | 1161 | 'price_field_id.price_set_id', |
4df23f2a EM |
1162 | 'price_field_value_id', |
1163 | 'financial_type_id', | |
1164 | 'label', | |
1165 | 'qty', | |
1166 | 'unit_price', | |
1167 | 'line_total', | |
1168 | 'tax_amount', | |
1169 | 'non_deductible_amount', | |
1170 | 'participant_count', | |
1171 | 'membership_num_terms', | |
1172 | ]) | |
1173 | ->execute(); | |
1174 | } | |
1175 | ||
ca1b238b EM |
1176 | /** |
1177 | * Get the default price set id for the given component. | |
1178 | * | |
1179 | * @param string $component | |
1180 | * | |
1181 | * @return int | |
1182 | * @throws \API_Exception | |
1183 | */ | |
1184 | protected function getDefaultPriceSetForComponent(string $component): int { | |
1185 | if (!isset($this->defaultPriceSets[$component])) { | |
1186 | $this->defaultPriceSets[$component] = PriceSet::get(FALSE) | |
1187 | ->addWhere('name', '=', ($component === 'membership' ? 'default_membership_type_amount' : 'default_contribution_amount')) | |
1188 | ->execute() | |
1189 | ->first()['id']; | |
1190 | } | |
1191 | return $this->defaultPriceSets[$component]; | |
1192 | } | |
1193 | ||
1194 | /** | |
1195 | * Fill in values for a default contribution line item. | |
1196 | * | |
1197 | * @param array $lineItem | |
1198 | * | |
1199 | * @throws \API_Exception | |
1200 | */ | |
1201 | protected function fillDefaultContributionLine(array &$lineItem): void { | |
1202 | $defaults = [ | |
1203 | 'qty' => 1, | |
1204 | 'price_field_id' => $this->getDefaultPriceFieldID(), | |
8193ed74 | 1205 | 'price_field_id.label' => $this->defaultPriceField['label'], |
60e5cf34 | 1206 | 'price_field_value_id' => $this->getDefaultPriceFieldValueID(), |
ca1b238b EM |
1207 | 'entity_table' => 'civicrm_contribution', |
1208 | 'unit_price' => $lineItem['line_total'], | |
1209 | 'label' => ts('Contribution Amount'), | |
1210 | ]; | |
1211 | $lineItem = array_merge($defaults, $lineItem); | |
1212 | } | |
1213 | ||
7aa78908 | 1214 | } |