BkfNewContact.php 12.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
/**
 * @author Jaap Jansma <jaap.jansma@civicoop.org>
 * @license AGPL-3.0
 */

use CRM_Barnekreftbanking_ExtensionUtil as E;

class CRM_Banking_PluginImpl_Matcher_BkfNewContact extends CRM_Banking_PluginModel_Matcher {

  /**
   * class constructor
   */
  function __construct($config_name) {
    parent::__construct($config_name);

    // read config, set defaults
    $config = $this->_plugin_config;
    if (!isset($config->auto_exec))              $config->auto_exec = false;
    if (!isset($config->threshold))              $config->threshold = 0.0;
jaapjansma's avatar
jaapjansma committed
21
22
23
24
25
26
27
    if (!isset($config->penalties)) {
     $penalty = new stdClass();
     $penalty->type = 'constant';
     $penalty->amount = 0.5;
     $config->penalties[] = $penalty;
    }

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    if (!isset($config->skip_fields)) {
      $config->skip_fields = [
        'contribution_page_id',
        'receive_date',
        'non_deductible_amount',
        'total_amount',
        'fee_amount',
        'net_amount',
        'contribution_status_id',
        'trxn_id',
        'invoice_id',
        'invoice_number',
        'currency',
        'cancel_date',
        'cancel_reason',
        'receipt_date',
        'thankyou_date',
        'amount_level',
        'contribution_recur_id',
        'is_test',
        'is_pay_later',
        'creditnote_id',
        'tax_amount',
        'revenue_recognition_date',
        'id',
        'contact_id',
        'address_id',
        'check_number',
        'payment_processor',
        'soft_credit_to',
        'honor_contact_id',
        'honor_type_id',
        'skipRecentView',
        'skipLineItem',
        'batch_id',
        'refund_trxn_id',
        'card_type_id'
      ];
    }
  }

  /**
   * Returns whether the plugin is configured to execute unsupervised
   *
   * @return bool
   */
  function autoExecute() {
    return false;
  }

  public function match(CRM_Banking_BAO_BankTransaction $btx, CRM_Banking_Matcher_Context $context) {
    $config = $this->_plugin_config;
    $threshold   = $this->getThreshold();
    $penalty     = $this->getPenalty($btx);
    $data_parsed = $btx->getDataParsed();

    $suggestion = new CRM_Banking_Matcher_Suggestion($this, $btx);
    $suggestion->setTitle(E::ts("Create a new contact with a contribution"));
    $probability = 1.0 - $penalty;
    if ($probability >= $threshold) {
      $suggestion->setProbability($probability);
      $btx->addSuggestion($suggestion);
    }

    return empty($this->_suggestions) ? null : $this->_suggestions;
  }

