Merge pull request #14889 from demeritcowboy/logging-report-clarification
[civicrm-core.git] / CRM / Member / Form / MembershipView.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | 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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * This class generates form components for Payment-Instrument
6a488035
TO
38 */
39class CRM_Member_Form_MembershipView extends CRM_Core_Form {
40
41 /**
fe482240 42 * The action links that we need to display for the browse screen.
6a488035
TO
43 *
44 * @var array
6a488035 45 */
971e129b 46 public static $_links = NULL;
6a488035 47
669fc25e
CR
48 /**
49 * The id of the membership being viewed.
50 *
51 * @var int
52 */
53 private $membershipID;
54
55 /**
56 * Contact's ID.
57 *
58 * @var int
59 */
60 private $contactID;
61
6a488035 62 /**
fe482240 63 * Add context information at the end of a link.
6a488035 64 *
72b3a70c
CW
65 * @return string
66 * extra query parameters
6a488035 67 */
00be9182 68 public function addContext() {
6a488035 69 $extra = '';
be2fb01f 70 foreach (['context', 'selectedChild'] as $arg) {
6a488035
TO
71 if ($value = CRM_Utils_Request::retrieve($arg, 'String', $this)) {
72 $extra .= "&{$arg}={$value}";
73 }
74 }
75 return $extra;
76 }
77
78 /**
fe482240 79 * Get action Links.
6a488035 80 *
a6c01b45
CW
81 * @return array
82 * (reference) of action links
6a488035 83 */
00be9182 84 public function &links() {
6a488035 85 if (!(self::$_links)) {
be2fb01f
CW
86 self::$_links = [
87 CRM_Core_Action::DELETE => [
6a488035
TO
88 'name' => ts('Delete'),
89 'url' => 'civicrm/contact/view/membership',
90 'qs' => 'action=view&id=%%id%%&cid=%%cid%%&relAction=delete&mid=%%mid%%&reset=1' . $this->addContext(),
91 'title' => ts('Cancel Related Membership'),
be2fb01f
CW
92 ],
93 CRM_Core_Action::ADD => [
6a488035
TO
94 'name' => ts('Create'),
95 'url' => 'civicrm/contact/view/membership',
96 'qs' => 'action=view&id=%%id%%&cid=%%cid%%&relAction=create&rid=%%rid%%&reset=1' . $this->addContext(),
97 'title' => ts('Create Related Membership'),
be2fb01f
CW
98 ],
99 ];
6a488035
TO
100 }
101 return self::$_links;
102 }
103
104 /**
fe482240 105 * Perform create or delete action on related memberships.
6a488035 106 *
b2363ea8
TO
107 * @param string $action
108 * Create or delete.
109 * @param array $owner
110 * Primary membership info (membership_id, contact_id, membership_type ...).
6a488035 111 */
00be9182 112 public function relAction($action, $owner) {
6a488035
TO
113 switch ($action) {
114 case 'delete':
115 $id = CRM_Utils_Request::retrieve('mid', 'Positive', $this);
116 $relatedContactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
117 $relatedDisplayName = CRM_Contact_BAO_Contact::displayName($relatedContactId);
3506b6cd 118 CRM_Member_BAO_Membership::del($id);
be2fb01f 119 CRM_Core_Session::setStatus(ts('Related membership for %1 has been deleted.', [1 => $relatedDisplayName]),
8d8bd076 120 ts('Membership Deleted'), 'success');
6a488035 121 break;
b09fe5ed 122
6a488035 123 case 'create':
be2fb01f
CW
124 $ids = [];
125 $params = [
8d8bd076 126 'contact_id' => CRM_Utils_Request::retrieve('rid', 'Positive', $this),
127 'membership_type_id' => $owner['membership_type_id'],
128 'owner_membership_id' => $owner['id'],
129 'join_date' => CRM_Utils_Date::processDate($owner['join_date'], NULL, TRUE, 'Ymd'),
130 'start_date' => CRM_Utils_Date::processDate($owner['start_date'], NULL, TRUE, 'Ymd'),
131 'end_date' => CRM_Utils_Date::processDate($owner['end_date'], NULL, TRUE, 'Ymd'),
132 'source' => ts('Manual Assignment of Related Membership'),
133 'is_test' => $owner['is_test'],
134 'campaign_id' => CRM_Utils_Array::value('campaign_id', $owner),
135 'status_id' => $owner['status_id'],
136 'skipStatusCal' => TRUE,
137 'createActivity' => TRUE,
be2fb01f 138 ];
6a488035
TO
139 CRM_Member_BAO_Membership::create($params, $ids);
140 $relatedDisplayName = CRM_Contact_BAO_Contact::displayName($params['contact_id']);
be2fb01f 141 CRM_Core_Session::setStatus(ts('Related membership for %1 has been created.', [1 => $relatedDisplayName]),
8d8bd076 142 ts('Membership Added'), 'success');
6a488035 143 break;
b09fe5ed 144
6a488035
TO
145 default:
146 CRM_Core_Error::fatal(ts("Invalid action specified in URL"));
147 }
148
149 // Redirect back to membership view page for the owner, without the relAction parameters
150 CRM_Utils_System::redirect(
151 CRM_Utils_System::url(
152 'civicrm/contact/view/membership',
153 "action=view&reset=1&id={$owner['membership_id']}&cid={$owner['contact_id']}" . $this->addContext()
154 )
155 );
156 }
157
158 /**
fe482240 159 * Set variables up before form is built.
6a488035
TO
160 *
161 * @return void
6a488035
TO
162 */
163 public function preProcess() {
be2fb01f 164 $values = [];
669fc25e
CR
165 $this->membershipID = CRM_Utils_Request::retrieve('id', 'Positive', $this);
166 $this->contactID = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
6a488035
TO
167
168 // Make sure context is assigned to template for condition where we come here view civicrm/membership/view
edc80cda 169 $context = CRM_Utils_Request::retrieve('context', 'Alphanumeric', $this);
6a488035
TO
170 $this->assign('context', $context);
171
669fc25e 172 if ($this->membershipID) {
be2fb01f 173 $params = ['id' => $this->membershipID];
6a488035 174 CRM_Member_BAO_Membership::retrieve($params, $values);
66af7c48
PN
175 if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
176 $finTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'financial_type_id');
177 $finType = CRM_Contribute_PseudoConstant::financialType($finTypeId);
66af7c48 178 if (!CRM_Core_Permission::check('view contributions of type ' . $finType)) {
4627f70f 179 CRM_Core_Error::statusBounce(ts('You do not have permission to access this page.'));
66af7c48 180 }
c826cd95 181 }
895d596d
E
182 else {
183 $this->assign('noACL', TRUE);
184 }
6a488035
TO
185 $membershipType = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($values['membership_type_id']);
186
187 // Do the action on related Membership if needed
188 $relAction = CRM_Utils_Request::retrieve('relAction', 'String', $this);
189 if ($relAction) {
190 $this->relAction($relAction, $values);
191 }
192
193 // build associated contributions
8d8bd076 194 $this->assign('accessContribution', FALSE);
195 if (CRM_Core_Permission::access('CiviContribute')) {
196 $this->assign('accessContribution', TRUE);
669fc25e 197 CRM_Member_Page_Tab::associatedContribution($values['contact_id'], $this->membershipID);
8d8bd076 198 }
6a488035
TO
199
200 //Provide information about membership source when it is the result of a relationship (CRM-1901)
201 $values['owner_membership_id'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership',
669fc25e 202 $this->membershipID,
6a488035
TO
203 'owner_membership_id'
204 );
205
206 if (isset($values['owner_membership_id'])) {
207 $values['owner_contact_id'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership',
208 $values['owner_membership_id'],
209 'contact_id',
210 'id'
211 );
212
213 $values['owner_display_name'] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
214 $values['owner_contact_id'],
215 'display_name',
216 'id'
217 );
218
219 $direction = strrev($membershipType['relationship_direction']);
220 // To display relationship type in view membership page
221 $relTypeIds = str_replace(CRM_Core_DAO::VALUE_SEPARATOR, ",", $membershipType['relationship_type_id']);
222 $sql = "
223SELECT relationship_type_id,
03e04002 224 CASE
6a488035
TO
225 WHEN contact_id_a = {$values['owner_contact_id']} AND contact_id_b = {$values['contact_id']} THEN 'b_a'
226 WHEN contact_id_b = {$values['owner_contact_id']} AND contact_id_a = {$values['contact_id']} THEN 'a_b'
227END AS 'relType'
03e04002 228 FROM civicrm_relationship
6a488035
TO
229 WHERE relationship_type_id IN ($relTypeIds)";
230 $dao = CRM_Core_DAO::executeQuery($sql);
231 $values['relationship'] = NULL;
232 while ($dao->fetch()) {
233 $typeId = $dao->relationship_type_id;
234 $direction = $dao->relType;
235 if ($direction && $typeId) {
236 if ($values['relationship']) {
237 $values['relationship'] .= ',';
238 }
239 $values['relationship'] .= CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_RelationshipType',
240 $typeId,
241 "name_$direction",
242 'id'
243 );
244 }
245 }
246 }
247
248 $this->assign('has_related', FALSE);
249 // if membership can be granted, and we are the owner of the membership
8cc574cf 250 if (!empty($membershipType['relationship_type_id']) && empty($values['owner_membership_id'])) {
6a488035
TO
251 // display related contacts/membership block
252 $this->assign('has_related', TRUE);
253 $this->assign('max_related', CRM_Utils_Array::value('max_related', $values, ts('Unlimited')));
254 // split the relations in 2 arrays based on direction
255 $relTypeId = explode(CRM_Core_DAO::VALUE_SEPARATOR, $membershipType['relationship_type_id']);
256 $relDirection = explode(CRM_Core_DAO::VALUE_SEPARATOR, $membershipType['relationship_direction']);
257 foreach ($relTypeId as $rid) {
3030f6f5 258 $relTypeDir[substr($relDirection[0], 0, 1)][] = $rid;
6a488035
TO
259 }
260 // build query in 2 parts with a UNION if necessary
261 // _x and _y are replaced with _a and _b first, then vice-versa
262 // comment is a qualifier for the relationship - now just job_title
263 $select = "
264SELECT r.id, c.id as cid, c.display_name as name, c.job_title as comment,
265 rt.name_x_y as relation, r.start_date, r.end_date,
266 m.id as mid, ms.is_current_member, ms.label as status
267 FROM civicrm_relationship r
268 LEFT JOIN civicrm_relationship_type rt ON rt.id = r.relationship_type_id
269 LEFT JOIN civicrm_contact c ON c.id = r.contact_id_x
8d8bd076 270 LEFT JOIN civicrm_membership m ON (m.owner_membership_id = {$values['id']}
271 AND m.contact_id = r.contact_id_x AND m.is_test = 0)
6a488035
TO
272 LEFT JOIN civicrm_membership_status ms ON ms.id = m.status_id
273 WHERE r.contact_id_y = {$values['contact_id']} AND r.is_active = 1 AND c.is_deleted = 0";
274 $query = '';
be2fb01f 275 foreach (['a', 'b'] as $dir) {
2eef47ee 276 if (isset($relTypeDir[$dir])) {
6a488035 277 $query .= ($query ? ' UNION ' : '')
8d8bd076 278 . str_replace('_y', '_' . $dir, str_replace('_x', '_' . ($dir == 'a' ? 'b' : 'a'), $select))
279 . ' AND r.relationship_type_id IN (' . implode(',', $relTypeDir[$dir]) . ')';
6a488035
TO
280 }
281 }
282 $query .= " ORDER BY is_current_member DESC";
283 $dao = CRM_Core_DAO::executeQuery($query);
be2fb01f 284 $related = [];
6a488035 285 $relatedRemaining = CRM_Utils_Array::value('max_related', $values, PHP_INT_MAX);
be2fb01f 286 $rowElememts = [
8d8bd076 287 'id',
288 'cid',
289 'name',
290 'comment',
291 'relation',
292 'mid',
293 'start_date',
294 'end_date',
295 'is_current_member',
21dfd5f5 296 'status',
be2fb01f 297 ];
8d8bd076 298
6a488035 299 while ($dao->fetch()) {
be2fb01f 300 $row = [];
8d8bd076 301 foreach ($rowElememts as $field) {
6a488035
TO
302 $row[$field] = $dao->$field;
303 }
304 if ($row['mid'] && ($row['is_current_member'] == 1)) {
305 $relatedRemaining--;
306 $row['action'] = CRM_Core_Action::formLink(self::links(), CRM_Core_Action::DELETE,
be2fb01f 307 [
6a488035
TO
308 'id' => CRM_Utils_Request::retrieve('id', 'Positive', $this),
309 'cid' => $row['cid'],
310 'mid' => $row['mid'],
be2fb01f 311 ],
87dab4a4
AH
312 ts('more'),
313 FALSE,
314 'membership.relationship.action',
315 'Relationship',
316 CRM_Utils_Request::retrieve('id', 'Positive', $this)
6a488035 317 );
8d8bd076 318 }
319 else {
320 if ($relatedRemaining > 0) {
6a488035 321 $row['action'] = CRM_Core_Action::formLink(self::links(), CRM_Core_Action::ADD,
be2fb01f 322 [
6a488035
TO
323 'id' => CRM_Utils_Request::retrieve('id', 'Positive', $this),
324 'cid' => $row['cid'],
325 'rid' => $row['cid'],
be2fb01f 326 ],
87dab4a4
AH
327 ts('more'),
328 FALSE,
329 'membership.relationship.action',
330 'Relationship',
331 CRM_Utils_Request::retrieve('id', 'Positive', $this)
6a488035 332 );
8d8bd076 333 }
6a488035
TO
334 }
335 $related[] = $row;
336 }
337 $this->assign('related', $related);
338 if ($relatedRemaining <= 0) {
339 $this->assign('related_text', ts('None available'));
8d8bd076 340 }
341 else {
342 if ($relatedRemaining < 100000) {
be2fb01f 343 $this->assign('related_text', ts('%1 available', [1 => $relatedRemaining]));
8d8bd076 344 }
345 else {
be2fb01f 346 $this->assign('related_text', ts('Unlimited', [1 => $relatedRemaining]));
8d8bd076 347 }
6a488035
TO
348 }
349 }
350
351 $displayName = CRM_Contact_BAO_Contact::displayName($values['contact_id']);
352 $this->assign('displayName', $displayName);
03e04002 353
6a488035
TO
354 // Check if this is default domain contact CRM-10482
355 if (CRM_Contact_BAO_Contact::checkDomainContact($values['contact_id'])) {
356 $displayName .= ' (' . ts('default organization') . ')';
357 }
358
8d8bd076 359 // omitting contactImage from title for now since the summary overlay css doesn't work outside crm-container
360 CRM_Utils_System::setTitle(ts('View Membership for') . ' ' . $displayName);
03e04002 361
6a488035
TO
362 // add viewed membership to recent items list
363 $recentTitle = $displayName . ' - ' . ts('Membership Type:') . ' ' . $values['membership_type'];
364 $url = CRM_Utils_System::url('civicrm/contact/view/membership',
365 "action=view&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
366 );
367
be2fb01f 368 $recentOther = [];
6a488035
TO
369 if (CRM_Core_Permission::checkActionPermission('CiviMember', CRM_Core_Action::UPDATE)) {
370 $recentOther['editUrl'] = CRM_Utils_System::url('civicrm/contact/view/membership',
371 "action=update&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
372 );
373 }
374 if (CRM_Core_Permission::checkActionPermission('CiviMember', CRM_Core_Action::DELETE)) {
375 $recentOther['deleteUrl'] = CRM_Utils_System::url('civicrm/contact/view/membership',
376 "action=delete&reset=1&id={$values['id']}&cid={$values['contact_id']}&context=home"
377 );
378 }
379 CRM_Utils_Recent::add($recentTitle,
380 $url,
381 $values['id'],
382 'Membership',
383 $values['contact_id'],
384 NULL,
385 $recentOther
386 );
387
8d8bd076 388 CRM_Member_Page_Tab::setContext($this, $values['contact_id']);
6a488035 389
669fc25e 390 $memType = CRM_Core_DAO::getFieldValue("CRM_Member_DAO_Membership", $this->membershipID, "membership_type_id");
6a488035 391
669fc25e
CR
392 $groupTree = CRM_Core_BAO_CustomGroup::getTree('Membership', NULL, $this->membershipID, 0, $memType);
393 CRM_Core_BAO_CustomGroup::buildCustomDataView($this, $groupTree, FALSE, NULL, NULL, NULL, $this->membershipID);
6a488035 394
669fc25e 395 $isRecur = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->membershipID, 'contribution_recur_id');
6a488035
TO
396
397 $autoRenew = $isRecur ? TRUE : FALSE;
398 }
399
a7488080 400 if (!empty($values['is_test'])) {
cd355351 401 $values['membership_type'] = CRM_Core_TestEntity::appendTestText($values['membership_type']);
6a488035
TO
402 }
403
669fc25e 404 $subscriptionCancelled = CRM_Member_BAO_Membership::isSubscriptionCancelled($this->membershipID);
6a488035
TO
405 $values['auto_renew'] = ($autoRenew && !$subscriptionCancelled) ? 'Yes' : 'No';
406
407 //do check for campaigns
408 if ($campaignId = CRM_Utils_Array::value('campaign_id', $values)) {
409 $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns($campaignId);
410 $values['campaign'] = $campaigns[$campaignId];
411 }
412
413 $this->assign($values);
414 }
415
416 /**
fe482240 417 * Build the form object.
6a488035 418 *
355ba699 419 * @return void
6a488035
TO
420 */
421 public function buildQuickForm() {
be2fb01f
CW
422 $this->addButtons([
423 [
c5c263ca
AH
424 'type' => 'cancel',
425 'name' => ts('Done'),
426 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
427 'isDefault' => TRUE,
be2fb01f
CW
428 ],
429 ]);
6a488035 430 }
96025800 431
6a488035 432}