Util.php 39.4 KB
Newer Older
Monish Deb's avatar
Monish Deb committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

class CRM_Lineitemedit_Util {

  /**
   * Function used to fetch associated line-item(s) of a contribution in tabular format
   *
   * @param array $order
   *   contribution infor with associated line items
   *
   * @return array $lineItemTable
   *   array of lineitems
   */
  public static function getLineItemTableInfo($order) {
    $lineItems = (array) $order['line_items'];
16
17
18
19
20
21

    // TODO: order.get API doesn't fetch cancelled line_items
    if (empty($lineItems)) {
      $lineItems = civicrm_api3('LineItem', 'Get', array('contribution_id' => $order['contribution_id']));
      $lineItems = $lineItems['values'];
    }
Edselopez's avatar
Edselopez committed
22
23
24
25
26
27
28
29
30
31
    $chapterCodes = CRM_Core_OptionGroup::values('chapter_codes');
    $fundCodes = CRM_Core_OptionGroup::values('fund_codes');
    foreach ($lineItems as $key => &$item) {
      $codes = CRM_Core_DAO::executeQuery("SELECT chapter_code, fund_code FROM civicrm_chapter_entity WHERE entity_table = 'civicrm_line_item' AND entity_id = {$item['id']}")->fetchAll()[0];
      if (empty($codes)) {
        continue;
      }
      $item['chapter_code'] = $chapterCodes[$codes['chapter_code']] . '-' . $codes['chapter_code'];
      $item['fund_code'] = $fundCodes[$codes['fund_code']] . '-' . $codes['fund_code'];
    }
32

Monish Deb's avatar
Monish Deb committed
33
34
35
    $lineItemTable = array(
      'rows' => array(),
    );
Monish Deb's avatar
Monish Deb committed
36
37
    $links = array(
      CRM_Core_Action::UPDATE => array(
38
        'name' => ts(''),
Monish Deb's avatar
Monish Deb committed
39
40
41
        'url' => 'civicrm/lineitem/edit',
        'qs' => 'reset=1&id=%%id%%',
        'title' => ts('Edit Line item'),
42
        'ref' => ' crm-i fa-pencil ',
Monish Deb's avatar
Monish Deb committed
43
44
      ),
      CRM_Core_Action::DELETE => array(
45
        'name' => ts(''),
Monish Deb's avatar
Monish Deb committed
46
47
48
        'url' => 'civicrm/lineitem/cancel',
        'qs' => 'reset=1&id=%%id%%',
        'title' => ts('Cancel Line item'),
49
        'ref' => ' crm-i fa-undo ',
Monish Deb's avatar
Monish Deb committed
50
51
52
53
54
55
56
57
58
59
60
61
62
      ),
    );

    $permissions = array(CRM_Core_Permission::VIEW);
    if (CRM_Core_Permission::check('edit contributions')) {
      $permissions[] = CRM_Core_Permission::EDIT;
    }
    if (CRM_Core_Permission::check('delete in CiviContribute')) {
      $permissions[] = CRM_Core_Permission::DELETE;
    }
    $mask = CRM_Core_Action::mask($permissions);
    foreach ($lineItems as $key => $lineItem) {
      $actions = array(
Monish Deb's avatar
Monish Deb committed
63
        'id' => $lineItem['id'],
Monish Deb's avatar
Monish Deb committed
64
      );
65

Monish Deb's avatar
Monish Deb committed
66
      $actionLinks = $links;
Monish Deb's avatar
Monish Deb committed
67
      if ($lineItem['qty'] == 0 || $lineItem['line_total'] == 0) {
Monish Deb's avatar
Monish Deb committed
68
69
        unset($actionLinks[CRM_Core_Action::DELETE]);
      }
Monish Deb's avatar
Monish Deb committed
70
      $lineItemTable['rows'][$key] = array(
Monish Deb's avatar
Monish Deb committed
71
        'id' => $lineItem['id'],
Monish Deb's avatar
Monish Deb committed
72
        'item' => CRM_Utils_Array::value('label', $lineItem),
Monish Deb's avatar
Monish Deb committed
73
        'financial_type' => CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'financial_type_id', $lineItem['financial_type_id']),
Edselopez's avatar
Edselopez committed
74
75
        'chapter_code' => $lineItem['chapter_code'],
        'fund_code' => $lineItem['fund_code'],
Monish Deb's avatar
Monish Deb committed
76
77
78
        'qty' => $lineItem['qty'],
        'unit_price' => $lineItem['unit_price'],
        'total_price' => $lineItem['line_total'],
79
        'tax_amount' => CRM_Utils_Array::value('tax_amount', $lineItem, 0.00),
Monish Deb's avatar
Monish Deb committed
80
        'currency' => $order['currency'],
Monish Deb's avatar
Monish Deb committed
81
        'actions' => CRM_Core_Action::formLink($actionLinks, $mask, $actions),
Monish Deb's avatar
Monish Deb committed
82
83
84
      );
    }

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
    return $lineItemTable;
  }

  /**
   * Function used to return 'Add Item(s)' link, later added above total amount by jquery
   *
   * @param int $contributionID
   *
   * @return string
   *   HTML anchor tag of 'Add Item(s)' action
   */
  public static function getAddLineItemLink($contributionID) {
    $permissions = array(CRM_Core_Permission::VIEW);
    if (CRM_Core_Permission::check('edit contributions')) {
      $permissions[] = CRM_Core_Permission::EDIT;
    }
    if (CRM_Core_Permission::check('delete in CiviContribute')) {
      $permissions[] = CRM_Core_Permission::DELETE;
    }
    $mask = CRM_Core_Action::mask($permissions);

Monish Deb's avatar
Monish Deb committed
106
    // don't show 'Add Item' action link if all the non-quick-config price-field options are used or
107
    //   quick-config price field is used for the existing contribution
Monish Deb's avatar
Monish Deb committed
108
109
110
111
    if (self::getPriceFieldLists($contributionID, TRUE) == 0) {
      return '';
    }

Monish Deb's avatar
Monish Deb committed
112
113
114
    $links = array(
      CRM_Core_Action::ADD => array(
        'name' => ts('Add Item(s)'),
115
        'url' => 'civicrm/lineitem/add',
Monish Deb's avatar
Monish Deb committed
116
117
118
119
        'qs' => 'reset=1&contribution_id=%%contribution_id%%',
        'title' => ts('Add Line-item(s)'),
      ),
    );
120
121

    return sprintf('<b>%s</b>',
Monish Deb's avatar
Monish Deb committed
122
123
124
      CRM_Core_Action::formLink(
        $links, $mask,
        array(
125
          'contribution_id' => $contributionID,
Monish Deb's avatar
Monish Deb committed
126
127
128
        )
      )
    );
129
  }