  /**
   * Generate html code to visualize the given match. The visualization may also provide interactive form elements.
   *
   * @val $match    match data as previously generated by this plugin instance
   * @val $btx      the bank transaction the match refers to
   * @return html code snippet
   */
  function visualize_match( CRM_Banking_Matcher_Suggestion $match, $btx) {
jaapjansma's avatar
jaapjansma committed
103
104
105
    $location_types = civicrm_api3('Address', 'getoptions', ['field' => 'location_type_id', 'api_action' => 'create']);
    $contact_types = civicrm_api3('Contact', 'getoptions', ['field' => 'contact_type', 'api_action' => 'create']);

106
107
108
    $skipContributionFields = $this->_plugin_config->skip_fields;
    $smarty_vars['data']  = $btx->getDataParsed();
    $data_parsed = $btx->getDataParsed();
jaapjansma's avatar
jaapjansma committed
109
110
111
112
113
114
115
116
    $bankKontoCustomFieldId = null;
    $defaultCampiagnId = null;
    try {
      $bankKontoCustomFieldId = civicrm_api3('CustomField', 'getvalue', ['name' => 'bankkonto', 'custom_group_id' => 'contribution_bankkonto', 'return' => 'id']);
      $defaultCampiagnId = civicrm_api3('Campaign', 'getvalue', ['name' => 'default_campaign', 'return' => 'id']);
    } catch (\Exception $e) {
      // Do nothing
    }
117
118

    $fields = [
jaapjansma's avatar
jaapjansma committed
119
      'contact.contact_type' => ['label' => E::ts('Contact type'), 'required' => true, 'options' => $contact_types['values']],
120
121
      'contact.first_name' => ['label' => E::ts('First name'), 'required' => true, 'size' => 64],
      'contact.last_name' => ['label' => E::ts('Last name'), 'required' => true, 'size' => 64],
jaapjansma's avatar
jaapjansma committed
122
123
124
      'contact.household_name' => ['label' => E::ts('Household name'), 'required' => true, 'size' => 64],
      'contact.organization_name' => ['label' => E::ts('Organization name'), 'required' => true, 'size' => 64],
      'address.location_type_id' => ['label' => E::ts('Location type'), 'required' => true, 'options' => $location_types['values']],
jaapjansma's avatar
update    
jaapjansma committed
125
      'address.supplemental_address_1' => ['label' => E::ts('Supplemental address'), 'required' => false, 'size' => 64],
jaapjansma's avatar
jaapjansma committed
126
127
128
      'address.street_address' => ['label' => E::ts('Street address'), 'required' => false, 'size' => 64],
      'address.postal_code' => ['label' => E::ts('Postal code'), 'required' => false, 'size' => 64],
      'address.city' => ['label' => E::ts('City'), 'required' => false, 'size' => 64],
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    ];

    $contributionFieldsApi = civicrm_api3('Contribution', 'getfields', ['api_action' => 'create']);
    foreach($contributionFieldsApi['values'] as $contributionField) {
      if (in_array($contributionField['name'], $skipContributionFields)) {
        continue;
      }
      $fields['contribution.'.$contributionField['name']] = [
        'label' => $contributionField['title'],
        'required' => isset($contributionField['api.required']) ? $contributionField['api.required'] : false,
      ];
      if (isset($contributionField['FKApiName'])) {
        $fields['contribution.'.$contributionField['name']]['FKApiName'] = $contributionField['FKApiName'];
      } elseif (isset($contributionField['pseudoconstant'])) {
        $options = civicrm_api3('Contribution', 'getoptions', [
          'field' => $contributionField['name'],
        ]);
        $fields['contribution.'.$contributionField['name']]['options'] = $options['values'];
      }
    }
    $smarty_vars['fields'] = $fields;

    $contact_params = $match->getParameter('contact_params');
    if (!is_array($contact_params)) {
jaapjansma's avatar
jaapjansma committed
153
154
155
156
157
      $contact_params['contact_type'] = 'Individual';
    }
    $address_params = $match->getParameter('address_params');
    if (!is_array($address_params)) {
      $address_params = [
158
159
160
161
162
        'street_address' => isset($data_parsed['street_address']) ? $data_parsed['street_address'] : null,
        'postal_code' => isset($data_parsed['postal_code']) ? $data_parsed['postal_code'] : null,
        'city' => isset($data_parsed['city']) ? $data_parsed['city'] : null,
      ];
    }
jaapjansma's avatar
jaapjansma committed
163
164
165
    if (!isset($address_params['location_type_id'])) {
      $address_params['location_type_id'] = civicrm_api3('LocationType', 'getvalue', ['is_default' => 1, 'return' => 'id']);
    }
166
167
168
169
170
171
172
    $contribution_params = $match->getParameter('contribution_params');
    if (!is_array($contribution_params)) {
      $contribution_params = [
        'payment_instrument_id' => isset($data_parsed['payment_instrument_id']) ? $data_parsed['payment_instrument_id'] : null,
        'financial_type_id' => 1, // Gave
        'note' => isset($data_parsed['purpose']) ? $data_parsed['purpose'] : null,
      ];
jaapjansma's avatar
jaapjansma committed
173
174
175
176
177
178
      if ($bankKontoCustomFieldId && isset($data_parsed['_NBAN_NO'])) {
        $contribution_params['custom_'.$bankKontoCustomFieldId] = $data_parsed['_NBAN_NO'];
      }
      if ($defaultCampiagnId) {
        $contribution_params['campaign_id'] = $defaultCampiagnId;
      }
179
180
181
182
183
    }
    $values = [];
    foreach($contact_params as $k => $v) {
      $values["contact.".$k] = $v;
    }
jaapjansma's avatar
jaapjansma committed
184
185
186
    foreach($address_params as $k => $v) {
      $values["address.".$k] = $v;
    }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    foreach($contribution_params as $k => $v) {
      $values["contribution.".$k] = $v;
    }
    $smarty_vars['values'] = $values;

    // assign to smarty and compile HTML
    $smarty = CRM_Core_Smarty::singleton();
    $smarty->pushScope($smarty_vars);
    $html_snippet = $smarty->fetch('CRM/Banking/PluginImpl/Matcher/BkfNewContact.suggestion.tpl');
    $smarty->popScope();
    return $html_snippet;
  }

