Your IP : 3.144.218.107
<?php
namespace Bitrix\Crm\Conversion;
use Bitrix\Main;
use Bitrix\Crm;
use Bitrix\Crm\Synchronization\UserFieldSynchronizer;
use Bitrix\Crm\Settings\ConversionSettings;
use Bitrix\Crm\EntityRequisite;
use Bitrix\Crm\Requisite\EntityLink;
use Bitrix\Crm\Binding\EntityBinding;
class QuoteConverter extends EntityConverter
{
/** @var array */
private static $maps = array();
/** @var QuoteConversionMapper|null */
private $mapper = null;
public function __construct(QuoteConversionConfig $config = null)
{
if($config === null)
{
$config = new QuoteConversionConfig();
}
parent::__construct($config);
}
/**
* Initialize converter.
* @return void
* @throws EntityConversionException If entity is not exist.
* @throws EntityConversionException If read or update permissions are denied.
*/
public function initialize()
{
if($this->currentPhase === QuoteConversionPhase::INTERMEDIATE)
{
$this->currentPhase = QuoteConversionPhase::DEAL_CREATION;
}
if(!\CCrmQuote::Exists($this->entityID))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Undefined,
EntityConversionException::TARG_SRC,
EntityConversionException::NOT_FOUND
);
}
/** @var \CCrmPerms $permissions */
$permissions = $this->getUserPermissions();
if(!\CCrmAuthorizationHelper::CheckReadPermission(\CCrmOwnerType::QuoteName, $this->entityID, $permissions))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Undefined,
EntityConversionException::TARG_SRC,
EntityConversionException::READ_DENIED
);
}
if(!\CCrmAuthorizationHelper::CheckUpdatePermission(\CCrmOwnerType::QuoteName, $this->entityID, $permissions))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Undefined,
EntityConversionException::TARG_SRC,
EntityConversionException::UPDATE_DENIED
);
}
}
/**
* Get converter entity type ID.
* @return int
*/
public function getEntityTypeID()
{
return \CCrmOwnerType::Quote;
}
/**
* Check if current phase is final.
* @return bool
*/
public function isFinished()
{
return QuoteConversionPhase::isFinal($this->currentPhase);
}
/**
* Get conversion mapper
* @return QuoteConversionMapper|null
*/
public function getMapper()
{
if($this->mapper === null)
{
$this->mapper = new QuoteConversionMapper($this->entityID);
}
return $this->mapper;
}
/**
* Get conversion map for for specified entity type.
* Try to load saved map. If map is not found then default map will be created.
* @param int $entityTypeID Entity Type ID.
* @return EntityConversionMap
*/
public static function getMap($entityTypeID)
{
return self::prepareMap($entityTypeID);
}
/**
* Map entity fields to specified type.
* @param int $entityTypeID Entity type ID.
* @param array|null $options Mapping options.
* @return array
*/
public function mapEntityFields($entityTypeID, array $options = null)
{
if(!is_array($options))
{
$options = array();
}
$options['INIT_DATA'] = $this->config->getEntityInitData($entityTypeID);
return $this->getMapper()->map($this->getMap($entityTypeID), $options);
}
/**
* Try to move converter to next phase
* @return bool
*/
public function moveToNextPhase()
{
switch($this->currentPhase)
{
case QuoteConversionPhase::INTERMEDIATE:
$this->currentPhase = QuoteConversionPhase::DEAL_CREATION;
return true;
break;
case QuoteConversionPhase::DEAL_CREATION:
$this->currentPhase = QuoteConversionPhase::INVOICE_CREATION;
return true;
break;
case QuoteConversionPhase::INVOICE_CREATION:
$this->currentPhase = QuoteConversionPhase::FINALIZATION;
return true;
break;
//case QuoteConversionPhase::FINALIZATION:
default:
return false;
}
}
/**
* Try to execute current conversion phase.
* @return bool
* @throws EntityConversionException If mapper return empty fields.
* @throws EntityConversionException If target entity is not found.
* @throws EntityConversionException If target entity fields are invalid.
* @throws EntityConversionException If target entity has bizproc workflows.
* @throws EntityConversionException If target entity creation is failed.
* @throws EntityConversionException If target entity update permission is denied.
*/
public function executePhase()
{
if($this->currentPhase === QuoteConversionPhase::DEAL_CREATION
|| $this->currentPhase === QuoteConversionPhase::INVOICE_CREATION)
{
Main\Localization\Loc::loadMessages(__FILE__);
if($this->currentPhase === QuoteConversionPhase::DEAL_CREATION)
{
$entityTypeID = \CCrmOwnerType::Deal;
}
else//if($this->currentPhase === QuoteConversionPhase::INVOICE_CREATION)
{
$entityTypeID = \CCrmOwnerType::Invoice;
}
$entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID);
$config = $this->config->getItem($entityTypeID);
if(!$config->isActive())
{
return false;
}
/** @var \CCrmPerms $permissions */
$permissions = $this->getUserPermissions();
$entityID = isset($this->contextData[$entityTypeName]) ? $this->contextData[$entityTypeName] : 0;
if($entityID > 0)
{
if($entityTypeID === \CCrmOwnerType::Deal)
{
if(!\CCrmDeal::Exists($entityID))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Deal,
EntityConversionException::TARG_DST,
EntityConversionException::NOT_FOUND
);
}
$entity = new \CCrmDeal(false);
$fields = array('QUOTE_ID' => $this->entityID);
$entity->Update($entityID, $fields, false, false);
$this->resultData[$entityTypeName] = $entityID;
}
else//if($entityTypeID === \CCrmOwnerType::Invoice)
{
if(!\CCrmInvoice::Exists($entityID))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Invoice,
EntityConversionException::TARG_DST,
EntityConversionException::NOT_FOUND
);
}
$entity = new \CCrmInvoice(false);
$fields = array('UF_QUOTE_ID' => $this->entityID);
try
{
$entity->Update($entityID, $fields);
}
catch(Main\DB\SqlQueryException $e)
{
}
$this->resultData[$entityTypeName] = $entityID;
}
return true;
}
if(!\CCrmAuthorizationHelper::CheckCreatePermission($entityTypeName , $permissions))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_DST,
EntityConversionException::CREATE_DENIED
);
}
if(UserFieldSynchronizer::needForSynchronization(\CCrmOwnerType::Quote, $entityTypeID))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_DST,
EntityConversionException::NOT_SYNCHRONIZED
);
}
if(!ConversionSettings::getCurrent()->isAutocreationEnabled())
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_DST,
EntityConversionException::AUTOCREATION_DISABLED
);
}
if($entityTypeID === \CCrmOwnerType::Deal
&& $this->isBizProcCheckEnabled()
&& \CCrmBizProcHelper::HasParameterizedAutoWorkflows($entityTypeID, \CCrmBizProcEventType::Create))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_DST,
EntityConversionException::HAS_WORKFLOWS
);
}
/** @var QuoteConversionMapper $mapper */
$mapper = $this->getMapper();
//We can't create deal from quote that created from deal
if($entityTypeID === \CCrmOwnerType::Deal
&& $mapper->getSourceFieldValue('DEAL_ID', 0) > 0)
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_SRC,
EntityConversionException::INVALID_OPERATION,
GetMessage('CRM_QUOTE_CONVERTER_DEAL_PROHIBITED')
);
}
$map = self::prepareMap($entityTypeID);
$fields = $mapper->map($map, array('INIT_DATA' => $config->getInitData()));
if(empty($fields))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
$entityTypeID,
EntityConversionException::TARG_DST,
EntityConversionException::EMPTY_FIELDS
);
}
//region Entity Creation Options
$entityCreationOptions = array();
if(isset($this->contextData['USER_ID']))
{
$entityCreationOptions['CURRENT_USER'] = $entityCreationOptions['USER_ID'] = $this->contextData['USER_ID'];
}
if(!$this->isUserFieldCheckEnabled())
{
$entityCreationOptions['DISABLE_USER_FIELD_CHECK'] = true;
}
//endregion
if($entityTypeID === \CCrmOwnerType::Deal)
{
$entity = new \CCrmDeal(false);
if(!$entity->CheckFields($fields, false, $entityCreationOptions))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Deal,
EntityConversionException::TARG_DST,
EntityConversionException::INVALID_FIELDS,
$entity->LAST_ERROR
);
}
$entityID = $entity->Add($fields, true, $entityCreationOptions);
if($entityID <= 0)
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Deal,
EntityConversionException::TARG_DST,
EntityConversionException::CREATE_FAILED,
$entity->LAST_ERROR
);
}
if(isset($fields['PRODUCT_ROWS'])
&& is_array($fields['PRODUCT_ROWS'])
&& !empty($fields['PRODUCT_ROWS']))
{
\CCrmDeal::SaveProductRows($entityID, $fields['PRODUCT_ROWS'], false, false, false);
}
// requisite link
$requisiteEntityList = array();
$mcRequisiteEntityList = array();
$requisite = new EntityRequisite();
if (isset($fields['QUOTE_ID']) && $fields['QUOTE_ID'] > 0)
{
$mcRequisiteEntityList[] = $requisiteEntityList[] =
array('ENTITY_TYPE_ID' => \CCrmOwnerType::Quote, 'ENTITY_ID' => $fields['QUOTE_ID']);
}
if (isset($fields['COMPANY_ID']) && $fields['COMPANY_ID'] > 0)
{
$requisiteEntityList[] = array('ENTITY_TYPE_ID' => \CCrmOwnerType::Company, 'ENTITY_ID' => $fields['COMPANY_ID']);
}
if (isset($fields['CONTACT_BINDINGS']) && is_array($fields['CONTACT_BINDINGS']))
{
$primaryContactID = EntityBinding::getPrimaryEntityID(
\CCrmOwnerType::Contact,
$fields['CONTACT_BINDINGS']
);
if($primaryContactID > 0)
{
$requisiteEntityList[] = array(
'ENTITY_TYPE_ID' => \CCrmOwnerType::Contact,
'ENTITY_ID' => $primaryContactID
);
}
}
if (isset($fields['MYCOMPANY_ID']) && $fields['MYCOMPANY_ID'] > 0)
$mcRequisiteEntityList[] = array('ENTITY_TYPE_ID' => \CCrmOwnerType::Company, 'ENTITY_ID' => $fields['MYCOMPANY_ID']);
$requisiteIdLinked = 0;
$bankDetailIdLinked = 0;
$mcRequisiteIdLinked = 0;
$mcBankDetailIdLinked = 0;
$requisiteInfoLinked = $requisite->getDefaultRequisiteInfoLinked($requisiteEntityList);
if (is_array($requisiteInfoLinked))
{
if (isset($requisiteInfoLinked['REQUISITE_ID']))
$requisiteIdLinked = (int)$requisiteInfoLinked['REQUISITE_ID'];
if (isset($requisiteInfoLinked['BANK_DETAIL_ID']))
$bankDetailIdLinked = (int)$requisiteInfoLinked['BANK_DETAIL_ID'];
}
$mcRequisiteInfoLinked = $requisite->getDefaultMyCompanyRequisiteInfoLinked($mcRequisiteEntityList);
if (is_array($mcRequisiteInfoLinked))
{
if (isset($mcRequisiteInfoLinked['MC_REQUISITE_ID']))
$mcRequisiteIdLinked = (int)$mcRequisiteInfoLinked['MC_REQUISITE_ID'];
if (isset($mcRequisiteInfoLinked['MC_BANK_DETAIL_ID']))
$mcBankDetailIdLinked = (int)$mcRequisiteInfoLinked['MC_BANK_DETAIL_ID'];
}
unset($requisite, $requisiteEntityList, $mcRequisiteEntityList, $requisiteInfoLinked, $mcRequisiteInfoLinked);
if ($requisiteIdLinked > 0 || $mcRequisiteIdLinked > 0)
{
EntityLink::register(
\CCrmOwnerType::Deal, $entityID,
$requisiteIdLinked, $bankDetailIdLinked,
$mcRequisiteIdLinked, $mcBankDetailIdLinked
);
}
unset($requisiteIdLinked, $bankDetailIdLinked, $mcRequisiteIdLinked, $mcBankDetailIdLinked);
//region BizProcess
$arErrors = array();
\CCrmBizProcHelper::AutoStartWorkflows(
\CCrmOwnerType::Deal,
$entityID,
\CCrmBizProcEventType::Create,
$arErrors
);
$starter = new Crm\Automation\Starter(\CCrmOwnerType::Deal, $entityID);
$starter->runOnAdd();
//endregion
$this->resultData[\CCrmOwnerType::DealName] = $entityID;
}
else//if($entityTypeID === \CCrmOwnerType::Invoice)
{
// requisite link 1 of 2
$requisiteEntityList = array();
$mcRequisiteEntityList = array();
$requisite = new EntityRequisite();
if (isset($fields['UF_QUOTE_ID']) && $fields['UF_QUOTE_ID'] > 0)
{
$mcRequisiteEntityList[] = $requisiteEntityList[] =
array('ENTITY_TYPE_ID' => \CCrmOwnerType::Quote, 'ENTITY_ID' => $fields['UF_QUOTE_ID']);
}
if (isset($fields['UF_DEAL_ID']) && $fields['UF_DEAL_ID'] > 0)
{
$mcRequisiteEntityList[] = $requisiteEntityList[] =
array('ENTITY_TYPE_ID' => \CCrmOwnerType::Deal, 'ENTITY_ID' => $fields['UF_DEAL_ID']);
}
if (isset($fields['UF_COMPANY_ID']) && $fields['UF_COMPANY_ID'] > 0)
$requisiteEntityList[] = array('ENTITY_TYPE_ID' => \CCrmOwnerType::Company, 'ENTITY_ID' => $fields['UF_COMPANY_ID']);
if (isset($fields['UF_CONTACT_ID']) && $fields['UF_CONTACT_ID'] > 0)
$requisiteEntityList[] = array('ENTITY_TYPE_ID' => \CCrmOwnerType::Contact, 'ENTITY_ID' => $fields['UF_CONTACT_ID']);
if (isset($fields['UF_MYCOMPANY_ID']) && $fields['UF_MYCOMPANY_ID'] > 0)
$mcRequisiteEntityList[] = array('ENTITY_TYPE_ID' => \CCrmOwnerType::Company, 'ENTITY_ID' => $fields['UF_MYCOMPANY_ID']);
$requisiteIdLinked = 0;
$bankDetailIdLinked = 0;
$mcRequisiteIdLinked = 0;
$mcBankDetailIdLinked = 0;
$requisiteInfoLinked = $requisite->getDefaultRequisiteInfoLinked($requisiteEntityList);
if (is_array($requisiteInfoLinked))
{
if (isset($requisiteInfoLinked['REQUISITE_ID']))
$requisiteIdLinked = (int)$requisiteInfoLinked['REQUISITE_ID'];
if (isset($requisiteInfoLinked['BANK_DETAIL_ID']))
$bankDetailIdLinked = (int)$requisiteInfoLinked['BANK_DETAIL_ID'];
}
$mcRequisiteInfoLinked = $requisite->getDefaultMyCompanyRequisiteInfoLinked($mcRequisiteEntityList);
if (is_array($mcRequisiteInfoLinked))
{
if (isset($mcRequisiteInfoLinked['MC_REQUISITE_ID']))
$mcRequisiteIdLinked = (int)$mcRequisiteInfoLinked['MC_REQUISITE_ID'];
if (isset($mcRequisiteInfoLinked['MC_BANK_DETAIL_ID']))
$mcBankDetailIdLinked = (int)$mcRequisiteInfoLinked['MC_BANK_DETAIL_ID'];
}
unset($requisite, $requisiteEntityList, $mcRequisiteEntityList, $requisiteInfoLinked, $mcRequisiteInfoLinked);
if (!isset($fields['UF_MYCOMPANY_ID']) || $fields['UF_MYCOMPANY_ID'] <= 0)
{
$defLink = EntityLink::getDefaultMyCompanyRequisiteLink();
if (is_array($defLink))
{
$fields['UF_MYCOMPANY_ID'] = isset($defLink['MYCOMPANY_ID']) ? (int)$defLink['MYCOMPANY_ID'] : 0;
$mcRequisiteIdLinked = isset($defLink['MC_REQUISITE_ID']) ? (int)$defLink['MC_REQUISITE_ID'] : 0;
$mcBankDetailIdLinked = isset($defLink['MC_BANK_DETAIL_ID']) ? (int)$defLink['MC_BANK_DETAIL_ID'] : 0;
}
unset($defLink);
}
$entity = new \CCrmInvoice(false);
$isSuccessful = \CCrmStatusInvoice::isStatusSuccess($fields['STATUS_ID']);
$isFailed = !$isSuccessful && \CCrmStatusInvoice::isStatusFailed($fields['STATUS_ID']);
if(!$entity->CheckFields($fields, false, $isSuccessful, $isFailed, $entityCreationOptions))
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Invoice,
EntityConversionException::TARG_DST,
EntityConversionException::INVALID_FIELDS,
$entity->LAST_ERROR
);
}
$recalculated = false;
$entityID = $entity->Add($fields, $recalculated, SITE_ID, $entityCreationOptions);
if($entityID <= 0)
{
throw new EntityConversionException(
\CCrmOwnerType::Quote,
\CCrmOwnerType::Invoice,
EntityConversionException::TARG_DST,
EntityConversionException::CREATE_FAILED,
$entity->LAST_ERROR
);
}
// requisite link 2 of 2
if ($requisiteIdLinked > 0 || $mcRequisiteIdLinked > 0)
{
EntityLink::register(
\CCrmOwnerType::Invoice, $entityID,
$requisiteIdLinked, $bankDetailIdLinked,
$mcRequisiteIdLinked, $mcBankDetailIdLinked
);
}
unset($requisiteIdLinked, $bankDetailIdLinked, $mcRequisiteIdLinked, $mcBankDetailIdLinked);
$this->resultData[\CCrmOwnerType::InvoiceName] = $entityID;
}
return true;
}
elseif($this->currentPhase === QuoteConversionPhase::FINALIZATION)
{
$this->onFinalizationPhase();
//Do not update DEAL_ID field here. This field is used, then quote is created from deal.
return true;
}
return false;
}
/**
* Preparation of conversion map for specified entity type.
* Try to load saved map. If map is not found then default map will be created.
* @param int $entityTypeID Entity Type ID.
* @return EntityConversionMap
*/
protected static function prepareMap($entityTypeID)
{
if(isset(self::$maps[$entityTypeID]))
{
return self::$maps[$entityTypeID];
}
$map = EntityConversionMap::load(\CCrmOwnerType::Quote, $entityTypeID);
if($map === null)
{
$map = QuoteConversionMapper::createMap($entityTypeID);
$map->save();
}
elseif($map->isOutOfDate())
{
QuoteConversionMapper::updateMap($map);
$map->save();
}
return (self::$maps[$entityTypeID] = $map);
}
/**
* Get Supported Destination Types.
* @return array
*/
public function getSupportedDestinationTypeIDs()
{
return array(\CCrmOwnerType::Deal, \CCrmOwnerType::Invoice);
}
}