Monish Deb's avatar
Monish Deb committed
130

131
132
133
  /**
   * Function used to format lineItem lists by appending edit and cancel item action links with label
   *
Monish Deb's avatar
Monish Deb committed
134
135
   * @param array $lineItems list of lineitems
   * @param bool $isParticipantCount
136
137
   *
   */
138
  public static function formatLineItemList(&$lineItems, $isParticipantCount) {
139
140
141
    foreach ($lineItems as $priceSetID => $records) {
      if ($records != 'skip') {
        foreach ($records as $lineItemID => $lineItem) {
142
          // do not show cancel and edit actions on membership OR if the item is already cancelled
Monish Deb's avatar
Monish Deb committed
143
          if ($lineItem['qty'] == 0) {
Monish Deb's avatar
Monish Deb committed
144
145
146
147
148
149
150
151
152
153
154
155
            $actionlinks = sprintf("
              <a class='action-item crm-hover-button' href=%s title='Edit Item'><i class='crm-i fa-pencil'></i></a>",
              CRM_Utils_System::url('civicrm/lineitem/edit', 'reset=1&id=' . $lineItemID)
            );
          }
          else {
            $actionlinks = sprintf("
              <a class='action-item crm-hover-button' href=%s title='Edit Item'><i class='crm-i fa-pencil'></i></a>
              <a class='action-item crm-hover-button' href=%s title='Cancel Item'><i class='crm-i fa-undo'></i></a>",
              CRM_Utils_System::url('civicrm/lineitem/edit', 'reset=1&id=' . $lineItemID),
              CRM_Utils_System::url('civicrm/lineitem/cancel', 'reset=1&id=' . $lineItemID)
            );
156
          }
157

158
159
          if (!$isParticipantCount) {
            $lineItems[$priceSetID][$lineItemID]['participant_count'] = '';
160
          }
Monish Deb's avatar
Monish Deb committed
161
          $lineItems[$priceSetID][$lineItemID]['participant_count'] = $lineItems[$priceSetID][$lineItemID]['participant_count'] . "</td><td>{$actionlinks}</td>";
162
163
164
        }
      }
    }
Monish Deb's avatar
Monish Deb committed
165
166
  }

167
168
169
170
171
172
173
174
  /**
   * Function used to return total tax amount of a contribution, calculated from associated line item records
   *
   * @param int $contributionID
   *
   * @return money
   *       total tax amount in money format
   */
Monish Deb's avatar
Monish Deb committed
175
  public static function getTaxAmountTotalFromContributionID($contributionID) {
176
177
178
179
    $taxAmount = CRM_Core_DAO::singleValueQuery("SELECT SUM(COALESCE(tax_amount,0)) FROM civicrm_line_item WHERE contribution_id = $contributionID AND qty > 0 ");
    return CRM_Utils_Money::format($taxAmount, NULL, NULL, TRUE);
  }

Monish Deb's avatar
Monish Deb committed
180
181
182
  /**
   * Function used to enter financial records upon addition of lineItem
   *
Monish Deb's avatar
Monish Deb committed
183
   * @param int $lineItem
Monish Deb's avatar
Monish Deb committed
184
185
186
   * @param CRM_Financial_DAO_FinancialTrxn $trxn
   *
   */
187
  public static function insertFinancialItemOnAdd($lineItem, $trxn) {
Monish Deb's avatar
Monish Deb committed
188
189
    $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $lineItem['contribution_id']));

Monish Deb's avatar
Monish Deb committed
190
    $accountRelName = self::getFinancialAccountRelationship($contribution['id'], $lineItem['id']);
Monish Deb's avatar
Monish Deb committed
191
    $revenueFinancialAccountID = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount(
192
      $lineItem['financial_type_id'],
193
      $accountRelName
Monish Deb's avatar
Monish Deb committed
194
195
196
197
198
    );

    $newFinancialItem = array(
      'transaction_date' => date('YmdHis'),
      'contact_id' => $contribution['contact_id'],
199
      'description' => ($lineItem['qty'] != 1 ? $lineItem['qty'] . ' of ' : '') . $lineItem['label'],
Monish Deb's avatar
Monish Deb committed
200
201
      'amount' => $lineItem['line_total'],
      'currency' => $contribution['currency'],
Monish Deb's avatar
Monish Deb committed
202
      'financial_account_id' => $revenueFinancialAccountID,
Monish Deb's avatar
Monish Deb committed
203
204
205
206
      'status_id' => array_search('Unpaid', CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id')),
      'entity_table' => 'civicrm_line_item',
      'entity_id' => $lineItem['id'],
    );
207
    $trxnId = array('id' => $trxn);
Monish Deb's avatar
Monish Deb committed
208
209

    // create financial item for added line item
210
    $newFinancialItemDAO = CRM_Financial_BAO_FinancialItem::create($newFinancialItem, NULL, $trxnId);
Monish Deb's avatar
Monish Deb committed
211
    if (!empty($lineItem['tax_amount']) && $lineItem['tax_amount'] != 0) {
Monish Deb's avatar
Monish Deb committed
212
213
      $taxTerm = CRM_Utils_Array::value('tax_term', Civi::settings()->get('contribution_invoice_settings'));
      $taxFinancialItemInfo = array_merge($newFinancialItem, array(
214
        'amount' => $lineItem['tax_amount'],
Monish Deb's avatar
Monish Deb committed
215
        'description' => $taxTerm,
216
        'financial_account_id' => self::getFinancialAccountId($lineItem['financial_type_id']),
Monish Deb's avatar
Monish Deb committed
217
218
219
220
      ));
      // create financial item for tax amount related to added line item
      CRM_Financial_BAO_FinancialItem::create($taxFinancialItemInfo, NULL, $trxnId);
    }
221
222

    $lineItem['financial_item_id'] = $newFinancialItemDAO->id;
223
    self::createDeferredTrxn($contribution['id'], $lineItem, 'addLineItem');
224
225
226
227
228
229
230
  }

  /**
   * Function used to enter deferred revenue records upon add/edit/cancel of lineitem
   *
   * @param int $contributionID
   * @param array $lineItem
Monish Deb's avatar
Monish Deb committed
231
   * @param string $context
232
233
   *
   */