  /**
   * If the user has modified the input fields provided by the "visualize" html code,
   * the new values will be passed here BEFORE execution
   *
   * CAUTION: there might be more parameters than provided. Only process the ones that
   *  'belong' to your suggestion.
   */
  public function update_parameters(CRM_Banking_Matcher_Suggestion $match, $parameters) {
    $contact_params = [];
    $contribution_params = [];
jaapjansma's avatar
jaapjansma committed
210
    $address_params = [];
211
212
213
    foreach($parameters as $key => $value) {
      if (stripos($key, "contact_") === 0) {
        $contact_params[substr($key, 8)] = $value;
jaapjansma's avatar
jaapjansma committed
214
215
      } elseif (stripos($key, "address_") === 0) {
        $address_params[substr($key, 8)] = $value;
216
217
218
219
220
      } elseif (stripos($key, "contribution_") === 0) {
        $contribution_params[substr($key, 13)] = $value;
      }
    }
    $match->setParameter('contact_params', $contact_params);
jaapjansma's avatar
jaapjansma committed
221
    $match->setParameter('address_params', $address_params);
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
    $match->setParameter('contribution_params', $contribution_params);
  }

  /**
   * Executes a previously generated match, i.e. the suggestion is accepted and realized
   *
   * Obviously, this method should be overwritten by the individual matchers,
   *  but DON'T forget to call parent::execute($match, $btx);
   *
   * @val $match    match data as previously generated by this plugin instance
   * @val $btx      the bank transaction the match refers to
   * @return the execution result:  TRUE       successfull
   *                                NULL/FALSE if not successfull
   *                                're-run'   if the analysis should be re-run (UI only)
   */
  public function execute( $match, $btx ) {
    $skipContributionFields = $this->_plugin_config->skip_fields;
    $contact_params = $match->getParameter('contact_params');
jaapjansma's avatar
jaapjansma committed
240
    $address_params = $match->getParameter('address_params');
241
242
    $contribution_params = $match->getParameter('contribution_params');

jaapjansma's avatar
jaapjansma committed
243
244
245
246
247
248
249
    if ($contact_params['contact_type'] == 'Individual' && (empty($contact_params['first_name']) || empty($contact_params['last_name']))) {
      return FALSE;
    }
    if ($contact_params['contact_type'] == 'Household' && empty($contact_params['household_name'])) {
      return FALSE;
    }
    if ($contact_params['contact_type'] == 'Organization' && empty($contact_params['organization_name'])) {
250
251
252
253
254
255
256
257
258
259
260
261
      return FALSE;
    }
    $contributionFieldsApi = civicrm_api3('Contribution', 'getfields', ['api_action' => 'create']);
    foreach($contributionFieldsApi['values'] as $contributionField) {
      if (!in_array($contributionField['name'], $skipContributionFields) && isset($contributionField['api.required']) && $contributionField['api.required'] && !isset($contribution_params[$contributionField['name']])) {
        return FALSE;
      }
    }

    $result = civicrm_api3('Contact', 'create', $contact_params);
    $contact_id = $result['id'];

jaapjansma's avatar
jaapjansma committed
262
263
264
265
266
    if (count($address_params) > 1) {
      $address_params['contact_id'] = $contact_id;
      civicrm_api3('Address', 'create', $address_params);
    }

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    $contribution_params['contact_id'] = $contact_id;
    $contribution_params['total_amount'] = $btx->amount;
    $contribution_params['receive_date'] = $btx->value_date;
    $contribution_params['currency'] = $btx->currency;
    $contribution_params['contribution_status_id'] = 1; //Completed

    $result = civicrm_api3('Contribution', 'create', $contribution_params);
    $contribution_id = $result['id'];
    $match->setParameter('contact_id', $contact_id);
    $match->setParameter('contribution_id', $contribution_id);

    // save the account
    $this->storeAccountWithContact($btx, $match->getParameter('contact_id'));

    // wrap it up
    $newStatus = banking_helper_optionvalueid_by_groupname_and_name('civicrm_banking.bank_tx_status', 'Processed');
jaapjansma's avatar
jaapjansma committed
283
284
285
    //$btx->setStatus($newStatus);
    //parent::execute($match, $btx);
    return FALSE;
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
    return TRUE;
  }

  /**
   * Generate html code to visualize the executed match.
   *
   * @val $match    match data as previously generated by this plugin instance
   * @val $btx      the bank transaction the match refers to
   * @return html code snippet
   */
  function visualize_execution_info( CRM_Banking_Matcher_Suggestion $match, $btx) {
    // just assign to smarty and compile HTML
    $smarty_vars = array();
    $smarty_vars['contribution_id'] = $match->getParameter('contribution_id');
    $smarty_vars['contact_id']      = $match->getParameter('contact_id');
    $smarty_vars['display_name'] = civicrm_api('Contact', 'getvalue', array('id' => $smarty_vars['contact_id'], 'return' => 'display_name', 'version' => 3));

    // assign to smarty and compile HTML
    $smarty = CRM_Banking_Helpers_Smarty::singleton();
    $smarty->pushScope($smarty_vars);
    $html_snippet = $smarty->fetch('CRM/Banking/PluginImpl/Matcher/BkfNewContact.execution.tpl');
    $smarty->popScope();
    return $html_snippet;
  }

}