getAcl()->getScopeForbiddenAttributeList('Opportunity'))) { throw new Forbidden(); } if ($dateFilter !== 'between' && $dateFilter !== 'ever') { list($dateFrom, $dateTo) = $this->getDateRangeByFilter($dateFilter); } $lostStageList = $this->getLostStageList(); $pdo = $this->getEntityManager()->getPDO(); $options = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.options', []); $selectManager = $this->getSelectManagerFactory()->create('Opportunity'); $stageField = 'stage'; if ($useLastStage) { $stageField = 'lastStage'; } $selectParams = [ 'select' => [$stageField, ['SUM:amountConverted', 'amount']], 'whereClause' => [ [$stageField . '!=' => $lostStageList], [$stageField . '!=' => null] ], 'orderBy' => 'LIST:'.$stageField.':' . implode(',', $options), 'groupBy' => [$stageField] ]; if ($dateFilter !== 'ever') { $selectParams['whereClause'][] = [ 'closeDate>=' => $dateFrom, 'closeDate<' => $dateTo ]; } $selectManager->applyAccess($selectParams); $this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams); $sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams); $sth = $pdo->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(\PDO::FETCH_ASSOC); $data = []; foreach ($rows as $row) { $data[$row[$stageField]] = floatval($row['amount']); } $dataList = []; $stageList = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.options', []); foreach ($stageList as $stage) { if (in_array($stage, $lostStageList)) continue; if (!in_array($stage, $lostStageList) && !isset($data[$stage])) { $data[$stage] = 0.0; } $dataList[] = [ 'stage' => $stage, 'value' => $data[$stage] ]; } return [ 'dataList' => $dataList ]; } public function reportByLeadSource($dateFilter, $dateFrom = null, $dateTo = null) { if (in_array('amount', $this->getAcl()->getScopeForbiddenAttributeList('Opportunity'))) { throw new Forbidden(); } if (in_array('leadSource', $this->getAcl()->getScopeForbiddenAttributeList('Opportunity'))) { throw new Forbidden(); } if ($dateFilter !== 'between' && $dateFilter !== 'ever') { list($dateFrom, $dateTo) = $this->getDateRangeByFilter($dateFilter); } $pdo = $this->getEntityManager()->getPDO(); $options = $this->getMetadata()->get('entityDefs.Lead.fields.source.options', []); $selectManager = $this->getSelectManagerFactory()->create('Opportunity'); $selectParams = [ 'select' => ['leadSource', ['SUM:amountWeightedConverted', 'amount']], 'whereClause' => [ 'stage!=' => $this->getLostStageList(), ['leadSource!=' => ''], ['leadSource!=' => null] ], 'orderBy' => 'LIST:leadSource:' . implode(',', $options), 'groupBy' => ['leadSource'] ]; if ($dateFilter !== 'ever') { $selectParams['whereClause'][] = [ 'closeDate>=' => $dateFrom, 'closeDate<' => $dateTo ]; } $selectManager->applyAccess($selectParams); $this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams); $sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams); $sth = $pdo->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(\PDO::FETCH_ASSOC); $result = array(); foreach ($rows as $row) { $result[$row['leadSource']] = floatval($row['amount']); } return $result; } public function reportByStage($dateFilter, $dateFrom = null, $dateTo = null) { if (in_array('amount', $this->getAcl()->getScopeForbiddenAttributeList('Opportunity'))) { throw new Forbidden(); } if ($dateFilter !== 'between' && $dateFilter !== 'ever') { list($dateFrom, $dateTo) = $this->getDateRangeByFilter($dateFilter); } $pdo = $this->getEntityManager()->getPDO(); $options = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.options', []); $selectManager = $this->getSelectManagerFactory()->create('Opportunity'); $selectParams = [ 'select' => ['stage', ['SUM:amountConverted', 'amount']], 'whereClause' => [ [ 'stage!=' => $this->getLostStageList() ], [ 'stage!=' => $this->getWonStageList() ] ], 'orderBy' => 'LIST:stage:' . implode(',', $options), 'groupBy' => ['stage'] ]; if ($dateFilter !== 'ever') { $selectParams['whereClause'][] = [ 'closeDate>=' => $dateFrom, 'closeDate<' => $dateTo ]; } $stageIgnoreList = array_merge($this->getLostStageList(), $this->getWonStageList()); $selectManager->applyAccess($selectParams); $this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams); $sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams); $sth = $pdo->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(\PDO::FETCH_ASSOC); $result = array(); foreach ($rows as $row) { if (in_array($row['stage'], $stageIgnoreList)) continue; $result[$row['stage']] = floatval($row['amount']); } return $result; } public function reportSalesByMonth($dateFilter, $dateFrom = null, $dateTo = null) { if (in_array('amount', $this->getAcl()->getScopeForbiddenAttributeList('Opportunity'))) { throw new Forbidden(); } if ($dateFilter !== 'between' && $dateFilter !== 'ever') { list($dateFrom, $dateTo) = $this->getDateRangeByFilter($dateFilter); } $pdo = $this->getEntityManager()->getPDO(); $selectManager = $this->getSelectManagerFactory()->create('Opportunity'); $selectParams = [ 'select' => [['MONTH:closeDate', 'month'], ['SUM:amountConverted', 'amount']], 'whereClause' => [ 'stage' => $this->getWonStageList() ], 'orderBy' => 1, 'groupBy' => ['MONTH:closeDate'] ]; if ($dateFilter !== 'ever') { $selectParams['whereClause'][] = [ 'closeDate>=' => $dateFrom, 'closeDate<' => $dateTo ]; } $selectManager->applyAccess($selectParams); $this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams); $sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams); $sth = $pdo->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(\PDO::FETCH_ASSOC); $result = array(); foreach ($rows as $row) { $result[$row['month']] = floatval($row['amount']); } $dt = new \DateTime($dateFrom); $dtTo = new \DateTime($dateTo); if (intval($dtTo->format('d')) !== 1) { $dtTo->setDate($dtTo->format('Y'), $dtTo->format('m'), 1); $dtTo->modify('+ 1 month'); } else { $dtTo->setDate($dtTo->format('Y'), $dtTo->format('m'), 1); } if ($dt && $dtTo) { $interval = new \DateInterval('P1M'); while ($dt->getTimestamp() <= $dtTo->getTimestamp()) { $month = $dt->format('Y-m'); if (!array_key_exists($month, $result)) { $result[$month] = 0; } $dt->add($interval); } } $keyList = array_keys($result); sort($keyList); $today = new \DateTime(); $endPosition = count($keyList) - 1; for ($i = count($keyList) - 1; $i >= 0; $i--) { $key = $keyList[$i]; $dt = new \DateTime($key . '-01'); if ($dt->getTimestamp() < $today->getTimestamp()) { break; } if (empty($result[$key])) { $endPosition = $i; } else { break; } } $keyList = array_slice($keyList, 0, $endPosition); return (object) [ 'keyList' => $keyList, 'dataMap' => $result ]; } protected function getDateRangeByFilter($dateFilter) { switch ($dateFilter) { case 'currentYear': $dt = new \DateTime(); return [ $dt->modify('first day of January this year')->format('Y-m-d'), $dt->add(new \DateInterval('P1Y'))->format('Y-m-d') ]; case 'currentQuarter': $dt = new \DateTime(); $quarter = ceil($dt->format('m') / 3); $dt->modify('first day of January this year'); return [ $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'), $dt->add(new \DateInterval('P3M'))->format('Y-m-d') ]; case 'currentMonth': $dt = new \DateTime(); return [ $dt->modify('first day of this month')->format('Y-m-d'), $dt->add(new \DateInterval('P1M'))->format('Y-m-d') ]; } return [0, 0]; } public function massConvertCurrency($field, $targetCurrency, $params, $baseCurrency, $rates) { $forbiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList($this->entityType, 'edit'); if (in_array($field, $forbiddenFieldList)) { throw new Forbidden(); } $count = 0; $idUpdatedList = []; $repository = $this->getRepository(); if (array_key_exists('where', $params)) { $where = $params['where']; $p = []; $p['where'] = $where; if (!empty($params['selectData']) && is_array($params['selectData'])) { foreach ($params['selectData'] as $k => $v) { $p[$k] = $v; } } $selectParams = $this->getSelectParams($p); } else if (array_key_exists('ids', $params)) { $selectParams = $this->getSelectParams([]); $selectParams['whereClause'][] = ['id' => $params['ids']]; } else { throw new Error(); } $collection = $repository->find($selectParams); $currencyAttribute = $field . 'Currency'; foreach ($collection as $entity) { if ($entity->get($field) === null) continue; $currentCurrency = $entity->get($currencyAttribute); $value = $entity->get($field); if ($currentCurrency === $targetCurrency) continue; if ($currentCurrency !== $baseCurrency && !property_exists($rates, $currentCurrency)) { continue; } $rate1 = property_exists($rates, $currentCurrency) ? $rates->$currentCurrency : 1.0; $value = $value * $rate1; $rate2 = property_exists($rates, $targetCurrency) ? $rates->$targetCurrency : 1.0; $value = $value / $rate2; if (!$rate2) continue; $value = round($value, 2); $data = []; $data[$currencyAttribute] = $targetCurrency; $data[$field] = $value; if ($this->getAcl()->check($entity, 'edit')) { $entity->set($data); if ($repository->save($entity)) { $idUpdatedList[] = $entity->id; $count++; $this->processActionHistoryRecord('update', $entity); } } } return array( 'count' => $count ); } protected function getLostStageList() { $lostStageList = []; $probabilityMap = $this->getMetadata()->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap'], []); $stageList = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.options', []); foreach ($stageList as $stage) { if (empty($probabilityMap[$stage])) { $lostStageList[] = $stage; } } return $lostStageList; } protected function getWonStageList() { $wonStageList = []; $probabilityMap = $this->getMetadata()->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap'], []); $stageList = $this->getMetadata()->get('entityDefs.Opportunity.fields.stage.options', []); foreach ($stageList as $stage) { if (!empty($probabilityMap[$stage]) && $probabilityMap[$stage] == 100) { $wonStageList[] = $stage; } } return $wonStageList; } public function getEmailAddressList($id) { $entity = $this->getEntity($id); $forbiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()); $list = []; $emailAddressList = []; if (!in_array('contacts', $forbiddenFieldList) && $this->getAcl()->checkScope('Contact')) { $contactIdList = $entity->getLinkMultipleIdList('contacts'); if (count($contactIdList)) { $contactForbiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList('Contact'); if (!in_array('emailAddress', $contactForbiddenFieldList)) { $selectManager = $this->getSelectManagerFactory()->create('Contact'); $selectParams = $selectManager->getEmptySelectParams(); $selectManager->applyAccess($selectParams); $contactList = $this->getEntityManager()->getRepository('Contact')->select(['id', 'emailAddress', 'name'])->where([ 'id' => $contactIdList ])->find($selectParams); foreach ($contactList as $contact) { $emailAddress = $contact->get('emailAddress'); if ($emailAddress && !in_array($emailAddress, $emailAddressList)) { $list[] = (object) [ 'emailAddress' => $emailAddress, 'name' => $contact->get('name'), 'entityType' => 'Contact' ]; $emailAddressList[] = $emailAddress; } } } } } if (empty($list)) { if (!in_array('account', $forbiddenFieldList) && $this->getAcl()->checkScope('Account')) { if ($entity->get('accountId')) { $account = $this->getEntityManager()->getEntity('Account', $entity->get('accountId')); if ($account && $account->get('emailAddress')) { $emailAddress = $account->get('emailAddress'); if ($this->getAcl()->checkEntity($account)) { $list[] = (object) [ 'emailAddress' => $emailAddress, 'name' => $account->get('name'), 'entityType' => 'Account' ]; $emailAddressList[] = $emailAddress; } } } } } return $list; } }