Monish Deb's avatar
Monish Deb committed
234
  public static function createDeferredTrxn($contributionID, $lineItem, $context) {
235
    if (CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled')) {
Monish Deb's avatar
Monish Deb committed
236
237
238
239
      $lineItem = array($contributionID => array($lineItem['id'] => $lineItem));
      CRM_Core_BAO_FinancialTrxn::createDeferredTrxn($lineItem, $contributionID, TRUE, $context);
    }
  }
240
241
242
243
244

  /**
   * Function used to enter/update financial records upon edit of lineItem
   *
   * @param int $lineItemID
Monish Deb's avatar
Monish Deb committed
245
   * @param array $previousLineItem
246
247
   *
   */
Monish Deb's avatar
Monish Deb committed
248
  public static function insertFinancialItemOnEdit($lineItemID, $previousLineItem) {
249
250
251
    $lineItem = civicrm_api3('LineItem', 'Getsingle', array(
      'id' => $lineItemID,
    ));
Pradeep Nayak's avatar
Pradeep Nayak committed
252
253
254
255
256
257
258
259
    $lineItem['tax_amount'] = $taxAmount = CRM_Utils_Array::value('tax_amount', $lineItem, 0);
    $newLineTotal = $lineItem['line_total'] + $lineItem['tax_amount'];
    $oldLineTotal = $previousLineItem['line_total'] + CRM_Utils_Array::value('tax_amount', $previousLineItem, 0);
    $recordChangedAttributes = array(
      'financialTypeChanged' => ($lineItem['financial_type_id'] != $previousLineItem['financial_type_id']),
      'amountChanged' => ($newLineTotal != $oldLineTotal),
      'taxAmountChanged' => ($lineItem['tax_amount'] != CRM_Utils_Array::value('tax_amount', $previousLineItem, 0)),
    );
260
261

    $previousFinancialItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($lineItemID);
262
263
264
265
266
    $financialItem = array(
      'transaction_date' => date('YmdHis'),
      'contact_id' => $previousFinancialItem['contact_id'],
      'description' => $previousFinancialItem['description'],
      'currency' => $previousFinancialItem['currency'],
267
      'financial_account_id' => $previousFinancialItem['financial_account_id'],
268
269
270
      'entity_id' => $lineItemID,
      'entity_table' => 'civicrm_line_item',
    );
Pradeep Nayak's avatar
Pradeep Nayak committed
271
272
273

    $balanceTaxAmount = $lineItem['tax_amount'] - CRM_Utils_Array::value('tax_amount', $previousLineItem, 0);
    $balanceAmount = $lineItem['line_total'] - $previousLineItem['line_total'];
274
275
    if ($recordChangedAttributes['financialTypeChanged']) {
      self::recordChangeInFT(
276
        $lineItem,
277
        $previousLineItem,
278
        $financialItem
279
280
      );
    }
Monish Deb's avatar
Monish Deb committed
281

282
283
    // if amount is changed
    if ($recordChangedAttributes['amountChanged']) {
284
      $financialItem['description'] = ($lineItem['qty'] > 1 ? $lineItem['qty'] . ' of ' : '') . $lineItem['label'];
285
286
287
288
289
290
291
      self::recordChangeInAmount(
        $lineItem['contribution_id'],
        $financialItem,
        $balanceAmount,
        $balanceTaxAmount,
        $recordChangedAttributes['taxAmountChanged']
      );
292
    }
Monish Deb's avatar
Monish Deb committed
293
294
  }

295
  public static function getRelatedCancelFinancialTrxn($financialItemID) {
Monish Deb's avatar
Monish Deb committed
296
    $query = "SELECT ft.*
297
298
299
300
301
302
   FROM civicrm_financial_trxn ft
   INNER JOIN civicrm_entity_financial_trxn eft ON eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_financial_item'
   WHERE eft.entity_id = %1
   ORDER BY eft.id DESC
   LIMIT 1; ";

Monish Deb's avatar
Monish Deb committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
    $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($financialItemID, 'Integer')));
    $financialTrxn = array();
    while ($dao->fetch()) {
      $financialTrxn = $dao->toArray();
      unset($financialTrxn['id']);
      $financialTrxn = array_merge($financialTrxn, array(
        'trxn_date' => date('YmdHis'),
        'total_amount' => -$financialTrxn['total_amount'],
        'net_amount' => -$financialTrxn['net_amount'],
        'entity_table' => 'civicrm_financial_item',
        'entity_id' => $financialItemID,
      ));
    }

    return $financialTrxn;
  }
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  /**
   * Function used fetch the latest Sale tax related financial item
   *
   * @param int $entityId
   *
   * @return array
   *       FinancialItem.Get API results
   */
  public static function getPreviousTaxableFinancialItem($entityId) {
    $params = array(
      'entity_id' => $entityId,
      'entity_table' => 'civicrm_line_item',
      'options' => array('limit' => 1, 'sort' => 'id DESC'),
    );
    $salesTaxFinancialAccounts = civicrm_api3('FinancialAccount', 'get', array('is_tax' => 1));
    if ($salesTaxFinancialAccounts['count']) {
      $params['financial_account_id'] = array('IN' => array_keys($salesTaxFinancialAccounts['values']));
    }
    return civicrm_api3('FinancialItem', 'get', $params);
  }

341
342
343
344
  /**
   * Function used to return list of price fields,
   *   later used in 'Add item' form
   *
Monish Deb's avatar
Monish Deb committed
345
346
   * @return array|int $priceFields
   *      list of price fields OR count of price fields
347
   */
