4 +--------------------------------------------------------------------+
5 | CiviCRM version 4.3 |
6 +--------------------------------------------------------------------+
7 | Copyright CiviCRM LLC (c) 2004-2013 |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007. |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
20 | You should have received a copy of the GNU Affero General Public |
21 | License along with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2013
35 class CRM_Upgrade_Incremental_php_FourThree
{
36 const BATCH_SIZE
= 5000;
38 function verifyPreDBstate(&$errors) {
43 * Compute any messages which should be displayed after upgrade
45 * @param $postUpgradeMessage string, alterable
46 * @param $rev string, an intermediate version; note that setPostUpgradeMessage is called repeatedly with different $revs
49 function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
50 if ($rev == '4.3.alpha1') {
51 // check if CiviMember component is enabled
52 $config = CRM_Core_Config
::singleton();
53 if (in_array('CiviMember', $config->enableComponents
)) {
54 $postUpgradeMessage .= '<br />' . ts('Membership renewal reminders must now be configured using the Schedule Reminders feature, which supports multiple renewal reminders (Administer > Communications > Schedule Reminders). The Update Membership Statuses scheduled job will no longer send membershp renewal reminders. You can use your existing renewal reminder message template(s) with the Schedule Reminders feature.');
55 $postUpgradeMessage .= '<br />' . ts('The Set Membership Reminder Dates scheduled job has been deleted since membership reminder dates stored in the membership table are no longer in use.');
59 //here we do the financial type check and migration
60 $isDefaultsModified = self
::_checkAndMigrateDefaultFinancialTypes();
61 if($isDefaultsModified) {
62 $postUpgradeMessage .= '<br />' . ts('Please review all price set financial type assignments.');
64 list($context, $orgName) = self
::createDomainContacts();
65 if ($context == 'added') {
66 $postUpgradeMessage .= '<br />' . ts("A new organization contact has been added as the default domain contact using the information from your Organization Address and Contact Info settings: '{$orgName}'.");
68 elseif ($context == 'merged') {
69 $postUpgradeMessage .= '<br />' . ts("The existing organization contact record for '{$orgName}' has marked as the default domain contact, and has been updated with information from your Organization Address and Contact Info settings.");
73 if ($rev == '4.3.alpha2') {
76 FROM civicrm_action_schedule
77 WHERE entity_value = '' OR entity_value IS NULL
80 $dao = CRM_Core_DAO
::executeQuery($sql);
83 while ($dao->fetch()) {
84 $reminder[$dao->id
] = $dao->title
;
85 $list .= "<li>{$dao->title}</li>";
87 if (!empty($reminder)) {
88 $list = "<br /><ul>" . $list . "</ul>";
89 $postUpgradeMessage .= '<br />' .ts("Scheduled Reminders must be linked to one or more 'entities' (Events, Event Templates, Activity Types, Membership Types). The following reminders are not configured properly and will not be run. Please review them and update or delete them: %1", array(1 => $list));
93 if ($rev == '4.3.beta1') {
94 $postUpgradeMessage .= '<br />' . ts('Default versions of the following System Workflow Message Templates have been modified to handle new functionality: <ul><li>Events - Registration Confirmation and Receipt (on-line)</li><li>Events - Registration Confirmation and Receipt (off-line)</li><li>Pledges - Acknowledgement</li><li>Pledges - Payment Reminder</li><li>Contributions - Receipt (off-line)</li><li>Contributions - Receipt (on-line)</li><li>Memberships - Signup and Renewal Receipts (off-line)</li><li>Memberships - Receipt (on-line)</li><li>Personal Campaign Pages - Admin Notification</li></ul> If you have modified these templates, please review the new default versions and implement updates as needed to your copies (Administer > Communications > Message Templates > System Workflow Messages).');
99 function upgrade_4_3_alpha1($rev) {
100 self
::task_4_3_alpha1_checkDBConstraints();
102 // task to process sql
103 $this->addTask(ts('Upgrade DB to 4.3.alpha1: SQL'), 'task_4_3_x_runSql', $rev);
106 $this->addTask(ts('Populate financial type values for price records'), 'assignFinancialTypeToPriceRecords');
107 //CRM-11514 create financial records for contributions
108 $this->addTask(ts('Create financial records for contributions'), 'createFinancialRecords');
110 $minId = CRM_Core_DAO
::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contact');
111 $maxId = CRM_Core_DAO
::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contact');
112 for ($startId = $minId; $startId <= $maxId; $startId +
= self
::BATCH_SIZE
) {
113 $endId = $startId + self
::BATCH_SIZE
- 1;
114 $title = ts('Upgrade timestamps (%1 => %2)', array(
118 $this->addTask($title, 'convertTimestamps', $startId, $endId);
122 // fix WP access control
123 $config = CRM_Core_Config
::singleton( );
124 if ($config->userFramework
== 'WordPress') {
125 civicrm_wp_set_capabilities( );
128 // Update phones CRM-11292.
129 $this->addTask(ts('Upgrade Phone Numbers'), 'phoneNumeric');
134 function upgrade_4_3_alpha2($rev) {
136 $isColumnPresent = CRM_Core_DAO
::checkFieldExists('civicrm_dedupe_rule_group', 'is_default');
137 if ($isColumnPresent) {
138 CRM_Core_DAO
::executeQuery('ALTER TABLE civicrm_dedupe_rule_group DROP COLUMN is_default');
140 $this->addTask(ts('Upgrade DB to 4.3.alpha2: SQL'), 'task_4_3_x_runSql', $rev);
143 function upgrade_4_3_alpha3($rev) {
144 $this->addTask(ts('Upgrade DB to 4.3.alpha3: SQL'), 'task_4_3_x_runSql', $rev);
148 function assignFinancialTypeToPriceRecords() {
149 $upgrade = new CRM_Upgrade_Form();
150 //here we update price set entries
151 $sqlFinancialIds = "SELECT id, name FROM civicrm_financial_type
152 WHERE name IN ('Donation', 'Event Fee', 'Member Dues');";
153 $daoFinancialIds = CRM_Core_DAO
::executeQuery($sqlFinancialIds);
154 while($daoFinancialIds->fetch()) {
155 $financialIds[$daoFinancialIds->name
] = $daoFinancialIds->id
;
157 $sqlPriceSetUpdate = "UPDATE civicrm_price_set ps
158 SET ps.financial_type_id = CASE
159 WHEN ps.extends LIKE '%1%' THEN {$financialIds['Event Fee']}
160 WHEN ps.extends LIKE '2' THEN {$financialIds['Donation']}
161 WHEN ps.extends LIKE '3' THEN {$financialIds['Member Dues']}
163 WHERE financial_type_id IS NULL";
164 CRM_Core_DAO
::executeQuery($sqlPriceSetUpdate);
166 //here we update price field value rows
167 $sqlPriceFieldValueUpdate = "UPDATE civicrm_price_field_value pfv
168 LEFT JOIN civicrm_membership_type mt ON (pfv.membership_type_id = mt.id)
169 INNER JOIN civicrm_price_field pf ON (pfv.price_field_id = pf.id)
170 INNER JOIN civicrm_price_set ps ON (pf.price_set_id = ps.id)
171 SET pfv.financial_type_id = CASE
172 WHEN pfv.membership_type_id IS NOT NULL THEN mt.financial_type_id
173 WHEN pfv.membership_type_id IS NULL THEN ps.financial_type_id
175 CRM_Core_DAO
::executeQuery($sqlPriceFieldValueUpdate);
180 static function _checkAndMigrateDefaultFinancialTypes() {
181 $modifiedDefaults = FALSE;
182 //insert types if not exists
183 $sqlFetchTypes = "SELECT id, name FROM civicrm_contribution_type
184 WHERE name IN ('Donation', 'Event Fee', 'Member Dues') AND is_active =1;";
185 $daoFetchTypes = CRM_Core_DAO
::executeQuery($sqlFetchTypes);
187 if ($daoFetchTypes->N
< 3) {
188 $modifiedDefaults = TRUE;
189 $insertStatments = array (
190 'Donation' => "('Donation', 0, 1, 1)",
191 'Member' => "('Member Dues', 0, 1, 1)",
192 'Event Fee' => "('Event Fee', 0, 1, 0)",
194 foreach ($insertStatments as $values) {
195 $query = "INSERT INTO civicrm_contribution_type (name, is_reserved, is_active, is_deductible)
197 ON DUPLICATE KEY UPDATE is_active = 1;";
198 CRM_Core_DAO
::executeQuery($query);
201 return $modifiedDefaults;
204 function createFinancialRecords() {
205 $upgrade = new CRM_Upgrade_Form();
207 // update civicrm_entity_financial_trxn.amount = civicrm_financial_trxn.total_amount
208 $query = "UPDATE civicrm_entity_financial_trxn ceft
209 LEFT JOIN civicrm_financial_trxn cft ON cft.id = ceft.financial_trxn_id
210 SET ceft.amount = total_amount
211 WHERE cft.net_amount IS NOT NULL AND ceft.entity_table = 'civicrm_contribution';";
212 CRM_Core_DAO
::executeQuery($query);
214 $contributionStatus = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
215 $completedStatus = array_search('Completed', $contributionStatus);
216 $pendingStatus = array_search('Pending', $contributionStatus);
217 $cancelledStatus = array_search('Cancelled', $contributionStatus);
218 $queryParams = array(
219 1 => array($completedStatus, 'Integer'),
220 2 => array($pendingStatus, 'Integer'),
221 3 => array($cancelledStatus, 'Integer')
224 $accountType = key(CRM_Core_PseudoConstant
::accountOptionValues('financial_account_type', NULL, " AND v.name = 'Asset' "));
225 $financialAccountId =
226 CRM_Core_DAO
::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$accountType}");
228 $accountRelationsips = CRM_Core_PseudoConstant
::accountOptionValues('account_relationship', NULL);
230 $accountsReceivableAccount = array_search('Accounts Receivable Account is', $accountRelationsips);
231 $incomeAccountIs = array_search('Income Account is', $accountRelationsips);
232 $assetAccountIs = array_search('Asset Account is', $accountRelationsips);
233 $expenseAccountIs = array_search('Expense Account is', $accountRelationsips);
235 $financialItemStatus = CRM_Core_PseudoConstant
::accountOptionValues('financial_item_status');
236 $unpaidStatus = array_search('Unpaid', $financialItemStatus);
237 $paidStatus = array_search('Paid', $financialItemStatus);
239 $validCurrencyCodes = CRM_Core_PseudoConstant
::currencyCode();
240 $validCurrencyCodes = implode("','", $validCurrencyCodes);
241 $config = CRM_Core_Config
::singleton();
242 $defaultCurrency = $config->defaultCurrency
;
243 $now = date( 'YmdHis' );
245 //adding financial_trxn records and entity_financial_trxn records related to contribution
246 //Add temp column for easy entry in entity_financial_trxn
247 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN contribution_id INT DEFAULT NULL";
248 CRM_Core_DAO
::executeQuery($sql);
250 //pending pay later status handling
252 INSERT INTO civicrm_financial_trxn
253 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
254 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
256 SELECT con.id as contribution_id, con.payment_instrument_id, IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}')
257 as currency, con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id,
258 con.check_number, efa.financial_account_id as to_financial_account_id, NULL as from_financial_account_id,
259 REPLACE(REPLACE(REPLACE(
261 WHEN con.receive_date IS NOT NULL THEN
263 WHEN con.receipt_date IS NOT NULL THEN
268 , '-', ''), ':', ''), ' ', '') as trxn_date
269 FROM civicrm_contribution con
270 LEFT JOIN civicrm_entity_financial_account efa
271 ON (con.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
272 AND efa.account_relationship = {$accountsReceivableAccount})
273 WHERE con.is_pay_later = 1 AND con.contribution_status_id = {$pendingStatus}";
274 CRM_Core_DAO
::executeQuery($sql);
276 //create a temp table to hold financial account id related to payment instruments
277 $tempTableName1 = CRM_Core_DAO
::createTempTableName();
279 $sql = "CREATE TEMPORARY TABLE {$tempTableName1}
281 SELECT ceft.financial_account_id financial_account_id, cov.value as instrument_id
282 FROM civicrm_entity_financial_account ceft
283 INNER JOIN civicrm_option_value cov ON cov.id = ceft.entity_id AND ceft.entity_table = 'civicrm_option_value'
284 INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id
285 WHERE cog.name = 'payment_instrument'";
286 CRM_Core_DAO
::executeQuery($sql);
288 //create temp table to process completed / cancelled contribution
289 $tempTableName2 = CRM_Core_DAO
::createTempTableName();
290 $sql = "CREATE TEMPORARY TABLE {$tempTableName2}
292 SELECT con.id as contribution_id, con.payment_instrument_id, IF(con.currency IN ('{$validCurrencyCodes}'), con.currency, '{$defaultCurrency}') as currency,
293 con.total_amount, con.net_amount, con.fee_amount, con.trxn_id, con.contribution_status_id, con.check_number, NULL as from_financial_account_id,
294 REPLACE(REPLACE(REPLACE(
296 WHEN con.receive_date IS NOT NULL THEN
298 WHEN con.receipt_date IS NOT NULL THEN
303 , '-', ''), ':', ''), ' ', '') as trxn_date,
305 WHEN con.payment_instrument_id IS NULL THEN
306 {$financialAccountId}
307 WHEN con.payment_instrument_id IS NOT NULL THEN
308 tpi.financial_account_id
309 END as to_financial_account_id,
310 IF(eft.financial_trxn_id IS NULL, 'insert', eft.financial_trxn_id) as action
311 FROM civicrm_contribution con
312 LEFT JOIN civicrm_entity_financial_trxn eft
313 ON (eft.entity_table = 'civicrm_contribution' AND eft.entity_id = con.id)
314 LEFT JOIN {$tempTableName1} tpi
315 ON con.payment_instrument_id = tpi.instrument_id
316 WHERE con.contribution_status_id IN ({$completedStatus}, {$cancelledStatus})";
317 CRM_Core_DAO
::executeQuery($sql);
319 //handling for completed contribution and cancelled contribution
320 //insertion of new records
322 INSERT INTO civicrm_financial_trxn
323 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
324 to_financial_account_id, from_financial_account_id, trxn_date)
325 SELECT tempI.contribution_id, tempI.payment_instrument_id, tempI.currency, tempI.total_amount, tempI.net_amount,
326 tempI.fee_amount, tempI.trxn_id, tempI.contribution_status_id, tempI.check_number,
327 tempI.to_financial_account_id, tempI.from_financial_account_id, tempI.trxn_date
328 FROM {$tempTableName2} tempI
329 WHERE tempI.action = 'insert';";
330 CRM_Core_DAO
::executeQuery($sql);
332 //update of existing records
334 UPDATE civicrm_financial_trxn ft
335 INNER JOIN {$tempTableName2} tempU
336 ON (tempU.action != 'insert' AND ft.id = tempU.action)
337 SET ft.from_financial_account_id = NULL,
338 ft.to_financial_account_id = tempU.to_financial_account_id,
339 ft.status_id = tempU.contribution_status_id,
340 ft.payment_instrument_id = tempU.payment_instrument_id,
341 ft.check_number = tempU.check_number,
342 ft.contribution_id = tempU.contribution_id;";
343 CRM_Core_DAO
::executeQuery($sql);
345 //insert the -ve transaction rows for cancelled contributions
347 INSERT INTO civicrm_financial_trxn
348 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id,
349 check_number, to_financial_account_id, from_financial_account_id, trxn_date)
350 SELECT ft.contribution_id, ft.payment_instrument_id, ft.currency, -ft.total_amount, ft.net_amount, ft.fee_amount, ft.trxn_id,
351 ft.status_id, ft.check_number, ft.to_financial_account_id, ft.from_financial_account_id, ft.trxn_date
352 FROM civicrm_financial_trxn ft
353 WHERE ft.status_id = {$cancelledStatus};";
354 CRM_Core_DAO
::executeQuery($sql);
356 //inserting entity financial trxn entries if its not present in entity_financial_trxn for completed and pending contribution statuses
357 //this also handles +ve and -ve both transaction entries for a cancelled contribution
359 INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
360 SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount as amount
361 FROM civicrm_financial_trxn ft
362 WHERE contribution_id IS NOT NULL AND
363 ft.id NOT IN (SELECT financial_trxn_id
364 FROM civicrm_entity_financial_trxn
365 WHERE entity_table = 'civicrm_contribution'
366 AND entity_id = ft.contribution_id)";
367 CRM_Core_DAO
::executeQuery($sql);
368 //end of adding financial_trxn records and entity_financial_trxn records related to contribution
370 //update all linked line_item rows
371 // set line_item.financial_type_id = contribution.financial_type_id if contribution page id is null and not participant line item
372 // set line_item.financial_type_id = price_field_value.financial_type_id if contribution page id is set and not participant line item
373 // set line_item.financial_type_id = event.financial_type_id if its participant line item and line_item.price_field_value_id is null
374 // set line_item.financial_type_id = price_field_value.financial_type_id if its participant line item and line_item.price_field_value_id is set
375 $updateLineItemSql = "
376 UPDATE civicrm_line_item li
377 LEFT JOIN civicrm_contribution con
378 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
379 LEFT JOIN civicrm_price_field_value cpfv
380 ON li.price_field_value_id = cpfv.id
381 LEFT JOIN civicrm_participant cp
382 ON (li.entity_id = cp.id AND li.entity_table = 'civicrm_participant')
383 LEFT JOIN civicrm_event ce
384 ON ce.id = cp.event_id
385 SET li.financial_type_id = CASE
386 WHEN (con.contribution_page_id IS NULL || li.price_field_value_id IS NULL) AND cp.id IS NULL THEN
387 con.financial_type_id
388 WHEN (con.contribution_page_id IS NOT NULL AND cp.id IS NULL) || (cp.id IS NOT NULL AND li.price_field_value_id IS NOT NULL) THEN
389 cpfv.financial_type_id
390 WHEN cp.id IS NOT NULL AND li.price_field_value_id IS NULL THEN
393 CRM_Core_DAO
::executeQuery($updateLineItemSql, $queryParams);
395 //add the financial_item entries
396 //add a temp column so that inserting entity_financial_trxn entries gets easy
397 $sql = "ALTER TABLE civicrm_financial_item ADD COLUMN f_trxn_id INT DEFAULT NULL";
398 CRM_Core_DAO
::executeQuery($sql);
400 //add financial_item entries for contribution completed / pending pay later / cancelled
401 $contributionlineItemSql = "
402 INSERT INTO civicrm_financial_item
403 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
405 SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
406 IF(ft.total_amount < 0 AND con.contribution_status_id = %3, -li.line_total, li.line_total) as line_total, con.currency, 'civicrm_line_item',
407 li.id as line_item_id, li.label as line_item_label,
408 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id, efa.financial_account_id as financial_account_id,
410 FROM civicrm_line_item li
411 INNER JOIN civicrm_contribution con
412 ON (li.entity_id = con.id AND li.entity_table = 'civicrm_contribution')
413 INNER JOIN civicrm_financial_trxn ft
414 ON (con.id = ft.contribution_id)
415 LEFT JOIN civicrm_entity_financial_account efa
416 ON (li.financial_type_id = efa.entity_id AND efa.entity_table = 'civicrm_financial_type'
417 AND efa.account_relationship = {$incomeAccountIs})
418 WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
419 CRM_Core_DAO
::executeQuery($contributionlineItemSql, $queryParams);
421 //add financial_item entries for event
422 $participantLineItemSql = "
423 INSERT INTO civicrm_financial_item
424 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
426 SELECT REPLACE(REPLACE(REPLACE(ft.trxn_date, '-', ''), ':', ''), ' ', ''), con.contact_id,
427 IF(ft.total_amount < 0 AND con.contribution_status_id = %3, -li.line_total, li.line_total) as line_total,
428 con.currency, 'civicrm_line_item', li.id as line_item_id, li.label as line_item_label,
429 IF(con.contribution_status_id = {$pendingStatus}, {$unpaidStatus}, {$paidStatus}) as status_id,
430 efa.financial_account_id as financial_account_id, ft.id as f_trxn_id
431 FROM civicrm_line_item li
432 INNER JOIN civicrm_participant par
433 ON (li.entity_id = par.id AND li.entity_table = 'civicrm_participant')
434 INNER JOIN civicrm_participant_payment pp
435 ON (pp.participant_id = par.id)
436 INNER JOIN civicrm_contribution con
437 ON (pp.contribution_id = con.id)
438 INNER JOIN civicrm_financial_trxn ft
439 ON (con.id = ft.contribution_id)
440 LEFT JOIN civicrm_entity_financial_account efa
441 ON (li.financial_type_id = efa.entity_id AND
442 efa.entity_table = 'civicrm_financial_type' AND efa.account_relationship = {$incomeAccountIs})
443 WHERE con.contribution_status_id IN (%1, %3) OR (con.is_pay_later = 1 AND con.contribution_status_id = %2)";
444 CRM_Core_DAO
::executeQuery($participantLineItemSql, $queryParams);
446 //fee handling for contributions
447 //insert fee entries in financial_trxn for contributions
448 $sql = "ALTER TABLE civicrm_financial_trxn ADD COLUMN is_fee TINYINT DEFAULT NULL";
449 CRM_Core_DAO
::executeQuery($sql);
452 INSERT INTO civicrm_financial_trxn
453 (contribution_id, payment_instrument_id, currency, total_amount, net_amount, fee_amount, trxn_id, status_id, check_number,
454 to_financial_account_id, from_financial_account_id, trxn_date, payment_processor_id, is_fee)
456 SELECT con.id, ft.payment_instrument_id, ft.currency, ft.fee_amount, NULL, NULL, ft.trxn_id, %1 as status_id,
457 ft.check_number, efaFT.financial_account_id as to_financial_account_id, CASE
458 WHEN efaPP.financial_account_id IS NOT NULL THEN
459 efaPP.financial_account_id
460 WHEN tpi.financial_account_id IS NOT NULL THEN
461 tpi.financial_account_id
463 {$financialAccountId}
464 END as from_financial_account_id, ft.trxn_date, ft.payment_processor_id, 1 as is_fee
465 FROM civicrm_contribution con
466 INNER JOIN civicrm_financial_trxn ft
467 ON (ft.contribution_id = con.id)
468 LEFT JOIN civicrm_entity_financial_account efaFT
469 ON (con.financial_type_id = efaFT.entity_id AND efaFT.entity_table = 'civicrm_financial_type'
470 AND efaFT.account_relationship = {$expenseAccountIs})
471 LEFT JOIN civicrm_entity_financial_account efaPP
472 ON (ft.payment_processor_id = efaPP.entity_id AND efaPP.entity_table = 'civicrm_payment_processor'
473 AND efaPP.account_relationship = {$assetAccountIs})
474 LEFT JOIN {$tempTableName1} tpi
475 ON ft.payment_instrument_id = tpi.instrument_id
476 WHERE con.fee_amount IS NOT NULL AND (con.contribution_status_id IN (%1, %3) OR (con.contribution_status_id =%2 AND con.is_pay_later = 1))
478 CRM_Core_DAO
::executeQuery($sql, $queryParams);
480 //link financial_trxn to contribution
482 INSERT INTO civicrm_entity_financial_trxn
483 (entity_table, entity_id, financial_trxn_id, amount)
484 SELECT 'civicrm_contribution', ft.contribution_id, ft.id, ft.total_amount
485 FROM civicrm_financial_trxn ft
486 WHERE ft.is_fee = 1";
487 CRM_Core_DAO
::executeQuery($sql);
489 //add fee related entries to financial item table
490 $domainId = CRM_Core_Config
::domainID();
491 $domainContactId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_Domain', $domainId, 'contact_id');
493 INSERT INTO civicrm_financial_item
494 (transaction_date, contact_id, amount, currency, entity_table, entity_id, description, status_id, financial_account_id, f_trxn_id)
495 SELECT ft.trxn_date, {$domainContactId} as contact_id, ft.total_amount, ft.currency, 'civicrm_financial_trxn', ft.id,
496 'Fee', {$paidStatus} as status_id, ft.to_financial_account_id as financial_account_id, ft.id as f_trxn_id
497 FROM civicrm_financial_trxn ft
498 WHERE ft.is_fee = 1;";
499 CRM_Core_DAO
::executeQuery($sql);
501 //add entries to entity_financial_trxn table
503 INSERT INTO civicrm_entity_financial_trxn (entity_table, entity_id, financial_trxn_id, amount)
504 SELECT 'civicrm_financial_item' as entity_table, fi.id as entity_id, fi.f_trxn_id as financial_trxn_id, fi.amount
505 FROM civicrm_financial_item fi";
506 CRM_Core_DAO
::executeQuery($sql);
508 //drop the temparory columns
509 $sql = "ALTER TABLE civicrm_financial_trxn
510 DROP COLUMN contribution_id,
511 DROP COLUMN is_fee;";
512 CRM_Core_DAO
::executeQuery($sql);
514 $sql = "ALTER TABLE civicrm_financial_item DROP f_trxn_id";
515 CRM_Core_DAO
::executeQuery($sql);
520 function createDomainContacts() {
521 $domainParams = $context = array();
523 ALTER TABLE `civicrm_domain` ADD `contact_id` INT( 10 ) UNSIGNED NULL DEFAULT NULL COMMENT 'FK to Contact ID. This is specifically not an FK to avoid circular constraints',
524 ADD CONSTRAINT `FK_civicrm_domain_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact` (`id`);";
525 CRM_Core_DAO
::executeQuery($query, CRM_Core_DAO
::$_nullArray, TRUE, NULL, FALSE, FALSE);
527 $query = 'SELECT cd.id, cd.name, ce.email FROM `civicrm_domain` cd
528 LEFT JOIN civicrm_loc_block clb ON clb.id = cd. loc_block_id
529 LEFT JOIN civicrm_email ce ON ce.id = clb.email_id ;' ;
530 $dao = CRM_Core_DAO
::executeQuery($query);
531 while($dao->fetch()) {
533 'sort_name' => $dao->name
,
534 'display_name' => $dao->name
,
535 'legal_name' => $dao->name
,
536 'organization_name' => $dao->name
,
537 'contact_type' => 'Organization'
539 $query = "SELECT cc.id FROM `civicrm_contact` cc
540 LEFT JOIN civicrm_email ce ON ce.contact_id = cc.id
541 WHERE cc.contact_type = 'Organization' AND cc.organization_name = '{$dao->name}' ";
543 $query .= " AND ce.email = '{$dao->email}' ";
545 $contactID = CRM_Core_DAO
::singleValueQuery($query);
546 $context[1] = $dao->name
;
547 if (empty($contactID)) {
548 $contact = CRM_Contact_BAO_Contact
::add($params);
549 $contactID = $contact->id
;
550 $context[0] = 'added';
553 $context[0] = 'merged';
555 $domainParams['contact_id'] = $contactID;
556 CRM_Core_BAO_Domain
::edit($domainParams, $dao->id
);
561 function task_4_3_alpha1_checkDBConstraints() {
562 //checking whether the foreign key exists before dropping it CRM-11260
563 $config = CRM_Core_Config
::singleton();
564 $dbUf = DB
::parseDSN($config->dsn
);
567 'autorenewal_msg_id' => array('tableName' => 'civicrm_membership_type', 'fkey' => 'FK_civicrm_membership_autorenewal_msg_id'),
568 'to_account_id' => array('tableName' => 'civicrm_financial_trxn', 'constraintName' => 'civicrm_financial_trxn_ibfk_2'),
569 'from_account_id' => array('tableName' => 'civicrm_financial_trxn', 'constraintName' => 'civicrm_financial_trxn_ibfk_1'),
570 'contribution_type_id' => array('tableName' => 'civicrm_contribution_recur', 'fkey' => 'FK_civicrm_contribution_recur_contribution_type_id'),
572 $query = "SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
573 WHERE table_name = 'civicrm_contribution_recur'
574 AND constraint_name = 'FK_civicrm_contribution_recur_contribution_type_id'
575 AND TABLE_SCHEMA = '{$dbUf['database']}'";
577 $dao = CRM_Core_DAO
::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
578 foreach($tables as $columnName => $value){
579 if ($value['tableName'] == 'civicrm_membership_type' ||
$value['tableName'] == 'civicrm_contribution_recur') {
580 $foreignKeyExists = CRM_Core_DAO
::checkConstraintExists($value['tableName'], $value['fkey']);
581 $fKey = $value['fkey'];
583 $foreignKeyExists = CRM_Core_DAO
::checkFKConstraintInFormat($value['tableName'], $columnName);
584 $fKey = "`FK_{$value['tableName']}_{$columnName}`";
586 if ($foreignKeyExists ||
$value['tableName'] == 'civicrm_financial_trxn') {
587 if ($value['tableName'] != 'civicrm_contribution_recur' ||
($value['tableName'] == 'civicrm_contribution_recur' && $dao->N
)) {
588 $constraintName = $foreignKeyExists ?
$fKey : $value['constraintName'];
589 CRM_Core_DAO
::executeQuery("ALTER TABLE {$value['tableName']} DROP FOREIGN KEY {$constraintName}", $params, TRUE, NULL, FALSE, FALSE);
591 CRM_Core_DAO
::executeQuery("ALTER TABLE {$value['tableName']} DROP INDEX {$fKey}", $params, TRUE, NULL, FALSE, FALSE);
594 // check if column contact_id is present or not in civicrm_financial_account
595 $fieldExists = CRM_Core_DAO
::checkFieldExists('civicrm_financial_account', 'contact_id', FALSE);
597 $query = "ALTER TABLE civicrm_financial_account ADD `contact_id` int(10) unsigned DEFAULT NULL COMMENT 'Version identifier of financial_type' AFTER `name`, ADD CONSTRAINT `FK_civicrm_financial_account_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact`(id);";
598 CRM_Core_DAO
::executeQuery($query, $params, TRUE, NULL, FALSE, FALSE);
603 * Read creation and modification times from civicrm_log; add
604 * them to civicrm_contact.
606 function convertTimestamps(CRM_Queue_TaskContext
$ctx, $startId, $endId) {
608 SELECT entity_id, min(modified_date) AS created, max(modified_date) AS modified
610 WHERE entity_table = 'civicrm_contact'
611 AND entity_id BETWEEN %1 AND %2
615 1 => array($startId, 'Integer'),
616 2 => array($endId, 'Integer'),
618 $dao = CRM_Core_DAO
::executeQuery($sql, $params);
619 while ($dao->fetch()) {
620 // FIXME civicrm_log.modified_date is DATETIME; civicrm_contact.modified_date is TIMESTAMP
621 CRM_Core_DAO
::executeQuery(
622 'UPDATE civicrm_contact SET created_date = %1, modified_date = %2 WHERE id = %3',
624 1 => array($dao->created
, 'String'),
625 2 => array($dao->modified
, 'String'),
626 3 => array($dao->entity_id
, 'Integer'),
635 * Update phones CRM-11292
637 * @return bool TRUE for success
639 static function phoneNumeric(CRM_Queue_TaskContext
$ctx) {
640 CRM_Core_DAO
::executeQuery(CRM_Contact_BAO_Contact
::DROP_STRIP_FUNCTION_43
);
641 CRM_Core_DAO
::executeQuery(CRM_Contact_BAO_Contact
::CREATE_STRIP_FUNCTION_43
);
642 CRM_Core_DAO
::executeQuery("UPDATE civicrm_phone SET phone_numeric = civicrm_strip_non_numeric(phone)");
647 * (Queue Task Callback)
649 static function task_4_3_x_runSql(CRM_Queue_TaskContext
$ctx, $rev) {
650 $upgrade = new CRM_Upgrade_Form();
651 $upgrade->processSQL($rev);
657 * Syntatic sugar for adding a task which (a) is in this class and (b) has
660 * After passing the $funcName, you can also pass parameters that will go to
661 * the function. Note that all params must be serializable.
663 protected function addTask($title, $funcName) {
664 $queue = CRM_Queue_Service
::singleton()->load(array(
666 'name' => CRM_Upgrade_Form
::QUEUE_NAME
,
669 $args = func_get_args();
670 $title = array_shift($args);
671 $funcName = array_shift($args);
672 $task = new CRM_Queue_Task(
673 array(get_class($this), $funcName),
677 $queue->createItem($task, array('weight' => -1));