本周,SuiteCRM 的首席 SuiteCRM 开发人员 Clemente Raposo 将带您了解如何在 SuiteCRM 8 中向模块添加自定义批量操作。
批量操作配置允许您将操作添加到列表视图的批量操作下拉菜单中。除了指定标签和操作处理程序之外,SuiteCRM 开发此配置还内置了应对其他几种情况的支持:设置最小和/或最大记录选择限制、打开记录面板以进行额外输入、在运行操作之前显示记录选择模式、在执行之前显示确认模式、在操作后重定向到新视图以及在完成后刷新当前列表视图。
在今天的示例中,我们将演示如何添加批量操作以打开记录面板以进行其他输入。我们将使用一个示例,将“动态重命名”操作引入商机模块列表视图中的批量操作菜单。
对于那些渴望开始的人,你可以从下面的视频中找到代码示例:
<?php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
return static function (ContainerBuilder $container): void {
// 1. Retrieve the actions for opportunities from the symfony container parameters
$actions = $container->getParameter('module.listview.bulk_action') ?? [];
$modules = $actions['modules'] ?? [];
$opportunities = $modules['opportunities'] ?? [];
$bulkActions = $opportunities['actions'] ?? [];
// 2. Add the dynamic rename action definition
$bulkActions['opportunity-dynamic-rename'] = [
'key' => 'opportunity-dynamic-rename',
'labelKey' => 'LBL_DYNAMIC_RENAME', // New label, defined in public/legacy/custom/Extension/application/Ext/Language
'asyncProcess' => 'true',
'modes' => ['list', 'detail', 'edit'],
'acl' => ['view', 'edit'],
'params' => [
'allowAll' => false,
'min' => 2,
'max' => 10,
'recordPanel' => [
'title' => 'LBL_DYNAMIC_RENAME',
'fields' => [
[
"name" => "prefix",
"label" => "LBL_PREFIX",
"fieldDefinition" => [
"name" => "prefix",
"vname" => "LBL_PREFIX",
"type" => "varchar",
"len" => "255",
],
"type" => "varchar",
]
],
'mode' => 'massupdate',
'actions' => [
[
'key' => 'cancel',
'labelKey' => 'LBL_CANCEL',
'modes' => ['massupdate']
],
[
'key' => 'bulk-action',
'labelKey' => 'LBL_SUBMIT_BUTTON_LABEL',
'modes' => ['massupdate'],
'klass' => ['btn', 'btn-danger', 'btn-sm'],
'params' => [
'allowAll' => false,
'min' => 2,
'max' => 10,
'bulkAction' => 'opportunity-dynamic-rename',
'displayConfirmation' => true,
'confirmationLabel' => 'LBL_BULK_ACTION_MASS_UPDATE_CONFIRMATION'
]
]
]
]
]
];
// 3. Add back to the symfony container parameters
$opportunities['actions'] = $bulkActions;
$modules['opportunities'] = $opportunities;
$actions['modules'] = $modules;
$container->setParameter('module.listview.bulk_action', $actions);
};
extensions/defaultExt/config/modules/Opportunities/listview/actions/dynamic-rename.php
<?php
namespace App\Extension\defaultExt\modules\Opportunities\Process\Service\BulkActions;
use ApiPlatform\Core\Exception\InvalidArgumentException;
use App\Engine\LegacyHandler\LegacyHandler;
use App\Process\Entity\Process;
use App\Process\Service\ProcessHandlerInterface;
use Exception;
class DynamicRenameBulkAction extends LegacyHandler implements ProcessHandlerInterface
{
protected const MSG_OPTIONS_NOT_FOUND = 'Process options is not defined';
protected const PROCESS_TYPE = 'bulk-opportunity-dynamic-rename';
/**
* @inheritDoc
*/
public function getProcessType(): string
{
return self::PROCESS_TYPE;
}
/**
* @inheritDoc
*/
public function getHandlerKey(): string
{
return $this->getProcessType();
}
/**
* @inheritDoc
*/
public function requiredAuthRole(): string
{
return 'ROLE_USER';
}
/**
* @inheritDoc
*/
public function getRequiredACLs(Process $process): array
{
$options = $process->getOptions();
$module = $options['module'] ?? '';
$ids = $options['ids'] ?? [];
return [
$module => [
[
'action' => 'edit',
'ids' => $ids
],
],
];
}
/**
* @inheritDoc
*/
public function configure(Process $process): void
{
//This process is synchronous
//We aren't going to store a record on db
//thus we will use process type as the id
$process->setId(self::PROCESS_TYPE);
$process->setAsync(false);
}
/**
* @inheritDoc
*/
public function validate(Process $process): void
{
if (empty($process->getOptions())) {
throw new InvalidArgumentException(self::MSG_OPTIONS_NOT_FOUND);
}
$options = $process->getOptions();
if (empty($options['module']) || empty($options['action'])) {
throw new InvalidArgumentException(self::MSG_OPTIONS_NOT_FOUND);
}
}
/**
* @inheritDoc
*/
public function run(Process $process)
{
$options = $process->getOptions();
$attributes = $options['payload']['panelRecord']['attributes'] ?? [];
if (empty($attributes)) {
$process->setStatus('error');
$process->setMessages(['LBL_BULK_ACTION_MASS_UPDATE_NO_FIELDS']);
return;
}
$result = $this->renameRecords($process);
$responseData = [
'reload' => true,
'dataUpdated' => true,
'reloadGlobalRecentlyViewed' => true,
'reloadRecentlyViewed' => true,
'reloadFavorites' => true
];
$process->setData($responseData);
$process->setStatus('success');
$process->setMessages($result['messages'] ?? ['LBL_BULK_ACTION_MASS_UPDATE_SUCCESS']);
if (!$result) {
$process->setStatus('error');
$process->setMessages(['LBL_ACTION_ERROR']);
}
$process->setData($responseData);
}
/**
* @param Process $process
* @return array
*/
protected function renameRecords(Process $process): array
{
$this->init();
$options = $process->getOptions();
$attributes = $options['payload']['panelRecord']['attributes'] ?? [];
/* MORE OPTIONS - Handle when criteria is sent
if (is_array($options['criteria'])) {
$criteria = $options['criteria'];
$sort = $options['sort'] ?? [];
}
*/
$notFound = [];
$failed = [];
$prefix = $attributes['prefix'];
$count = count($options['ids']);
if (is_array($options['ids']) && $count) {
foreach ($options['ids'] as $id) {
/** @var \Opportunity $opportunity */
$opportunity = \BeanFactory::getBean('Opportunities', $id);
if (empty($opportunity)) {
$notFound[] = $id;
continue;
}
try {
$opportunity->name = $prefix . $opportunity->name;
$opportunity->save();
} catch (Exception $e) {
$failed[] = $id;
}
}
}
$totalFailed = count($failed) + count($notFound);
$this->close();
if ($count === $totalFailed) {
return [
'success' => false,
'messages' => ['LBL_BULK_ACTION_MASS_UPDATE_NO_RECORDS']
];
}
if ($totalFailed > 0) {
return [
'success' => true,
'messages' => ['LBL_BULK_ACTION_MASS_UPDATE_NO_RECORDS']
];
}
return [
'success' => true,
'messages' => ['LBL_BULK_ACTION_MASS_UPDATE_SUCCESS']
];
}
}
extensions/defaultExt/modules/Opportunities/Process/Service/BulkActions/DynamicRenameBulkAction.php
<?php
$app_strings['LBL_RENAME'] = 'Rename';
$app_strings['LBL_DYNAMIC_RENAME'] = 'Dynamic Rename';
$app_strings['LBL_PREFIX'] = 'Prefix';
public/legacy/custom/Extension/application/Ext/Language/en_us.dynamic_rename.php
以上内容可作为如何在 SuiteCRM 8 中向模块添加批量操作的示例。
如果您正在寻找更多开发见解,SalesAgility 的开发团队已创建了由讲师指导的大师班。专为开发人员设计,涵盖 SuiteCRM 8.x 和 SuiteCRM 7.x,请前往大师班了解更多信息。
关于SuiteCRM
SuiteCRM 是全球最受欢迎的 CRM 应用程序之一。我们功能丰富的企业级 Salesforce 替代方案可让您的销售团队更智能地销售、营销和服务。以大幅降低的成本提供 CRM 的所有优势,同时享受开源的自由和灵活性。
您可以在自己的服务器、公有云/私有云中下载并托管 SuiteCRM,或者试用我们的 SAAS 产品SuiteCRM Hosted。这是终极自由,让您完全掌控业务数据。在此免费试用 SuiteCRM 。
帮助支持 SuiteCRM 项目!