Monish Deb's avatar
Monish Deb committed
348
  public static function getPriceFieldLists($contributionID, $getCount = FALSE) {
Monish Deb's avatar
Monish Deb committed
349

350
351
352
    $sql = "
SELECT    pfv.id as pfv_id,
          pfv.label as pfv_label,
Monish Deb's avatar
Monish Deb committed
353
          pf.id as pf_id,
354
355
          ps.title as ps_label,
          ps.is_quick_config as is_quick,
Monish Deb's avatar
Monish Deb committed
356
          ps.id as set_id
357
358
359
FROM      civicrm_price_field_value as pfv
LEFT JOIN civicrm_price_field as pf ON (pf.id = pfv.price_field_id)
LEFT JOIN civicrm_price_set as ps ON (ps.id = pf.price_set_id AND ps.is_active = 1)
360
LEFT JOIN civicrm_line_item as cli ON cli.contribution_id = {$contributionID} AND cli.qty != 0 AND pf.id = cli.price_field_id
Pradeep Nayak's avatar
Pradeep Nayak committed
361
362
WHERE  ps.is_quick_config = 0 AND ((cli.id IS NULL )  || (pf.html_type = 'Checkbox' AND pfv.id NOT IN (SELECT price_field_value_id FROM civicrm_line_item
  WHERE contribution_id = {$contributionID} AND qty <> 0))) AND ps.id IN (SELECT pf.price_set_id FROM civicrm_line_item cli
363
364
  INNER JOIN civicrm_price_field as pf ON (pf.id = cli.price_field_id AND cli.contribution_id = {$contributionID})
)
365
366
367
ORDER BY  ps.id, pf.weight ;
";
    $dao = CRM_Core_DAO::executeQuery($sql);
Monish Deb's avatar
Monish Deb committed
368

369
370
    $priceFields = array();
    while ($dao->fetch()) {
Monish Deb's avatar
Monish Deb committed
371
      $priceFields[$dao->pfv_id] = sprintf("%s :: %s", $dao->ps_label, $dao->pfv_label);
372
373
    }

Monish Deb's avatar
Monish Deb committed
374
375
376
377
    if ($getCount) {
      return count($priceFields);
    }

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    return $priceFields;
  }

  /**
   * AJAX function used to return list of price field information
   *   on given price field value id as 'pfv_id'
   *
   * @return json
   *      list of price field information
   */
  public static function getPriceFieldInfo() {
    if (!empty($_GET['pfv_id'])) {
      $priceFieldValueID = $_GET['pfv_id'];
      $priceFieldValueInfo = civicrm_api3('PriceFieldValue', 'getsingle', array('id' => $priceFieldValueID));

      // calculate tax amount
      $contributeSettings = Civi::settings()->get('contribution_invoice_settings');
      $taxRates = CRM_Core_PseudoConstant::getTaxRates();
      if (!empty($contributeSettings['invoicing']) &&
        array_key_exists($priceFieldValueInfo['financial_type_id'], $taxRates)
      ) {
        $taxRate = $taxRates[$priceFieldValueInfo['financial_type_id']];
Monish Deb's avatar
Monish Deb committed
400
        $priceFieldValueInfo['tax_amount'] = CRM_Utils_Array::value('tax_amount', CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount(
401
402
          $priceFieldValueInfo['amount'],
          $taxRate
Monish Deb's avatar
Monish Deb committed
403
        ), 0.00);
404
405
406
407
408
409
      }

      return CRM_Utils_JSON::output(array(
        'qty' => 1,
        'label' => $priceFieldValueInfo['label'],
        'financial_type_id' => $priceFieldValueInfo['financial_type_id'],
410
411
412
        'unit_price' => CRM_Utils_Money::format($priceFieldValueInfo['amount'], NULL, NULL, TRUE),
        'line_total' => CRM_Utils_Money::format($priceFieldValueInfo['amount'], NULL, NULL, TRUE),
        'tax_amount' => CRM_Utils_Money::format(CRM_Utils_Array::value('tax_amount', $priceFieldValueInfo, 0.00), NULL, NULL, TRUE),
413
414
415
416
      ));
    }
  }

Monish Deb's avatar
Monish Deb committed
417
418
419
  /**
   * Function used to return lineItem fieldnames used for edit/add
   *
Monish Deb's avatar
Monish Deb committed
420
421
   * @param bool $isAddItem
   *
Monish Deb's avatar
Monish Deb committed
422
423
424
   * @return array
   *   array of field names
   */
Monish Deb's avatar
Monish Deb committed
425
  public static function getLineitemFieldNames($isAddItem = FALSE) {
Monish Deb's avatar
Monish Deb committed
426
    $fieldNames = [
Monish Deb's avatar
Monish Deb committed
427
428
429
430
431
      'label',
      'financial_type_id',
      'qty',
      'unit_price',
      'line_total',
Monish Deb's avatar
Monish Deb committed
432
    ];
433

Monish Deb's avatar
Monish Deb committed
434
435
436
437
    if ($isAddItem) {
      array_unshift($fieldNames, "price_field_value_id");
    }

438
439
440
441
442
443
444
    // if tax is enabled append tax_amount field name
    $contributeSettings = Civi::settings()->get('contribution_invoice_settings');
    if (!empty($contributeSettings['invoicing'])) {
      $fieldNames = array_merge($fieldNames, array('tax_amount'));
    }

    return $fieldNames;
Monish Deb's avatar
Monish Deb committed
445
446
  }

Monish Deb's avatar
Monish Deb committed
447
448
449
450
451
  /**
   * Record adjusted amount, copied from CRM_Event_BAO_Participant::recordAdjustedAmt(..) to tackle a core bug
   *
   * @param int $updatedAmount
   * @param int $contributionId
Monish Deb's avatar
Monish Deb committed
452
453
   * @param money $taxAmount
   * @param bool $createTrxn
454
   * @param bool $return
Monish Deb's avatar
Monish Deb committed
455
456
457
   *
   * @return bool|\CRM_Core_BAO_FinancialTrxn
   */
