I am encountering the following error when trying to save a Custom Entity:
EspoCRM Version: 8.1.1
PHP Version: PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS)
STEPS TO REPRODUCE
My Custom Entity inside a custom Module is Defined as follows.
File: custom/Espo/Modules/Natera/Resources/metadata/entityDefs/NateraJob.json
File: custom/Espo/Modules/Natera/Entities/NateraJob.php
When I try to update an Entity I get the above error.
For testing to recreate the error, I created code as follows inside a CLI job:
Output from code:
Code:
Espo\Core\FieldProcessing\NextNumber\BeforeSaveProcessor::process(): Argument #1 ($entity) must be of type Espo\Core\ORM\Entity, Espo\Modules\Natera\Entities\NateraJob given, called in /App/application/Espo/Hooks/Common/NextNumber.php on line 51
EspoCRM Version: 8.1.1
PHP Version: PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS)
STEPS TO REPRODUCE
My Custom Entity inside a custom Module is Defined as follows.
File: custom/Espo/Modules/Natera/Resources/metadata/entityDefs/NateraJob.json
PHP Code:
{
"fields": {
"jobId": {
"label": "Natera Job ID",
"type": "varchar",
"length": 12,
"required": true,
"readOnlyAfterCreate": true
},
"assignmentId": {
"label": "Assignment",
"type": "varchar",
"length": 17,
"required": false
},
"technicianId": {
"label": "Natera Technician ID",
"type": "varchar",
"length": 12,
"required": true
},
"status": {
"label": "Job Status",
"type": "enum",
"required": true,
"default": "available",
"options": [
"available",
"published",
"assigned",
"scheduled",
"on_the_way",
"on_site",
"in_progress",
"completed",
"cancelled",
"error"
]
},
"mpxData": {
"type": "text",
"required": true,
"isEncrypted": true
},
"mpxLog": {
"type": "text",
"required": true
},
"createdAt": {
"type": "datetime",
"readOnly": true
},
"modifiedAt": {
"type": "datetime",
"readOnly": true
},
"address": {
"type": "address",
"notStorable": true,
"utility": true
}
},
"indexes": {
"natera_id": {
"columns": ["jobId"],
"unique": true
},
"entity_id": {
"columns": ["assignmentId"]
},
"by_status": {
"columns": [
"status",
"createdAt"
]
}
},
"collection": {
"orderBy": "createdAt",
"order": "asc",
"textFilterFields": [
"status"
]
}
}
PHP Code:
namespace Espo\Modules\Natera\Entities;
use Espo\ORM\BaseEntity;
use Espo\ORM\EntityManager;
use Espo\ORM\Value\ValueAccessorFactory;
use Espo\Core\Utils\Crypt;
class NateraJob extends BaseEntity
{
private $isEncrypted;
public function __construct(
string $entityType,
array $defs,
?EntityManager $entityManager = null,
?ValueAccessorFactory $valueAccessorFactory = null,
private Crypt $crypt,
) {
parent::__construct(
$entityType,
$defs,
$entityManager,
$valueAccessorFactory
);
$this->isEncrypted = [];
foreach ($defs['fields'] as $field => $value) {
if (array_key_exists('isEncrypted', $value) && $value['isEncrypted']) {
$this->isEncrypted[] = $field;
}
}
}
protected function setInContainer(string $attribute, $value): void
{
if (in_array($attribute, $this->isEncrypted)) {
$value = $this->crypt->encrypt($value);
}
parent::setInContainer($attribute, $value);
return;
}
public function setFetched(string $attribute, $value): void
{
if (in_array($attribute, $this->isEncrypted)) {
$value = $this->crypt->decrypt($value);
parent::setInContainer($attribute, $value);
}
parent::setFetched($attribute, $value);
}
protected function getFromContainer(string $attribute)
{
$value = parent::getFromContainer($attribute);
if (in_array($attribute, $this->isEncrypted)) {
return $this->crypt->decrypt($value);
}
return $value;
}
public function getFetched(string $attribute)
{
$value = parent::getFetched($attribute);
if (in_array($attribute, $this->isEncrypted) && !is_null($value)) {
$value = $this->crypt->decrypt($value);
}
return $value;
}
}
For testing to recreate the error, I created code as follows inside a CLI job:
PHP Code:
try {
$em = $this->container->get('entityManager');
$entity = $em->getEntityById('NateraJob', '65e26caac9c5d60f9');
print_r($entity->getValueMap());
$entity->set('assignmentId', '65a0d16b7f222e498');
$em->saveEntity($entity, ['SKIP_NATERA' => true]);
} catch (\Throwable $error) {
echo $error->getMessage();
echo "\n";
echo $error->getTraceAsString();
}
Code:
stdClass Object ( [id] => 65e26caac9c5d60f9 [deleted] => [jobId] => h9c74fg2 [assignmentId] => [technicianId] => wosv2mwl [status] => scheduled [mpxData] => {"id":"h9c74fg2",/** removed private data **/} [mpxLog] => [{"at":"2024-01-12 19:33:19","type":"EVENT","message":"Complete Job Data Updated"},{"at":"2024-01-17 17:55:25","type":"EVENT","message":"Job Status changed to ASSIGNED"},{"at":"2024-01-17 17:55:25","type":"EVENT","message":"Job assignee changed"},{"at":"2024-01-17 17:55:25","type":"EVENT","message":"Complete Job Data Updated"},{"at":"2024-01-31 15:58:42","type":"EVENT","message":"Job Status changed to SCHEDULED"},{"at":"2024-01-31 15:58:42","type":"EVENT","message":"Job startTime changed"},{"at":"2024-03-02 00:02:50","type":"EVENT","message":"Job Migrated"}] [createdAt] => 2024-03-02 00:02:50 [modifiedAt] => 2024-03-02 00:02:50 ) Espo\Core\FieldProcessing\NextNumber\BeforeSaveProcessor::process(): Argument #1 ($entity) must be of type Espo\Core\ORM\Entity, Espo\Modules\Natera\Entities\NateraJob given, called in /App/application/Espo/Hooks/Common/NextNumber.php on line 51 #0 /App/application/Espo/Hooks/Common/NextNumber.php(51): Espo\Core\FieldProcessing\NextNumber\BeforeSaveProcessor->process() #1 /App/application/Espo/Core/Hook/GeneralInvoker.php(186): Espo\Hooks\Common\NextNumber->beforeSave() #2 /App/application/Espo/Core/HookManager.php(118): Espo\Core\Hook\GeneralInvoker->invoke() #3 /App/application/Espo/Core/Repositories/Database.php(298): Espo\Core\HookManager->process() #4 /App/application/Espo/ORM/Repository/RDBRepository.php(139): Espo\Core\Repositories\Database->beforeSave() #5 /App/application/Espo/Core/Repositories/Database.php(136): Espo\ORM\Repository\RDBRepository->save() #6 /App/application/Espo/ORM/EntityManager.php(244): Espo\Core\Repositories\Database->save() #7 /App/custom/Espo/Modules/Natera/Services/Utils/Tasks/Task/Test.php(25): Espo\ORM\EntityManager->saveEntity() #8 /App/custom/Espo/Modules/Natera/Services/Utils/Tasks/TaskManager.php(49): Espo\Modules\Natera\Services\Utils\Tasks\Task\Test->execute() #9 /App/application/Espo/Core/Job/JobRunner.php(233): Espo\Modules\Natera\Services\Utils\Tasks\TaskManager->run() #10 /App/application/Espo/Core/Job/JobRunner.php(194): Espo\Core\Job\JobRunner->runJob() #11 /App/application/Espo/Core/Job/JobRunner.php(123): Espo\Core\Job\JobRunner->runJobNamed() #12 /App/application/Espo/Core/Job/JobRunner.php(77): Espo\Core\Job\JobRunner->runInternal() #13 /App/application/Espo/Core/Job/JobManager.php(145): Espo\Core\Job\JobRunner->runThrowingException() #14 /App/application/Espo/Core/Console/Commands/RunJob.php(92): Espo\Core\Job\JobManager->runJob() #15 /App/application/Espo/Core/Console/CommandManager.php(95): Espo\Core\Console\Commands\RunJob->run() #16 /App/application/Espo/Core/ApplicationRunners/Command.php(51): Espo\Core\Console\CommandManager->run() #17 /App/application/Espo/Core/Application/RunnerRunner.php(84): Espo\Core\ApplicationRunners\Command->run() #18 /App/application/Espo/Core/Application.php(78): Espo\Core\Application\RunnerRunner->run() #19 /App/command.php(35): Espo\Core\Application->run() #20 /App/bin/command(4): include('...') #21 {main}
Comment