opportunity probability allow empty

This commit is contained in:
Yuri Kuznetsov
2025-02-24 13:43:08 +02:00
parent 75e5701a3b
commit 8350bebb50
9 changed files with 89 additions and 55 deletions
@@ -34,22 +34,16 @@ use Espo\Core\MassAction\Params;
use Espo\Core\MassAction\Result;
use Espo\Core\MassAction\Data;
use Espo\Core\MassAction\MassAction;
use Espo\Tools\MassUpdate\Data as MassUpdateData;
use Espo\Core\Utils\Metadata;
class MassUpdate implements MassAction
{
private MassUpdateOriginal $massUpdateOriginal;
private Metadata $metadata;
public function __construct(MassUpdateOriginal $massUpdateOriginal, Metadata $metadata)
{
$this->massUpdateOriginal = $massUpdateOriginal;
$this->metadata = $metadata;
}
public function __construct(
private MassUpdateOriginal $massUpdateOriginal,
private Metadata $metadata
) {}
public function process(Params $params, Data $data): Result
{
@@ -60,8 +54,7 @@ class MassUpdate implements MassAction
$stage = $massUpdateData->getValue('stage');
if ($stage && !$massUpdateData->has('probability')) {
$probability = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap', $stage]);
$probability = $this->metadata->get("entityDefs.Opportunity.fields.stage.probabilityMap.$stage");
}
if ($probability !== null) {
@@ -56,7 +56,11 @@ class BeforeUpdate implements SaveHook
$stage = $entity->getStage();
$probability = $this->metadata->get("entityDefs.Opportunity.fields.stage.probabilityMap.$stage") ?? 0;
$probability = $this->metadata->get("entityDefs.Opportunity.fields.stage.probabilityMap.$stage");
if ($probability === null) {
return;
}
$entity->setProbability($probability);
}
@@ -33,13 +33,13 @@ use Espo\Core\Select\Primary\Filter;
use Espo\ORM\Query\SelectBuilder;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListPoriver;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListProvider;
class Lost implements Filter
{
private $stageListPoriver;
public function __construct(StageListPoriver $stageListPoriver)
public function __construct(StageListProvider $stageListPoriver)
{
$this->stageListPoriver = $stageListPoriver;
}
@@ -33,13 +33,13 @@ use Espo\Core\Select\Primary\Filter;
use Espo\ORM\Query\SelectBuilder;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListPoriver;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListProvider;
class Open implements Filter
{
private $stageListPoriver;
public function __construct(StageListPoriver $stageListPoriver)
public function __construct(StageListProvider $stageListPoriver)
{
$this->stageListPoriver = $stageListPoriver;
}
@@ -33,13 +33,13 @@ use Espo\Core\Select\Primary\Filter;
use Espo\ORM\Query\SelectBuilder;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListPoriver;
use Espo\Modules\Crm\Classes\Select\Opportunity\Utils\StageListProvider;
class Won implements Filter
{
private $stageListPoriver;
public function __construct(StageListPoriver $stageListPoriver)
public function __construct(StageListProvider $stageListPoriver)
{
$this->stageListPoriver = $stageListPoriver;
}
@@ -31,34 +31,29 @@ namespace Espo\Modules\Crm\Classes\Select\Opportunity\Utils;
use Espo\Core\Utils\Metadata;
class StageListPoriver
class StageListProvider
{
private $metadata;
public function __construct(Metadata $metadata)
{
$this->metadata = $metadata;
}
public function __construct(private Metadata $metadata)
{}
/**
* @return string[]
*/
public function getLost(): array
{
$lostStageList = [];
$output = [];
$probabilityMap = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap']) ?? [];
$probabilityMap = $this->getProbabilityMap();
$stageList = $this->metadata->get('entityDefs.Opportunity.fields.stage.options') ?? [];
foreach ($this->getStageList() as $stage) {
$value = $probabilityMap[$stage] ?? null;
foreach ($stageList as $stage) {
if (empty($probabilityMap[$stage])) {
$lostStageList[] = $stage;
if ($value === 0 || $value === 0.0) {
$output[] = $stage;
}
}
return $lostStageList;
return $output;
}
/**
@@ -66,19 +61,37 @@ class StageListPoriver
*/
public function getWon(): array
{
$wonStageList = [];
$output = [];
$probabilityMap = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap']) ?? [];
$probabilityMap = $this->getProbabilityMap();
$stageList = $this->metadata->get('entityDefs.Opportunity.fields.stage.options') ?? [];
foreach ($this->getStageList() as $stage) {
$value = $probabilityMap[$stage] ?? null;
foreach ($stageList as $stage) {
if (!empty($probabilityMap[$stage]) && $probabilityMap[$stage] == 100) {
$wonStageList[] = $stage;
if ($value == 100) {
$output[] = $stage;
}
}
return $wonStageList;
return $output;
}
/**
* @return array<string, ?int>
*/
private function getProbabilityMap(): array
{
/** @var array<string, ?int> $probabilityMap */
$probabilityMap = $this->metadata->get('entityDefs.Opportunity.fields.stage.probabilityMap') ?? [];
return $probabilityMap;
}
/**
* @return string[]
*/
private function getStageList(): array
{
return $this->metadata->get('entityDefs.Opportunity.fields.stage.options') ?? [];
}
}
@@ -107,6 +107,11 @@ class Opportunity extends Entity
return $this->get('lastStage');
}
public function setLastStage(?string $lastStage): void
{
$this->set('lastStage', $lastStage);
}
public function getProbability(): ?int
{
return $this->get('probability');
@@ -56,19 +56,20 @@ class LastStage implements BeforeSave
return;
}
$probability = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap', $entity->getStage() ?? '']) ?? 0;
$stage = $entity->getStage();
if ($probability) {
$entity->set('lastStage', $entity->getStage());
$probability = $this->metadata->get("entityDefs.Opportunity.fields.stage.probabilityMap.$stage");
if ($probability !== 0) {
$entity->setLastStage($entity->getStage());
return;
}
$probabilityMap = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap']) ?? [];
// Lost.
$stageList = $this->metadata->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'options']) ?? [];
$probabilityMap = $this->getProbabilityMap();
$stageList = $this->getStageList();
if (!count($stageList)) {
return;
@@ -85,7 +86,7 @@ class LastStage implements BeforeSave
if (
$itemProbability === null ||
$itemProbability === 100 ||
$itemProbability == 100 ||
$itemProbability === 0 ||
$itemProbability >= $min
) {
@@ -100,7 +101,7 @@ class LastStage implements BeforeSave
return;
}
$entity->set('lastStage', $minStage);
$entity->setLastStage($minStage);
return;
}
@@ -111,8 +112,7 @@ class LastStage implements BeforeSave
return;
}
$lastStageProbability = $this->metadata
->get(['entityDefs', 'Opportunity', 'fields', 'stage', 'probabilityMap', $entity->getLastStage()]) ?? 0;
$lastStageProbability = $probabilityMap[$entity->getLastStage()] ?? null;
if ($lastStageProbability !== 100) {
return;
@@ -141,6 +141,25 @@ class LastStage implements BeforeSave
return;
}
$entity->set('lastStage', $maxStage);
$entity->setLastStage($maxStage);
}
/**
* @return array<string, ?int>
*/
private function getProbabilityMap(): array
{
/** @var array<string, ?int> $probabilityMap */
$probabilityMap = $this->metadata->get('entityDefs.Opportunity.fields.stage.probabilityMap') ?? [];
return $probabilityMap;
}
/**
* @return string[]
*/
private function getStageList(): array
{
return $this->metadata->get('entityDefs.Opportunity.fields.stage.options') ?? [];
}
}
@@ -53,7 +53,7 @@ class Probability implements BeforeSave
return;
}
if ($entity->get('probability') !== null) {
if ($entity->getProbability() !== null) {
return;
}