458
  public static function recordAdjustedAmt($updatedAmount, $contributionId, $taxAmount = NULL, $createTrxn = TRUE, $return = FALSE) {
459
460
461
462
    $contribution = civicrm_api3('Contribution', 'getsingle', array(
      'return' => array("total_amount"),
      'id' => $contributionId,
    ));
463
464
465
466
467
468
469
470
471
472
    $paidAmount = CRM_Utils_Array::value(
      'paid',
      CRM_Contribute_BAO_Contribution::getPaymentInfo(
        $contributionId,
        'contribution',
        FALSE,
        TRUE
      )
    );

473
474
    $balanceAmt = $updatedAmount - $paidAmount;
    if ($contribution['total_amount'] != $paidAmount) {
475
      $balanceAmt -= self::getPendingAmount($contributionId, $contribution['total_amount'], $paidAmount);
476
    }
Monish Deb's avatar
Monish Deb committed
477
478
479
480
481
482

    $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');

    $updatedContributionDAO = new CRM_Contribute_BAO_Contribution();
    $adjustedTrxn = $skip = FALSE;
    if ($balanceAmt) {
483
484
485
      if ($paidAmount <= 0 && $balanceAmt != 0) {
        $contributionStatusVal = 'Pending';
      }
Pradeep Nayak's avatar
Pradeep Nayak committed
486
487
488
      elseif ($updatedAmount == $paidAmount) {
        $contributionStatusVal = 'Completed';
      }
489
490
      elseif ($paidAmount && $updatedAmount > $paidAmount) {
        $contributionStatusVal = 'Partially paid';
Monish Deb's avatar
Monish Deb committed
491
      }
492
      elseif ($balanceAmt < $paidAmount) {
493
494
        $contributionStatusVal = 'Pending refund';
      }
495
      elseif ($balanceAmt = $paidAmount) {
Monish Deb's avatar
Monish Deb committed
496
497
498
        //skip updating the contribution status if no payment is made
        $skip = TRUE;
      }
499

Monish Deb's avatar
Monish Deb committed
500
501
      // update contribution status and total amount without trigger financial code
      // as this is handled in current BAO function used for change selection
502
      $contriParams = ['id' => $contributionId];
Monish Deb's avatar
Monish Deb committed
503
      if (!$skip) {
504
        $contriParams['contribution_status_id'] = array_search($contributionStatusVal, $contributionStatuses);
505
        if ($contributionStatusVal == 'Pending') {
506
          $contriParams['is_pay_later'] = TRUE;
507
        }
Monish Deb's avatar
Monish Deb committed
508
      }
509
510
511
512
513
514
515
516
      $updatedContribution = civicrm_api3(
        'Contribution',
        'getsingle',
        array(
          'id' => $contributionId,
          'return' => array('fee_amount'),
        )
      );
517
518
      $contriParams['total_amount'] = $updatedAmount;
      $contriParams['net_amount'] = $updatedAmount - CRM_Utils_Array::value('fee_amount', $updatedContribution, 0);
519
      if ($taxAmount) {
520
        $contriParams['tax_amount'] = $taxAmount;
521
      }
522
      $updatedContributionDAO->copyValues($contriParams);
Monish Deb's avatar
Monish Deb committed
523
      $updatedContributionDAO->save();
Monish Deb's avatar
Monish Deb committed
524

525
526
527
528
      if (!$createTrxn) {
        return NULL;
      }
      $adjustedTrxn = self::createFinancialTrxnEntry($contributionId, $balanceAmt);
Monish Deb's avatar
Monish Deb committed
529
    }
530

531
532
533
534
    if ($return) {
      return [$adjustedTrxn, $contriParams];
    }

Monish Deb's avatar
Monish Deb committed
535
536
    return $adjustedTrxn;
  }
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  /**
   * Function used to tell that given price field ID support variable Qty or not
   *
   * @param int $priceFieldValueID
   *
   * @return bool
   *
   */
  public static function isPriceFieldSupportQtyChange($priceFieldValueID) {
    $is_enter_qty = CRM_Core_DAO::singleValueQuery("SELECT pf.is_enter_qty
      FROM civicrm_price_field pf
      INNER JOIN civicrm_price_field_value pfv ON pfv.price_field_id = pf.id
      WHERE pfv.id = {$priceFieldValueID}
    ");
    return (bool) $is_enter_qty;
  }
554
555
556
557
558
559
560
561
562
563
564

  /**
   * Function used to cancel membership or participant registration
   *
   * @param int $entityID
   * @param string $entityTable
   *
   */
  public static function cancelEntity($entityID, $entityTable) {
    switch ($entityTable) {
      case 'civicrm_membership':
Monish Deb's avatar
Monish Deb committed
565
        $cancelStatusID = CRM_Core_PseudoConstant::getKey('CRM_Member_BAO_Membership', 'status_id', 'Cancelled');
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
        civicrm_api3('Membership', 'create', array(
          'id' => $entityID,
          'status_id' => $cancelStatusID,
        ));
        break;

      case 'civicrm_participant':
        civicrm_api3('Participant', 'create', array(
          'id' => $entityID,
          'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'status_id', 'Cancelled'),
        ));
        break;

      default:
        break;
    }
  }
583
584
585
586
587
588
589
590
591
592

  /**
   * Function used to add membership or participant record on adding related line-item
   *
   * @param int $priceFieldValueID
   * @param int $contributionID
   * @param int $qty
   *
   * @return array
   */
593
  public static function addEntity($priceFieldValueID, $contributionID, $qty, $entityId = NULL) {
594
595
596
597
598
599
600
601
602
603
604
    $entityInfo = $eventID = NULL;
    $entityTable = 'civicrm_contribution';
    $entityID = $contributionID;

    $sql = "
    SELECT pf.price_set_id as ps_id, pfv.membership_type_id mt_id, pfv.membership_num_terms m_nt, pfv.label as pfv_label, pfv.amount as pfv_amount
    FROM civicrm_price_field pf
    INNER JOIN civicrm_price_field_value pfv ON pfv.price_field_id = pf.id
    WHERE pfv.id = %1
     ";

Monish Deb's avatar
Monish Deb committed
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
    $dao = CRM_Core_DAO::executeQuery($sql, array(1 => array($priceFieldValueID, 'Integer')));
    while ($dao->fetch()) {
      $entityInfo = $dao->toArray();
      break;
    }

    if (!empty($entityInfo['mt_id'])) {
      $entityTable = 'civicrm_membership';
    }
    elseif (!$entityId) {
      try {
        $result = civicrm_api3('LineItem', 'getsingle', array(
          'return' => array("entity_id", 'entity_table'),
          'contribution_id' => $contributionID,
          'entity_table' => 'civicrm_participant',
          'options' => array('limit' => 1),
        ));
        $entityId = $result['entity_id'];
        $entityTable = 'civicrm_participant';
      }
      catch (CiviCRM_API3_Exception $e) {
        // do nothing.
      }
    }

    switch ($entityTable) {
      case 'civicrm_membership':
632
        $memTypeNumTerms = CRM_Utils_Array::value('m_nt', $entityInfo, 1);
633
        $memTypeNumTerms = $qty * $memTypeNumTerms;
634
        // NOTE: membership.create API already calculate membership dates
635
        $params = array(
636
637
638
          'membership_type_id' => $entityInfo['mt_id'],
          'contact_id' => CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionID, 'contact_id'),
          'num_terms' => $memTypeNumTerms,
639
640
641
642
          'skipLineItem' => TRUE,
        );
        if ($entityId) {
          $params['id'] = $entityId;
643
          $params['skipStatusCal'] = FALSE;
644
645
        }
        $membership = civicrm_api3('Membership', 'create', $params);
646
647
648
649
650
651
        $entityID = $membership['id'];
        civicrm_api3('MembershipPayment', 'create', array(
          'membership_id' => $entityID,
          'contribution_id' => $contributionID,
        ));
        break;
Monish Deb's avatar
Monish Deb committed
652
    }
653

Monish Deb's avatar
Monish Deb committed
654
    return array($entityTable, $entityID);
655
656
  }

657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  public static function recordChangeInAmount(
    $contributionId,
    $financialItem,
    $balanceAmount,
    $balanceTaxAmount,
    $taxAmountChanged
  ) {
    $trxnId = self::createFinancialTrxnEntry($contributionId, $balanceAmount + $balanceTaxAmount);
    $trxnId = array('id' => $trxnId);
    $lineItem = civicrm_api3(
      'lineItem',
      'getsingle',
      array(
        'id' => $financialItem['entity_id'],
      )
    );
    $financialItem['amount'] = $balanceAmount;
    $financialItem['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Unpaid');
Monish Deb's avatar
Monish Deb committed
675
    $accountRelName = self::getFinancialAccountRelationship($contributionId, $financialItem['entity_id']);
676
    $financialItem['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($lineItem['financial_type_id'], $accountRelName);
677
    $ftItem = CRM_Financial_BAO_FinancialItem::create($financialItem, NULL, $trxnId);
Pradeep Nayak's avatar
Pradeep Nayak committed
678
    if ($taxAmountChanged && $balanceTaxAmount != 0) {
679
680
681
682
683
684
685
686
687
      $taxTerm = CRM_Utils_Array::value('tax_term', Civi::settings()->get('contribution_invoice_settings'));
      $taxFinancialItemInfo = array_merge($financialItem, array(
        'amount' => $balanceTaxAmount,
        'description' => $taxTerm,
        'financial_account_id' => CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($lineItem['financial_type_id'], 'Sales Tax Account is'),
      ));
      // create financial item for tax amount related to added line item
      CRM_Financial_BAO_FinancialItem::create($taxFinancialItemInfo, NULL, $trxnId);
    }
688
689
    $lineItem['deferred_line_total'] = $balanceAmount;
    $lineItem['financial_item_id'] = $ftItem->id;
690
    self::createDeferredTrxn($contributionId, $lineItem, 'UpdateLineItem');
691
692
693
  }

  public static function recordChangeInFT(
694
695
    $newLineItem,
    $prevLineItem,
696
697
    $financialItem
  ) {
698
699
700
701
702
703
    $contributionId = $newLineItem['contribution_id'];
    $contribution = civicrm_api3(
      'Contribution',
      'getsingle',
      array(
        'id' => $contributionId,
Pradeep Nayak's avatar
Pradeep Nayak committed
704
        'return' => array('payment_instrument_id'),
705
706
707
      )
    );

Monish Deb's avatar
Monish Deb committed
708
    $accountRelName = self::getFinancialAccountRelationship($contributionId, $newLineItem['id']);
709
    $prevLineItem['deferred_line_total'] = -($prevLineItem['line_total']);
710
711
712
713
714
    $trxnArray[1] = array(
      'ft_amount' => -($prevLineItem['line_total'] + $prevLineItem['tax_amount']),
      'fi_amount' => -$prevLineItem['line_total'],
      'tax_amount' => -$prevLineItem['tax_amount'],
      'tax_ft' => $prevLineItem['financial_type_id'],
715
      'deferred_line_item' => $prevLineItem,
716
    );
Pradeep Nayak's avatar
Pradeep Nayak committed
717
718
719
    $taxRates = CRM_Core_PseudoConstant::getTaxRates();
    $taxRates = CRM_Utils_Array::value($newLineItem['financial_type_id'], $taxRates, 0);
    $newtax = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($prevLineItem['line_total'], $taxRates);
720
    $trxnArray[2] = array(
Pradeep Nayak's avatar
Pradeep Nayak committed
721
      'ft_amount' => ($prevLineItem['line_total'] + $newtax['tax_amount']),
Pradeep Nayak's avatar
Pradeep Nayak committed
722
      'fi_amount' => $prevLineItem['line_total'],
Pradeep Nayak's avatar
Pradeep Nayak committed
723
      'tax_amount' => $newtax['tax_amount'],
724
      'tax_ft' => $newLineItem['financial_type_id'],
725
      'deferred_line_item' => $newLineItem,
726
727
728
729
730
    );
    $trxnArray[2]['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($newLineItem['financial_type_id'], $accountRelName);

    $trxnArray[1]['to_financial_account_id'] = $trxnArray[2]['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']);

Pradeep Nayak's avatar
Pradeep Nayak committed
731
    $financialItem['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid');
732
733
734
735
736
737
738
    foreach ($trxnArray as $values) {
      $trxnId = self::createFinancialTrxnEntry($contributionId, $values['ft_amount'], $values['to_financial_account_id']);
      if (!empty($values['financial_account_id'])) {
        $financialItem['financial_account_id'] = $values['financial_account_id'];
      }
      $financialItem['amount'] = $values['fi_amount'];
      $trxnId = array('id' => $trxnId);
739
      $ftItem = CRM_Financial_BAO_FinancialItem::create($financialItem, NULL, $trxnId);
740
741
742
743
744
745
746
747
748
749
      if ($values['tax_amount'] != 0) {
        $taxTerm = CRM_Utils_Array::value('tax_term', Civi::settings()->get('contribution_invoice_settings'));
        $taxFinancialItemInfo = array_merge($financialItem, array(
          'amount' => $values['tax_amount'],
          'description' => $taxTerm,
          'financial_account_id' => CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($values['tax_ft'], 'Sales Tax Account is'),
        ));
        // create financial item for tax amount related to added line item
        CRM_Financial_BAO_FinancialItem::create($taxFinancialItemInfo, NULL, $trxnId);
      }
750
      $values['deferred_line_item']['financial_item_id'] = $ftItem->id;
751
      self::createDeferredTrxn($contributionId, $values['deferred_line_item'], 'UpdateLineItem');
752
    }
753
754
755
756
  }

  public static function createFinancialTrxnEntry($contributionId, $amount, $toFinancialAccount = NULL) {
    $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $contributionId));
Pradeep Nayak's avatar
Pradeep Nayak committed
757
    $isPayment = TRUE;
758
759
    if (!$toFinancialAccount) {
      $toFinancialAccount = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contribution['financial_type_id'], 'Accounts Receivable Account is');
Pradeep Nayak's avatar
Pradeep Nayak committed
760
      $isPayment = FALSE;
761
762
763
764
765
766
    }
    $adjustedTrxnValues = array(
      'from_financial_account_id' => NULL,
      'to_financial_account_id' => $toFinancialAccount,
      'total_amount' => $amount,
      'net_amount' => $amount,
Pradeep Nayak's avatar
Pradeep Nayak committed
767
      // TODO: What should be status incase of FT change?
768
769
770
771
772
      'status_id' => $contribution['contribution_status_id'],
      'payment_instrument_id' => $contribution['payment_instrument_id'],
      'contribution_id' => $contributionId,
      'trxn_date' => date('YmdHis'),
      'currency' => $contribution['currency'],
Pradeep Nayak's avatar
Pradeep Nayak committed
773
      'is_payment' => $isPayment,
774
775
776
777
778
    );
    $adjustedTrxn = CRM_Core_BAO_FinancialTrxn::create($adjustedTrxnValues);
    return $adjustedTrxn->id;
  }

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
  public static function getPendingAmount($contributionId, $contributionAmount, $paidAmount) {
    $contributionFinancialTypeId = CRM_Core_DAO::getFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'financial_type_id');
    $toFinancialAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionFinancialTypeId, 'Accounts Receivable Account is');
    $hasARAmount = civicrm_api3('EntityFinancialTrxn', 'getCount', array(
      'financial_trxn_id.status_id' => "Pending",
      'entity_table' => "civicrm_contribution",
      'entity_id' => $contributionId,
      'financial_trxn_id.to_financial_account_id' => $toFinancialAccountId,
    ));
    if ($hasARAmount) {
      $pendingAmount = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId);
      $pendingAmount = CRM_Utils_Array::value('total_amount', $pendingAmount, 0);
      $pendingAmount -= $paidAmount;
    }
    else {
      $pendingAmount = $contributionAmount - $paidAmount;
    }
    return $pendingAmount;
797
798
  }

Monish Deb's avatar
Monish Deb committed
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
  /**
   * Function to decide account relationship name for financial entries.
   *
   * @param int $contributionId
   *
   * @param int $lineItemId
   *
   * @return string
   */
  public static function getFinancialAccountRelationship($contributionId, $lineItemId = NULL) {
    $accountRelName = 'Income Account is';
    $contribution = civicrm_api3('Contribution', 'getSingle', array(
      'return' => array("revenue_recognition_date", "receive_date"),
      'id' => $contributionId,
    ));
    $date = CRM_Utils_Array::value('receive_date', $contribution);
    if (!$date) {
      $date = date('Ymt');
    }
    else {
      $date = date('Ymt', strtotime($date));
    }
    $isMembership = FALSE;
    if ($lineItemId) {
      $result = civicrm_api3('LineItem', 'getsingle', array(
        'return' => array("price_field_value_id.membership_type_id"),
        'id' => $lineItemId,
      ));
      if (!empty($result['price_field_value_id.membership_type_id'])) {
        $isMembership = TRUE;
      }
    }
    if (!empty($contribution['revenue_recognition_date'])
      && (date('Ymt', strtotime($contribution['revenue_recognition_date'])) > $date
        || $isMembership
      )
    ) {
      $accountRelName = 'Deferred Revenue Account is';
    }
    return $accountRelName;
  }
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860

  /**
   * Get financial account id has 'Sales Tax Account is' account relationship with financial type.
   *
   * @param int $financialTypeId
   *
   * @return int
   *   Financial Account Id
   */
  public static function getFinancialAccountId($financialTypeId) {
    $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
    $searchParams = array(
      'entity_table' => 'civicrm_financial_type',
      'entity_id' => $financialTypeId,
      'account_relationship' => $accountRel,
    );
    $result = array();
    CRM_Financial_BAO_FinancialTypeAccount::retrieve($searchParams, $result);
    return CRM_Utils_Array::value('financial_account_id', $result);
  }

861
862
863
864
865
866
867
  /**
   * Build lineitem rows and assign other form variables
   *
   * @param CRM_Contribute_Form_Contribution $form
   * @param int $contributionID
   *
   */
Monish Deb's avatar
Monish Deb committed
868
869
870
  public static function buildLineItemRows(&$form, $contributionID = NULL) {
    $fields = CRM_Lineitemedit_Util::getLineitemFieldNames(TRUE);
    $submittedValues = $pvIDs = [];
871
872
    $chapterCodes = CRM_Core_OptionGroup::values('chapter_codes');
    $fundCodes = CRM_Core_OptionGroup::values('fund_codes');
Monish Deb's avatar
Monish Deb committed
873
874
875
876
877
    if (!empty($contributionID)) {
      $options = CRM_Lineitemedit_Util::getPriceFieldLists($contributionID) + ['new' => ts('Create new item')];
      $pvIDs = array_keys($options);
      $form->add('select', 'add_item', ts('Add item'), ['' => '- select any price-field -'] + $options);
    }
Monish Deb's avatar
Monish Deb committed
878
    for ($rowNumber = 0; $rowNumber <= 10; $rowNumber++) {
Monish Deb's avatar
Monish Deb committed
879
880
881
      if (!empty($_POST['item_unit_price']) && !empty($_POST['item_unit_price'][$rowNumber])) {
        $submittedValues[] = $rowNumber;
      }
882
883
884
885
886
887
888
889
      $form->add('select', "item_chapter_code[$rowNumber]",
        ts('Chapter Code'),
        $chapterCodes
      );
      $form->add('select', "item_fund_code[$rowNumber]",
        ts('Fund Code'),
        $fundCodes
      );
Monish Deb's avatar
Monish Deb committed
890
891
      foreach ($fields as $fieldName) {
        if ($fieldName != 'price_field_value_id') {
892
893
          if (in_array($fieldName, ['line_total', 'tax_amount'])) {
            $form->add('text', "item_{$fieldName}[$rowNumber]", NULL, array(
Monish Deb's avatar
Monish Deb committed
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
              'size' => 6,
              'maxlength' => 14,
              'readonly' => TRUE)
            );
            continue;
          }
          $properties = array(
            'entity' => 'LineItem',
            'name' => $fieldName,
            'context' => 'add',
            'action' => 'create',
          );
          if ($fieldName == 'financial_type_id') {
            CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes);
            $properties['options'] = $financialTypes;
          }
          elseif ($fieldName == 'qty') {
            $properties['size'] = 2;
          }
          elseif ($fieldName == 'label') {
            $properties['size'] = 20;
          }
          $fieldName = sprintf("item_%s[%d]", $fieldName, $rowNumber);
          $form->addField($fieldName, $properties);
          if ($fieldName == "item_unit_price[$rowNumber]") {
            $form->addRule($fieldName, ts('Please enter a monetary value for this field.'), 'money');
          }
          elseif ($fieldName == "item_qty[$rowNumber]") {
            $form->addRule($fieldName, ts('Qty must be a number (with or without decimal point).'), 'numeric');
            $form->setDefaults([$fieldName => 1.00]);
          }
        }
        else {
          $form->add('text', "item_price_field_value_id[$rowNumber]", '', ['size' => 2, 'class' => 'hiddenElement']);
          if (count($pvIDs) > 0) {
            $pvID = $pvIDs[key($pvIDs)];
            $form->setDefaults(["item_price_field_value_id[$rowNumber]" => $pvID]);
            if ($pvID != 'new') {
              unset($pvIDs[key($pvIDs)]);
            }
          }
          else {
Monish Deb's avatar
Monish Deb committed
936
937
938
939
940
941
            if ($rowNumber == 0) {
              $priceFieldValue = civicrm_api3('PriceFieldValue', 'get', ['name' => 'contribution_amount']);
            }
            else {
              $priceFieldValue = civicrm_api3('PriceFieldValue', 'get', ['name' => 'additional_item_' . $rowNumber]);
            }
Monish Deb's avatar
Monish Deb committed
942
943
944
945
946
            $form->setDefaults(["item_price_field_value_id[$rowNumber]" => $priceFieldValue['id']]);
          }
        }
      }
    }
947
948
949
    $contributeSettings = Civi::settings()->get('contribution_invoice_settings');
    $form->assign('taxEnabled', (!empty($contributeSettings['invoicing'])));
    $form->assign('taxRates', json_encode(CRM_Core_PseudoConstant::getTaxRates()));
Monish Deb's avatar
Monish Deb committed
950
    $form->assign('lineItemSubmitted', json_encode($submittedValues));
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
  }

  /**
   * Build lineitem rows and assign other form variables
   *
   * @param int $contributionID
   *
   */
  public static function createPriceFieldByContributionID($contributionID) {
    $previousLineItem = civicrm_api3('LineItem', 'getsingle', [
      'contribution_id' => $contributionID,
      'options' => ['limit' => 1],
    ]);

    $priceSetID = civicrm_api3('PriceField', 'getvalue', ['id' => $previousLineItem['price_field_id'], 'return' => 'price_set_id']);
    $totalPF = civicrm_api3('PriceField', 'getcount', ['price_set_id' => $priceSetID]);

    $newPriceField = civicrm_api3('PriceField', 'create', [
      'label' => ts('Additional Lineitem ' . $totalPF),
      'price_set_id' => $priceSetID,
      'html_type' => "Text",
      'is_enter_qty' => FALSE,
      'is_required' => FALSE,
      'visibility_id' => "admin",
    ]);

    $newPriceFieldValue = civicrm_api3('PriceFieldValue', 'create', [
      'label' => ts('Additional Lineitem ' . $totalPF),
      'price_field_id' => $newPriceField['id'],
      'amount' => 1.00,
      'financial_type_id' => civicrm_api3('PriceFieldValue', 'getvalue', ['id' => $previousLineItem['price_field_value_id'], 'return' => 'financial_type_id']),
    ]);

    return [$newPriceField['id'], $newPriceFieldValue['id']];
  }

  public static function generatePriceField() {
    $priceField = civicrm_api3('PriceField',
      'getsingle',
      [
        'price_set_id' => civicrm_api3('PriceSet', 'getvalue', ['name' => 'default_contribution_amount', 'return' => 'id']),
        'options' => ['limit' => 1],
      ]
    );
    $priceFieldParams = $priceField;
    unset($priceFieldParams['id'], $priceFieldParams['name'], $priceFieldParams['weight'], $priceFieldParams['is_required']);
    $priceFieldValue = civicrm_api3('PriceFieldValue',
      'getsingle',
      [
        'price_field_id' => $priceField['id'],
For faster browsing, not all history is shown. View entire blame